Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
DC-TOM
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
刘照晖
DC-TOM
Commits
d49271c4
Commit
d49271c4
authored
May 23, 2025
by
Cai Wei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(*): 首页及除尘器总览连调
parent
d5aaddd8
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
454 additions
and
438 deletions
+454
-438
dashboard.js
src/request/api/dashboard.js
+7
-0
dustOverview.js
src/request/api/dustOverview.js
+75
-3
map-svg.vue
src/views/dashboard/components/map-svg.vue
+62
-38
index.vue
src/views/dashboard/index.vue
+12
-47
addDustCollectorDialog.vue
src/views/dustOverview/components/addDustCollectorDialog.vue
+163
-87
index.vue
src/views/dustOverview/index.vue
+135
-263
No files found.
src/request/api/dashboard.js
View file @
d49271c4
...
...
@@ -19,3 +19,10 @@ export function getExceptionMonitor() {
method
:
"get"
,
});
}
export
function
getDusterAlarm
()
{
return
request
({
url
:
"/api/home/duster/alarm"
,
method
:
"get"
,
});
}
src/request/api/dustOverview.js
View file @
d49271c4
...
...
@@ -7,15 +7,87 @@ export function getDusterLeakNum() {
}
export
function
getHealthPercent
()
{
return
request
({
url
:
"/getHealthPercent"
,
method
:
"get"
,
});
}
export
function
getCloseLoopNum
()
{
return
request
({
url
:
"/getCloseLoopNum"
,
method
:
"get"
,
});
}
export
function
getProductionLine
()
{
return
request
({
url
:
"/transaction/getProductionLine"
,
method
:
"get"
,
});
}
export
function
getDusterList
(
params
)
{
return
request
({
url
:
"/getDusterList"
,
method
:
"get"
,
params
,
});
}
export
function
getVisDusterList
(
params
)
{
return
request
({
url
:
"/
getHealthPercen
t"
,
url
:
"/
queryVisDusterLis
t"
,
method
:
"get"
,
params
,
});
}
export
function
postAddDuster
(
params
)
{
return
request
({
url
:
"/addDuster"
,
method
:
"post"
,
data
:
params
,
});
}
export
function
postUpdateDuster
(
params
)
{
return
request
({
url
:
"/updateDuster"
,
method
:
"post"
,
data
:
params
,
});
}
export
function
getCompartAllocation
(
params
)
{
return
request
({
url
:
"/queryCompartAllocation"
,
method
:
"get"
,
params
,
});
}
export
function
postAddCompartAllocation
(
params
)
{
return
request
({
url
:
"/addCompartAllocation"
,
method
:
"post"
,
data
:
params
,
});
}
export
function
postAddValveInfo
(
params
)
{
return
request
({
url
:
"/addValveInfo"
,
method
:
"post"
,
data
:
params
,
});
}
export
function
get
CloseLoopNum
(
)
{
export
function
get
ValveAllocation
(
params
)
{
return
request
({
url
:
"/
getCloseLoopNum
"
,
url
:
"/
queryValveAllocation
"
,
method
:
"get"
,
params
,
});
}
\ No newline at end of file
src/views/dashboard/components/map-svg.vue
View file @
d49271c4
...
...
@@ -59,48 +59,65 @@
</
template
>
<
script
setup
>
import
{
onMounted
,
onBeforeUnmount
,
ref
}
from
"vue"
;
import
{
onMounted
,
onBeforeUnmount
,
ref
,
watch
}
from
"vue"
;
import
*
as
echarts
from
"echarts"
;
import
{
getLineOption
}
from
"@/utils/chart"
;
// 定义坐标点位数据
const
spots
=
ref
([
{
id
:
1
,
no
:
"wp001"
,
x
:
41
,
y
:
22
,
name
:
"4#除尘器"
,
status
:
0
,
description
:
[
"无异常"
],
},
{
id
:
2
,
no
:
"wp001"
,
x
:
45
,
y
:
70
,
name
:
"站点B"
,
status
:
0
,
description
:
[
"运行正常"
],
},
{
id
:
3
,
no
:
"wp001"
,
x
:
77
,
y
:
36
,
name
:
"3#除尘器"
,
status
:
1
,
description
:
[
"三仓室存在轻微泄漏"
,
"三仓室存在轻微泄漏"
,
"三仓室存在轻微泄漏"
],
const
props
=
defineProps
({
mapList
:
{
type
:
Array
,
default
:
()
=>
[],
},
{
id
:
4
,
no
:
"wp001"
,
x
:
50
,
y
:
65
,
name
:
"2#除尘器"
,
status
:
1
,
description
:
[
"除尘器脉冲阀故障或者提升阀故障"
],
});
watch
(
()
=>
props
.
mapList
,
()
=>
{
initMap
();
},
{
deep
:
true
}
);
// 定义坐标点位数据
const
spots
=
ref
([
// {
// id:1,
// no: "wp001",
// x: 41,
// y: 22,
// name: "4#除尘器",
// status: 0,
// description: ["无异常"],
// },
// {
// id:2,
// no: "wp001",
// x: 45,
// y: 70,
// name: "站点B",
// status: 0,
// description: ["运行正常"],
// },
// {
// id:3,
// no: "wp001",
// x: 77,
// y: 36,
// name: "3#除尘器",
// status: 1,
// description: ["三仓室存在轻微泄漏", "三仓室存在轻微泄漏", "三仓室存在轻微泄漏"],
// },
// {
// id:4,
// no: "wp001",
// x: 50,
// y: 65,
// name: "2#除尘器",
// status: 1,
// description: ["除尘器脉冲阀故障或者提升阀故障"],
// },
]);
const
activeSpot
=
ref
(
null
);
...
...
@@ -160,7 +177,14 @@ const getStatusText = (status) => {
return
statusMap
[
status
]
||
status
;
};
onMounted
(()
=>
{});
const
initMap
=
()
=>
{
console
.
log
(
props
.
mapList
,
'props.mapList'
)
spots
.
value
=
props
.
mapList
||
[];
}
onMounted
(()
=>
{
initMap
();
});
onBeforeUnmount
(()
=>
{
clearTimer
();
...
...
src/views/dashboard/index.vue
View file @
d49271c4
...
...
@@ -28,14 +28,14 @@
</div>
<div
class=
"map-box"
>
<map-svg></map-svg>
<map-svg
:mapList=
"mapList"
></map-svg>
</div>
</div>
</
template
>
<
script
setup
>
import
{
ref
,
onMounted
,
onBeforeUnmount
,
computed
,
nextTick
}
from
"vue"
;
import
{
getHealthOverview
,
getHealthStatistic
,
getExceptionMonitor
}
from
"@/request/api/dashboard"
;
import
{
getHealthOverview
,
getHealthStatistic
,
getExceptionMonitor
,
getDusterAlarm
}
from
"@/request/api/dashboard"
;
import
{
useRoute
,
useRouter
}
from
"vue-router"
;
import
msgItem
from
"./components/msg-item.vue"
;
import
chartLine
from
"./components/chart-line.vue"
;
...
...
@@ -58,6 +58,7 @@ const router = useRouter();
const
msgList
=
ref
([
]);
const
mapList
=
ref
([]);
const
customColorMethod
=
(
percentage
)
=>
{
if
(
percentage
<
60
)
{
...
...
@@ -76,69 +77,33 @@ const healthOverview = () => {
pulseValve
.
value
=
Number
(
res
.
data
.
pulseValve
.
split
(
'%'
)[
0
])
poppetValve
.
value
=
Number
(
res
.
data
.
poppetValve
.
split
(
'%'
)[
0
])
})
// const res = {
// "data": {
// "average": "20%",
// "bag": "10%",
// "pulseValve": "20%",
// "poppetValve": "30%"
// },
// msg: "访问成功",
// success: true,
// code: 1
// }
}
const
healthStatistic
=
()
=>
{
getHealthStatistic
().
then
(
res
=>
{
chartData
.
value
=
res
.
data
;
})
// const res = {
// "data": [
// {
// "date": "2025-05-01",
// "healthDegree": "75"
// },
// {
// "date": "2025-05-02",
// "healthDegree": "68"
// }
// ],
// "msg": "访问成功",
// "success": true,
// code: 1,
// };
};
const
exceptionMonitor
=
()
=>
{
getExceptionMonitor
().
then
(
res
=>
{
msgList
.
value
=
res
.
data
;
})
// const res = {
// "data": [
// {
// "date": "2025-05-01 10:00",
// "dusterName": "3#除尘器",
// "message": "三仓室存在轻重泄露"
// },
// {
// "date": "2025-05-01 10:00",
// "dusterName": "3#除尘器",
// "message": "三仓室存在轻重泄露"
// }
// ],
// msg: "访问成功",
// success: true,
// code: 1
// }
// msgList.value = res.data;
}
const
handleDusterAlarm
=
()
=>
{
getDusterAlarm
().
then
(
res
=>
{
mapList
.
value
=
res
.
data
;
})
}
onMounted
(
async
()
=>
{
healthOverview
();
healthStatistic
();
exceptionMonitor
();
handleDusterAlarm
();
});
onBeforeUnmount
(()
=>
{
});
...
...
src/views/dustOverview/components/addDustCollectorDialog.vue
View file @
d49271c4
<
template
>
<el-dialog
:model-value=
"modelValue"
title=
"新增除尘器"
width=
"460px"
:close-on-click-modal=
"false"
:close-on-press-escape=
"false"
@
update:model-value=
"$emit('update:modelValue', $event)"
>
<el-dialog
:model-value=
"modelValue"
title=
"新增除尘器"
width=
"460px"
:close-on-click-modal=
"false"
:close-on-press-escape=
"false"
@
update:model-value=
"$emit('update:modelValue', $event)"
>
<div
class=
"add-dust-form"
>
<div
class=
"form-item"
>
<div
class=
"selector-wrap"
>
<el-select
v-model=
"formData.dustType"
placeholder=
"除尘器选择"
style=
"width: 238px"
>
<el-option
v-for=
"item in dustTypeOptions"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
<el-select
v-model=
"formData.dustType"
placeholder=
"除尘器选择"
style=
"width: 238px"
filterable
remote
:remote-method=
"handleSearch"
:loading=
"loading"
>
<el-option
v-for=
"item in dustTypeOptions"
:key=
"item.deviceNo"
:label=
"item.deviceName"
:value=
"item.deviceNo"
/>
</el-select>
<el-button
type=
"primary"
size=
"default"
@
click=
"selectDustType"
>
选择
</el-button>
</div>
...
...
@@ -27,19 +18,15 @@
<el-form-item
label=
"除尘器名称"
prop=
"name"
>
<el-input
v-model=
"formData.name"
placeholder=
"请输入"
/>
</el-form-item>
<el-form-item
label=
"除尘器编号"
prop=
"code"
>
<el-input
v-model=
"formData.code"
placeholder=
"请输入"
/>
</el-form-item>
<el-form-item
label=
"所属工序"
prop=
"process"
>
<el-select
v-model=
"formData.process"
placeholder=
"工序选择"
>
<el-option
v-for=
"item in processOptions"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
<el-option
v-for=
"item in processOptions"
:key=
"item.productionLineId"
:label=
"item.productionLineName"
:value=
"item.productionLineId"
/>
</el-select>
</el-form-item>
...
...
@@ -51,17 +38,36 @@
<el-input
v-model
.
number=
"formData.valveCount"
placeholder=
"请输入"
/>
</el-form-item>
<el-form-item
label=
"合理压差范围"
prop=
"pressureRange"
>
<el-form-item
label=
"合理压差范围"
>
<div
class=
"range-input"
>
<el-input
v-model
.
number=
"formData.pressureMin"
placeholder=
"请输入"
/>
<el-form-item
prop=
"pressureMin"
class=
"coordinate-item"
>
<el-input
v-model
.
number=
"formData.pressureMin"
placeholder=
"请输入"
/>
</el-form-item>
<span
class=
"separator"
>
~
</span>
<el-input
v-model
.
number=
"formData.pressureMax"
placeholder=
"请输入"
/>
<el-form-item
prop=
"pressureMax"
class=
"coordinate-item"
>
<el-input
v-model
.
number=
"formData.pressureMax"
placeholder=
"请输入"
/>
</el-form-item>
</div>
</el-form-item>
<el-form-item
label=
"服务器IP"
prop=
"serverIp"
>
<el-form-item
label=
"服务器IP"
prop=
"serverIp"
required
>
<el-input
v-model=
"formData.serverIp"
placeholder=
"请输入"
/>
</el-form-item>
<el-form-item
label=
"二维图坐标"
required
>
<div
class=
"coordinate-inputs"
>
<el-form-item
prop=
"coordinateX"
class=
"coordinate-item"
>
<el-input
v-model
.
number=
"formData.coordinateX"
placeholder=
"X坐标"
>
<template
#
prefix
>
X:
</
template
>
</el-input>
</el-form-item>
<el-form-item
prop=
"coordinateY"
class=
"coordinate-item"
>
<el-input
v-model
.
number=
"formData.coordinateY"
placeholder=
"Y坐标"
>
<
template
#
prefix
>
Y:
</
template
>
</el-input>
</el-form-item>
</div>
</el-form-item>
</el-form>
</div>
...
...
@@ -75,29 +81,26 @@
</template>
<
script
setup
>
import
{
ref
,
reactive
}
from
'vue'
;
import
{
ref
,
reactive
,
onMounted
}
from
'vue'
;
import
{
getVisDusterList
,
getProductionLine
}
from
"@/request/api/dustOverview"
;
const
props
=
defineProps
({
modelValue
:
{
type
:
Boolean
,
default
:
false
}
}
,
});
const
emit
=
defineEmits
([
'update:modelValue'
,
'save'
]);
const
formRef
=
ref
(
null
);
const
dustTypeOptions
=
[
{
value
:
1
,
label
:
'除尘器类型1'
},
{
value
:
2
,
label
:
'除尘器类型2'
},
{
value
:
3
,
label
:
'除尘器类型3'
}
];
const
dustTypeOptions
=
ref
([]);
const
allDustOptions
=
ref
([]);
const
processOptions
=
ref
([]);
const
processOptions
=
[
{
value
:
1
,
label
:
'转炉'
},
{
value
:
2
,
label
:
'炼铁'
}
];
const
lastSearchQuery
=
ref
(
''
);
const
formData
=
reactive
({
dustType
:
''
,
...
...
@@ -108,7 +111,9 @@ const formData = reactive({
valveCount
:
null
,
pressureMin
:
null
,
pressureMax
:
null
,
serverIp
:
''
serverIp
:
''
,
coordinateX
:
null
,
coordinateY
:
null
});
const
rules
=
{
...
...
@@ -125,45 +130,124 @@ const rules = {
],
pressureMin
:
[
{
required
:
true
,
message
:
'请输入最小压差'
,
trigger
:
'blur'
},
{
type
:
'number'
,
message
:
'必须为数字'
,
trigger
:
'blur'
}
{
type
:
'number'
,
min
:
1
,
message
:
'最小压差必须大于0'
,
trigger
:
'blur'
},
{
validator
:
(
rule
,
value
,
callback
)
=>
{
if
(
value
&&
formData
.
pressureMax
&&
value
>=
formData
.
pressureMax
)
{
callback
(
new
Error
(
'必须小于最大压差'
));
}
else
{
callback
();
}
},
trigger
:
'blur'
}
],
pressureMax
:
[
{
required
:
true
,
message
:
'请输入最大压差'
,
trigger
:
'blur'
},
{
type
:
'number'
,
message
:
'必须为数字'
,
trigger
:
'blur'
}
{
type
:
'number'
,
min
:
0
,
message
:
'最大压差必须大于0'
,
trigger
:
'blur'
},
{
validator
:
(
rule
,
value
,
callback
)
=>
{
if
(
value
&&
formData
.
pressureMin
&&
value
<=
formData
.
pressureMin
)
{
callback
(
new
Error
(
'必须大于最小压差'
));
}
else
{
callback
();
}
},
trigger
:
'blur'
}
],
serverIp
:
[
{
required
:
true
,
message
:
'请输入服务器IP'
,
trigger
:
'blur'
},
{
pattern
:
/^
(\d{1,3}\.){3}\d{1,3}
$/
,
message
:
'IP地址格式不正确'
,
trigger
:
'blur'
}
],
coordinateX
:
[
{
required
:
true
,
message
:
'请输入X坐标'
,
trigger
:
'blur'
},
{
type
:
'number'
,
message
:
'X坐标必须为数字'
,
trigger
:
'blur'
}
],
coordinateY
:
[
{
required
:
true
,
message
:
'请输入Y坐标'
,
trigger
:
'blur'
},
{
type
:
'number'
,
message
:
'Y坐标必须为数字'
,
trigger
:
'blur'
}
]
};
const
selectDustType
=
()
=>
{
// 这里可以根据选择的除尘器类型预填充表单数据
// 如果有预设模板数据,可以在这里设置
console
.
log
(
'Selected dust type:'
,
formData
.
dustType
);
const
loading
=
ref
(
false
);
const
initDustOptions
=
()
=>
{
loading
.
value
=
true
;
getVisDusterList
().
then
(
res
=>
{
dustTypeOptions
.
value
=
res
.
data
;
allDustOptions
.
value
=
res
.
data
;
loading
.
value
=
false
;
}).
catch
(()
=>
{
loading
.
value
=
false
;
});
};
const
handleSearch
=
(
query
)
=>
{
if
(
query
===
lastSearchQuery
.
value
)
{
return
;
}
lastSearchQuery
.
value
=
query
;
if
(
!
query
)
{
dustTypeOptions
.
value
=
allDustOptions
.
value
;
return
;
}
loading
.
value
=
true
;
const
params
=
{
deviceName
:
query
};
getVisDusterList
(
params
).
then
(
res
=>
{
dustTypeOptions
.
value
=
res
.
data
;
loading
.
value
=
false
;
}).
catch
(()
=>
{
loading
.
value
=
false
;
});
};
const
productionLine
=
()
=>
{
getProductionLine
().
then
(
res
=>
{
processOptions
.
value
=
res
.
data
;
})
}
onMounted
(()
=>
{
productionLine
();
initDustOptions
();
});
const
selectDustType
=
()
=>
{
const
item
=
dustTypeOptions
.
value
.
find
(
item
=>
item
.
deviceNo
===
formData
.
dustType
);
formData
.
name
=
item
.
deviceName
;
formData
.
code
=
item
.
deviceNo
;
formData
.
process
=
item
.
productionLineId
;
// 校验表单
formRef
.
value
.
validate
((
valid
)
=>
{
});
};
const
submitForm
=
()
=>
{
if
(
!
formRef
.
value
)
return
;
formRef
.
value
.
validate
((
valid
)
=>
{
if
(
valid
)
{
// 组装压差范围
const
pressureRange
=
`
${
formData
.
pressureMin
}
~
${
formData
.
pressureMax
}
`
;
// 准备提交的数据
const
submitData
=
{
dustType
:
formData
.
dustType
,
deviceName
:
formData
.
name
,
deviceNo
:
formData
.
code
,
process
:
formData
.
process
,
healthScore
:
formData
.
chamberCount
,
// 仓室数量保存在healthScore
health2Score
:
formData
.
valveCount
,
// 电磁阀数量保存在health2Score
lastAlarmTime
:
pressureRange
,
// 合理压差范围保存在lastAlarmTime字段
serverIp
:
formData
.
serverIp
,
// 生成默认的状态矩阵
status
:
generateDefaultStatus
(
formData
.
chamberCount
)
deviceName
:
formData
.
name
,
productionLineId
:
formData
.
process
,
compartNum
:
formData
.
chamberCount
,
valveNum
:
formData
.
valveCount
,
serviceIp
:
formData
.
serverIp
,
pressureDiffLow
:
formData
.
pressureMin
,
pressureDiffHigh
:
formData
.
pressureMax
,
x
:
formData
.
coordinateX
,
y
:
formData
.
coordinateY
,
};
// 发送数据到父组件处理保存逻辑
emit
(
'save'
,
submitData
);
emit
(
'update:modelValue'
,
false
);
...
...
@@ -183,33 +267,11 @@ const cancel = () => {
formData
.
process
=
''
;
formData
.
chamberCount
=
null
;
formData
.
valveCount
=
null
;
formData
.
coordinateX
=
null
;
formData
.
coordinateY
=
null
;
emit
(
'update:modelValue'
,
false
);
};
// 生成默认的状态矩阵
const
generateDefaultStatus
=
(
totalChambers
)
=>
{
// 默认状态:正常(status=1),每排最多5个仓室
const
rows
=
Math
.
ceil
(
totalChambers
/
5
);
const
result
=
[];
let
chamberIndex
=
1
;
for
(
let
rowIndex
=
0
;
rowIndex
<
rows
;
rowIndex
++
)
{
const
row
=
[];
const
chambersInRow
=
Math
.
min
(
5
,
totalChambers
-
rowIndex
*
5
);
for
(
let
i
=
0
;
i
<
chambersInRow
;
i
++
)
{
row
.
push
({
index
:
chamberIndex
++
,
status
:
1
,
// 正常状态
count
:
1
// 默认阀门数量
});
}
result
.
push
(
row
);
}
return
result
;
};
</
script
>
<
style
lang=
"scss"
scoped
>
...
...
@@ -220,7 +282,7 @@ const generateDefaultStatus = (totalChambers) => {
margin-bottom
:
20px
;
padding
:
0
0
0
50px
;
box-sizing
:
border-box
;
.number-badge
{
width
:
24px
;
height
:
24px
;
...
...
@@ -232,7 +294,7 @@ const generateDefaultStatus = (totalChambers) => {
font-weight
:
bold
;
margin-right
:
10px
;
}
.selector-wrap
{
display
:
flex
;
align-items
:
center
;
...
...
@@ -240,26 +302,26 @@ const generateDefaultStatus = (totalChambers) => {
flex
:
1
;
}
}
.form-content
{
padding
:
0
30px
;
.range-input
{
display
:
flex
;
align-items
:
center
;
.separator
{
margin
:
0
5px
;
color
:
#606266
;
}
}
}
.form-footer
{
margin-top
:
20px
;
display
:
flex
;
justify-content
:
center
;
.el-button
{
width
:
120px
;
}
...
...
@@ -278,4 +340,18 @@ const generateDefaultStatus = (totalChambers) => {
:deep
(
.el-select
)
{
width
:
100%
;
}
</
style
>
\ No newline at end of file
.coordinate-inputs
{
display
:
flex
;
gap
:
10px
;
.coordinate-item
{
flex
:
1
;
margin-bottom
:
0
;
:deep
(
.el-input__prefix
)
{
color
:
#606266
;
}
}
}
</
style
>
\ No newline at end of file
src/views/dustOverview/index.vue
View file @
d49271c4
...
...
@@ -33,14 +33,20 @@
<el-select
v-model=
"formInline.region"
placeholder=
"请选择工序"
style=
"width: 120px"
clearable
style=
"width: 180px"
filterable
:filter-method=
"filterProductionLine"
>
<el-option
key=
"all"
label=
"全部"
value=
"all"
/>
<el-option
v-for=
"item in
options
"
:key=
"item.
value
"
:label=
"item.
label
"
:value=
"item.
value
"
v-for=
"item in
productionLineFiltered
"
:key=
"item.
productionLineId
"
:label=
"item.
productionLineName
"
:value=
"item.
productionLineId
"
/>
</el-select>
</el-form-item>
...
...
@@ -54,7 +60,7 @@
</el-form-item>
<el-form-item>
<el-button
type=
"default"
class=
"default-btn"
@
click=
"
onSubmit
"
<el-button
type=
"default"
class=
"default-btn"
@
click=
"
refreshData
"
>
重置
</el-button
>
<el-button
type=
"primary"
class=
"search-btn"
@
click=
"onSubmit"
...
...
@@ -83,20 +89,20 @@
<template
#
index=
"
{ $index }">
{{
getIndex
(
$index
)
}}
</
template
>
<
template
#
healthScore
=
"{ row }"
>
<
template
#
compartNum
=
"{ row }"
>
<span
class=
"health-score"
@
click=
"handleHealthScoreClick(row)"
>
{{
row
.
healthScore
row
.
compartNum
}}
</span>
</
template
>
<
template
#
health2Score
=
"{ row }"
>
<span
class=
"health-score"
@
click=
"handle
Health2Score
Click(row)"
>
{{
row
.
health2Score
<
template
#
valveNum
=
"{ row }"
>
<span
class=
"health-score"
@
click=
"handle
valveNum
Click(row)"
>
{{
row
.
valveNum
}}
</span>
</
template
>
<
template
#
status
=
"{ row }"
>
<div
class=
"status-matrix"
>
<
template
#
compartHealthList
=
"{ row }"
>
<div
class=
"status-matrix"
v-if=
"row.compartHealthList.length > 0"
>
<div
v-for=
"(row, rowIndex) in row.
status
"
v-for=
"(row, rowIndex) in row.
compartHealthList
"
:key=
"rowIndex"
class=
"matrix-row"
>
...
...
@@ -105,18 +111,25 @@
:key=
"colIndex"
class=
"status-dot"
:class=
"
{
'status-normal': status.
s
tatus === 1,
'status-warning': status.
s
tatus === 2,
'status-error': status.
s
tatus === 3,
'status-normal': status.
healthS
tatus === 1,
'status-warning': status.
healthS
tatus === 2,
'status-error': status.
healthS
tatus === 3,
}"
>
</div>
</div>
</div>
<div
v-else
>
-
</div>
</
template
>
<
template
#
healthPercent=
"{ row }"
>
<span
:style=
"
{ color: getHealthScoreColor(row.healthPercent) }">
{{
row
.
healthPercent
}}
</span>
</
template
>
<
template
#
alarmCount
=
"{ row }"
>
<span
:style=
"
{ color: getHealthScoreColor(row.alarmCount) }"
>
{{
row
.
alarmCount
}}
<
template
#
pressureDiffLow
=
"{ row }"
>
<span>
{{
row
.
pressureDiffLow
}}
~
{{
row
.
pressureDiffHigh
}}
</span>
</
template
>
...
...
@@ -153,8 +166,8 @@
</template>
<
script
setup
>
import
{
ref
,
onMounted
,
onBeforeUnmount
,
computed
}
from
"vue"
;
import
{
getDusterLeakNum
,
getHealthPercent
,
getCloseLoopNum
}
from
"@/request/api/dustOverview"
;
import
{
ref
,
onMounted
,
onBeforeUnmount
,
computed
,
watch
}
from
"vue"
;
import
{
getDusterLeakNum
,
getHealthPercent
,
getCloseLoopNum
,
getProductionLine
,
getDusterList
,
postAddDuster
,
postUpdateDuster
}
from
"@/request/api/dustOverview"
;
import
CommonTable
from
"@/components/commonTable/index.vue"
;
import
RoomSettingDialog
from
"./components/roomSettingDialog.vue"
;
import
ValveSettingDialog
from
"./components/valveSettingDialog.vue"
;
...
...
@@ -162,7 +175,7 @@ import AddDustCollectorDialog from "./components/addDustCollectorDialog.vue";
const
formInline
=
ref
({
deviceName
:
""
,
region
:
1
,
region
:
'all'
,
});
const
currentPage
=
ref
(
1
);
...
...
@@ -171,16 +184,8 @@ const dusterLeakNum = ref(0);
const
healthPercent
=
ref
(
'100%'
);
const
closeLoopNum
=
ref
(
0
);
const
options
=
ref
([
{
value
:
1
,
label
:
"转炉"
,
},
{
value
:
2
,
label
:
"炼铁"
,
},
]);
const
productionLine
=
ref
([]);
const
productionLineFiltered
=
ref
([]);
// 用于存储过滤后的工序
const
tableColumns
=
ref
([
{
...
...
@@ -199,32 +204,32 @@ const tableColumns = ref([
width
:
"12%"
,
},
{
prop
:
"pro
cess
"
,
prop
:
"pro
ductionLine
"
,
label
:
"所属工序"
,
width
:
"5%"
,
},
{
prop
:
"
healthScore
"
,
prop
:
"
compartNum
"
,
label
:
"仓室数量"
,
width
:
"8%"
,
},
{
prop
:
"
health2Score
"
,
prop
:
"
valveNum
"
,
label
:
"电磁阀数量"
,
width
:
"8%"
,
},
{
prop
:
"
status
"
,
prop
:
"
compartHealthList
"
,
label
:
"仓室健康状态"
,
width
:
"25%"
,
},
{
prop
:
"
alarmCou
nt"
,
prop
:
"
healthPerce
nt"
,
label
:
"健康度"
,
width
:
"5%"
,
},
{
prop
:
"
lastAlarmTime
"
,
prop
:
"
pressureDiffLow
"
,
label
:
"合理压差范围"
,
width
:
"10%"
,
},
...
...
@@ -235,216 +240,21 @@ const tableColumns = ref([
},
]);
const
tableData
=
[
{
deviceName
:
"1#除尘器"
,
deviceNo
:
"1234567890"
,
process
:
"转炉"
,
healthScore
:
10
,
health2Score
:
11
,
status
:
[
[
{
index
:
1
,
status
:
1
,
count
:
1
,
},
{
index
:
2
,
status
:
2
,
count
:
2
,
},
{
index
:
3
,
status
:
1
,
count
:
1
,
},
{
index
:
4
,
status
:
1
,
count
:
1
,
},
{
index
:
5
,
status
:
3
,
count
:
1
,
},
],
[
{
index
:
6
,
status
:
1
,
count
:
1
,
},
{
index
:
7
,
status
:
1
,
count
:
1
,
},
{
index
:
8
,
status
:
1
,
count
:
1
,
},
{
index
:
9
,
status
:
1
,
count
:
1
,
},
{
index
:
10
,
status
:
2
,
count
:
1
,
},
],
],
alarmCount
:
"98%"
,
lastAlarmTime
:
"-"
,
location
:
"一号转炉东侧"
,
},
{
deviceName
:
"2#除尘器"
,
deviceNo
:
"1234567890"
,
process
:
"转炉"
,
healthScore
:
10
,
health2Score
:
11
,
status
:
[
[
{
index
:
1
,
status
:
1
,
count
:
1
,
},
{
index
:
2
,
status
:
2
,
count
:
2
,
},
{
index
:
3
,
status
:
1
,
count
:
1
,
},
{
index
:
4
,
status
:
1
,
count
:
1
,
},
{
index
:
5
,
status
:
3
,
count
:
1
,
},
],
[
{
index
:
6
,
status
:
1
,
count
:
1
,
},
{
index
:
7
,
status
:
1
,
count
:
1
,
},
{
index
:
8
,
status
:
1
,
count
:
1
,
},
{
index
:
9
,
status
:
1
,
count
:
1
,
},
{
index
:
10
,
status
:
2
,
count
:
1
,
},
],
],
alarmCount
:
"45%"
,
lastAlarmTime
:
"100~3000"
,
location
:
"二号转炉西侧"
,
},
{
deviceName
:
"3#除尘器"
,
deviceNo
:
"1234567890"
,
process
:
"炼铁"
,
healthScore
:
12
,
health2Score
:
13
,
status
:
[
[
{
index
:
1
,
status
:
1
,
count
:
1
,
},
{
index
:
2
,
status
:
2
,
count
:
2
,
},
{
index
:
3
,
status
:
1
,
count
:
1
,
},
{
index
:
4
,
status
:
1
,
count
:
1
,
},
{
index
:
5
,
status
:
3
,
count
:
1
,
},
],
[
{
index
:
6
,
status
:
1
,
count
:
1
,
},
{
index
:
7
,
status
:
1
,
count
:
1
,
},
{
index
:
8
,
status
:
1
,
count
:
1
,
},
{
index
:
9
,
status
:
1
,
count
:
1
,
},
{
index
:
10
,
status
:
2
,
count
:
1
,
},
{
index
:
11
,
status
:
1
,
count
:
1
,
},
{
index
:
12
,
status
:
2
,
count
:
1
,
},
],
],
alarmCount
:
"78%"
,
lastAlarmTime
:
"100~3000"
,
location
:
"炼铁区域北侧"
,
},
];
const
tableData
=
ref
([]);
watch
(
productionLine
,
(
newVal
)
=>
{
productionLineFiltered
.
value
=
newVal
;
});
const
filterProductionLine
=
(
query
)
=>
{
if
(
!
query
)
{
productionLineFiltered
.
value
=
productionLine
.
value
;
}
else
{
productionLineFiltered
.
value
=
productionLine
.
value
.
filter
(
item
=>
item
.
productionLineName
.
toLowerCase
().
includes
(
query
.
toLowerCase
())
);
}
};
const
getStatusType
=
(
status
)
=>
{
const
statusMap
=
{
...
...
@@ -456,7 +266,8 @@ const getStatusType = (status) => {
};
const
getHealthScoreColor
=
(
score
)
=>
{
const
value
=
parseInt
(
score
);
// 去除百分号
const
value
=
parseInt
(
score
.
replace
(
'%'
,
''
));
if
(
value
>=
90
)
return
"#67C23A"
;
if
(
value
>=
70
)
return
"#E6A23C"
;
return
"#F56C6C"
;
...
...
@@ -481,7 +292,9 @@ const handlePaginationChange = (pagination) => {
};
const
onSubmit
=
()
=>
{
console
.
log
(
"submit!"
,
formInline
.
value
);
currentPage
.
value
=
1
;
pageSize
.
value
=
10
;
getData
();
};
// 仓室设置相关
...
...
@@ -545,12 +358,12 @@ const handleRoomSettingConfirm = (distributionData) => {
};
// 点击电磁阀数量时打开弹窗
const
handle
Health2Score
Click
=
(
row
)
=>
{
const
handle
ValveNum
Click
=
(
row
)
=>
{
// 创建一个扁平化的状态数组用于电磁阀设置
currentEditingRow
.
value
=
JSON
.
parse
(
JSON
.
stringify
(
row
));
const
flattenedStatus
=
row
.
status
.
flat
().
map
(
item
=>
({...
item
}));
currentEditingRow
.
value
.
status
=
flattenedStatus
;
valveForm
.
value
.
total
=
row
.
health2Score
;
valveForm
.
value
.
total
=
row
.
valveNum
;
valveSettingVisible
.
value
=
true
;
};
...
...
@@ -560,7 +373,7 @@ const handleValveSettingConfirm = (updatedStatusData) => {
// 更新总数
const
originalRow
=
tableData
.
find
(
item
=>
item
===
currentEditingRow
.
value
);
if
(
originalRow
)
{
originalRow
.
health2Score
=
valveForm
.
value
.
total
;
originalRow
.
valveNum
=
valveForm
.
value
.
total
;
// 更新各个仓室的电磁阀数量
const
flatStatusMap
=
new
Map
();
...
...
@@ -588,19 +401,38 @@ const handleAddDustCollector = () => {
// 保存新增除尘器
const
handleSaveDustCollector
=
(
data
)
=>
{
if
(
data
.
id
)
{
postUpdateDuster
(
data
).
then
(
res
=>
{
if
(
res
.
code
==
1
)
{
ElMessage
.
success
(
'更新除尘器成功'
);
isAddDustCollectorVisible
.
value
=
false
;
refreshData
();
}
else
{
ElMessage
.
error
(
res
.
message
);
}
}).
catch
(
err
=>
{
ElMessage
.
error
(
err
.
message
);
})
}
else
{
postAddDuster
(
data
).
then
(
res
=>
{
if
(
res
.
code
==
1
)
{
ElMessage
.
success
(
'新增除尘器成功'
);
isAddDustCollectorVisible
.
value
=
false
;
refreshData
();
}
else
{
ElMessage
.
error
(
res
.
message
);
}
}).
catch
(
err
=>
{
ElMessage
.
error
(
err
.
message
);
})
}
console
.
log
(
"保存新增除尘器数据:"
,
data
);
// 添加到表格数据中
tableData
.
push
({
...
data
,
alarmCount
:
"100%"
,
// 设置默认健康度
location
:
""
,
// 可以根据需要设置默认位置
});
// 这里可以调用API进行保存
// await api.addDustCollector(data);
// 关闭弹窗
isAddDustCollectorVisible
.
value
=
false
;
};
...
...
@@ -623,10 +455,50 @@ const IcloseLoopNum = () => {
})
}
const
IproductionLine
=
()
=>
{
getProductionLine
().
then
(
res
=>
{
productionLine
.
value
=
res
.
data
||
[];
// 默认显示全部
productionLineFiltered
.
value
=
res
.
data
||
[];
})
}
const
getData
=
()
=>
{
const
params
=
{
pageNo
:
currentPage
.
value
,
pageSize
:
pageSize
.
value
,
productionLineId
:
formInline
.
value
.
region
===
'all'
?
''
:
formInline
.
value
.
region
,
keyword
:
formInline
.
value
.
deviceName
,
}
getDusterList
(
params
).
then
(
res
=>
{
console
.
log
(
res
);
if
(
res
.
code
==
1
)
{
tableData
.
value
=
res
.
data
.
records
||
[];
// total.value = res.data.total || 0;
}
else
{
ElMessage
.
error
(
res
.
message
);
}
})
}
const
refreshData
=
()
=>
{
currentPage
.
value
=
1
;
pageSize
.
value
=
10
;
formInline
.
value
=
{
region
:
''
,
deviceName
:
''
,
}
getData
();
}
onMounted
(
async
()
=>
{
IdusterLeakNum
();
IhealthPercent
();
IcloseLoopNum
();
IproductionLine
();
getData
();
});
onBeforeUnmount
(()
=>
{});
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment