@ -31,7 +31,13 @@ function mapRow(row) {
deviceCode : row . device _code ,
deviceCode : row . device _code ,
installPosition : row . install _position ,
installPosition : row . install _position ,
installPositionName : row . install _position _name ,
installPositionName : row . install _position _name ,
collectingDeviceId : row . collecting _device _id ,
collectingDeviceName : row . collecting _device _name ,
deviceType : row . device _type ,
deviceType : row . device _type ,
isDeviceGroup : row . is _device _group || '0' ,
parentDeviceGroupId : row . parent _device _group _id ,
parentDeviceGroupName : row . parent _device _group _name ,
childDevices : row . child _devices || [ ] ,
measuringUnit : row . measuring _unit _summary || row . measuring _unit ,
measuringUnit : row . measuring _unit _summary || row . measuring _unit ,
standardUnit : row . standard _unit ,
standardUnit : row . standard _unit ,
standardUnitName : row . standard _unit _name _summary || row . standard _unit _name ,
standardUnitName : row . standard _unit _name _summary || row . standard _unit _name ,
@ -45,6 +51,9 @@ function mapRow(row) {
communicationProtocol : row . communication _protocol ,
communicationProtocol : row . communication _protocol ,
communicationAddress : row . communication _address ,
communicationAddress : row . communication _address ,
collectionCycle : row . collection _cycle ,
collectionCycle : row . collection _cycle ,
lastCollectionTime : row . last _collection _time ,
alarmRules : row . alarm _rules || [ ] ,
alarmRuleNames : row . alarm _rule _names || '' ,
status : row . status ,
status : row . status ,
lastVerificationDate : row . last _verification _date ,
lastVerificationDate : row . last _verification _date ,
responsibleDept : row . responsible _dept ,
responsibleDept : row . responsible _dept ,
@ -85,12 +94,16 @@ function normalizeUnits(body = {}) {
function normalizeBody ( body = { } ) {
function normalizeBody ( body = { } ) {
const units = normalizeUnits ( body ) ;
const units = normalizeUnits ( body ) ;
const firstUnit = units [ 0 ] || { } ;
const firstUnit = units [ 0 ] || { } ;
return {
const isDeviceGroup = body . isDeviceGroup === true || body . isDeviceGroup === '1' || body . isDeviceGroup === 1 ? '1' : '0' ;
const data = {
deviceId : body . deviceId || null ,
deviceId : body . deviceId || null ,
deviceName : body . deviceName || null ,
deviceName : body . deviceName || null ,
deviceCode : body . deviceCode || null ,
deviceCode : body . deviceCode || null ,
installPosition : body . installPosition || null ,
installPosition : body . installPosition || null ,
collectingDeviceId : body . collectingDeviceId || null ,
deviceType : body . deviceType === undefined || body . deviceType === null || body . deviceType === '' ? null : String ( body . deviceType ) ,
deviceType : body . deviceType === undefined || body . deviceType === null || body . deviceType === '' ? null : String ( body . deviceType ) ,
isDeviceGroup ,
parentDeviceGroupId : body . parentDeviceGroupId || null ,
measuringUnit : firstUnit . measuringUnit || null ,
measuringUnit : firstUnit . measuringUnit || null ,
standardUnit : firstUnit . standardUnit || null ,
standardUnit : firstUnit . standardUnit || null ,
conversionFactor : firstUnit . conversionFactor ? ? null ,
conversionFactor : firstUnit . conversionFactor ? ? null ,
@ -103,16 +116,39 @@ function normalizeBody(body = {}) {
communicationProtocol : body . communicationProtocol || null ,
communicationProtocol : body . communicationProtocol || null ,
communicationAddress : body . communicationAddress || null ,
communicationAddress : body . communicationAddress || null ,
collectionCycle : body . collectionCycle || null ,
collectionCycle : body . collectionCycle || null ,
status : body . status || null ,
status : body . status === undefined || body . status === null || body . status === '' ? null : String ( body . status ) ,
lastVerificationDate : body . lastVerificationDate || null ,
lastVerificationDate : body . lastVerificationDate || null ,
responsibleDept : body . responsibleDept || null ,
responsibleDept : body . responsibleDept || null ,
responsiblePerson : body . responsiblePerson || null ,
responsiblePerson : body . responsiblePerson || null ,
remark : body . remark || null
remark : body . remark || null
} ;
} ;
if ( isDeviceGroup === '1' ) {
data . installPosition = null ;
data . collectingDeviceId = null ;
data . specificationModel = null ;
data . manufacturer = null ;
data . factoryNo = null ;
data . accuracyLevel = null ;
data . measureRange = null ;
data . communicationProtocol = null ;
data . communicationAddress = null ;
data . collectionCycle = null ;
data . lastVerificationDate = null ;
data . responsibleDept = null ;
data . responsiblePerson = null ;
}
return data ;
}
}
const TABLE = 'measuring_device' ;
const TABLE = 'measuring_device' ;
const selectSql = ` select md.* from ${ TABLE } md ` ;
const selectSql = `
select md . * ,
cd . device _name as collecting _device _name ,
parent . device _name as parent _device _group _name
from $ { TABLE } md
left join collecting _device cd on cd . id collate utf8mb4 _general _ci = md . collecting _device _id collate utf8mb4 _general _ci and cd . del _flag = '0'
left join $ { TABLE } parent on parent . id collate utf8mb4 _general _ci = md . parent _device _group _id collate utf8mb4 _general _ci and parent . del _flag = '0'
` ;
async function loadFloorPathMap ( ) {
async function loadFloorPathMap ( ) {
const rows = await query (
const rows = await query (
@ -201,17 +237,123 @@ async function loadUnitsMap(deviceIds, metricNameMap, deviceTypeMap) {
return map ;
return map ;
}
}
async function loadAlarmRuleMap ( deviceDeviceIds = [ ] ) {
const validDeviceIds = [ ... new Set ( deviceDeviceIds . map ( ( item ) => String ( item || '' ) . trim ( ) ) . filter ( Boolean ) ) ] ;
if ( ! validDeviceIds . length ) return new Map ( ) ;
const rows = await query (
` select id,
rule _name ,
alarm _type ,
alarm _level ,
enabled ,
bind _device _ids
from alarm _rule _info
where del _flag = '0'
and bind _device _ids is not null
and bind _device _ids < > '' `
) ;
const map = new Map ( ) ;
rows . forEach ( ( row ) => {
const bindDeviceIds = String ( row . bind _device _ids || '' )
. split ( ',' )
. map ( ( item ) => item . trim ( ) )
. filter ( Boolean ) ;
bindDeviceIds . forEach ( ( deviceId ) => {
if ( ! validDeviceIds . includes ( deviceId ) ) return ;
if ( ! map . has ( deviceId ) ) map . set ( deviceId , [ ] ) ;
map . get ( deviceId ) . push ( {
id : row . id ,
ruleName : row . rule _name ,
alarmType : row . alarm _type ,
alarmLevel : row . alarm _level ,
enabled : row . enabled
} ) ;
} ) ;
} ) ;
return map ;
}
async function loadChildDeviceMap ( deviceIds = [ ] ) {
const ids = [ ... new Set ( deviceIds . map ( ( item ) => String ( item || '' ) . trim ( ) ) . filter ( Boolean ) ) ] ;
if ( ! ids . length ) return new Map ( ) ;
const params = { } ;
const placeholders = ids . map ( ( id , index ) => {
params [ ` id ${ index } ` ] = id ;
return ` :id ${ index } ` ;
} ) ;
const rows = await query (
` select id,
device _id ,
device _name ,
device _code ,
device _type ,
is _device _group ,
parent _device _group _id ,
specification _model ,
manufacturer ,
factory _no ,
accuracy _level ,
measure _range ,
communication _protocol ,
communication _address ,
collection _cycle ,
status ,
last _verification _date ,
responsible _person ,
remark
from $ { TABLE }
where del _flag = '0'
and parent _device _group _id in ( $ { placeholders . join ( ', ' ) } )
order by is _device _group desc , create _time asc , id asc ` ,
params
) ;
const map = new Map ( ) ;
rows . forEach ( ( row ) => {
const parentId = String ( row . parent _device _group _id || '' ) ;
if ( ! map . has ( parentId ) ) map . set ( parentId , [ ] ) ;
map . get ( parentId ) . push ( {
id : row . id ,
deviceId : row . device _id ,
deviceName : row . device _name ,
deviceCode : row . device _code ,
deviceType : row . device _type ,
isDeviceGroup : row . is _device _group || '0' ,
parentDeviceGroupId : row . parent _device _group _id ,
specificationModel : row . specification _model ,
manufacturer : row . manufacturer ,
factoryNo : row . factory _no ,
accuracyLevel : row . accuracy _level ,
measureRange : row . measure _range ,
communicationProtocol : row . communication _protocol ,
communicationAddress : row . communication _address ,
collectionCycle : row . collection _cycle ,
status : row . status ,
lastVerificationDate : row . last _verification _date ,
responsiblePerson : row . responsible _person ,
remark : row . remark
} ) ;
} ) ;
return map ;
}
async function decorateRows ( rows ) {
async function decorateRows ( rows ) {
const [ floorPathMap , metricNameMap ] = await Promise . all ( [ loadFloorPathMap ( ) , loadMetricNameMap ( ) ] ) ;
const [ floorPathMap , metricNameMap ] = await Promise . all ( [ loadFloorPathMap ( ) , loadMetricNameMap ( ) ] ) ;
const deviceTypeMap = new Map ( rows . map ( ( row ) => [ String ( row . id ) , row . device _type ] ) ) ;
const deviceTypeMap = new Map ( rows . map ( ( row ) => [ String ( row . id ) , row . device _type ] ) ) ;
const unitsMap = await loadUnitsMap ( rows . map ( ( row ) => row . id ) , metricNameMap , deviceTypeMap ) ;
const [ unitsMap , alarmRuleMap , childDeviceMap ] = await Promise . all ( [
loadUnitsMap ( rows . map ( ( row ) => row . id ) , metricNameMap , deviceTypeMap ) ,
loadAlarmRuleMap ( rows . map ( ( row ) => row . device _id ) ) ,
loadChildDeviceMap ( rows . filter ( ( row ) => row . is _device _group === '1' ) . map ( ( row ) => row . id ) )
] ) ;
return rows . map ( ( row ) => ( {
return rows . map ( ( row ) => ( {
... row ,
... row ,
install _position _name : floorPathMap . get ( String ( row . install _position ) ) || '' ,
install _position _name : floorPathMap . get ( String ( row . install _position ) ) || '' ,
standard _unit _name : metricNameMap . get ( ` ${ String ( row . device _type ) } : ${ row . standard _unit } ` ) || row . standard _unit ,
standard _unit _name : metricNameMap . get ( ` ${ String ( row . device _type ) } : ${ row . standard _unit } ` ) || row . standard _unit ,
measuring _unit _summary : ( unitsMap . get ( String ( row . id ) ) || [ ] ) . map ( ( item ) => item . unit . measuringUnit ) . filter ( Boolean ) . join ( '、' ) ,
measuring _unit _summary : ( unitsMap . get ( String ( row . id ) ) || [ ] ) . map ( ( item ) => item . unit . measuringUnit ) . filter ( Boolean ) . join ( '、' ) ,
standard _unit _name _summary : ( unitsMap . get ( String ( row . id ) ) || [ ] ) . map ( ( item ) => item . label ) . filter ( Boolean ) . join ( '; ' ) ,
standard _unit _name _summary : ( unitsMap . get ( String ( row . id ) ) || [ ] ) . map ( ( item ) => item . label ) . filter ( Boolean ) . join ( '; ' ) ,
units : ( unitsMap . get ( String ( row . id ) ) || [ ] ) . map ( ( item ) => item . unit )
units : ( unitsMap . get ( String ( row . id ) ) || [ ] ) . map ( ( item ) => item . unit ) ,
alarm _rules : alarmRuleMap . get ( String ( row . device _id ) ) || [ ] ,
alarm _rule _names : ( alarmRuleMap . get ( String ( row . device _id ) ) || [ ] ) . map ( ( item ) => item . ruleName ) . filter ( Boolean ) . join ( '、' ) ,
child _devices : childDeviceMap . get ( String ( row . id ) ) || [ ]
} ) ) ;
} ) ) ;
}
}
@ -235,6 +377,8 @@ async function saveUnits(deviceId, units = []) {
}
}
async function syncInstallPositionByDeviceId ( ) {
async function syncInstallPositionByDeviceId ( ) {
// floorInfo 现在只维护普通楼层节点,设备树以 measuring_device 为准。
return ;
const [ deviceRows , floorRows ] = await Promise . all ( [
const [ deviceRows , floorRows ] = await Promise . all ( [
query (
query (
` select id, device_id, install_position
` select id, device_id, install_position
@ -301,6 +445,10 @@ async function list(params = {}) {
where . push ( 'md.device_name like :deviceName' ) ;
where . push ( 'md.device_name like :deviceName' ) ;
sqlParams . deviceName = ` % ${ String ( params . deviceName ) . trim ( ) } % ` ;
sqlParams . deviceName = ` % ${ String ( params . deviceName ) . trim ( ) } % ` ;
}
}
if ( params . keyword ) {
where . push ( '(md.device_id like :keyword or md.device_name like :keyword or md.device_code like :keyword)' ) ;
sqlParams . keyword = ` % ${ String ( params . keyword ) . trim ( ) } % ` ;
}
if ( params . deviceCode ) {
if ( params . deviceCode ) {
where . push ( 'md.device_code like :deviceCode' ) ;
where . push ( 'md.device_code like :deviceCode' ) ;
sqlParams . deviceCode = ` % ${ String ( params . deviceCode ) . trim ( ) } % ` ;
sqlParams . deviceCode = ` % ${ String ( params . deviceCode ) . trim ( ) } % ` ;
@ -313,6 +461,14 @@ async function list(params = {}) {
where . push ( 'md.device_type = :deviceType' ) ;
where . push ( 'md.device_type = :deviceType' ) ;
sqlParams . deviceType = String ( params . deviceType ) ;
sqlParams . deviceType = String ( params . deviceType ) ;
}
}
if ( params . isDeviceGroup !== undefined && params . isDeviceGroup !== '' ) {
where . push ( 'md.is_device_group = :isDeviceGroup' ) ;
sqlParams . isDeviceGroup = String ( params . isDeviceGroup ) ;
}
if ( params . parentDeviceGroupId !== undefined && params . parentDeviceGroupId !== '' ) {
where . push ( 'md.parent_device_group_id = :parentDeviceGroupId' ) ;
sqlParams . parentDeviceGroupId = String ( params . parentDeviceGroupId ) ;
}
if ( params . installPosition ) {
if ( params . installPosition ) {
where . push ( 'md.install_position = :installPosition' ) ;
where . push ( 'md.install_position = :installPosition' ) ;
sqlParams . installPosition = String ( params . installPosition ) ;
sqlParams . installPosition = String ( params . installPosition ) ;
@ -345,13 +501,14 @@ async function get(id) {
async function add ( body = { } ) {
async function add ( body = { } ) {
const id = body . id ? String ( body . id ) : nextId ( ) ;
const id = body . id ? String ( body . id ) : nextId ( ) ;
const data = normalizeBody ( body ) ;
const data = normalizeBody ( body ) ;
await assertParentDeviceGroup ( data . parentDeviceGroupId , id ) ;
await query (
await query (
` insert into ${ TABLE }
` insert into ${ TABLE }
( id , device _id , device _name , device _code , install _position , device_type , measuring _unit , standard _unit , conversion _factor ,
( id , device _id , device _name , device _code , install _position , collecting_device _id , device_type , is _device _group , parent _device _group _id , measuring _unit , standard _unit , conversion _factor ,
specification _model , manufacturer , factory _no , accuracy _level , measure _range , communication _protocol , communication _address ,
specification _model , manufacturer , factory _no , accuracy _level , measure _range , communication _protocol , communication _address ,
collection _cycle , status , last _verification _date , responsible _dept , responsible _person , remark , create _time , update _time , del _flag )
collection _cycle , status , last _verification _date , responsible _dept , responsible _person , remark , create _time , update _time , del _flag )
values
values
( : id , : deviceId , : deviceName , : deviceCode , : installPosition , : deviceType, : measuringUnit , : standardUnit , : conversionFactor ,
( : id , : deviceId , : deviceName , : deviceCode , : installPosition , : collectingDeviceId, : deviceType, : isDeviceGroup , : parentDeviceGroupId , : measuringUnit , : standardUnit , : conversionFactor ,
: specificationModel , : manufacturer , : factoryNo , : accuracyLevel , : measureRange , : communicationProtocol , : communicationAddress ,
: specificationModel , : manufacturer , : factoryNo , : accuracyLevel , : measureRange , : communicationProtocol , : communicationAddress ,
: collectionCycle , : status , : lastVerificationDate , : responsibleDept , : responsiblePerson , : remark , now ( ) , now ( ) , '0' ) ` ,
: collectionCycle , : status , : lastVerificationDate , : responsibleDept , : responsiblePerson , : remark , now ( ) , now ( ) , '0' ) ` ,
{ id , ... data }
{ id , ... data }
@ -363,13 +520,17 @@ async function add(body = {}) {
async function update ( body = { } ) {
async function update ( body = { } ) {
if ( ! body . id ) throw new Error ( 'ID不能为空' ) ;
if ( ! body . id ) throw new Error ( 'ID不能为空' ) ;
const data = normalizeBody ( body ) ;
const data = normalizeBody ( body ) ;
await assertParentDeviceGroup ( data . parentDeviceGroupId , body . id ) ;
await query (
await query (
` update ${ TABLE }
` update ${ TABLE }
set device _id = : deviceId ,
set device _id = : deviceId ,
device _name = : deviceName ,
device _name = : deviceName ,
device _code = : deviceCode ,
device _code = : deviceCode ,
install _position = : installPosition ,
install _position = : installPosition ,
collecting _device _id = : collectingDeviceId ,
device _type = : deviceType ,
device _type = : deviceType ,
is _device _group = : isDeviceGroup ,
parent _device _group _id = : parentDeviceGroupId ,
measuring _unit = : measuringUnit ,
measuring _unit = : measuringUnit ,
standard _unit = : standardUnit ,
standard _unit = : standardUnit ,
conversion _factor = : conversionFactor ,
conversion _factor = : conversionFactor ,
@ -393,6 +554,294 @@ async function update(body = {}) {
await saveUnits ( body . id , data . units ) ;
await saveUnits ( body . id , data . units ) ;
}
}
async function assertParentDeviceGroup ( parentDeviceGroupId , selfId ) {
if ( ! parentDeviceGroupId ) return ;
if ( String ( parentDeviceGroupId ) === String ( selfId ) ) {
throw new Error ( '所属设备组不能选择自己' ) ;
}
const parent = await queryOne (
` select id
from $ { TABLE }
where id = : id
and del _flag = '0'
and is _device _group = '1'
limit 1 ` ,
{ id : parentDeviceGroupId }
) ;
if ( ! parent ) throw new Error ( '所属设备组不存在' ) ;
}
async function descendantGroupIds ( parentId , result = new Set ( ) ) {
const children = await query (
` select id
from $ { TABLE }
where del _flag = '0'
and is _device _group = '1'
and parent _device _group _id = : parentId ` ,
{ parentId }
) ;
for ( const child of children ) {
const id = String ( child . id ) ;
if ( result . has ( id ) ) continue ;
result . add ( id ) ;
await descendantGroupIds ( id , result ) ;
}
return result ;
}
async function mountChildren ( body = { } ) {
if ( ! body . parentDeviceGroupId ) throw new Error ( '设备组不能为空' ) ;
const parentId = String ( body . parentDeviceGroupId ) ;
const parent = await queryOne (
` select id
from $ { TABLE }
where id = : id
and del _flag = '0'
and is _device _group = '1'
limit 1 ` ,
{ id : parentId }
) ;
if ( ! parent ) throw new Error ( '设备组不存在' ) ;
const childIds = Array . isArray ( body . childIds )
? body . childIds . map ( ( item ) => String ( item ) . trim ( ) ) . filter ( Boolean )
: String ( body . childIds || '' ) . split ( ',' ) . map ( ( item ) => item . trim ( ) ) . filter ( Boolean ) ;
const uniqueChildIds = [ ... new Set ( childIds ) ] ;
if ( ! uniqueChildIds . length ) return ;
const descendants = await descendantGroupIds ( parentId ) ;
for ( const childId of uniqueChildIds ) {
if ( childId === parentId ) throw new Error ( '不能挂载自身' ) ;
if ( descendants . has ( childId ) ) throw new Error ( '不能重复挂载当前设备组的下级设备组' ) ;
const childDescendants = await descendantGroupIds ( childId ) ;
if ( childDescendants . has ( parentId ) ) throw new Error ( '不能将上级设备组挂载到下级设备组下' ) ;
await query (
` update ${ TABLE }
set parent _device _group _id = : parentId ,
update _time = now ( )
where id = : childId
and del _flag = '0' ` ,
{ parentId , childId }
) ;
}
}
async function unmountChild ( body = { } ) {
if ( ! body . parentDeviceGroupId ) throw new Error ( '设备组不能为空' ) ;
if ( ! body . childId ) throw new Error ( '设备不能为空' ) ;
await query (
` update ${ TABLE }
set parent _device _group _id = null ,
update _time = now ( )
where id = : childId
and parent _device _group _id = : parentDeviceGroupId
and del _flag = '0' ` ,
{
parentDeviceGroupId : String ( body . parentDeviceGroupId ) ,
childId : String ( body . childId )
}
) ;
}
function deviceKey ( row = { } ) {
return row . device _id || row . deviceId || row . device _code || row . deviceCode || row . id || '' ;
}
async function syncFloorNodesForMeasuringDevice ( oldRow , newRow ) {
const oldKey = deviceKey ( oldRow ) ;
const newKey = deviceKey ( newRow ) ;
if ( ! oldKey && ! newKey ) return ;
const isGroup = newRow . isDeviceGroup === '1' || oldRow ? . is _device _group === '1' ;
const idColumn = isGroup ? 'device_group_id' : 'device_id' ;
const flagColumn = isGroup ? 'is_device_group' : 'is_device' ;
await query (
` update floorInfo
set $ { idColumn } = : newKey ,
name = : name ,
device _type = : deviceType ,
update _time = now ( )
where del _flag = '0'
and $ { flagColumn } = '1'
and $ { idColumn } collate utf8mb4 _general _ci = : oldKey collate utf8mb4 _general _ci ` ,
{
oldKey : String ( oldKey || newKey ) ,
newKey : String ( newKey || oldKey ) ,
name : newRow . deviceName || oldRow ? . device _name || '' ,
deviceType : newRow . deviceType === undefined || newRow . deviceType === null || newRow . deviceType === '' ? null : Number ( newRow . deviceType )
}
) ;
}
async function markFloorNodesRemovedForMeasuringDevices ( rows = [ ] ) {
for ( const row of rows ) {
const key = deviceKey ( row ) ;
if ( ! key ) continue ;
const isGroup = row . is _device _group === '1' ;
const idColumn = isGroup ? 'device_group_id' : 'device_id' ;
const flagColumn = isGroup ? 'is_device_group' : 'is_device' ;
const matched = await query (
` select id
from floorInfo
where del _flag = '0'
and $ { flagColumn } = '1'
and $ { idColumn } collate utf8mb4 _general _ci = : deviceKey collate utf8mb4 _general _ci ` ,
{ deviceKey : String ( key ) }
) ;
await removeFloorNodes ( matched . map ( ( item ) => item . id ) ) ;
}
}
async function removeFloorNodes ( ids = [ ] ) {
const uniqueIds = [ ... new Set ( ids . map ( ( item ) => String ( item || '' ) . trim ( ) ) . filter ( Boolean ) ) ] ;
if ( ! uniqueIds . length ) return ;
const rows = await query ( ` select id, pid from floorInfo where del_flag = '0' ` ) ;
const removeIds = [ ] ;
const visit = ( id ) => {
if ( removeIds . includes ( String ( id ) ) ) return ;
removeIds . push ( String ( id ) ) ;
rows . filter ( ( row ) => String ( row . pid || '0' ) === String ( id ) ) . forEach ( ( row ) => visit ( row . id ) ) ;
} ;
uniqueIds . forEach ( visit ) ;
const params = { } ;
const placeholders = removeIds . map ( ( id , index ) => {
params [ ` id ${ index } ` ] = id ;
return ` :id ${ index } ` ;
} ) ;
await query (
` update floorInfo
set del _flag = '1' ,
update _time = now ( )
where id in ( $ { placeholders . join ( ',' ) } ) ` ,
params
) ;
}
async function syncFloorGroupsByMeasuringGroupIds ( groupIds = [ ] , visited = new Set ( ) ) {
const ids = [ ... new Set ( groupIds . map ( ( item ) => String ( item || '' ) . trim ( ) ) . filter ( Boolean ) ) ] ;
for ( const id of ids ) {
if ( visited . has ( id ) ) continue ;
visited . add ( id ) ;
const group = await queryOne (
` select id, device_id, device_name, device_code, device_type
from $ { TABLE }
where id = : id
and del _flag = '0'
and is _device _group = '1'
limit 1 ` ,
{ id }
) ;
if ( ! group ) continue ;
await syncOneFloorGroup ( group , visited ) ;
}
}
async function syncOneFloorGroup ( group , visited ) {
const groupKeys = [ group . id , group . device _id , group . device _code ] . map ( ( item ) => String ( item || '' ) . trim ( ) ) . filter ( Boolean ) ;
if ( ! groupKeys . length ) return ;
const params = { } ;
const groupPlaceholders = groupKeys . map ( ( key , index ) => {
params [ ` groupKey ${ index } ` ] = key ;
return ` :groupKey ${ index } ` ;
} ) ;
const floorGroups = await query (
` select id
from floorInfo
where del _flag = '0'
and is _device _group = '1'
and device _group _id in ( $ { groupPlaceholders . join ( ',' ) } ) ` ,
params
) ;
if ( ! floorGroups . length ) return ;
const children = await query (
` select id, device_id, device_name, device_code, device_type, is_device_group
from $ { TABLE }
where del _flag = '0'
and parent _device _group _id = : groupId
order by is _device _group desc , create _time asc , id asc ` ,
{ groupId : group . id }
) ;
const expected = new Set ( children . map ( ( child ) => ` ${ child . is _device _group === '1' ? 'group' : 'device' } : ${ deviceKey ( child ) } ` ) ) ;
for ( const floorGroup of floorGroups ) {
await query (
` update floorInfo
set name = : name ,
device _type = : deviceType ,
update _time = now ( )
where id = : id ` ,
{
id : floorGroup . id ,
name : group . device _name || group . device _code || group . device _id || '' ,
deviceType : group . device _type === undefined || group . device _type === null ? null : Number ( group . device _type )
}
) ;
const currentChildren = await query (
` select id, is_device, device_id, is_device_group, device_group_id
from floorInfo
where del _flag = '0'
and pid = : pid
and ( is _device = '1' or is _device _group = '1' ) ` ,
{ pid : floorGroup . id }
) ;
const staleIds = currentChildren
. filter ( ( child ) => {
const key = child . is _device _group === '1' ? ` group: ${ child . device _group _id } ` : ` device: ${ child . device _id } ` ;
return ! expected . has ( key ) ;
} )
. map ( ( child ) => child . id ) ;
await removeFloorNodes ( staleIds ) ;
for ( const child of children ) {
const isGroup = child . is _device _group === '1' ;
const childKey = deviceKey ( child ) ;
const existing = await queryOne (
` select id
from floorInfo
where del _flag = '0'
and $ { isGroup ? 'is_device_group' : 'is_device' } = '1'
and $ { isGroup ? 'device_group_id' : 'device_id' } collate utf8mb4 _general _ci = : childKey collate utf8mb4 _general _ci
limit 1 ` ,
{ childKey : String ( childKey ) }
) ;
if ( existing ) {
await query (
` update floorInfo
set pid = : pid ,
name = : name ,
device _type = : deviceType ,
update _time = now ( )
where id = : id ` ,
{
id : existing . id ,
pid : floorGroup . id ,
name : child . device _name || child . device _code || child . device _id || '' ,
deviceType : child . device _type === undefined || child . device _type === null ? null : Number ( child . device _type )
}
) ;
} else {
await query (
` insert into floorInfo
( id , pid , name , create _time , update _time , del _flag , is _device , device _id , is _device _group , device _group _id , device _type , reserve5 )
values
( : id , : pid , : name , now ( ) , now ( ) , '0' , : isDevice , : deviceId , : isDeviceGroup , : deviceGroupId , : deviceType , null ) ` ,
{
id : nextId ( ) ,
pid : floorGroup . id ,
name : child . device _name || child . device _code || child . device _id || '' ,
isDevice : isGroup ? '0' : '1' ,
deviceId : isGroup ? null : childKey ,
isDeviceGroup : isGroup ? '1' : '0' ,
deviceGroupId : isGroup ? childKey : null ,
deviceType : child . device _type === undefined || child . device _type === null ? null : Number ( child . device _type )
}
) ;
}
if ( isGroup ) await syncFloorGroupsByMeasuringGroupIds ( [ child . id ] , visited ) ;
}
}
}
async function remove ( ids ) {
async function remove ( ids ) {
const list = String ( ids || '' )
const list = String ( ids || '' )
. split ( ',' )
. split ( ',' )
@ -419,5 +868,7 @@ module.exports = {
get ,
get ,
add ,
add ,
update ,
update ,
mountChildren ,
unmountChild ,
remove
remove
} ;
} ;