|
|
@@ -1,343 +1,344 @@
|
|
|
-<template>
|
|
|
-
|
|
|
- <a-card title="设备统计" >
|
|
|
- <a-row justify="center">
|
|
|
- <a-col
|
|
|
- v-for="item in state.deviceCount"
|
|
|
- :key="item.key"
|
|
|
- :xs="12" :sm="12" :md="6" :lg="8" :xl="4"
|
|
|
- >
|
|
|
- <div class="statistic" >
|
|
|
- <span class="count" :style="{color: item.color}" >{{item.value}}</span>
|
|
|
- <span>台</span>
|
|
|
- </div>
|
|
|
- <div class="label" >
|
|
|
- {{item.label}}
|
|
|
- </div>
|
|
|
- </a-col>
|
|
|
- </a-row>
|
|
|
- </a-card>
|
|
|
-
|
|
|
- <a-card style="margin-top: 20px;">
|
|
|
- <a-row justify="space-between" >
|
|
|
- <a-col :span="20" >
|
|
|
- <a-form layout="inline" >
|
|
|
- <a-form-item >
|
|
|
- <a-select allowClear style="width: 176px;" v-model:value="searchState.deviceStatus" placeholder="请输入设备状态">
|
|
|
- <a-select-option
|
|
|
- v-for="item in DeviceContriller.deviceStatus"
|
|
|
- :key="item.key"
|
|
|
- :value="item.key"
|
|
|
- >{{item.name}}</a-select-option>
|
|
|
- </a-select>
|
|
|
- </a-form-item>
|
|
|
- <a-form-item style="width: 400px;">
|
|
|
- <a-input-group compact >
|
|
|
- <a-select allowClear v-model:value="searchState.searchKey" style="width: 150px;" >
|
|
|
- <a-select-option v-for="item in searchList" :key="item.key" :value="item.key">{{item.name}}</a-select-option>
|
|
|
- </a-select>
|
|
|
- <a-input allowClear v-model:value="searchState.searchValue" style="width: 176px" placeholder="请输入查询值"/>
|
|
|
- </a-input-group>
|
|
|
- </a-form-item>
|
|
|
- <a-form-item><a-button @click="resetFields([])">重置</a-button></a-form-item>
|
|
|
- <a-form-item><a-button type="primary" @click="getDevicePage">搜索</a-button> </a-form-item>
|
|
|
- </a-form>
|
|
|
- </a-col>
|
|
|
- <a-col :span="2" >
|
|
|
- <a-button type="primary" @click="openModal('add', {})"> + 新增设备</a-button>
|
|
|
- </a-col>
|
|
|
- </a-row>
|
|
|
-
|
|
|
- <a-table
|
|
|
- style="margin-top: 20px;width: 100%;"
|
|
|
- :columns="columns"
|
|
|
- :data-source="state.dataSource"
|
|
|
- :loading="state.loading"
|
|
|
- :pagination="searchState"
|
|
|
- @change="changePage"
|
|
|
- >
|
|
|
- <template #bodyCell="{column, record}">
|
|
|
- <template v-if="column.key === 'id'" >
|
|
|
- <a @click="goDetailPage(record.id)">{{record.id}}</a>
|
|
|
- </template>
|
|
|
- <template v-if="column.key === 'deviceStatus'" >
|
|
|
- <a-tag :color="record.deviceStatus.color" >{{record.deviceStatus.name}}</a-tag>
|
|
|
- </template>
|
|
|
- <template v-if="column.key === 'deviceNodeType'" >
|
|
|
- <a-tag>{{record.deviceNodeType == 'GATEWAY'?'直连类型':'非直连类型'}}</a-tag>
|
|
|
- </template>
|
|
|
- <template v-if="column.key === 'rtsUrl'" >
|
|
|
- {{record.rtsUrl ? '支持': '否'}}
|
|
|
- </template>
|
|
|
- <template v-if="column.key === 'action'">
|
|
|
- <a-space>
|
|
|
- <a @click="goDetailPage(record.id)">查看</a>
|
|
|
- <a @click="goDebugPage(record.id)" >调试</a>
|
|
|
- <a @click="goAnalysisPage(record.id)">分析</a>
|
|
|
- <a-popconfirm
|
|
|
- title="确实要删除吗?"
|
|
|
- ok-text="确定"
|
|
|
- cancel-text="取消"
|
|
|
- @confirm="delDevice(record.id)"
|
|
|
- >
|
|
|
- <a href="#">删除</a>
|
|
|
- </a-popconfirm>
|
|
|
- </a-space>
|
|
|
- </template>
|
|
|
- </template>
|
|
|
- </a-table>
|
|
|
- </a-card>
|
|
|
-
|
|
|
- <a-modal
|
|
|
- title="单设备注册"
|
|
|
- :open="state.visible"
|
|
|
- @cancel="state.visible = false"
|
|
|
- @ok="ok"
|
|
|
- >
|
|
|
- <a-form :labelCol="{span: 6}" :wrapperCol="{span: 14}" >
|
|
|
- <a-form-item label="所属产品" v-bind="validateInfosDeviceState.modelId" >
|
|
|
- <a-select allowClear v-model:value="deviceState.modelId" >
|
|
|
- <a-select-option
|
|
|
- v-for="item in state.modelList"
|
|
|
- :key="item.id"
|
|
|
- :value="item.id"
|
|
|
- >
|
|
|
- {{item.modelLabel}}
|
|
|
- </a-select-option>
|
|
|
- </a-select>
|
|
|
- </a-form-item>
|
|
|
- <a-form-item label="设备标识码" v-bind="validateInfosDeviceState.deviceCode" >
|
|
|
- <a-input allowClear v-model:value="deviceState.deviceCode" />
|
|
|
- </a-form-item>
|
|
|
- <a-form-item label="设备名称" >
|
|
|
- <a-input allowClear v-model:value="deviceState.deviceLabel" />
|
|
|
- </a-form-item>
|
|
|
- <a-form-item label="设备认证类型" >
|
|
|
- <a-radio-group v-model:value="deviceState.deviceAuthType">
|
|
|
- <a-radio value="SECRET">密钥认证</a-radio>
|
|
|
- <a-radio value="X509CERT">x509证书</a-radio>
|
|
|
- </a-radio-group>
|
|
|
- </a-form-item>
|
|
|
- <a-form-item label="密匙" v-if="deviceState.deviceAuthType === DeviceAuthTypeEnum.SECRET " >
|
|
|
- <a-input-password allowClear v-model:value="deviceState.deviceSecret" />
|
|
|
- </a-form-item>
|
|
|
- <a-form-item label="确认密匙" v-if="deviceState.deviceAuthType === DeviceAuthTypeEnum.SECRET ">
|
|
|
- <a-input-password allowClear v-model:value="deviceState.confirmSecret" />
|
|
|
- </a-form-item>
|
|
|
- </a-form>
|
|
|
- </a-modal>
|
|
|
-
|
|
|
-</template>
|
|
|
-
|
|
|
-<script lang="ts" setup >
|
|
|
-
|
|
|
-import { DeviceContriller, ModelController } from '@/controller/index'
|
|
|
-import { onMounted, reactive, ref, toRefs, nextTick, computed, watch } from 'vue'
|
|
|
-import { Form, message } from 'ant-design-vue'
|
|
|
-import { DeviceAuthTypeEnum } from '@/enum/common'
|
|
|
-import { useRoute, useRouter } from 'vue-router'
|
|
|
-import { DownOutlined } from '@ant-design/icons-vue'
|
|
|
-
|
|
|
-const useForm = Form.useForm
|
|
|
-const router = useRouter()
|
|
|
-
|
|
|
-const modelId = (useRoute().query.modelId || '') as string
|
|
|
-
|
|
|
-console.log('modelId:', modelId)
|
|
|
-
|
|
|
-const columns = [
|
|
|
- {
|
|
|
- title: '设备ID',
|
|
|
- dataIndex: 'id',
|
|
|
- key: 'id',
|
|
|
- ellipsis: true
|
|
|
- },
|
|
|
- {
|
|
|
- title: '设备名称',
|
|
|
- dataIndex: 'deviceLabel',
|
|
|
- ellipsis: true
|
|
|
- },
|
|
|
- {
|
|
|
- title: '设备标识码',
|
|
|
- dataIndex: 'deviceCode',
|
|
|
- ellipsis: true
|
|
|
- },
|
|
|
- {
|
|
|
- title: '设备描述',
|
|
|
- dataIndex: 'deviceDescription',
|
|
|
- ellipsis: true
|
|
|
- },
|
|
|
- {
|
|
|
- title: '节点类型',
|
|
|
- dataIndex: 'deviceNodeType',
|
|
|
- key: 'deviceNodeType',
|
|
|
- width: 100
|
|
|
- },
|
|
|
- {
|
|
|
- title: '所属产品',
|
|
|
- dataIndex: 'modelLabel',
|
|
|
- ellipsis: true
|
|
|
- },
|
|
|
- {
|
|
|
- title: '支持live',
|
|
|
- dataIndex: 'rtsUrl',
|
|
|
- key: 'rtsUrl',
|
|
|
- width: 100
|
|
|
- },
|
|
|
- {
|
|
|
- title: '状态',
|
|
|
- dataIndex: 'deviceStatus',
|
|
|
- key: 'deviceStatus',
|
|
|
- ellipsis: true,
|
|
|
- width: 80
|
|
|
- },
|
|
|
- {
|
|
|
- title: '操作',
|
|
|
- key: 'action'
|
|
|
- }
|
|
|
-]
|
|
|
-
|
|
|
-const searchList = [
|
|
|
- { name: '设备id', key: 'deviceId' },
|
|
|
- { name: '设备名称', key: 'deviceLabel' },
|
|
|
- { name: '设备标识码', key: 'deviceCode' }
|
|
|
-]
|
|
|
-
|
|
|
-const analysisList = [
|
|
|
- { label: '上下线分析', key: 'session' },
|
|
|
- { label: '属性分析', key: 'attr' }
|
|
|
-]
|
|
|
-
|
|
|
-const state = reactive<{
|
|
|
- modelId: string,
|
|
|
- deviceCount: any,
|
|
|
- dataSource: IOT.API.DEVICE.Device[],
|
|
|
- loading: boolean,
|
|
|
- visible: boolean,
|
|
|
- opraState: 'add' | 'update',
|
|
|
- modelList: IOT.API.MODEL.ModelDot[]
|
|
|
- analysisVisible: boolean
|
|
|
- analysisType: 'session' | 'attr' | ''
|
|
|
-}>({
|
|
|
- modelId: modelId,
|
|
|
- deviceCount: [],
|
|
|
- dataSource: [],
|
|
|
- modelList: [],
|
|
|
- loading: false,
|
|
|
- visible: false,
|
|
|
- analysisVisible: false,
|
|
|
- analysisType: '',
|
|
|
- opraState: 'add'
|
|
|
-})
|
|
|
-
|
|
|
-const searchState = reactive({
|
|
|
- page: 1,
|
|
|
- pageSize: 10,
|
|
|
- total: 0,
|
|
|
- deviceStatus: null,
|
|
|
- modelId: modelId,
|
|
|
- searchKey: 'deviceId',
|
|
|
- searchValue: '',
|
|
|
- showSizeChanger: false
|
|
|
-})
|
|
|
-
|
|
|
-const deviceState = reactive({
|
|
|
- id: '',
|
|
|
- modelId: '',
|
|
|
- deviceLabel: '',
|
|
|
- deviceCode: '',
|
|
|
- deviceDescription: '',
|
|
|
- deviceAuthType: DeviceAuthTypeEnum.SECRET,
|
|
|
- modelLabel: '',
|
|
|
- deviceSecret: '',
|
|
|
- confirmSecret: ''
|
|
|
-})
|
|
|
-
|
|
|
-const { resetFields, validate, validateInfos } = useForm(searchState, {})
|
|
|
-
|
|
|
-const { resetFields: resetFieldsDevice, validate: validateDevice, validateInfos: validateInfosDeviceState } = useForm(deviceState, reactive({
|
|
|
- modelId: [{ required: true, message: '请选择所属产品' }],
|
|
|
- deviceCode: [{ required: true, message: '请填写设备码' }]
|
|
|
-}))
|
|
|
-
|
|
|
-const changePage = ({ current }) => {
|
|
|
- searchState.page = current
|
|
|
- getDevicePage()
|
|
|
-}
|
|
|
-
|
|
|
-const goDebugPage = (id: string) => {
|
|
|
- router.push({ path: '/devOps/onlineTest', query: { id } })
|
|
|
-}
|
|
|
-
|
|
|
-const goDetailPage = (id: string) => {
|
|
|
- router.push({ path: '/device/detail', query: { id } })
|
|
|
-}
|
|
|
-
|
|
|
-const delDevice = async (id: string) => {
|
|
|
- await DeviceContriller.del(id)
|
|
|
- getDevicePage()
|
|
|
-}
|
|
|
-
|
|
|
-const goAnalysisPage = (id: string) => {
|
|
|
- router.push({ path: '/device/analysis', query: { id } })
|
|
|
-}
|
|
|
-
|
|
|
-const ok = () => {
|
|
|
- if (deviceState.deviceAuthType === DeviceAuthTypeEnum.SECRET && deviceState.deviceSecret !== deviceState.confirmSecret) {
|
|
|
- message.warn('两次密匙输入不同')
|
|
|
- return
|
|
|
- }
|
|
|
- validateDevice().then(async (r) => {
|
|
|
- await DeviceContriller.post(deviceState)
|
|
|
- state.visible = false
|
|
|
- getDevicePage()
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-const getModelList = async () => {
|
|
|
- const { data } = await ModelController.list()
|
|
|
- state.modelList = data
|
|
|
-}
|
|
|
-
|
|
|
-const openModal = (opraState: 'add' | 'update', record:Partial<IOT.API.DEVICE.Device> = {}) => {
|
|
|
- state.visible = true
|
|
|
- state.opraState = opraState
|
|
|
- getModelList()
|
|
|
- resetFieldsDevice({})
|
|
|
-}
|
|
|
-
|
|
|
-const getDevicePage = async () => {
|
|
|
- state.loading = true
|
|
|
- const { data, sum } = await DeviceContriller.page(searchState)
|
|
|
- state.loading = false
|
|
|
- state.dataSource = data
|
|
|
- searchState.total = sum
|
|
|
-}
|
|
|
-
|
|
|
-const getDeviceStatistics = async () => {
|
|
|
- const data = await DeviceContriller.statistics({ modelId: state.modelId })
|
|
|
- state.deviceCount = data as any
|
|
|
-}
|
|
|
-
|
|
|
-onMounted(() => {
|
|
|
- getDeviceStatistics()
|
|
|
- getDevicePage()
|
|
|
-})
|
|
|
-
|
|
|
-</script>
|
|
|
-
|
|
|
-<style lang="less" scoped >
|
|
|
-@import '~@/styles/theme.less';
|
|
|
-.statistic {
|
|
|
- color: @sublabel-color;
|
|
|
- .count {
|
|
|
- font-size: 48px;
|
|
|
- margin-right: 10px;
|
|
|
- }
|
|
|
-}
|
|
|
-.label {
|
|
|
- font-size: 18px;
|
|
|
- color: @sublabel-color;
|
|
|
-}
|
|
|
-
|
|
|
-</style>
|
|
|
+<template>
|
|
|
+
|
|
|
+ <a-card title="设备统计" >
|
|
|
+ <a-row justify="center">
|
|
|
+ <a-col
|
|
|
+ v-for="item in state.deviceCount"
|
|
|
+ :key="item.key"
|
|
|
+ :xs="12" :sm="12" :md="6" :lg="8" :xl="4"
|
|
|
+ >
|
|
|
+ <div class="statistic" >
|
|
|
+ <span class="count" :style="{color: item.color}" >{{item.value}}</span>
|
|
|
+ <span>台</span>
|
|
|
+ </div>
|
|
|
+ <div class="label" >
|
|
|
+ {{item.label}}
|
|
|
+ </div>
|
|
|
+ </a-col>
|
|
|
+ </a-row>
|
|
|
+ </a-card>
|
|
|
+
|
|
|
+ <a-card style="margin-top: 20px;">
|
|
|
+ <a-row justify="space-between" >
|
|
|
+ <a-col :span="20" >
|
|
|
+ <a-form layout="inline" >
|
|
|
+ <a-form-item >
|
|
|
+ <a-select allowClear style="width: 176px;" v-model:value="searchState.deviceStatus" placeholder="请输入设备状态">
|
|
|
+ <a-select-option
|
|
|
+ v-for="item in DeviceContriller.deviceStatus"
|
|
|
+ :key="item.key"
|
|
|
+ :value="item.key"
|
|
|
+ >{{item.name}}</a-select-option>
|
|
|
+ </a-select>
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item style="width: 400px;">
|
|
|
+ <a-input-group compact >
|
|
|
+ <a-select allowClear v-model:value="searchState.searchKey" style="width: 150px;" >
|
|
|
+ <a-select-option v-for="item in searchList" :key="item.key" :value="item.key">{{item.name}}</a-select-option>
|
|
|
+ </a-select>
|
|
|
+ <a-input allowClear v-model:value="searchState.searchValue" style="width: 176px" placeholder="请输入查询值"/>
|
|
|
+ </a-input-group>
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item><a-button @click="resetFields([])">重置</a-button></a-form-item>
|
|
|
+ <a-form-item><a-button type="primary" @click="getDevicePage">搜索</a-button> </a-form-item>
|
|
|
+ </a-form>
|
|
|
+ </a-col>
|
|
|
+ <a-col :span="2" >
|
|
|
+ <a-button type="primary" @click="openModal('add', {})"> + 新增设备</a-button>
|
|
|
+ </a-col>
|
|
|
+ </a-row>
|
|
|
+
|
|
|
+ <a-table
|
|
|
+ style="margin-top: 20px;width: 100%;"
|
|
|
+ :columns="columns"
|
|
|
+ :data-source="state.dataSource"
|
|
|
+ :loading="state.loading"
|
|
|
+ :pagination="searchState"
|
|
|
+ @change="changePage"
|
|
|
+ >
|
|
|
+ <template #bodyCell="{column, record}">
|
|
|
+ <template v-if="column.key === 'id'" >
|
|
|
+ <a @click="goDetailPage(record.id)">{{record.id}}</a>
|
|
|
+ </template>
|
|
|
+ <template v-if="column.key === 'deviceStatus'" >
|
|
|
+ <a-tag :color="record.deviceStatus.color" >{{record.deviceStatus.name}}</a-tag>
|
|
|
+ </template>
|
|
|
+ <template v-if="column.key === 'deviceNodeType'" >
|
|
|
+ <a-tag>{{record.deviceNodeType == 'GATEWAY'?'直连类型':'非直连类型'}}</a-tag>
|
|
|
+ </template>
|
|
|
+ <template v-if="column.key === 'rtsUrl'" >
|
|
|
+ {{record.rtsUrl ? '支持': '否'}}
|
|
|
+ </template>
|
|
|
+ <template v-if="column.key === 'action'">
|
|
|
+ <a-space>
|
|
|
+ <a @click="goDetailPage(record.id)">查看</a>
|
|
|
+ <a @click="goDebugPage(record.id)" >调试</a>
|
|
|
+ <a @click="goAnalysisPage(record.id)">分析</a>
|
|
|
+ <a-popconfirm
|
|
|
+ title="确实要删除吗?"
|
|
|
+ ok-text="确定"
|
|
|
+ cancel-text="取消"
|
|
|
+ @confirm="delDevice(record.id)"
|
|
|
+ >
|
|
|
+ <a href="#">删除</a>
|
|
|
+ </a-popconfirm>
|
|
|
+ </a-space>
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ </a-table>
|
|
|
+ </a-card>
|
|
|
+
|
|
|
+ <a-modal
|
|
|
+ title="单设备注册"
|
|
|
+ :open="state.visible"
|
|
|
+ @cancel="state.visible = false"
|
|
|
+ @ok="ok"
|
|
|
+ >
|
|
|
+ <a-form :labelCol="{span: 6}" :wrapperCol="{span: 14}" >
|
|
|
+ <a-form-item label="所属产品" v-bind="validateInfosDeviceState.modelId" >
|
|
|
+ <a-select allowClear v-model:value="deviceState.modelId" >
|
|
|
+ <a-select-option
|
|
|
+ v-for="item in state.modelList"
|
|
|
+ :key="item.id"
|
|
|
+ :value="item.id"
|
|
|
+ >
|
|
|
+ {{item.modelLabel}}
|
|
|
+ </a-select-option>
|
|
|
+ </a-select>
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="设备标识码" v-bind="validateInfosDeviceState.deviceCode" >
|
|
|
+ <a-input allowClear v-model:value="deviceState.deviceCode" />
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="设备名称" >
|
|
|
+ <a-input allowClear v-model:value="deviceState.deviceLabel" />
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="设备认证类型" >
|
|
|
+ <a-radio-group v-model:value="deviceState.deviceAuthType">
|
|
|
+ <a-radio value="SECRET">密钥认证</a-radio>
|
|
|
+ <a-radio value="X509CERT">x509证书</a-radio>
|
|
|
+ </a-radio-group>
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="密匙" v-if="deviceState.deviceAuthType === DeviceAuthTypeEnum.SECRET " >
|
|
|
+ <a-input-password allowClear v-model:value="deviceState.deviceSecret" />
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="确认密匙" v-if="deviceState.deviceAuthType === DeviceAuthTypeEnum.SECRET ">
|
|
|
+ <a-input-password allowClear v-model:value="deviceState.confirmSecret" />
|
|
|
+ </a-form-item>
|
|
|
+ </a-form>
|
|
|
+ </a-modal>
|
|
|
+
|
|
|
+</template>
|
|
|
+
|
|
|
+<script lang="ts" setup >
|
|
|
+
|
|
|
+import { DeviceContriller, ModelController } from '@/controller/index'
|
|
|
+import { onMounted, reactive, ref, toRefs, nextTick, computed, watch } from 'vue'
|
|
|
+import { Form, message } from 'ant-design-vue'
|
|
|
+import { DeviceAuthTypeEnum } from '@/enum/common'
|
|
|
+import { useRoute, useRouter } from 'vue-router'
|
|
|
+import { DownOutlined } from '@ant-design/icons-vue'
|
|
|
+
|
|
|
+const useForm = Form.useForm
|
|
|
+
|
|
|
+const router = useRouter()
|
|
|
+
|
|
|
+const modelId = (useRoute().query.modelId || '') as string
|
|
|
+
|
|
|
+console.log('modelId:', modelId)
|
|
|
+
|
|
|
+const columns = [
|
|
|
+ {
|
|
|
+ title: '设备ID',
|
|
|
+ dataIndex: 'id',
|
|
|
+ key: 'id',
|
|
|
+ ellipsis: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '设备名称',
|
|
|
+ dataIndex: 'deviceLabel',
|
|
|
+ ellipsis: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '设备标识码',
|
|
|
+ dataIndex: 'deviceCode',
|
|
|
+ ellipsis: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '设备描述',
|
|
|
+ dataIndex: 'deviceDescription',
|
|
|
+ ellipsis: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '节点类型',
|
|
|
+ dataIndex: 'deviceNodeType',
|
|
|
+ key: 'deviceNodeType',
|
|
|
+ width: 100
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '所属产品',
|
|
|
+ dataIndex: 'modelLabel',
|
|
|
+ ellipsis: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '支持live',
|
|
|
+ dataIndex: 'rtsUrl',
|
|
|
+ key: 'rtsUrl',
|
|
|
+ width: 100
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '状态',
|
|
|
+ dataIndex: 'deviceStatus',
|
|
|
+ key: 'deviceStatus',
|
|
|
+ ellipsis: true,
|
|
|
+ width: 80
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '操作',
|
|
|
+ key: 'action'
|
|
|
+ }
|
|
|
+]
|
|
|
+
|
|
|
+const searchList = [
|
|
|
+ { name: '设备id', key: 'deviceId' },
|
|
|
+ { name: '设备名称', key: 'deviceLabel' },
|
|
|
+ { name: '设备标识码', key: 'deviceCode' }
|
|
|
+]
|
|
|
+
|
|
|
+const analysisList = [
|
|
|
+ { label: '上下线分析', key: 'session' },
|
|
|
+ { label: '属性分析', key: 'attr' }
|
|
|
+]
|
|
|
+
|
|
|
+const state = reactive<{
|
|
|
+ modelId: string,
|
|
|
+ deviceCount: any,
|
|
|
+ dataSource: IOT.API.DEVICE.Device[],
|
|
|
+ loading: boolean,
|
|
|
+ visible: boolean,
|
|
|
+ opraState: 'add' | 'update',
|
|
|
+ modelList: IOT.API.MODEL.ModelDot[]
|
|
|
+ analysisVisible: boolean
|
|
|
+ analysisType: 'session' | 'attr' | ''
|
|
|
+}>({
|
|
|
+ modelId: modelId,
|
|
|
+ deviceCount: [],
|
|
|
+ dataSource: [],
|
|
|
+ modelList: [],
|
|
|
+ loading: false,
|
|
|
+ visible: false,
|
|
|
+ analysisVisible: false,
|
|
|
+ analysisType: '',
|
|
|
+ opraState: 'add'
|
|
|
+})
|
|
|
+
|
|
|
+const searchState = reactive({
|
|
|
+ page: 1,
|
|
|
+ pageSize: 10,
|
|
|
+ total: 0,
|
|
|
+ deviceStatus: null,
|
|
|
+ modelId: modelId,
|
|
|
+ searchKey: 'deviceId',
|
|
|
+ searchValue: '',
|
|
|
+ showSizeChanger: false
|
|
|
+})
|
|
|
+
|
|
|
+const deviceState = reactive({
|
|
|
+ id: '',
|
|
|
+ modelId: '',
|
|
|
+ deviceLabel: '',
|
|
|
+ deviceCode: '',
|
|
|
+ deviceDescription: '',
|
|
|
+ deviceAuthType: DeviceAuthTypeEnum.SECRET,
|
|
|
+ modelLabel: '',
|
|
|
+ deviceSecret: '',
|
|
|
+ confirmSecret: ''
|
|
|
+})
|
|
|
+
|
|
|
+const { resetFields, validate, validateInfos } = useForm(searchState, {})
|
|
|
+
|
|
|
+const { resetFields: resetFieldsDevice, validate: validateDevice, validateInfos: validateInfosDeviceState } = useForm(deviceState, reactive({
|
|
|
+ modelId: [{ required: true, message: '请选择所属产品' }],
|
|
|
+ deviceCode: [{ required: true, message: '请填写设备码' }]
|
|
|
+}))
|
|
|
+
|
|
|
+const changePage = ({ current }) => {
|
|
|
+ searchState.page = current
|
|
|
+ getDevicePage()
|
|
|
+}
|
|
|
+
|
|
|
+const goDebugPage = (id: string) => {
|
|
|
+ router.push({ path: '/devOps/onlineTest', query: { id } })
|
|
|
+}
|
|
|
+
|
|
|
+const goDetailPage = (id: string) => {
|
|
|
+ router.push({ path: '/device/detail', query: { id } })
|
|
|
+}
|
|
|
+
|
|
|
+const delDevice = async (id: string) => {
|
|
|
+ await DeviceContriller.del(id)
|
|
|
+ getDevicePage()
|
|
|
+}
|
|
|
+
|
|
|
+const goAnalysisPage = (id: string) => {
|
|
|
+ router.push({ path: '/device/analysis', query: { id } })
|
|
|
+}
|
|
|
+
|
|
|
+const ok = () => {
|
|
|
+ if (deviceState.deviceAuthType === DeviceAuthTypeEnum.SECRET && deviceState.deviceSecret !== deviceState.confirmSecret) {
|
|
|
+ message.warn('两次密匙输入不同')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ validateDevice().then(async (r) => {
|
|
|
+ await DeviceContriller.post(deviceState)
|
|
|
+ state.visible = false
|
|
|
+ getDevicePage()
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const getModelList = async () => {
|
|
|
+ const { data } = await ModelController.list()
|
|
|
+ state.modelList = data
|
|
|
+}
|
|
|
+
|
|
|
+const openModal = (opraState: 'add' | 'update', record:Partial<IOT.API.DEVICE.Device> = {}) => {
|
|
|
+ state.visible = true
|
|
|
+ state.opraState = opraState
|
|
|
+ getModelList()
|
|
|
+ resetFieldsDevice({})
|
|
|
+}
|
|
|
+
|
|
|
+const getDevicePage = async () => {
|
|
|
+ state.loading = true
|
|
|
+ const { data, sum } = await DeviceContriller.page(searchState)
|
|
|
+ state.loading = false
|
|
|
+ state.dataSource = data
|
|
|
+ searchState.total = sum
|
|
|
+}
|
|
|
+
|
|
|
+const getDeviceStatistics = async () => {
|
|
|
+ const data = await DeviceContriller.statistics({ modelId: state.modelId })
|
|
|
+ state.deviceCount = data as any
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ getDeviceStatistics()
|
|
|
+ getDevicePage()
|
|
|
+})
|
|
|
+
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="less" scoped >
|
|
|
+@import '~@/styles/theme.less';
|
|
|
+.statistic {
|
|
|
+ color: @sublabel-color;
|
|
|
+ .count {
|
|
|
+ font-size: 48px;
|
|
|
+ margin-right: 10px;
|
|
|
+ }
|
|
|
+}
|
|
|
+.label {
|
|
|
+ font-size: 18px;
|
|
|
+ color: @sublabel-color;
|
|
|
+}
|
|
|
+
|
|
|
+</style>
|