|
@@ -0,0 +1,211 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div class="algoCardWrapper">
|
|
|
|
|
+ <div style="display: flex; justify-content: space-between">
|
|
|
|
|
+ <ElSelect v-model="currentAlgoId" style="width: 150px">
|
|
|
|
|
+ <ElOption v-for="item in data" :key="item.id" :value="item.id" :label="item.name">
|
|
|
|
|
+ {{ item.name }}
|
|
|
|
|
+ <span style="margin-left: 5px" v-if="isAlgoAdded(item.id)">√</span>
|
|
|
|
|
+ </ElOption>
|
|
|
|
|
+ </ElSelect>
|
|
|
|
|
+ <ElSwitch v-model="enableCard" />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <div class="algoRow">
|
|
|
|
|
+ <div class="algoLabel">电子围栏:</div>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <ElSwitch v-model="electronicFence" size="small" />
|
|
|
|
|
+ <span style="font-size: 10px; margin-left: 20px; color: #262626"
|
|
|
|
|
+ >备注:请绘制电子围栏</span
|
|
|
|
|
+ >
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="presetList"> 预置位1 预置位2 预置位3 </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="algoRow">
|
|
|
|
|
+ <div class="algoLabel">检测时间:</div>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <div v-for="x in timeRangeArr" :key="x.id">
|
|
|
|
|
+ <el-time-picker
|
|
|
|
|
+ v-model="x.value"
|
|
|
|
|
+ is-range
|
|
|
|
|
+ arrow-control
|
|
|
|
|
+ range-separator="-"
|
|
|
|
|
+ start-placeholder="Start time"
|
|
|
|
|
+ end-placeholder="End time"
|
|
|
|
|
+ :clearable="false"
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ style="width: 180px; margin-bottom: 10px"
|
|
|
|
|
+ @change="handleTimeChange(x.id, $event)"
|
|
|
|
|
+ />
|
|
|
|
|
+ <span @click="removeTime(x.id)" v-if="timeRangeArr.length > 1">
|
|
|
|
|
+ <el-icon style="color: #8c8c8c"><CircleCloseFilled /></el-icon
|
|
|
|
|
+ ></span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div @click="handleAddTimeRange"
|
|
|
|
|
+ ><el-icon style="cursor: pointer; background-color: #f5f5f5; font-size: 20px"
|
|
|
|
|
+ ><CirclePlus /></el-icon
|
|
|
|
|
+ ></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="algoRow" style="align-items: center">
|
|
|
|
|
+ <div class="algoLabel">检测频率:</div>
|
|
|
|
|
+ <ElInputNumber
|
|
|
|
|
+ v-model="detectionNum"
|
|
|
|
|
+ controls-position="right"
|
|
|
|
|
+ :min="0"
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ style="width: 80px"
|
|
|
|
|
+ />
|
|
|
|
|
+ <ElSelect size="small" style="width: 60px; margin-left: 10px" v-model="detectionUnit">
|
|
|
|
|
+ <ElOption
|
|
|
|
|
+ v-for="x in frequencyOptions"
|
|
|
|
|
+ :key="x.value"
|
|
|
|
|
+ :value="x.value"
|
|
|
|
|
+ :label="x.label"
|
|
|
|
|
+ />
|
|
|
|
|
+ </ElSelect>
|
|
|
|
|
+ <span style="font-size: 12px; margin-left: 5px">/次</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div style="display: flex; justify-content: flex-end">
|
|
|
|
|
+ <ElButton size="small" @click="emits('onRemove', currentAlgoId)">删除</ElButton>
|
|
|
|
|
+ <ElButton size="small" type="primary" @click="handleSave">保存</ElButton>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+<script lang="ts" setup>
|
|
|
|
|
+ import { ElSelect, ElOption, ElSwitch, ElInputNumber, ElTimePicker } from 'element-plus';
|
|
|
|
|
+ import { CirclePlus, CircleCloseFilled } from '@element-plus/icons-vue';
|
|
|
|
|
+ import useAllAlgos from './useAllAlgos';
|
|
|
|
|
+ import { ref, watch } from 'vue';
|
|
|
|
|
+ import { uid } from 'uid';
|
|
|
|
|
+ import { storeToRefs } from 'pinia';
|
|
|
|
|
+ import useCameraAlgoStore from '../../store/useCameraAlgoStore';
|
|
|
|
|
+ import { STATUS } from './types';
|
|
|
|
|
+
|
|
|
|
|
+ const { data, loading } = useAllAlgos();
|
|
|
|
|
+
|
|
|
|
|
+ const cameraAlgoStore = useCameraAlgoStore();
|
|
|
|
|
+
|
|
|
|
|
+ const { data: cameraAlogList } = storeToRefs(cameraAlgoStore);
|
|
|
|
|
+
|
|
|
|
|
+ const props = defineProps<{ activeAlgoId: number | null }>();
|
|
|
|
|
+
|
|
|
|
|
+ interface Param {
|
|
|
|
|
+ /** 算法id */
|
|
|
|
|
+ algoId: number;
|
|
|
|
|
+ /** 检测频率,单位是秒 */
|
|
|
|
|
+ detectionFrequency: number;
|
|
|
|
|
+ /** 检测时间段,可以有多个,转化为字符串,格式为 09:00-10:00;11:00-12:00 */
|
|
|
|
|
+ detectionTime: string;
|
|
|
|
|
+ /** 电子围栏是否开启 */
|
|
|
|
|
+ electronicFence: STATUS;
|
|
|
|
|
+ /** 算法是否启用 */
|
|
|
|
|
+ status: STATUS;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const emits = defineEmits<{
|
|
|
|
|
+ (e: 'onSubmit', param: Param): Promise<unknown>;
|
|
|
|
|
+ (e: 'onRemove', algoId: number): Promise<unknown>;
|
|
|
|
|
+ }>();
|
|
|
|
|
+
|
|
|
|
|
+ enum FrequencyEnum {
|
|
|
|
|
+ second = 1,
|
|
|
|
|
+ miniute = 60,
|
|
|
|
|
+ hour = 3600,
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ watch(
|
|
|
|
|
+ () => props.activeAlgoId,
|
|
|
|
|
+ () => {
|
|
|
|
|
+ if (props.activeAlgoId) {
|
|
|
|
|
+ currentAlgoId.value = props.activeAlgoId;
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ immediate: true,
|
|
|
|
|
+ },
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ const frequencyOptions = [
|
|
|
|
|
+ { label: '秒', value: FrequencyEnum.second },
|
|
|
|
|
+ { label: '分钟', value: FrequencyEnum.miniute },
|
|
|
|
|
+ { label: '小时', value: FrequencyEnum.hour },
|
|
|
|
|
+ ];
|
|
|
|
|
+ const createDefaultTime = () => {
|
|
|
|
|
+ return { id: uid(), value: [new Date(), new Date()] as [Date, Date] };
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const isAlgoAdded = (algoId: number) => {
|
|
|
|
|
+ return cameraAlogList.value?.some((x) => x.id === algoId);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const timeRangeArr = ref([createDefaultTime()]);
|
|
|
|
|
+
|
|
|
|
|
+ const detectionUnit = ref(FrequencyEnum.miniute);
|
|
|
|
|
+
|
|
|
|
|
+ const currentAlgoId = ref<number>(1);
|
|
|
|
|
+
|
|
|
|
|
+ /** 电子围栏开关 */
|
|
|
|
|
+ const electronicFence = ref(true);
|
|
|
|
|
+
|
|
|
|
|
+ const detectionNum = ref(5);
|
|
|
|
|
+
|
|
|
|
|
+ const enableCard = ref(true);
|
|
|
|
|
+
|
|
|
|
|
+ const handleAddTimeRange = () => {
|
|
|
|
|
+ timeRangeArr.value.push(createDefaultTime());
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const handleTimeChange = (...rest) => {
|
|
|
|
|
+ console.log(timeRangeArr);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const removeTime = (id: string) => {
|
|
|
|
|
+ timeRangeArr.value = timeRangeArr.value.filter((x) => x.id !== id);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const getTimeStr = (d: Date) => {
|
|
|
|
|
+ return d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds();
|
|
|
|
|
+ };
|
|
|
|
|
+ const getTimeStrs = (d: [Date, Date]) => {
|
|
|
|
|
+ return getTimeStr(d[0]) + '-' + getTimeStr(d[1]);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const handleSave = () => {
|
|
|
|
|
+ const param = {
|
|
|
|
|
+ algoId: currentAlgoId.value,
|
|
|
|
|
+ detectionFrequency: detectionNum.value * detectionUnit.value,
|
|
|
|
|
+ detectionTime: timeRangeArr.value
|
|
|
|
|
+ .map((x) => {
|
|
|
|
|
+ return getTimeStrs(x.value);
|
|
|
|
|
+ })
|
|
|
|
|
+ .join(';'),
|
|
|
|
|
+ electronicFence: electronicFence.value ? STATUS.enabled : STATUS.disabled,
|
|
|
|
|
+ status: enableCard.value ? STATUS.enabled : STATUS.disabled,
|
|
|
|
|
+ };
|
|
|
|
|
+ emits('onSubmit', param);
|
|
|
|
|
+ console.log('param', param);
|
|
|
|
|
+ };
|
|
|
|
|
+</script>
|
|
|
|
|
+<style scoped>
|
|
|
|
|
+ .algoCardWrapper {
|
|
|
|
|
+ border: 1px solid #ccc;
|
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
+ padding: 10px;
|
|
|
|
|
+ width: 400px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .algoRow {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ margin: 10px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .algoLabel {
|
|
|
|
|
+ margin-right: 10px;
|
|
|
|
|
+ }
|
|
|
|
|
+ .presetList {
|
|
|
|
|
+ font-size: 12px;
|
|
|
|
|
+ }
|
|
|
|
|
+</style>
|