index.vue 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. <template>
  2. <StatisticsTemplate
  3. title="产品统计"
  4. :list="state.modelCount"
  5. />
  6. <a-card style="margin-top: 20px;" >
  7. <a-row justify="space-between" >
  8. <a-col>
  9. <a-input-search
  10. allowClear
  11. v-model:value="state.queryParams.modelLabel"
  12. placeholder="请输入产品模型名称"
  13. enter-button
  14. @search="getModel"
  15. />
  16. </a-col>
  17. <a-col>
  18. <a-space>
  19. <a-button type="primary" @click="openModel('add')" >
  20. 新增
  21. <template #icon>
  22. <plus-outlined />
  23. </template>
  24. </a-button>
  25. </a-space>
  26. </a-col>
  27. </a-row>
  28. <a-table
  29. style="margin-top: 10px;"
  30. :columns="columns"
  31. :dataSource="state.dataSource"
  32. :pagination="state.queryParams"
  33. :loading="state.loading"
  34. @change="change"
  35. >
  36. <template #name="{ text }">
  37. <a @click="goDetailPage(text)" >{{ text }}</a>
  38. </template>
  39. <template #bodyCell="{ column, record }">
  40. <template v-if="column.key === 'id'" >
  41. <a @click="goDetailPage(record.id)">{{record.id}}</a>
  42. </template>
  43. <template v-if="column.key === 'transportType'" >
  44. <a-tag >{{record.transportType}}</a-tag>
  45. </template>
  46. <template v-if="column.key === 'payloadType'" >
  47. <a-tag color="blue">{{record.payloadType}}</a-tag>
  48. </template>
  49. <template v-if="column.key === 'action'">
  50. <a-space>
  51. <a @click="goDetailPage(record.id)" >查看</a>
  52. <a @click="goDevicePage(record.id)">管理</a>
  53. <a-popconfirm
  54. title="确实要删除吗?"
  55. ok-text="确定"
  56. cancel-text="取消"
  57. @confirm="confirmDel(record.id)"
  58. >
  59. <a href="#">删除</a>
  60. </a-popconfirm>
  61. </a-space>
  62. </template>
  63. </template>
  64. </a-table>
  65. </a-card>
  66. <a-modal
  67. :title="modalTitle"
  68. :open="state.visible"
  69. ok-text="确定"
  70. cancel-text="取消"
  71. @cancel="closeModel"
  72. @ok="ok"
  73. destroyOnClose
  74. >
  75. <a-form :hideRequiredMark="formOptions.hideRequiredMark" :label-col="{span: 4}" :wrapper-col="{span: 14}">
  76. <a-form-item v-bind="validateInfos.modelTemplateId">
  77. <template v-slot:label >
  78. <a-tooltip>
  79. <template #title>选择了模型库后不需要再填写产品数据</template>
  80. <question-circle-outlined /> 模型库
  81. </a-tooltip>
  82. </template>
  83. <a-select allowClear v-model:value="modelRef.modelTemplateId" >
  84. <a-select-option
  85. :value="item.id"
  86. v-for="item in state.modelTemplateList"
  87. :key="item.id"
  88. >{{item.templateLabel}}
  89. </a-select-option>
  90. </a-select>
  91. </a-form-item>
  92. <a-form-item label="模型名称" v-bind="validateInfos.modelLabel">
  93. <a-input allowClear :disabled="formOptions.disabled" v-model:value="modelRef.modelLabel" />
  94. </a-form-item>
  95. <a-form-item label="协议类型" v-bind="validateInfos.transportType">
  96. <a-select allowClear :disabled="formOptions.disabled" v-model:value="modelRef.transportType" >
  97. <a-select-option :value="item.port" v-for="item in state.transport" :key="item.port" >{{item.port}}</a-select-option>
  98. </a-select>
  99. </a-form-item>
  100. <a-form-item label="数据格式" v-bind="validateInfos.payloadType">
  101. <a-select allowClear :disabled="formOptions.disabled" v-model:value="modelRef.payloadType" >
  102. <a-select-option :value="item.value" v-for="item in payloadTypeList" :key="item.value" >{{item.label}}</a-select-option>
  103. </a-select>
  104. </a-form-item>
  105. <a-form-item label="设备类型" >
  106. <a-input allowClear :disabled="formOptions.disabled" v-model:value="modelRef.deviceType" />
  107. </a-form-item>
  108. <a-form-item label="厂商描述">
  109. <a-textarea :disabled="formOptions.disabled" v-model:value="modelRef.modelDescription" />
  110. </a-form-item>
  111. <!-- <a-form-item label="支持视频流">
  112. <a-switch v-model:checked="modelRef.rts" checked-children="支持" un-checked-children="不支持" />
  113. </a-form-item> -->
  114. </a-form>
  115. </a-modal>
  116. </template>
  117. <script lang="ts" setup >
  118. import { CommonController, ModelController } from '@/controller/index'
  119. import { onMounted, reactive, watch } from 'vue'
  120. import { computed } from '@vue/reactivity'
  121. import { Form, TableColumnProps } from 'ant-design-vue'
  122. import { useRouter } from 'vue-router'
  123. import StatisticsTemplate from '@/components/StatisticsTemplate/index.vue'
  124. import { QuestionCircleOutlined } from '@ant-design/icons-vue'
  125. // question-circle-outlined
  126. const columns: TableColumnProps[] = [
  127. {
  128. title: '产品模型名称',
  129. dataIndex: 'modelLabel',
  130. key: 'modelLabel'
  131. },
  132. {
  133. title: '产品模型id',
  134. dataIndex: 'id',
  135. key: 'id'
  136. },
  137. {
  138. title: '传输协议',
  139. dataIndex: 'transportType',
  140. key: 'transportType'
  141. },
  142. {
  143. title: '数据格式',
  144. dataIndex: 'payloadType',
  145. key: 'payloadType'
  146. },
  147. {
  148. title: '设备类型',
  149. dataIndex: 'deviceType',
  150. key: 'deviceType'
  151. },
  152. {
  153. title: '模型描述',
  154. dataIndex: 'modelDescription',
  155. key: 'modelDescription'
  156. },
  157. {
  158. title: '操作',
  159. key: 'action'
  160. }
  161. ]
  162. const payloadTypeList = [
  163. {
  164. value: 'JSON',
  165. label: 'JSON'
  166. },
  167. {
  168. value: 'BINARY',
  169. label: '二进制流'
  170. }
  171. ]
  172. const state = reactive<{
  173. dataSource: IOT.API.MODEL.ModelDot[],
  174. modelTemplateList: IOT.API.MODELTEMPLATE.modelTemplate[]
  175. [key: string]: any
  176. }>({
  177. loading: false,
  178. opraState: 'add',
  179. visible: false,
  180. dataSource: [],
  181. queryParams: {
  182. page: 1,
  183. pageSize: 10,
  184. total: 0,
  185. modelLabel: ''
  186. },
  187. payloadType: ['JSON', '二进制流'],
  188. modelCount: [],
  189. modelTemplateList: []
  190. })
  191. const formOptions = reactive({
  192. disabled: false,
  193. hideRequiredMark: false
  194. })
  195. const modalTitle = computed(() => state.opraState === 'add' ? '新增产品模型' : '编辑产品模型')
  196. const useForm = Form.useForm
  197. const router = useRouter()
  198. const modelRef = reactive({
  199. modelTemplateId: '',
  200. modelLabel: '',
  201. transportType: null,
  202. payloadType: null,
  203. deviceType: '',
  204. modelDescription: ''
  205. // rts: false
  206. })
  207. const rulesRef = reactive({
  208. modelLabel: [{ required: true, message: '请填写标题' }],
  209. transportType: [{ required: true, message: '请选择协议' }],
  210. payloadType: [{ required: true, message: '请填写数据格式' }]
  211. })
  212. watch(
  213. () => modelRef.modelTemplateId,
  214. () => {
  215. if (modelRef.modelTemplateId) {
  216. formOptions.hideRequiredMark = true
  217. formOptions.disabled = true
  218. } else {
  219. formOptions.hideRequiredMark = false
  220. formOptions.disabled = false
  221. }
  222. }
  223. )
  224. const { resetFields, validate, validateInfos } = useForm(modelRef, rulesRef)
  225. const goDevicePage = (id: string) => {
  226. router.push({ path: '/device/index', query: { modelId: id } })
  227. }
  228. // 获取产品模型库列表
  229. const getModelTemplateList = async () => {
  230. const { data } = await ModelController.modelTemplate({
  231. page: 1,
  232. pageSize: 200
  233. })
  234. state.modelTemplateList = data
  235. }
  236. // 获取统计
  237. const getModelCount = async () => {
  238. const { data } = await ModelController.count()
  239. state.modelCount = Object.keys(data).map(key => {
  240. const item = ModelController.forwardStatisticMap.get(key)
  241. return {
  242. ...item,
  243. value: data[key]
  244. }
  245. })
  246. }
  247. const change = ({ current }) => {
  248. state.queryParams.page = current
  249. getModel()
  250. console.log('page:', current)
  251. }
  252. const ok = async () => {
  253. if (modelRef.modelTemplateId) {
  254. await opraModel()
  255. state.visible = false
  256. resetFields({})
  257. getModel()
  258. } else {
  259. validate().then(async () => {
  260. await opraModel()
  261. state.visible = false
  262. getModel()
  263. resetFields({})
  264. }).catch(() => {})
  265. }
  266. }
  267. const goDetailPage = (id: string) => {
  268. router.push({ path: '/product/detail', query: { id, type: 'model' } })
  269. }
  270. const confirmDel = async (id: string) => {
  271. await ModelController.del(id)
  272. getModel()
  273. }
  274. const openModel = (opraState: 'add' | 'update') => {
  275. state.opraState = opraState
  276. state.visible = true
  277. }
  278. const opraModel = async () => {
  279. if (state.opraState === 'add') {
  280. await ModelController.post(modelRef)
  281. }
  282. }
  283. const closeModel = () => {
  284. resetFields({})
  285. state.visible = false
  286. }
  287. const getModel = async () => {
  288. state.loading = true
  289. const { data, sum } = await ModelController.page(state.queryParams)
  290. state.loading = false
  291. state.dataSource = data
  292. state.queryParams.total = sum
  293. }
  294. onMounted(async () => {
  295. getModel()
  296. state.transport = await CommonController.getTransport()
  297. getModelCount()
  298. getModelTemplateList()
  299. })
  300. </script>
  301. <style></style>