Commit bbb317a3 authored by liuyangyang's avatar liuyangyang

布袋周期页面开发合并

parents ad0197af ac7fcb14
......@@ -9,6 +9,7 @@
"preview": "vite preview"
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"axios": "^1.9.0",
"crypto-js": "^4.2.0",
"echarts": "^5.6.0",
......
......@@ -3,6 +3,8 @@ import { createWebHistory, createRouter } from 'vue-router'
import Dashboard from '../views/dashboard/index.vue'
import DustOverview from '../views/dustOverview/index.vue'
import AboutView from '../views/AboutView.vue'
import CollectorList from '../views/collectorList/collectorList.vue'
import User from '../views/user.vue'
import Layout from '../layout/index.vue'
import Login from '../views/login/index.vue'
import equipmentManagement from '../views/equipmentManagement/index.vue'
......@@ -35,6 +37,11 @@ const routes = [
path: '/monitor',
component: dustMonitoring,
meta: { title: '除尘器监控' },
},
{
path: '/collectorList',
component: CollectorList,
meta: { title: '布袋周期' },
},
{
path: '/bag-monitor',
......
import { color } from "echarts";
export const getLineOption = (xData = [], seriesData = []) => ({
tooltip: {
trigger: 'axis',
},
grid: {
left: '3%',
right: '4%',
bottom: '15%',
top: '5%',
containLabel: true,
},
legend: {
data: ['健康度指数(%)'],
bottom: '0%',
icon:"circle",
itemWidth: 10,
itemHeight: 10,
itemGap: 10,
},
xAxis: {
type: 'category',
axisTick: {
show: false,
},
axisLine: {
lineStyle: {
color: '#E9ECF2',
},
tooltip: {
trigger: "axis",
},
grid: {
left: "3%",
right: "4%",
bottom: "15%",
top: "5%",
containLabel: true,
},
legend: {
data: ["健康度指数(%)"],
bottom: "0%",
icon: "circle",
itemWidth: 10,
itemHeight: 10,
itemGap: 10,
},
xAxis: {
type: "category",
axisTick: {
show: false,
},
axisLine: {
lineStyle: {
color: "#E9ECF2",
},
axisLabel: {
color: 'rgba(0,0,0,0.6)',
},
axisLabel: {
color: "rgba(0,0,0,0.6)",
},
data: xData,
},
yAxis: {
type: "value",
axisLabel: {
color: "rgba(0,0,0,0.6)",
},
splitLine: {
lineStyle: {
color: "#E9ECF2",
type: "dashed",
},
data: xData,
},
},
series: [
{
name: "健康度指数(%)",
type: "line",
color: "#399DFA",
data: seriesData,
smooth: true,
},
],
});
export const getDustLineOption = (xData = [], seriesData = []) => ({
tooltip: {
trigger: "axis",
},
grid: {
left: "3%",
right: "4%",
bottom: "15%",
top: "5%",
containLabel: true,
},
legend: {
data: ["健康度指数(%)"],
bottom: "0%",
icon: "circle",
itemWidth: 10,
itemHeight: 10,
itemGap: 10,
},
xAxis: {
type: "category",
axisTick: {
show: false,
},
yAxis: {
type: 'value',
axisLabel: {
color: 'rgba(0,0,0,0.6)',
},
splitLine: {
lineStyle: {
color: '#E9ECF2',
type: 'dashed',
},
axisLine: {
lineStyle: {
color: "#E9ECF2",
},
},
series: [
{
name: '健康度指数(%)',
type: 'line',
color: '#399DFA',
data: seriesData,
smooth: true,
axisLabel: {
color: "rgba(0,0,0,0.6)",
},
data: xData,
},
yAxis: {
type: "value",
axisLabel: {
color: "rgba(0,0,0,0.6)",
},
splitLine: {
lineStyle: {
color: "#E9ECF2",
type: "dashed",
},
],
});
},
},
series: [
{
name: "",
type: "line",
color: "#399DFA",
data: seriesData,
smooth: true,
},
],
});
// 布袋监测图表配置
export const getBagMonitoringChartOption = (xData = [], seriesData = []) => ({
tooltip: {
trigger: 'axis',
trigger: "axis",
axisPointer: {
type: 'line',
type: "line",
lineStyle: {
color: '#6E7079',
width: 1
}
}
color: "#6E7079",
width: 1,
},
},
},
grid: {
left: '20',
right: '20',
bottom: '30',
top: '3%',
containLabel: true
left: "20",
right: "20",
bottom: "30",
top: "3%",
containLabel: true,
},
xAxis: {
type: 'category',
type: "category",
boundaryGap: false,
axisLine: {
lineStyle: {
color: '#E9ECF2'
}
color: "#E9ECF2",
},
},
axisLabel: {
color: 'rgba(0,0,0,0.6)',
color: "rgba(0,0,0,0.6)",
fontSize: 12,
interval: 'auto',
rotate: 0
interval: "auto",
rotate: 0,
},
axisTick: {
show: false
show: false,
},
data: xData
data: xData,
},
yAxis: {
type: 'value',
type: "value",
min: 0,
max: 600,
interval: 200,
axisLabel: {
color: 'rgba(0,0,0,0.6)',
formatter: '{value}'
color: "rgba(0,0,0,0.6)",
formatter: "{value}",
},
splitLine: {
lineStyle: {
color: '#E9ECF2',
type: 'dashed'
}
}
color: "#E9ECF2",
type: "dashed",
},
},
},
series: [
{
name: '监测值',
type: 'line',
name: "监测值",
type: "line",
smooth: false,
symbol: 'none',
sampling: 'average',
symbol: "none",
sampling: "average",
itemStyle: {
color: '#7B68EE'
color: "#7B68EE",
},
lineStyle: {
width: 1
width: 1,
},
areaStyle: {
color: {
type: 'linear',
type: "linear",
x: 0,
y: 0,
x2: 0,
......@@ -136,16 +191,16 @@ export const getBagMonitoringChartOption = (xData = [], seriesData = []) => ({
colorStops: [
{
offset: 0,
color: 'rgba(123, 104, 238, 0.4)'
color: "rgba(123, 104, 238, 0.4)",
},
{
offset: 1,
color: 'rgba(123, 104, 238, 0.1)'
}
]
}
color: "rgba(123, 104, 238, 0.1)",
},
],
},
},
data: seriesData,
}
]
});
\ No newline at end of file
},
],
});
<template>
<div class="page-container collectorList">
<div class="content-box">
<div class="search">
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="仓室">
<el-input
v-model="formInline.deviceName"
placeholder="请输入仓室名称"
style="width: 200px"
clearable
/>
</el-form-item>
<el-form-item label="除尘器名称">
<el-input
v-model="formInline.deviceName"
placeholder="请输入除尘器名称"
style="width: 200px"
clearable
/>
</el-form-item>
<el-form-item label="更换时间">
<el-date-picker
v-model="formInline.date"
type="datetimerange"
range-separator="~"
start-placeholder="开始时间"
end-placeholder="结束时间"
:teleported="false"
/>
</el-form-item>
<el-form-item>
<el-button type="default" class="default-btn" @click="onSubmit"
>重置</el-button
>
<el-button type="primary" class="search-btn" @click="onSubmit"
>查询</el-button
>
<el-button type="success" class="add-btn" @click="openDialog()"
>更换周期分析</el-button
>
</el-form-item>
</el-form>
</div>
<div class="table-box">
<common-table
:data="tableData.list"
:columns="tableColumns"
:default-page-size="10"
@pagination-change="handlePaginationChange"
:pagination-texts="{
total: '共',
sizeChange: '条/页',
prev: '前一页',
next: '后一页',
jumper: '跳至',
}"
>
<template #index="{ $index }">
{{ getIndex($index) }}
</template>
<template #deviceName="{ row }">
<span class="health-score" @dblclick="openDialog(row.deviceName)">{{
row.deviceName
}}</span>
</template>
<!-- <template #operation="{ row }">
<span class="view-btn" @click="handleView(row)">详情</span>
<span class="edit-btn" @click="handleEdit(row)">编辑</span>
</template> -->
</common-table>
</div>
</div>
<!-- 除尘器曲线 -->
<el-dialog
class="dustListDialog"
v-model="dustLineisShow"
title="仓室数量设置"
width="1000px"
:close-on-click-modal="false"
:close-on-press-escape="false"
>
<div class="input-group">
<span>仓室编号:</span>
<el-select
v-model="selectDustNo"
@change="changeDust"
style="width: 120px"
>
<el-option
v-for="i in dustList.list"
:key="i"
:label="`${i.deviceName}`"
:value="i.deviceNo"
/>
</el-select>
</div>
<div class="echartBox">
<chartLine :dustLineInfo="dustLineInfo.list"></chartLine>
</div>
<!-- <template #footer>
<span class="dialog-footer">
<el-button @click="dustLine = false">取消</el-button>
<el-button type="primary" @click="handleRoomSettingConfirm">
确认
</el-button>
</span>
</template> -->
</el-dialog>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount, computed, reactive } from "vue";
import CommonTable from "@/components/commonTable/index.vue";
import chartLine from "./components/chart-line.vue";
const formInline = ref({
compart: "",
dusterName: "",
date: "",
});
const currentPage = ref(1);
const pageSize = ref(10);
const dustLineisShow = ref(false);
const tableColumns = ref([
{
prop: "index",
label: "序号",
width: "5%",
},
{
prop: "deviceName",
label: "除尘器名称",
width: "8%",
},
{
prop: "compart",
label: "仓室",
width: "8%",
},
{
prop: "position",
label: "布袋位置(排/列)",
width: "8%",
},
{
prop: "changeDateRemind",
label: "布袋更换提醒时间",
width: "8%",
},
{
prop: "changeDate",
label: "更换时间",
width: "8%",
},
{
prop: "changePeo",
label: "更换人",
width: "8%",
},
{
prop: "ownerdeviceName",
label: "所属除尘器",
width: "8%",
},
{
prop: "lastAlarmTime",
label: "布袋更换提醒时间",
width: "10%",
},
{
prop: "changeRound",
label: "更换周期(与上次更换比)",
width: "6%",
},
]);
const tableData = reactive({
list: [
{
deviceName: "1#除尘器",
compart: "1234567890",
position: "转炉",
changeDateRemind: "xx",
changeDate: "xx",
changePeo: "xx",
ownerdeviceName: "xx",
lastAlarmTime: "xx",
changeRound: "xx",
},
],
});
const selectDustNo = ref("");
const dustList = reactive({
list: [],
});
const getHealthScoreColor = (score) => {
const value = parseInt(score);
if (value >= 90) return "#67C23A";
if (value >= 70) return "#E6A23C";
return "#F56C6C";
};
const getIndex = (index) => {
return (currentPage.value - 1) * pageSize.value + index + 1;
};
const handleView = (row) => {
console.log("查看详情", row);
};
const handleEdit = (row) => {
console.log("编辑", row);
};
const handlePaginationChange = (pagination) => {
currentPage.value = pagination.currentPage;
pageSize.value = pagination.pageSize;
console.log("分页变化", pagination);
};
const onSubmit = () => {
console.log("submit!", formInline.value);
};
const dustLineInfo = reactive({ list: [{}] });
const openDialog = (deviceName) => {
changeDust(deviceName);
dustLineisShow.value = true;
};
const getDustList = () => {
return [
{
deviceName: "1#除尘器",
deviceNo: "11111",
},
{
deviceName: "2#除尘器",
deviceNo: "22222",
},
{
deviceName: "3#除尘器",
deviceNo: "333333",
},
];
};
const getDustListInfo = () => {
return [
{ time: "1", value: "20" },
{ time: "2", value: "30" },
{ time: "4", value: "40" },
{ time: "8", value: "45" },
{ time: "10", value: "15" },
{ time: "周期", value: "20" },
];
};
const changeDust = (deviceName) => {
dustList.list = getDustList();
if (deviceName) {
dustList.list.forEach((i) => {
if (i.deviceName == deviceName) {
selectDustNo.value = i.deviceNo;
}
});
} else {
selectDustNo.value = dustList.list[0].deviceNo || "";
}
let list = getDustListInfo();
dustLineInfo.list = list;
};
onMounted(async () => {});
onBeforeUnmount(() => {});
</script>
<style lang="scss" scoped>
.collectorList {
width: 100%;
height: calc(100% - 14px);
box-sizing: border-box;
:deep(.el-input--small) {
width: 100%;
}
.content-box {
margin-top: 24px;
.search {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
}
.table-box {
width: 100%;
height: calc(100vh - 400px);
}
}
.default-btn {
width: 85px;
}
.search-btn {
width: 85px;
background: #2182a0;
border: 1px solid #2182a0;
}
.add-btn {
width: 85px;
}
.health-score {
color: #027ffc;
cursor: pointer;
display: block;
width: 100%;
}
.status-matrix {
width: fit-content;
display: flex;
padding: 10px;
box-sizing: border-box;
flex-direction: column;
align-items: flex-start;
gap: 6px;
border: 1px solid #e4e7ed;
border-radius: 4px;
background-color: #ffffff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
.matrix-row {
display: flex;
gap: 6px;
justify-content: flex-start;
}
.status-dot {
width: 14px;
height: 14px;
border-radius: 50%;
&:hover {
cursor: pointer;
transform: scale(1.2);
}
}
.status-normal {
background-color: #67c23a; // 绿色
}
.status-warning {
background-color: #e6a23c; // 橙色
}
.status-error {
background-color: #f56c6c; // 红色
}
}
.view-btn {
margin-right: 8px;
}
.dialog-footer {
display: flex;
justify-content: center;
gap: 12px;
}
:deep(.el-dialog__body) {
padding: 20px;
}
.distribution-table {
margin-top: 20px;
border-top: 1px solid #ebeef5;
padding-top: 20px;
}
.table-title {
font-size: 14px;
color: #2182a0;
margin-bottom: 16px;
font-weight: 500;
}
:deep(.el-input-number.el-input-number--small) {
width: 130px;
}
:deep(.distribution-table .el-table--border .el-table__cell) {
border-right: 1px solid #ebeef5 !important;
}
.valve-setting {
.setting-row {
display: flex;
align-items: center;
gap: 20px;
margin-bottom: 20px;
.input-group {
display: flex;
align-items: center;
gap: 8px;
span {
white-space: nowrap;
color: #606266;
}
}
}
}
.valve-distribution-grid {
display: flex;
flex-direction: column;
gap: 8px;
padding: 12px;
background: #f5f7fa;
border-radius: 4px;
.valve-row {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.valve-cell {
width: 41px;
background: white;
padding: 4px;
border-radius: 4px;
text-align: center;
border: 1px solid #dcdfe6;
.cell-index {
font-size: 12px;
color: #909399;
margin-bottom: 8px;
}
.cell-value {
:deep(.el-input-number) {
width: 100px;
}
}
}
}
.readonly-value {
font-size: 14px;
color: #606266;
line-height: 32px;
padding: 0 12px;
}
.distribution-warning {
display: inline-block;
font-size: 13px;
margin-left: 12px;
padding: 2px 8px;
border-radius: 4px;
&.warning-more {
color: #e6a23c;
background-color: #fdf6ec;
}
&.warning-less {
color: #f56c6c;
background-color: #fef0f0;
}
}
.dustListDialog {
.echartBox {
margin: 0 auto;
width: 950px;
height: 450px;
> div {
width: 950px;
height: 450px;
}
}
}
}
</style>
<template>
<div ref="chartDustRef" class="chart-line"></div>
</template>
<script setup>
import { onMounted, onBeforeUnmount, ref, watch, nextTick } from "vue";
import * as echarts from "echarts";
import { getDustLineOption } from "@/utils/chart";
const props = defineProps({
// 表格数据
dustLineInfo: {
type: Array,
required: true,
default: () => [],
},
});
const chartDustRef = ref(null);
let chartInstance = null;
const initChart = () => {
if (chartDustRef.value) {
let xData = [];
let seriesData = [];
if (props.dustLineInfo) {
props.dustLineInfo.forEach((i) => {
xData.push(i.time);
seriesData.push(i.value);
});
}
chartInstance = echarts.init(chartDustRef.value);
const option = getDustLineOption(xData, seriesData);
nextTick(() => {
// DOM 更新完成后执行
chartInstance.setOption(option);
});
}
};
watch(
() => props.dustLineInfo,
() => {
initChart();
console.log("props.dustLineInfo", props.dustLineInfo);
},
{ deep: true }
);
onMounted(() => {
initChart();
window.addEventListener("resize", () => {
chartInstance?.resize();
});
});
onBeforeUnmount(() => {
chartInstance?.dispose();
});
</script>
<style lang="scss" scoped>
.chart-line {
canvas {
width: 100%;
height: 100%;
}
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment