wuhan-gl/src/views/linkConfig/sensorConfig.vue

421 lines
10 KiB
Vue

<template>
<div class="sensor-threshold-config">
<!-- 页面标题 -->
<div class="page-header">
<h2>传感器报警阈值配置</h2>
<p class="page-description">配置传感器上报警阈值</p>
</div>
<!-- 传感器列表 -->
<div class="sensor-list">
<el-card class="sensor-card" v-for="sensor in sensors" :key="sensor.id">
<template #header>
<div class="card-header">
<div class="sensor-info">
<h3>{{ sensor.model_name }}</h3>
</div>
</div>
</template>
<!-- 阈值配置表单 -->
<el-form
:model="sensor"
:rules="thresholdRules"
ref="formRefs"
:label-width="sensor.model_id == 86 ? '120px' : '80px'"
class="threshold-form"
>
<template v-if="sensor.model_id == 86">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item
label="温度限值一"
prop="upper_threshold"
>
<el-input-number
v-model="sensor.upper_threshold"
:min="0"
:max="1000"
:precision="2"
controls-position="right"
style="width: 100%"
:placeholder="`请输入阈值${sensor.unit}`"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="温度限值二"
prop="lower_threshold"
>
<el-input-number
v-model="sensor.lower_threshold"
:min="0"
:max="1000"
:precision="2"
controls-position="right"
style="width: 100%"
:placeholder="`请输入阈值${sensor.unit}`"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item
label="湿度限值一"
prop="upper_threshold"
>
<el-input-number
v-model="sensor.upper_threshold_2"
:min="0"
:max="1000"
:precision="2"
controls-position="right"
style="width: 100%"
:placeholder="`请输入阈值${sensor.unit}`"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="湿度限值二"
prop="lower_threshold"
>
<el-input-number
v-model="sensor.lower_threshold_2"
:min="0"
:max="1000"
:precision="2"
controls-position="right"
style="width: 100%"
:placeholder="`请输入阈值${sensor.unit}`"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item
label="采集频率(分钟)"
prop="lower_threshold"
class="sp sp-label"
>
<el-input-number
v-model="sensor.history_data_frequency"
:min="1"
:max="1000"
:precision="2"
controls-position="right"
style="width: 100%"
:placeholder="`请输入采集频率`"
/>
</el-form-item>
</el-col>
</el-row>
</template>
<template v-else>
<el-row :gutter="20">
<el-col :span="7">
<el-form-item
label="限值一"
prop="upper_threshold"
>
<el-input-number
v-model="sensor.upper_threshold"
:min="0"
:max="1000"
:precision="2"
controls-position="right"
style="width: 100%"
:placeholder="`请输入阈值${sensor.unit}`"
/>
</el-form-item>
</el-col>
<el-col :span="7">
<el-form-item
label="限值二"
prop="lower_threshold"
>
<el-input-number
v-model="sensor.lower_threshold"
:min="0"
:max="1000"
:precision="2"
controls-position="right"
style="width: 100%"
:placeholder="`请输入阈值${sensor.unit}`"
/>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item
label="采集频率(分钟)"
prop="lower_threshold"
class="sp-label"
>
<el-input-number
v-model="sensor.history_data_frequency"
:min="1"
:max="1000"
:precision="2"
controls-position="right"
style="width: 100%"
:placeholder="`请输入采集频率`"
/>
</el-form-item>
</el-col>
</el-row>
</template>
<el-form-item>
<el-button
type="primary"
@click="saveThresholds(sensor)"
:loading="saving"
>
保存配置
</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { ElMessage } from "element-plus";
import { getDeviceType, setDeviceType } from "@/api/device.js";
// import { handlerData } from "@/api/index";
// 响应式数据
const saving = ref(false);
const formRefs = ref({});
// 阈值验证规则
const thresholdRules = {
upper_threshold: [
{ required: true, message: "请输入阈值一", trigger: "blur" },
// {
// type: "number",
// min: 0,
// message: "阈值必须大于等于0",
// trigger: "blur",
// },
],
lower_threshold: [
{ required: true, message: "请输入阈值二", trigger: "blur" },
// {
// type: "number",
// min: 0,
// message: "阈值必须大于等于0",
// trigger: "blur",
// },
],
};
// 传感器数据
const sensors = ref([]);
const fetchDeviceTypes = async () => {
const params = {
page: 1,
page_size: 100,
is_sensor: 1
};
const res = await getDeviceType(params);
if (res && res.code === 200) {
sensors.value = res.data?.device_types || [];
console.log(sensors.value);
}
};
// 方法
const saveThresholds = async (sensor) => {
try {
// 验证表单
const formRef = formRefs.value[sensor.id];
if (formRef) {
await formRef.validate();
}
// 验证阈值逻辑
// if (sensor.upper_threshold <= sensor.lower_threshold) {
// ElMessage.error("阈值必须大于阈值");
// return;
// }
saving.value = true;
let res = await setDeviceType(sensor);
if (res && res.code == 200) {
ElMessage.success(`${sensor.model_name} 阈值配置保存成功`);
} else {
ElMessage.error("保存失败,请检查输入值");
}
} catch (error) {
ElMessage.error("保存失败,请检查输入值");
} finally {
saving.value = false;
}
};
// 生命周期
onMounted(() => {
fetchDeviceTypes();
console.log("传感器阈值配置页面已加载");
});
</script>
<style scoped>
.sensor-threshold-config {
padding: 20px;
background-color: #f5f7fa;
min-height: 100vh;
}
.page-header {
margin-bottom: 30px;
}
.page-header h2 {
color: #303133;
font-size: 20px;
font-weight: 600;
margin: 0 0 8px 0;
}
.page-description {
color: #909399;
font-size: 14px;
margin: 0;
}
.sensor-list {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px;
}
.sensor-card {
border-radius: 8px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
transition: box-shadow 0.3s ease;
}
.sensor-card:hover {
box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.15);
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 10px;
}
.sensor-info {
display: flex;
align-items: center;
gap: 10px;
flex-wrap: wrap;
}
.sensor-info h3 {
margin: 0;
color: #303133;
font-size: 16px;
font-weight: 600;
}
.value-label {
color: #606266;
font-size: 14px;
}
.normal-value {
color: #67c23a;
font-weight: 600;
font-size: 16px;
}
.alarm-value {
color: #f56c6c;
font-weight: 600;
font-size: 16px;
}
.threshold-form {
margin-top: 20px;
}
/* 响应式设计 */
@media (max-width: 768px) {
.sensor-threshold-config {
padding: 10px;
}
.sensor-list {
grid-template-columns: 1fr;
}
.card-header {
flex-direction: column;
align-items: flex-start;
}
.sensor-info {
width: 100%;
justify-content: flex-start;
}
}
/* 卡片样式优化 */
:deep(.el-card__header) {
background-color: #f8f9fa;
border-bottom: 1px solid #e4e7ed;
padding: 15px 20px;
}
:deep(.el-card__body) {
padding: 20px;
}
/* 表单样式优化 */
:deep(.el-form-item__label) {
font-weight: 500;
color: #606266;
}
:deep(.el-input-number) {
width: 100%;
}
:deep(.el-input-number .el-input__inner) {
text-align: left;
}
/* 按钮样式优化 */
:deep(.el-button) {
border-radius: 6px;
}
:deep(.el-button--primary) {
background-color: #409eff;
border-color: #409eff;
}
:deep(.el-button--primary:hover) {
background-color: #66b1ff;
border-color: #66b1ff;
}
::v-deep .sp-label .el-form-item__label {
width: 120px !important;
}
</style>