物模型:修改时禁止修改物模型编码
新增:量测页面
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"]]
|
VITE_APP_PROXY=[["/api","https://test.jsspisoft.com/api"]]
|
||||||
|
|
||||||
|
@ -142,8 +142,16 @@ export const downloadModelReq = (data: { id: string }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const getDeviceTypeEnumReq = () => {
|
export const getDeviceTypeEnumReq = () => {
|
||||||
return createAxios<never,RequestReturnType<DeviceType[]>>({
|
return createAxios<never, RequestReturnType<DeviceType[]>>({
|
||||||
url: '/api/equipment/type',
|
url: '/api/equipment/type',
|
||||||
method: 'post',
|
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',
|
name: 'univer',
|
||||||
component: () => import('/@/views/backend/node/univer.vue'),
|
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 })
|
const staticFiles: Record<string, Record<string, RouteRecordRaw>> = import.meta.glob('./static/*.ts', { eager: true })
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="iotModelCode" :label="ModelFieldsEnums['iotModelCode']">
|
<el-form-item prop="iotModelCode" :label="ModelFieldsEnums['iotModelCode']">
|
||||||
<el-input
|
<el-input
|
||||||
:disabled="modelDialogState === ModelDialogTitleStateType['detail']"
|
:disabled="!(modelDialogState === ModelDialogTitleStateType['add'])"
|
||||||
v-model="modelForm.iotModelCode"
|
v-model="modelForm.iotModelCode"
|
||||||
:placeholder="'请输入' + ModelFieldsEnums['iotModelCode']"
|
:placeholder="'请输入' + ModelFieldsEnums['iotModelCode']"
|
||||||
></el-input>
|
></el-input>
|
||||||
|
@ -49,11 +49,13 @@
|
|||||||
<el-table-column property="model" label="规格型号" />
|
<el-table-column property="model" label="规格型号" />
|
||||||
<el-table-column property="address" label="操作">
|
<el-table-column property="address" label="操作">
|
||||||
<template #default="scope">
|
<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"> | </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"> | </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>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@ -425,6 +427,25 @@
|
|||||||
<ControlPage :deviceId="contorlData.deviceId" :iotModelId="contorlData.iotModelId" :show="showControlPage"></ControlPage>
|
<ControlPage :deviceId="contorlData.deviceId" :iotModelId="contorlData.iotModelId" :show="showControlPage"></ControlPage>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -447,6 +468,7 @@ import { ElTable, ElMessage, ElMessageBox } from 'element-plus'
|
|||||||
import { useAdminInfo } from '/@/stores/adminInfo'
|
import { useAdminInfo } from '/@/stores/adminInfo'
|
||||||
import { encrypt_aes, generateRandomNumber } from '/@/utils/crypto'
|
import { encrypt_aes, generateRandomNumber } from '/@/utils/crypto'
|
||||||
import ControlPage from './control.vue'
|
import ControlPage from './control.vue'
|
||||||
|
import MeasurementPage from './measurement.vue'
|
||||||
|
|
||||||
const adminInfo = useAdminInfo()
|
const adminInfo = useAdminInfo()
|
||||||
interface Tree {
|
interface Tree {
|
||||||
@ -955,9 +977,25 @@ const contorlData = reactive({
|
|||||||
const openControl = (data: any) => {
|
const openControl = (data: any) => {
|
||||||
contorlData.deviceId = data.row.id
|
contorlData.deviceId = data.row.id
|
||||||
contorlData.iotModelId = data.row.iotModelId
|
contorlData.iotModelId = data.row.iotModelId
|
||||||
if(contorlData.iotModelId){
|
if (contorlData.iotModelId) {
|
||||||
showControlPage.value = true
|
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('该设备没有绑定物模型!')
|
ElMessage.warning('该设备没有绑定物模型!')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1052,4 +1090,10 @@ $paginationHeight: 32px;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.measureSlotHeader {
|
||||||
|
display: flex;
|
||||||
|
.measureSlotHeaderRight {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</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