Browse Source

feat: 完成了电子围栏的名称和标签的修改

louhangfei 1 year ago
parent
commit
4acd192367

+ 1 - 1
src/api/camera/camera-preview.ts

@@ -297,7 +297,7 @@ export interface UpdateFenceParams {
   fenceName?: string;
 
   /*电子围栏点位信息 */
-  fencePolygon: string;
+  fencePolygon?: string;
 
   /*是否开启(该算法电子围栏总开关) */
   isDisabled?: boolean;

+ 4 - 4
src/views/cameras/algo-params-setting/components/CameraViewSetting/CameraViewSetting.vue

@@ -18,6 +18,7 @@
             :dom-width="domWidth"
             :canvas-size="{ width: canvasWidth, height: canvasHeight }"
             :line-points="fenceStore.allFences"
+            :fence-id="fenceStore.currentFenceId"
             @save="handleSaveFence"
             @select="handleSelectFencePolygon"
           />
@@ -41,9 +42,8 @@
       <AddPresetModal v-if="addPresetModalVisible" @close="handleClose" @ok="handleAddPresetOk" />
     </div>
   </div>
-  <div class="presetWrapper">
+  <div class="presetWrapper" :style="{ display: drawable ? 'block' : 'none' }">
     <FenceToolbar
-      :style="{ display: drawable ? 'block' : 'none' }"
       :is-edit="isEdit"
       @remove="handleRemove"
       @save="handleSave"
@@ -157,7 +157,6 @@
   // 选中电子围栏列表时
   const handleSelectFenceList = (nextFenceId: number) => {
     fenceStore.currentFenceId = nextFenceId;
-    fenceEditorRef.value?.selectFence(nextFenceId);
   };
 
   const handleSaveFence = (data: { fenceId?: number; polygon: FencePolygonPoints }) => {
@@ -329,7 +328,7 @@
     top: 0;
     width: 260px;
     height: 540px;
-    border: 1px solid #f00;
+    /* border: 1px solid #f00; */
     background: #fff;
     /* width: 962px; */
     /* padding: 20px;
@@ -339,6 +338,7 @@
     margin-bottom: 15px;
     display: flex;
     justify-content: space-between; */
+    transform: scale(1);
   }
   .videoAlgoListWrapper {
     display: flex;

+ 3 - 1
src/views/cameras/algo-params-setting/components/FenceEditor/constants.ts

@@ -38,5 +38,7 @@ export type ServerLinePoint = [number, number];
 /** 一个多边形的所有点坐标 */
 export type ServerLine = ServerLinePoint[];
 
+export type ServerLineInfo =  { id: number; name: string; label: string; polygon: ServerLine }
+
 /** 图上所有的多边形 */
-export type ServerLines = { id: number; name: string; label: string; polygon: ServerLine }[];
+export type ServerLineInfos = ServerLineInfo[];

+ 19 - 9
src/views/cameras/algo-params-setting/components/FenceEditorV2/FenceEditor.vue

@@ -44,6 +44,8 @@
     canvasSize: { width: number; height: number };
     /** dom的真实尺寸 */
     domWidth: number;
+    /** 当前选中的是哪个分组 */
+    fenceId: number;
   }>();
 
   // 保存修改后的电子围栏, fenceId为空表示新建的,否则表示编辑已存在的
@@ -79,12 +81,29 @@
           return createGroupConfig({ fenceId: points.id, points: flattenedPoints, scale: scale.value });
         }) || [];
       fenceGroups.value = configs;
+
+      const currentGroup = fenceGroups.value.find((x) => x.fenceId === props.fenceId);
+      const groupId = currentGroup?.uid;
+      if (groupId) {
+        currentGroupId.value = groupId;
+      }
     },
     {
       immediate: true,
     },
   );
 
+  watch(
+    () => props.fenceId,
+    (nextFenceId) => {
+      const currentGroup = fenceGroups.value.find((x) => x.fenceId === nextFenceId);
+      const groupId = currentGroup?.uid;
+      if (groupId) {
+        currentGroupId.value = groupId;
+      }
+    },
+  );
+
   onMounted(() => {
     /** 取消默认的右键 */
     document.oncontextmenu = function () {
@@ -266,21 +285,12 @@
     isEdit.value = true;
   };
 
-  const selectFence = (fenceId: number) => {
-    const currentGroup = fenceGroups.value.find((x) => x.fenceId === fenceId);
-    const groupId = currentGroup?.uid;
-    if (groupId) {
-      currentGroupId.value = groupId;
-    }
-  };
-
   defineExpose({
     clear,
     remove,
     toObject,
     exitEditMode,
     setEditMode,
-    selectFence,
   });
 </script>
 

+ 70 - 0
src/views/cameras/algo-params-setting/components/FenceToolbar/EditFenceDialog.vue

@@ -0,0 +1,70 @@
+<template>
+  <ElDialog title="编辑电子围栏" v-model="visible" append-to=".presetWrapper" width="95%" top="50px">
+    <!-- 设置 label-position 为 top -->
+    <ElForm :model="form" label-width="100%" label-position="top" ref="formRef" :rules="rules">
+      <!-- 添加名称输入项 -->
+      <ElFormItem label="名称" prop="name">
+        <ElInput v-model="form.name" placeholder="请输入名称" />
+      </ElFormItem>
+      <!-- 添加标签输入项 -->
+      <ElFormItem label="标签" prop="label">
+        <ElInput v-model="form.label" placeholder="请输入标签" />
+      </ElFormItem>
+    </ElForm>
+
+    <template #footer>
+      <ElButton @click="handleCancel">取消</ElButton>
+      <ElButton type="primary" @click="handleConfirm">确定</ElButton>
+    </template>
+  </ElDialog>
+</template>
+<script lang="ts" setup>
+  import { ref } from 'vue';
+  import { ElDialog, ElForm, ElFormItem, ElInput, ElButton, FormInstance } from 'element-plus';
+
+  // 定义表单数据
+  const props = defineProps<{
+    detail: {
+      name: string;
+      label: string;
+    };
+  }>();
+  const emits = defineEmits<{ (e: 'cancel'): void; (e: 'submit', param: { name: string; label: string }): void }>();
+
+  const form = ref({
+    name: props.detail.name,
+    label: props.detail.label,
+  });
+
+  const formRef = ref<FormInstance>();
+  const rules = ref({
+    name: [
+      { required: true, message: '不能为空', trigger: 'change' },
+      { max: 15, message: '最多支持15个字符', trigger: 'change' },
+    ],
+    label: [{ max: 15, message: '最多支持15个字符', trigger: 'change' }],
+  });
+
+  const visible = ref(true);
+
+  // 处理取消按钮点击事件
+  const handleCancel = () => {
+    // 这里可以添加关闭对话框的逻辑
+    emits('cancel');
+  };
+
+  // 处理确定按钮点击事件
+  const handleConfirm = () => {
+    if (!formRef.value) return;
+    // 这里可以添加提交表单的逻辑
+    formRef.value.validate((valid) => {
+      if (valid) {
+        emits('submit', form.value);
+      } else {
+        console.log('表单验证失败');
+      }
+    });
+  };
+</script>
+
+<style></style>

+ 51 - 10
src/views/cameras/algo-params-setting/components/FenceToolbar/FenceToolbar.vue

@@ -15,34 +15,42 @@
         :key="item.id"
         @click="handleSelectFence(item.id)"
         @delete="handleDeleteFence"
-        @edit="handleEditFenceInfo"
+        @edit="handleEditFenceInfo(item)"
+      />
+    </div>
+    <div>
+      <EditFenceDialog
+        v-if="showEditFenceDialog"
+        @cancel="handleEditCancel"
+        @submit="handleEditSubmit"
+        :detail="selectedDetail"
       />
     </div>
 
-    <div class="toolbar">
-      <!-- <div class="fenceDrawingTip" v-if="isEdit">
+    <!-- <div class="toolbar"> -->
+    <!-- <div class="fenceDrawingTip" v-if="isEdit">
         {{ cameraAlgoStore.selectedAlgoDetail?.algoInfo?.name }}算法电子围栏绘制中
       </div> -->
-      <!-- <template v-if="props.isEdit"> -->
-      <!-- <ToolbarIcon
+    <!-- <template v-if="props.isEdit"> -->
+    <!-- <ToolbarIcon
         :src="deleteIcon"
         :active="false"
         @click="emits('toggleFence')"
         tip="检测范围反选"
       /> -->
-      <!-- <ToggleFenceStatus @click="emits('toggleRange')" />
+    <!-- <ToggleFenceStatus @click="emits('toggleRange')" />
         <ToolbarIcon :src="deleteIcon" :active="false" @click="emits('remove')" tip="删除电子围栏" />
         <ToolbarIcon :src="saveIcon" :active="false" @click="emits('save')" tip="保存电子围栏" />
       </template> -->
 
-      <!-- <ElButton type="primary" size="small" @click="toggleEdit">{{
+    <!-- <ElButton type="primary" size="small" @click="toggleEdit">{{
         props.isEdit ? '退出编辑' : '编辑电子围栏'
       }}</ElButton> -->
-    </div>
+    <!-- </div> -->
   </div>
 </template>
 <script setup lang="ts">
-  import { defineEmits } from 'vue';
+  import { defineEmits, ref } from 'vue';
   import { ElButton, ElSwitch } from 'element-plus';
   import ToolbarIcon from '../ToolbarIcon/ToolbarIcon.vue';
   import saveIcon from '@/assets/images/camera/save.png';
@@ -54,6 +62,8 @@
   import useFenceStore from '../../store/useFenceStore';
   import useCameraDetailStore from '../../store/useCameraDetailStore';
   import usePresetListStore from '../../store/usePresetListStore';
+  import EditFenceDialog from './EditFenceDialog.vue';
+  import { ServerLineInfo } from '../FenceEditor/constants';
   const cameraAlgoStore = useCameraAlgoStore();
 
   const fenceStore = useFenceStore();
@@ -61,6 +71,9 @@
   const presetStore = usePresetListStore();
   const props = defineProps<{ isEdit: boolean }>();
 
+  const showEditFenceDialog = ref(false);
+  const selectedDetail = ref<ServerLineInfo | null>(null);
+
   const emits = defineEmits<{
     (e: 'toggleEditable', editState: boolean): unknown;
     (e: 'toggleRange'): unknown;
@@ -77,7 +90,15 @@
     emits('select', nextFenceId);
   };
 
-  const handleEditFenceInfo = (fenceId: number) => {};
+  const handleEditFenceInfo = (detail) => {
+    showEditFenceDialog.value = true;
+    selectedDetail.value = detail;
+  };
+
+  const handleEditCancel = () => {
+    showEditFenceDialog.value = false;
+    selectedDetail.value = null;
+  };
 
   const handleDeleteFence = (fenceId: number) => {
     const cameraId = cameraDetailStore.cameraId;
@@ -85,6 +106,26 @@
     const presetToken = presetStore.currentPresetToken;
     fenceStore.deleteFence({ cameraId, algoId, presetToken, fenceId });
   };
+
+  const handleEditSubmit = (data: { label: string; name: string }) => {
+    const cameraId = cameraDetailStore.cameraId;
+    const algoId = cameraAlgoStore.selectedAlgoId!;
+    const presetToken = presetStore.currentPresetToken;
+    const fenceId = selectedDetail.value?.id;
+    if (!fenceId) return;
+    fenceStore
+      .editFence({
+        cameraId,
+        algoId,
+        presetToken,
+        fenceId: fenceId,
+        fenceLabel: data.label,
+        fenceName: data.name,
+      })
+      .then(() => {
+        handleEditCancel();
+      });
+  };
 </script>
 
 <style scoped>

+ 4 - 4
src/views/cameras/algo-params-setting/store/useFenceStore.ts

@@ -10,13 +10,13 @@ import {
 } from '@/api/camera/camera-preview';
 import { defineStore } from 'pinia';
 import { ref } from 'vue';
-import { ServerLine, ServerLines } from '../components/FenceEditor/constants';
+import { ServerLine, ServerLineInfos } from '../components/FenceEditor/constants';
 import safeParse from '@/utils/safeParse';
 
 /** 当前电子围栏的store */
 export const useFenceStore = defineStore('fencePolygonStore', () => {
   /** 当前相机-预置位-算法对应的所有的电子围栏 */
-  const allFences = ref<ServerLines>([]);
+  const allFences = ref<ServerLineInfos>([]);
   /** 当前正在操作的电子围栏id */
   const currentFenceId = ref<number | null>(null);
   const loading = ref(false);
@@ -31,7 +31,7 @@ export const useFenceStore = defineStore('fencePolygonStore', () => {
         // const pointsJSON = points.poly
         const newFence = fence.map((x) => {
           return { ...x, polygon: safeParse(x.polygon) as ServerLine };
-        }) as unknown as ServerLines;
+        }) as unknown as ServerLineInfos;
         allFences.value = newFence;
       })
       .catch(() => {
@@ -56,7 +56,7 @@ export const useFenceStore = defineStore('fencePolygonStore', () => {
 
   /** 修改电子围栏信息 */
   const editFence = (param: UpdateFenceParams) => {
-    return editFenceApi(param);
+    return editFenceApi(param).then(() => getFence(param));
   };
 
   const deleteFence = (param: DeleteFenceParams) => {