421 lines
10 KiB
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>
|