物模型:修改时禁止修改物模型编码
新增:量测页面
This commit is contained in:
parent
aa7831af36
commit
b3902bcb90
@ -6,7 +6,7 @@ VITE_BASE_PATH = './'
|
||||
|
||||
# 代理配置(开发使用),必须在一行中
|
||||
# 本地
|
||||
# VITE_APP_PROXY=[["/api","http://192.168.130.12:8080/api"]]
|
||||
# VITE_APP_PROXY=[["/api","http://192.168.130.22:8080/api"]]
|
||||
# 线上
|
||||
VITE_APP_PROXY=[["/api","https://test.jsspisoft.com/api"]]
|
||||
|
||||
|
@ -142,8 +142,16 @@ export const downloadModelReq = (data: { id: string }) => {
|
||||
}
|
||||
|
||||
export const getDeviceTypeEnumReq = () => {
|
||||
return createAxios<never,RequestReturnType<DeviceType[]>>({
|
||||
return createAxios<never, RequestReturnType<DeviceType[]>>({
|
||||
url: '/api/equipment/type',
|
||||
method: 'post',
|
||||
})
|
||||
}
|
||||
|
||||
export const getRealValueListReq = (data: { deviceId: string, attributes: string[] }[]) => {
|
||||
return createAxios<never, RequestReturnType<any>>({
|
||||
url: '/api/data/snapshot',
|
||||
method: 'post',
|
||||
data: data,
|
||||
})
|
||||
}
|
||||
|
@ -70,11 +70,6 @@ const staticRoutes: Array<RouteRecordRaw> = [
|
||||
name: 'univer',
|
||||
component: () => import('/@/views/backend/node/univer.vue'),
|
||||
},
|
||||
{
|
||||
path: adminBaseRoutePath +'/airBlower',
|
||||
name: 'airBlower',
|
||||
component: () => import('/@/views/backend/equipment/airBlower/index.vue'),
|
||||
}
|
||||
]
|
||||
|
||||
const staticFiles: Record<string, Record<string, RouteRecordRaw>> = import.meta.glob('./static/*.ts', { eager: true })
|
||||
|
@ -11,7 +11,7 @@
|
||||
</el-form-item>
|
||||
<el-form-item prop="iotModelCode" :label="ModelFieldsEnums['iotModelCode']">
|
||||
<el-input
|
||||
:disabled="modelDialogState === ModelDialogTitleStateType['detail']"
|
||||
:disabled="!(modelDialogState === ModelDialogTitleStateType['add'])"
|
||||
v-model="modelForm.iotModelCode"
|
||||
:placeholder="'请输入' + ModelFieldsEnums['iotModelCode']"
|
||||
></el-input>
|
||||
|
@ -49,11 +49,13 @@
|
||||
<el-table-column property="model" label="规格型号" />
|
||||
<el-table-column property="address" label="操作">
|
||||
<template #default="scope">
|
||||
<span style="color: #0064aa; cursor: pointer" @click="openControl(scope)">调控 </span>
|
||||
<span style="color: #0064aa; cursor: pointer" @click="openMeasure(scope)">量测</span>
|
||||
<span style="color: #0064aa"> | </span>
|
||||
<span style="color: #0064aa; cursor: pointer" @click="viewDeviceDetails(scope)">查看 </span>
|
||||
<span style="color: #0064aa; cursor: pointer" @click="openControl(scope)">调控</span>
|
||||
<span style="color: #0064aa"> | </span>
|
||||
<span style="color: #0064aa; cursor: pointer" @click="deviceDeletion(scope)"> 删除 </span>
|
||||
<span style="color: #0064aa; cursor: pointer" @click="viewDeviceDetails(scope)">查看</span>
|
||||
<span style="color: #0064aa"> | </span>
|
||||
<span style="color: #0064aa; cursor: pointer" @click="deviceDeletion(scope)">删除</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@ -425,6 +427,25 @@
|
||||
<ControlPage :deviceId="contorlData.deviceId" :iotModelId="contorlData.iotModelId" :show="showControlPage"></ControlPage>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<el-dialog v-model="showMeasure" title="量测">
|
||||
<template #header>
|
||||
<div class="measureSlotHeader">
|
||||
<span style="font-size: 20px">量测</span>
|
||||
<div class="measureSlotHeaderRight">
|
||||
<span>自动更新:</span>
|
||||
<el-switch v-model="measureData.autoUpdate"></el-switch>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="measureSlot">
|
||||
<MeasurementPage
|
||||
:show="showMeasure"
|
||||
:deviceId="measureData.deviceId"
|
||||
:iotModelId="measureData.iotModelId"
|
||||
:autoUpdate="measureData.autoUpdate"
|
||||
></MeasurementPage>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -447,6 +468,7 @@ import { ElTable, ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { useAdminInfo } from '/@/stores/adminInfo'
|
||||
import { encrypt_aes, generateRandomNumber } from '/@/utils/crypto'
|
||||
import ControlPage from './control.vue'
|
||||
import MeasurementPage from './measurement.vue'
|
||||
|
||||
const adminInfo = useAdminInfo()
|
||||
interface Tree {
|
||||
@ -955,9 +977,25 @@ const contorlData = reactive({
|
||||
const openControl = (data: any) => {
|
||||
contorlData.deviceId = data.row.id
|
||||
contorlData.iotModelId = data.row.iotModelId
|
||||
if(contorlData.iotModelId){
|
||||
if (contorlData.iotModelId) {
|
||||
showControlPage.value = true
|
||||
}else{
|
||||
} else {
|
||||
ElMessage.warning('该设备没有绑定物模型!')
|
||||
}
|
||||
}
|
||||
|
||||
const measureData = reactive({
|
||||
deviceId: '',
|
||||
iotModelId: '',
|
||||
autoUpdate: false,
|
||||
})
|
||||
const showMeasure = ref(false)
|
||||
const openMeasure = (data: any) => {
|
||||
measureData.deviceId = data.row.id
|
||||
measureData.iotModelId = data.row.iotModelId
|
||||
if (measureData.iotModelId) {
|
||||
showMeasure.value = true
|
||||
} else {
|
||||
ElMessage.warning('该设备没有绑定物模型!')
|
||||
}
|
||||
}
|
||||
@ -1052,4 +1090,10 @@ $paginationHeight: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.measureSlotHeader {
|
||||
display: flex;
|
||||
.measureSlotHeaderRight {
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -0,0 +1,229 @@
|
||||
<template>
|
||||
<div class="measurement">
|
||||
<el-table :columns="tableColumn" :data="tableData" @sort-change="sortChange" max-height="600">
|
||||
<el-table-column
|
||||
v-for="item in tableColumn"
|
||||
:key="item.prop"
|
||||
:label="item.label"
|
||||
:prop="item.prop"
|
||||
:width="item.width ?? ''"
|
||||
:align="item.align"
|
||||
sortable="custom"
|
||||
>
|
||||
<template #default="scope">
|
||||
<div v-if="item.prop === 'realTimeValue'">
|
||||
<el-button @click="openChart(scope.row)" text type="primary">{{ scope.row.realTimeValue }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div>
|
||||
<el-pagination
|
||||
v-model:current-page="pageSetting.current"
|
||||
v-model:page-size="pageSetting.pageSize"
|
||||
:total="pageSetting.total"
|
||||
:page-sizes="pageSetting.pageSizes"
|
||||
background
|
||||
:pager-count="7"
|
||||
layout="prev, pager, next, jumper,sizes,total"
|
||||
@change="getcurrentPage"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, watch } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import type { ModelAttributeFieldsEnums, GetModelAttributeType } from '/@/views/backend/auth/model/type'
|
||||
import { getModelAttributeListReq, getRealValueListReq } from '/@/api/backend/deviceModel/request'
|
||||
|
||||
const props = defineProps({
|
||||
iotModelId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
deviceId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
autoUpdate: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
|
||||
const tableColumn = [
|
||||
{
|
||||
label: '序号',
|
||||
prop: 'porder',
|
||||
width: 80,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
label: '属性名称',
|
||||
prop: 'attributeName',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
label: '属性编码',
|
||||
prop: 'attributeCode',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
label: '子系统',
|
||||
prop: 'subSystem',
|
||||
align: 'center',
|
||||
width: 110,
|
||||
},
|
||||
{
|
||||
label: '实时值',
|
||||
prop: 'realTimeValue',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
},
|
||||
]
|
||||
const tableData = ref<any[]>([])
|
||||
|
||||
const getAttributeList = () => {
|
||||
const requestData: GetModelAttributeType = {
|
||||
iotModelId: props.iotModelId,
|
||||
pageNum: pageSetting.current,
|
||||
pageSize: pageSetting.pageSize,
|
||||
orderColumn: sortData.orderColumn,
|
||||
orderType: sortData.orderType,
|
||||
}
|
||||
|
||||
return new Promise((resolve) => {
|
||||
getModelAttributeListReq(requestData)
|
||||
.then((res) => {
|
||||
if (res.rows && res.rows.length > 0) {
|
||||
const codeList: any = []
|
||||
const data = res.rows!.map((item) => {
|
||||
codeList.push(item.attributeCode)
|
||||
return {
|
||||
...item,
|
||||
attributeTypeName:
|
||||
item.attributeType === 138
|
||||
? '模拟量'
|
||||
: item.attributeType === 139
|
||||
? '累积量'
|
||||
: item.attributeType === 140
|
||||
? '离散量'
|
||||
: item.attributeType!,
|
||||
}
|
||||
})
|
||||
pageSetting.total = res.total
|
||||
resolve({ data, codeList })
|
||||
} else {
|
||||
if (res.rows && res.rows.length === 0) {
|
||||
tableData.value = []
|
||||
} else {
|
||||
ElMessage.error(res.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
ElMessage.error(err?.response?.data?.msg ?? '查询失败')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const getRealValueList = (data: { deviceId: string; attributes: string[] }, list?: any) => {
|
||||
return new Promise((resolve) => {
|
||||
getRealValueListReq([data]).then((res) => {
|
||||
if (res.success && res.data) {
|
||||
resolve({ realVal: res.data, list })
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const getCompleteData = () => {
|
||||
console.time('实时数据!')
|
||||
getAttributeList()
|
||||
.then(({ data, codeList }: any) => {
|
||||
return getRealValueList({ deviceId: props.deviceId, attributes: codeList }, data)
|
||||
})
|
||||
.then((realData: any) => {
|
||||
const data = realData.list.map((item: any) => {
|
||||
const realValItem = realData.realVal[props.deviceId]?.[item.attributeCode] ?? '-'
|
||||
return {
|
||||
...item,
|
||||
realTimeValue: realValItem,
|
||||
}
|
||||
})
|
||||
|
||||
tableData.value = data
|
||||
console.timeEnd('实时数据!')
|
||||
})
|
||||
}
|
||||
|
||||
const sortData = reactive<{ orderColumn?: keyof typeof ModelAttributeFieldsEnums; orderType?: 'asc' | 'desc' }>({
|
||||
orderColumn: 'porder',
|
||||
orderType: 'asc',
|
||||
})
|
||||
|
||||
const sortChange = ({ prop, order }: { prop: keyof typeof ModelAttributeFieldsEnums; order: 'ascending' | 'descending' | null }) => {
|
||||
const propEnums = {
|
||||
attributeCode: 'attribute_code',
|
||||
attributeName: 'attribute_name',
|
||||
attributeTypeName: 'attribute_type',
|
||||
porder: 'porder',
|
||||
serviceCode: 'service_code',
|
||||
serviceName: 'service_name',
|
||||
serviceTypeName: 'service_type',
|
||||
}
|
||||
const orderType = order === 'ascending' ? 'asc' : order === 'descending' ? 'desc' : undefined
|
||||
const filed = propEnums[prop as keyof typeof propEnums] as keyof typeof ModelAttributeFieldsEnums
|
||||
sortData.orderColumn = orderType ? filed : undefined
|
||||
sortData.orderType = orderType
|
||||
getCompleteData()
|
||||
}
|
||||
|
||||
const pageSetting = reactive({
|
||||
current: 1,
|
||||
pageSize: 20,
|
||||
total: 0,
|
||||
pageSizes: [10, 20, 30],
|
||||
})
|
||||
|
||||
const getcurrentPage = () => {
|
||||
getCompleteData()
|
||||
}
|
||||
|
||||
const openChart = (data: any) => {}
|
||||
|
||||
watch(
|
||||
() => props.show,
|
||||
(newVal) => {
|
||||
newVal && getCompleteData()
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
}
|
||||
)
|
||||
let autoUpdateTimer: any = null
|
||||
watch(
|
||||
() => props.autoUpdate,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
if (!autoUpdateTimer) {
|
||||
autoUpdateTimer = setInterval(() => {
|
||||
console.log('刷新')
|
||||
getCompleteData()
|
||||
}, 2000)
|
||||
}
|
||||
} else {
|
||||
clearInterval(autoUpdateTimer)
|
||||
autoUpdateTimer = null
|
||||
}
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
Loading…
Reference in New Issue
Block a user