style:设备运行参数分析/表管理/设备分组修改树状接口

main
黄伟杰 1 week ago
parent 2b905e8749
commit aa0eca7ede

@ -23,8 +23,8 @@ export const DeviceLineApi = {
return await request.get({ url: `/mes/device-line/get?id=` + id }) return await request.get({ url: `/mes/device-line/get?id=` + id })
}, },
getDeviceLineTree: async () => { getDeviceLineTree: async (params?: { filterNoDeviceLine?: number }) => {
return await request.get({ url: `/mes/device-line/tree` }) return await request.get({ url: `/mes/device-line/tree`, params })
}, },
regenerateCode: async (id: number, code: string) => { regenerateCode: async (id: number, code: string) => {

@ -73,7 +73,7 @@ export const OrganizationApi = {
return await request.download({ url: `/mes/organization/export-excel`, params }) return await request.download({ url: `/mes/organization/export-excel`, params })
}, },
deviceParameterAnalysis: async (params: { keyword?: string, showDevices?: number }) => { deviceParameterAnalysis: async (params: { keyword?: string, showDevices?: number, filterNoDeviceLine?: number }) => {
return await request.get({ url: `/mes/device-line/deviceParameterAnalysis`, params }) return await request.get({ url: `/mes/device-line/deviceParameterAnalysis`, params })
} }
} }

@ -851,7 +851,7 @@ export default {
packageCount: 'Package Count', packageCount: 'Package Count',
outPackageCount: 'Outbound Package Count', outPackageCount: 'Outbound Package Count',
outLockedPackageCount: 'Outbound Locked Package Count', outLockedPackageCount: 'Outbound Locked Package Count',
outPackageCountExceededWarning: 'Outbound package count cannot exceed package count minus outbound locked package count. It has been adjusted to {count}.', outPackageCountExceededWarning: 'Pallet code {code}: outbound package count cannot exceed package count minus outbound locked package count. It has been adjusted to {count}.',
inPackageCount: 'Inbound Package Count', inPackageCount: 'Inbound Package Count',
inItemCount: 'Inbound Count', inItemCount: 'Inbound Count',
inCount: 'Inbound Quantity', inCount: 'Inbound Quantity',

@ -851,7 +851,7 @@ export default {
packageCount: '包数', packageCount: '包数',
outPackageCount: '出库包数', outPackageCount: '出库包数',
outLockedPackageCount: '出库锁定包数', outLockedPackageCount: '出库锁定包数',
outPackageCountExceededWarning: '出库包数不能大于包数减出库锁定包数,已自动调整为{count}', outPackageCountExceededWarning: '托盘编码{code}出库包数不能大于包数减出库锁定包数,已自动调整为{count}',
inPackageCount: '入库包数', inPackageCount: '入库包数',
inItemCount: '入库个数', inItemCount: '入库个数',
inCount: '入库数量', inCount: '入库数量',

@ -382,7 +382,11 @@ const extractApiOrgs = (res: any): ApiTreeOrg[] => {
const loadTree = async () => { const loadTree = async () => {
treeLoading.value = true treeLoading.value = true
try { try {
const res = await OrganizationApi.deviceParameterAnalysis({ keyword: keyword.value || undefined, showDevices: 1 }) const res = await OrganizationApi.deviceParameterAnalysis({
keyword: keyword.value || undefined,
showDevices: 1,
filterNoDeviceLine: 1
})
treeData.value = buildTreeFromApi(extractApiOrgs(res)) treeData.value = buildTreeFromApi(extractApiOrgs(res))
defaultExpandedKeys.value = buildDefaultExpandedKeys(treeData.value, 'pipeline') defaultExpandedKeys.value = buildDefaultExpandedKeys(treeData.value, 'pipeline')
await nextTick() await nextTick()

@ -255,7 +255,7 @@ const getDeviceLedgerOptions = async (groupId?: string) => {
} }
const getFilterOptions = async () => { const getFilterOptions = async () => {
const deviceLineTree = await DeviceLineApi.getDeviceLineTree() const deviceLineTree = await DeviceLineApi.getDeviceLineTree({ filterNoDeviceLine: 1 })
groupOptions.value = normalizeDeviceLineTree(Array.isArray(deviceLineTree) ? deviceLineTree : []) groupOptions.value = normalizeDeviceLineTree(Array.isArray(deviceLineTree) ? deviceLineTree : [])
await getDeviceLedgerOptions(queryParams.value.groupId) await getDeviceLedgerOptions(queryParams.value.groupId)
} }

@ -247,6 +247,12 @@
@click="openIotDeviceDialog" @click="openIotDeviceDialog"
> >
<template #append> <template #append>
<el-button
v-if="iotDeviceDisplay"
@click.stop.prevent="clearIotDevice"
>
<Icon icon="ep:close" />
</el-button>
<el-button @click.stop="openIotDeviceDialog"> <el-button @click.stop="openIotDeviceDialog">
<Icon icon="ep:search" /> <Icon icon="ep:search" />
</el-button> </el-button>
@ -1475,6 +1481,11 @@ const openIotDeviceDialog = async () => {
const clearIotDevice = () => { const clearIotDevice = () => {
formData.value.dvId = undefined formData.value.dvId = undefined
delete formData.value.iotDeviceCode
delete formData.value.iotDeviceName
delete formData.value.iotDeviceLabel
delete formData.value.iotDevice
delete formData.value.device
iotDeviceSelectedLabel.value = '' iotDeviceSelectedLabel.value = ''
iotDeviceDraftId.value = undefined iotDeviceDraftId.value = undefined
iotDeviceDraftRow.value = undefined iotDeviceDraftRow.value = undefined
@ -1682,6 +1693,11 @@ const buildSubmitData = () => {
delete (data as any).deviceManagerIds delete (data as any).deviceManagerIds
delete (data as any).componentIds delete (data as any).componentIds
delete (data as any).beijianIds delete (data as any).beijianIds
delete (data as any).iotDeviceCode
delete (data as any).iotDeviceName
delete (data as any).iotDeviceLabel
delete (data as any).iotDevice
delete (data as any).device
return data return data
} }

@ -73,7 +73,7 @@
clearable clearable
class="!w-full" class="!w-full"
:placeholder="t('EnergyManagement.EnergyDevice.dialogRulesPointPlaceholder')" :placeholder="t('EnergyManagement.EnergyDevice.dialogRulesPointPlaceholder')"
:loading="devicePointLoading" :loading="analysisLoading"
@change="(val) => handlePointSelected(index, val)" @change="(val) => handlePointSelected(index, val)"
/> />
@ -131,8 +131,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { EnergyDeviceApi, EnergyDeviceVO } from '@/api/mes/energydevice' import { EnergyDeviceApi, EnergyDeviceVO } from '@/api/mes/energydevice'
import { EnergyTypeApi, EnergyTypeVO } from '@/api/mes/energytype' import { EnergyTypeApi, EnergyTypeVO } from '@/api/mes/energytype'
import { DeviceLineApi, DeviceLineTreeVO } from '@/api/mes/deviceline' import { OrganizationApi } from '@/api/mes/organization'
import { DeviceApi } from '@/api/iot/device'
import { Remove } from '@element-plus/icons-vue' import { Remove } from '@element-plus/icons-vue'
/** 能源设备 表单 */ /** 能源设备 表单 */
@ -205,8 +204,48 @@ const formRules = reactive({
const formRef = ref() // Ref const formRef = ref() // Ref
const analysisLoading = ref(false) const analysisLoading = ref(false)
type OrgSelectNode = DeviceLineTreeVO & { children?: OrgSelectNode[] }
type AnalysisParameter = {
id: number | string
name: string
code?: string
type?: string | null
dataType?: string | null
unit?: string | null
}
type AnalysisEquipment = {
id: number | string
name: string
parameters?: AnalysisParameter[]
}
type AnalysisOrgNode = {
id: number | string
name: string
orgClass?: string
parentId?: number | string | null
equipments?: AnalysisEquipment[]
children?: AnalysisOrgNode[]
}
type OrgSelectNode = {
id: number | string
name: string
orgClass?: string
parentId?: number | string | null
children?: OrgSelectNode[]
}
type EquipmentTreeNode = {
id: string
name: string
disabled?: boolean
dataType?: string | null
children?: EquipmentTreeNode[]
}
const analysisTree = ref<AnalysisOrgNode[]>([])
const orgSelectTree = ref<OrgSelectNode[]>([]) const orgSelectTree = ref<OrgSelectNode[]>([])
const orgTreeSelectProps = { const orgTreeSelectProps = {
@ -240,121 +279,109 @@ const findOrgNode = (nodes: OrgSelectNode[], id: any): OrgSelectNode | undefined
return undefined return undefined
} }
const devicePointLoading = ref(false) const normalizeAnalysisId = (value: any) => String(value ?? '')
const devicePointTree = ref<any[]>([])
const normalizeAnalysisTree = (nodes: any[] = []): AnalysisOrgNode[] => {
return nodes.map((node) => ({
id: node?.id,
name: String(node?.name ?? ''),
orgClass: node?.orgClass ? String(node.orgClass) : undefined,
parentId: node?.parentId ?? undefined,
equipments: Array.isArray(node?.equipments) ? node.equipments : [],
children: Array.isArray(node?.children) ? normalizeAnalysisTree(node.children) : undefined
}))
}
const loadDevicePointTree = async () => { const buildOrgSelectTree = (nodes: AnalysisOrgNode[] = []): OrgSelectNode[] => {
if (devicePointTree.value.length > 0) { return nodes.map((node) => ({
return id: node.id,
} name: node.name,
devicePointLoading.value = true orgClass: node.orgClass,
try { parentId: node.parentId,
const res: any = await DeviceApi.devicePointList() children: Array.isArray(node.children) ? buildOrgSelectTree(node.children) : undefined
const list = Array.isArray(res) ? res : Array.isArray(res?.data) ? res.data : [] }))
}
const normalizeToString = (v: any) => String(v ?? '')
const isNonEmptyArray = (v: any) => Array.isArray(v) && v.length > 0
const deviceGroups = new Map<string, { deviceId: string; deviceName: string; points: any[] }>()
const pushPoint = (
deviceId: any,
deviceName: any,
pointId: any,
pointName: any,
dataType?: any
) => {
const dId = normalizeToString(deviceId)
if (!dId) return
const group = deviceGroups.get(dId) ?? {
deviceId: dId,
deviceName: String(deviceName ?? ''),
points: []
}
if (!group.deviceName) group.deviceName = String(deviceName ?? '')
const pId = normalizeToString(pointId)
if (!pId) {
deviceGroups.set(dId, group)
return
}
group.points.push({
id: `${dId}:${pId}`,
name: `${group.deviceName}: ${String(pointName ?? '')}`.trim(),
dataType
})
deviceGroups.set(dId, group)
}
if ( const extractAnalysisOrgs = (res: any): AnalysisOrgNode[] => {
isNonEmptyArray(list) && if (Array.isArray(res)) return normalizeAnalysisTree(res)
((list[0] as any)?.deviceId !== undefined || (list[0] as any)?.deviceName !== undefined) if (Array.isArray(res?.data)) return normalizeAnalysisTree(res.data)
) { if (Array.isArray(res?.result)) return normalizeAnalysisTree(res.result)
;(list as any[]).forEach((row) => { if (Array.isArray(res?.list)) return normalizeAnalysisTree(res.list)
const deviceId = row?.deviceId ?? row?.devId ?? row?.device_id return []
const deviceName = row?.deviceName ?? row?.devName ?? row?.device_name }
const points =
row?.contactModelDOList ?? const findAnalysisNode = (nodes: AnalysisOrgNode[], id: any): AnalysisOrgNode | undefined => {
row?.points ?? for (const node of nodes) {
row?.pointList ?? if (isSameId(node.id, id)) return node
row?.devicePoints ?? const children = Array.isArray(node.children) ? node.children : []
row?.devicePointList ?? if (children.length) {
row?.parameters const found = findAnalysisNode(children, id)
if (Array.isArray(points)) { if (found) return found
points.forEach((p) => {
const pointId = p?.pointId ?? p?.id
const pointName = p?.attributeName ?? p?.pointName ?? p?.name
pushPoint(deviceId, deviceName, pointId, pointName, (p as any)?.dataType)
})
} else {
const pointId = row?.pointId ?? row?.attributeId ?? row?.devicePointId
const pointName = row?.attributeName ?? row?.pointName ?? row?.attributeName
pushPoint(deviceId, deviceName, pointId, pointName)
}
})
} else if (isNonEmptyArray(list)) {
;(list as any[]).forEach((row) => {
const deviceId = row?.deviceId ?? row?.devId
const deviceName = row?.deviceName ?? row?.devName
const pointId = row?.pointId ?? row?.id
const pointName = row?.attributeName ?? row?.pointName ?? row?.name
pushPoint(deviceId, deviceName, pointId, pointName, (row as any)?.dataType)
})
} }
}
return undefined
}
devicePointTree.value = Array.from(deviceGroups.values()) const collectEquipmentTree = (nodes: AnalysisOrgNode[] = []): EquipmentTreeNode[] => {
.map((g) => { const equipmentNodes: EquipmentTreeNode[] = []
const children = (g.points ?? []).filter((p) => p?.id)
if (!children.length) return null const walk = (node: AnalysisOrgNode) => {
return { id: `device:${g.deviceId}`, name: g.deviceName, disabled: true, children } const equipments = Array.isArray(node.equipments) ? node.equipments : []
}) equipments.forEach((equipment) => {
.filter(Boolean) as any[] const deviceId = normalizeAnalysisId(equipment?.id)
} finally { if (!deviceId) return
devicePointLoading.value = false const parameterNodes = (Array.isArray(equipment.parameters) ? equipment.parameters : [])
.map((parameter) => {
const pointId = normalizeAnalysisId(parameter?.id)
if (!pointId) return undefined
return {
id: deviceId + ':' + pointId,
name: String(parameter?.name ?? parameter?.code ?? pointId),
dataType: parameter?.dataType ?? parameter?.type ?? undefined
}
})
.filter(Boolean) as EquipmentTreeNode[]
if (parameterNodes.length) {
equipmentNodes.push({
id: 'device:' + deviceId,
name: String(equipment?.name ?? deviceId),
disabled: true,
children: parameterNodes
})
}
})
const children = Array.isArray(node.children) ? node.children : []
children.forEach(walk)
} }
nodes.forEach(walk)
return equipmentNodes
} }
const equipmentTree = computed(() => { const equipmentTree = computed(() => {
return devicePointTree.value if (!formData.value.orgId) return []
const selectedOrg = findAnalysisNode(analysisTree.value, formData.value.orgId)
return selectedOrg ? collectEquipmentTree([selectedOrg]) : []
}) })
const findPointDataType = (deviceId: any, pointId: any): string | undefined => { const findPointDataType = (deviceId: any, pointId: any): string | undefined => {
const dId = String(deviceId ?? '') const deviceKey = normalizeAnalysisId(deviceId)
const pId = String(pointId ?? '') const pointKey = normalizeAnalysisId(pointId)
if (!dId || !pId) return undefined if (!deviceKey || !pointKey) return undefined
const key = `${dId}:${pId}` const key = deviceKey + ':' + pointKey
const groups = devicePointTree.value ?? [] for (const group of collectEquipmentTree(analysisTree.value)) {
for (const g of groups) { const children = Array.isArray(group.children) ? group.children : []
const children = Array.isArray((g as any).children) ? (g as any).children : [] for (const child of children) {
for (const c of children) { if (String(child.id ?? '') === key) {
if (String((c as any).id ?? '') === key) { return child.dataType as string | undefined
return (c as any).dataType as string | undefined
} }
} }
} }
return undefined return undefined
} }
/** 打开弹窗 */
const open = async (type: string, id?: number) => { const open = async (type: string, id?: number) => {
dialogVisible.value = true dialogVisible.value = true
dialogTitle.value = t('action.' + type) dialogTitle.value = t('action.' + type)
@ -362,7 +389,6 @@ const open = async (type: string, id?: number) => {
resetForm() resetForm()
await loadAnalysis() await loadAnalysis()
await loadDevicePointTree()
// //
if (id) { if (id) {
formLoading.value = true formLoading.value = true
@ -446,13 +472,17 @@ onMounted(async () => {
}) })
const loadAnalysis = async () => { const loadAnalysis = async () => {
if (orgSelectTree.value.length > 0) { if (analysisTree.value.length > 0) {
return return
} }
analysisLoading.value = true analysisLoading.value = true
try { try {
const res = await DeviceLineApi.getDeviceLineTree() const res = await OrganizationApi.deviceParameterAnalysis({
orgSelectTree.value = (Array.isArray(res) ? res : []) as OrgSelectNode[] showDevices: 1,
filterNoDeviceLine: 1
})
analysisTree.value = extractAnalysisOrgs(res)
orgSelectTree.value = buildOrgSelectTree(analysisTree.value)
} finally { } finally {
analysisLoading.value = false analysisLoading.value = false
} }
@ -464,9 +494,17 @@ const handleDeviceTypeChange = () => {
)?.unit )?.unit
} }
const resetOperationRules = () => {
formData.value.operationRulesVOList = [
{ deviceId: undefined, pointId: undefined, operator: undefined, pointValue: undefined }
]
}
const handleOrgChange = () => { const handleOrgChange = () => {
const org = findOrgNode(orgSelectTree.value ?? [], formData.value.orgId) const org = findOrgNode(orgSelectTree.value ?? [], formData.value.orgId)
formData.value.orgName = org?.name formData.value.orgName = org?.name
resetOperationRules()
formRef.value?.clearValidate('operationRulesVOList')
} }
const handlePointSelected = (index: number, val: any) => { const handlePointSelected = (index: number, val: any) => {

Loading…
Cancel
Save