S.规则设置逻辑和拆分更新,boxApi方法调用

This commit is contained in:
龚皓 2024-11-22 17:52:28 +08:00
parent 1c0a51ed5e
commit 11ea95b902
1 changed files with 365 additions and 0 deletions

365
src/html/CameraRules.vue Normal file
View File

@ -0,0 +1,365 @@
<template>
<div>
<!-- 打开弹窗按钮 -->
<!-- <el-button type="primary" @click="openDialog">打开设置弹窗</el-button> -->
<!-- 弹窗 -->
<!-- <el-dialog title="设置规则" v-model="dialogVisible" width="50%" @close="resetDialog"> -->
<el-dialog v-model="localVisible" width="50%" :modal="false" @close="handleClose">
<!-- 显示摄像头基本信息 -->
<div v-if="CameraDialog.id" class="camera-title">
<p><strong>摄像头名称</strong>{{ CameraDialog.name }} <strong> &nbsp;&nbsp;&nbsp;通道号: </strong>{{ CameraDialog.id }}
</p>
<!-- <p><strong>摄像头状态</strong>{{ CameraDialog.status }}</p> -->
<!-- <img :src="CameraDialog.snapshot" alt="Snapshot" style="max-width: 100%; margin-bottom: 20px" /> -->
</div>
<el-radio-group v-model="CameraDialog.mode" @change="handleGlobalModeChange" style="margin-bottom: 20px">
<el-radio label="on">ON</el-radio>
<el-radio label="off">OFF</el-radio>
</el-radio-group>
<div v-for="(rule, index) in CameraDialog.rules" :key="rule.id" class="rule-block">
<h3>{{ rule.name }} (模式: {{ rule.mode }})</h3>
<el-radio-group v-model="rule.mode" :disabled="CameraDialog.mode === 'off'" @change="handleRuleModeChange(rule)">
<el-radio label="on">ON</el-radio>
<el-radio label="off">OFF</el-radio>
<el-radio label="schedule">时间段</el-radio>
</el-radio-group>
<div v-if="rule.mode === 'schedule'">
<el-select v-model="rule.schedule.type" placeholder="请选择" style="margin: 10px 0">
<el-option label="每日" value="daily"></el-option>
</el-select>
<div v-for="(time, timeIndex) in rule.schedule.time_slots" :key="timeIndex" class="time-period">
<el-time-picker v-model="rule.schedule.time_slots[timeIndex][0]" format="HH:mm" value-format="HH:mm"
placeholder="Start Time" @change="validateTime(rule.schedule.time_slots, timeIndex)" />
<el-time-picker v-model="rule.schedule.time_slots[timeIndex][1]" format="HH:mm" value-format="HH:mm"
placeholder="End Time" @change="validateTime(rule.schedule.time_slots, timeIndex)" />
<el-button type="danger" @click="removeTimeSlot(rule.schedule.time_slots, timeIndex)">删除</el-button>
<p v-if="!rule.schedule.time_slots[timeIndex][0] || !rule.schedule.time_slots[timeIndex][1]"
style="color: red; margin-top: 5px">
*
</p>
</div>
<el-button type="primary" @click="addTimeSlot(rule.schedule.time_slots)">新增时间段</el-button>
<p v-if="!rule.schedule.time_slots.length" style="color: red; margin-top: 10px">
请至少添加一个时间段
</p>
</div>
</div>
<!-- 弹窗底部操作 -->
<span slot="footer" class="dialog-footer">
<el-button @click="handleClose">取消</el-button>
<el-button type="success" @click="saveRules">保存</el-button>
</span>
</el-dialog>
</div>
</template>
<script setup>
import { ref, watch, reactive } from "vue";
import { ElMessage } from "element-plus";
import { BoxApi } from "@/utils/boxApi.ts";
const props = defineProps({
cameraData: Object, //
visible: Boolean, //
});
const emit = defineEmits(["update:visible", "save-result"]);
// API
const apiInstance = new BoxApi();
const cameraDataZ = ref({});
const localVisible = ref(props.visible);
const cameraData = ref({}); //
const CameraDialog = ref({}); //
//
// const dialogVisible = ref(false);
//
// const openDialog = async () => {
// try {
// const token = localStorage.getItem("alertToken");
// const cameraId = 1;
// const camera = await apiInstance.getCameraById(token, cameraId);
// cameraData.value = camera;
// console.log(":", cameraData.value);
// formatCameraData();
// dialogVisible.value = true;
// } catch (error) {
// console.error(":", error);
// }
// };
watch(
() => props.visible,
(newVal) => {
localVisible.value = newVal;
// console.log("newVal:", newVal);
if (newVal) {
// cameraDataZ.value = JSON.parse(JSON.stringify(newVal));
Object.assign(cameraDataZ.value, JSON.parse(JSON.stringify(props.cameraData)));
console.log("cameraDataZ:", cameraDataZ.value);
formatCameraData(cameraDataZ.value);
}
}
);
// watch(
// () => props.cameraData,
// (newVal) => {
// console.log(" cameraData:", newVal);
// },
// { immediate: true } //
// );
// watch(
// () => props.visible,
// (newVal) => {
// console.log(" visible :", newVal);
// },
// { immediate: true }
// );
const handleClose = () => {
emit("update:visible", false);
};
// cameraData CameraDialog
const formatCameraData = () => {
CameraDialog.value = {
id: cameraDataZ.value.id,
name: cameraDataZ.value.name,
status: cameraDataZ.value.status,
mode: cameraDataZ.value.mode,
// snapshot: cameraData.value.snapshot,
rules: cameraDataZ.value.rules.map((rule) => ({
id: rule.id,
name: rule.name,
mode: rule.mode,
schedule: {
type: rule.schedule?.type || "",
time_slots: rule.schedule?.time_slots
? rule.schedule.time_slots.map(([start, end]) => [
start !== undefined ? convertMinutesToTime(start) : "00:00",
end !== undefined ? convertMinutesToTime(end) : "00:00",
])
: [],
},
})),
};
};
const handleGlobalModeChange = () => {
if (CameraDialog.value.mode === "off") {
// off mode off
CameraDialog.value.rules.forEach((rule) => {
rule.mode = "off";
});
} else if (CameraDialog.value.mode === "on") {
// on
CameraDialog.value.rules.forEach((rule) => {
if (rule.mode === "schedule") {
rule.schedule.type = "daily"; // daily
rule.schedule.time_slots = []; //
} else if (rule.mode === "on" || rule.mode === "off") {
rule.schedule.type = ""; // type
rule.schedule.time_slots = []; //
}
});
}
};
const handleRuleModeChange = (rule) => {
if (rule.mode === "schedule") {
rule.schedule.type = "daily"; // daily
rule.schedule.time_slots = []; //
} else {
// schedule schedule
rule.schedule.type = ""; // type
rule.schedule.time_slots = []; //
}
};
const handleModeChange = (rule) => {
if (rule.mode === "schedule") {
rule.schedule.type = "daily";
}
};
//
const validateTime = (timeSlots, index) => {
const [startTime, endTime] = timeSlots[index];
if (!startTime || !endTime) {
ElMessage.error("请填写完整时间段");
return;
}
if (endTime <= startTime) {
ElMessage.error("开始时间必须小于结束时间");
timeSlots[index][1] = "00:00"; //
}
if (endTime && startTime >= endTime) {
ElMessage.error("开始时间和结束时间不合理");
timeSlots[index][1] = "";
return;
}
for (let i = 0; i < timeSlots.length; i++) {
if (
i !== index &&
timeSlots[i][0] &&
timeSlots[i][1] &&
startTime &&
endTime &&
!(
endTime <= timeSlots[i][0] ||
startTime >= timeSlots[i][1]
)
) {
ElMessage.error("时间段重叠,请重新选择");
timeSlots[index][0] = "";
timeSlots[index][1] = "";
break;
}
}
};
//
const addTimeSlot = (timeSlots) => {
timeSlots.push([]);
};
//
const removeTimeSlot = (timeSlots, index) => {
timeSlots.splice(index, 1);
};
//
const convertMinutesToTime = (minutes) => {
const hours = Math.floor(minutes / 60);
const mins = minutes % 60;
return `${String(hours).padStart(2, "0")}:${String(mins).padStart(2, "0")}`;
};
//
const convertTimeToMinutes = (timeString) => {
const [hours, minutes] = timeString.split(":").map(Number);
return hours * 60 + minutes;
};
//
const saveRules = async() => {
let invalidSchedule = false;
// schedule
CameraDialog.value.rules.forEach((rule) => {
if (rule.mode === "schedule") {
if (rule.schedule.type && rule.schedule.time_slots.length === 0) {
//
ElMessage.error(`规则 "${rule.name}" 的时间段不能为空,请添加至少一个时间段`);
invalidSchedule = true;
}
}
});
//
if (invalidSchedule) return;
// cameraUpdate
const cameraUpdate = {
id: CameraDialog.value.id,
name: CameraDialog.value.name,
mode: CameraDialog.value.mode,
// rules: CameraDialog.value.rules.map((rule) => ({
// id: rule.id,
// name: rule.name,
// mode: rule.mode,
// })),
};
console.log("页面的cameraUpdate》》》》》》》》》》》:", cameraUpdate);
// ruleUpdate
const ruleUpdate = CameraDialog.value.rules.map((rule) => ({
id: rule.id,
name: rule.name,
mode: CameraDialog.value.mode === "off" ? "off" : rule.mode,
schedule: rule.mode === "schedule" ? {
type: rule.schedule.type,
time_slots: rule.schedule.time_slots.map(([start, end]) => [
convertTimeToMinutes(start),
convertTimeToMinutes(end),
]),
} : {}, // schedule schedule
}));
try {
const token = localStorage.getItem('alertToken');
// API camera rules
await apiInstance.updateCamera(token, cameraUpdate.id, cameraUpdate); //
await apiInstance.updateRule(token, ruleUpdate); //
// ElMessage.success("");
emit("save-result", { success: true, message: "规则保存成功" });
emit("update:visible", false);
// dialogVisible.value = false;
} catch (error) {
console.error("保存失败:", error);
// ElMessage.error("");
emit("save-result", { success: false, message: "规则保存失败,请重试" });
}
};
const closeDialog = () => {
dialogVisible.value = false;
};
</script>
<style scoped>
.time-period {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 10px;
}
.rule-block {
border: 1px solid #ddd;
padding: 20px;
margin-bottom: 20px;
}
.dialog-footer {
/* text-align: right; */
display: flex;
justify-content: flex-end;
}
.camera-title{
font-size: 20px;
}
</style>