Преглед изворни кода

Merge branch 'dev-bxy' into 'dev'

feat: 保卫保密监控调阅记录表单修改

See merge request product-group-fe/sfy-safety-group/sfy-safety!223
毕欣怡 пре 7 месеци
родитељ
комит
e859c97dfd

+ 2 - 3
src/api/security-confidentiality-surveillance/index.ts

@@ -67,11 +67,10 @@ export const updateSurveillanceInfo = (params: SurveillanceInfoStruct) => {
 /**
  * @description: 删除监控调阅记录(单个)
  */
-export const deleteSurveillanceInfo = (params: { recordId: number }) => {
+export const deleteSurveillanceInfo = (recordId: number) => {
   return http.request({
-    url: '/MonitorAccessRecord/deleteMonitorAccessRecord',
+    url: `/MonitorAccessRecord/deleteMonitorAccessRecord?recordId=${recordId}`,
     method: 'delete',
-    params,
   });
 };
 

+ 0 - 1
src/views/security-confidentiality/confidentiality-position/monitor-records/components/InvasionSnapshot.vue

@@ -70,7 +70,6 @@
   import { useUserInfoHook } from '@/hooks/useUserInfoHook';
   import { SECURITY_CONFIDENTIALITY_PERMISSIONS } from '@/views/security-confidentiality/constant';
   import ImageViewer from '@/views/traffic/violation/act/components/ImageViewer.vue';
-
   import {
     getInvasionSnapshotSwitch,
     updateInvasionSnapshotSwitch,

+ 2 - 0
src/views/security-confidentiality/constant/index.ts

@@ -6,4 +6,6 @@ export const SECURITY_CONFIDENTIALITY_PERMISSIONS = {
   CONFIDENTIALITY_POSITION_MANAGEMENT: 'security_business_module:confidentiality_position_management',
   // 保密要害部位监测抓拍管理
   CONFIDENTIALITY_POSITION_MONITOR_MANAGEMENT: 'security_business_module:confidentiality_position_monitor_management',
+  // 监控调阅记录管理
+  SURVEILLANCE_MANAGEMENT: 'security_business_module:surveillance_management',
 };

+ 11 - 32
src/views/security-confidentiality/surveillance-management/SurveillanceManagement.vue

@@ -101,18 +101,7 @@
               </el-tag>
             </template>
             <template #approvalForm="scope">
-              <div class="image-viewer">
-                <div v-if="scope.row.approvalFormUrl">
-                  <el-image
-                    fit="cover"
-                    :src="scope.row.approvalFormUrl"
-                    :preview-src-list="[scope.row.approvalFormUrl]"
-                    class="image-viewer__image"
-                    :preview-teleported="true"
-                  />
-                </div>
-                <div v-else>-</div>
-              </div>
+              <ImageViewer :file-list="scope.row.approvalFormUrl" />
             </template>
             <template #accessStatus="scope">
               <el-tag :type="scope.row.accessStatus === 1 ? 'success' : 'warning'">
@@ -146,11 +135,14 @@
   import BasicTable from '@/components/BasicTable.vue';
   import ActionButton from '@/components/ActionButton.vue';
   import ManageDrawer from './components/ManageDrawer.vue';
+  import ImageViewer from '@/views/traffic/violation/act/components/ImageViewer.vue';
   import { downloadByData } from '@/utils/file/download';
   import { msgConfirm } from '@/utils/element-plus/messageBox';
   import { getCurrentDateTimeString } from '@/utils/dateUtil';
   import type { QueryPageRequest } from '@/types/basic-query';
   import useTableConfig from '@/hooks/useTableConfigHook';
+  import { useUserInfoHook } from '@/hooks/useUserInfoHook';
+  import { SECURITY_CONFIDENTIALITY_PERMISSIONS } from '@/views/security-confidentiality/constant';
   import {
     SURVEILLANCE_LIST_TABLE_MAX_HEIGHT_DEFAULT,
     SURVEILLANCE_LIST_TABLE_MAX_HEIGHT_PERMISSION,
@@ -168,6 +160,7 @@
 
   const { tableConfig, pagination } = useTableConfig(SURVEILLANCE_LIST_TABLE_COLUMNS, SURVEILLANCE_LIST_TABLE_OPTIONS);
 
+  const { permissions } = useUserInfoHook();
   const surveillanceManagePermission = ref<boolean>(false);
 
   const searchSelectedType = ref(FIELDTYPE.NAME);
@@ -276,7 +269,7 @@
 
   const handleDeleteSurveillanceInfo = (row: SurveillanceInfoStruct) => {
     if (!row.id) return;
-    deleteSurveillanceInfo({ recordId: row.id }).then(() => {
+    deleteSurveillanceInfo(row.id).then(() => {
       ElMessage.success('删除成功');
       getTableData();
     });
@@ -310,9 +303,12 @@
   };
 
   onMounted(() => {
+    surveillanceManagePermission.value = Boolean(
+      permissions.find(
+        (item: { code: string }) => item.code === SECURITY_CONFIDENTIALITY_PERMISSIONS.SURVEILLANCE_MANAGEMENT,
+      ),
+    );
     getTableData();
-    // 假设有监控调阅管理权限,实际应该从权限系统获取
-    surveillanceManagePermission.value = true;
     tableConfig.maxHeight = surveillanceManagePermission.value
       ? SURVEILLANCE_LIST_TABLE_MAX_HEIGHT_PERMISSION
       : SURVEILLANCE_LIST_TABLE_MAX_HEIGHT_DEFAULT;
@@ -353,21 +349,4 @@
     width: 100%;
     height: 100%;
   }
-
-  .image-viewer {
-    width: 120px;
-    height: 90px;
-    position: relative;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    margin: auto;
-  }
-
-  .image-viewer__image {
-    display: block;
-    width: 120px;
-    height: 90px;
-    border-radius: 5px;
-  }
 </style>

+ 46 - 61
src/views/security-confidentiality/surveillance-management/components/ManageDrawer.vue

@@ -1,12 +1,12 @@
 <template>
   <el-drawer
     v-model="isDrawer"
-    size="480"
+    size="500"
     :title="props.type === 'add' ? '添加监控调阅记录' : '编辑监控调阅记录'"
     @close="handleCloseDrawer"
   >
     <el-form ref="formRef" :model="formParams" :rules="rules" label-placement="left" :label-width="95">
-      <el-form-item label="工号" prop="staffNo" style="margin-bottom: 8px">
+      <el-form-item label="工号" prop="staffNo" style="margin-bottom: 18px">
         <el-input placeholder="请输入工号" v-model="formParams.staffNo" v-if="staffNoHtmlType === 'INPUT'" />
         <el-tree-select
           v-model="formParams.staffNo"
@@ -36,20 +36,24 @@
           :disabled="staffNoHtmlType === 'SELECT'"
         />
       </el-form-item>
-      <el-form-item label="所属部门" prop="deptName">
+      <el-form-item label="所属部门" prop="deptId">
         <el-tree-select
-          v-model="formParams.deptName"
+          v-model="formParams.deptId"
           :data="departmentArr"
           :render-after-expand="false"
           :default-expand-all="true"
-          check-strictly
           :placeholder="staffNoHtmlType === 'INPUT' ? '请选择部门' : '请选择工号,此项自动填充'"
           class="protocal-select"
           :filter-node-method="filterDept"
           filterable
           clearable
           :disabled="staffNoHtmlType === 'SELECT'"
-        />
+          @change="handleChangeDept"
+        >
+          <template #default>
+            {{ formParams.deptName }}
+          </template>
+        </el-tree-select>
       </el-form-item>
       <el-form-item label="调阅位置" prop="accessLocation">
         <el-input
@@ -69,6 +73,7 @@
           end-placeholder="结束时间"
           format="YYYY-MM-DD HH:mm:ss"
           value-format="YYYY-MM-DD HH:mm:ss"
+          placement="left"
           style="width: 100%"
           @change="handleChangeAccessTimeRange"
         />
@@ -85,7 +90,7 @@
           <el-radio :value="1">已调阅</el-radio>
         </el-radio-group>
       </el-form-item>
-      <el-form-item label="审批单上传" prop="approvalFormUrl" :rules="approvalFormRules">
+      <el-form-item label="审批单上传" prop="approvalFormUrl">
         <UploadImages
           ref="uploadImagesRef"
           :maxCount="1"
@@ -142,7 +147,7 @@
   const { id, realname, staffNo } = useUserInfoHook();
 
   const formRef = ref<FormInstance>();
-  const formParams = ref<SurveillanceInfoStruct & { accessTimeRange: [string, string] }>({
+  const formParams = ref<SurveillanceInfoStruct & { accessTimeRange: [string, string] | null }>({
     id: 0,
     staffNo: '',
     userName: '',
@@ -151,7 +156,7 @@
     accessLocation: '',
     accessStartTime: '',
     accessEndTime: '',
-    accessTimeRange: ['', ''],
+    accessTimeRange: null,
     isCopy: 0,
     accessStatus: 0,
     approvalFormUrl: '',
@@ -166,25 +171,23 @@
   const rules = reactive<FormRules<SurveillanceInfoStruct & { accessTimeRange: [string, string] }>>({
     staffNo: { required: true, message: '工号不能为空', trigger: 'blur' },
     userName: { required: true, message: '姓名不能为空', trigger: 'blur' },
-    deptName: { required: true, message: '所属部门不能为空', trigger: 'blur' },
+    deptId: { required: true, message: '所属部门不能为空', trigger: 'blur' },
     accessLocation: { required: true, message: '调阅位置不能为空', trigger: 'blur' },
-    accessTimeRange: { required: true, message: '调阅时段不能为空', trigger: 'change' },
-    isCopy: { required: true, message: '请选择是否拷贝', trigger: 'change' },
-    accessStatus: { required: true, message: '请选择调阅状态', trigger: 'change' },
-  });
-
-  // 审批单上传验证规则
-  const approvalFormRules = [
-    {
-      validator: (_: unknown, value: string, callback: (err?: Error) => void) => {
-        if (!value || value.trim() === '') {
-          return callback(new Error('请上传审批单'));
+    accessTimeRange: {
+      required: true,
+      validator: (rule, value, callback) => {
+        if (!value || !Array.isArray(value) || value.length !== 2 || !value[0] || !value[1]) {
+          callback(new Error('调阅时段不能为空'));
+        } else {
+          callback();
         }
-        callback();
       },
-      trigger: ['blur', 'change'],
+      trigger: 'change',
     },
-  ];
+    isCopy: { required: true, message: '请选择是否拷贝', trigger: 'change' },
+    accessStatus: { required: true, message: '请选择调阅状态', trigger: 'change' },
+    approvalFormUrl: { required: true, message: '请上传审批单', trigger: 'change' },
+  });
 
   const isDrawer = ref(true);
   const loading = ref(false);
@@ -203,14 +206,7 @@
 
   const approvalImageList = computed(() => {
     if (!formParams.value.approvalFormUrl) return [];
-    // 如果是单个URL字符串,转换为数组格式
-    try {
-      const parsed = JSON.parse(formParams.value.approvalFormUrl);
-      return Array.isArray(parsed) ? parsed : [parsed];
-    } catch {
-      // 如果不是JSON格式,直接作为单个URL处理
-      return [{ url: formParams.value.approvalFormUrl }];
-    }
+    return JSON.parse(formParams.value.approvalFormUrl);
   });
 
   // 通过工号查询组织结构树
@@ -289,8 +285,12 @@
     }
   };
 
+  const handleChangeDept = (value) => {
+    const dept = findNodeInTree(departmentArr.value, value);
+    formParams.value.deptName = dept ? dept.label : '';
+  };
+
   const handleChangeAccessTimeRange = () => {
-    console.log('accessTimeRange', formParams.value.accessTimeRange);
     if (formParams.value.accessTimeRange && formParams.value.accessTimeRange.length === 2) {
       formParams.value.accessStartTime = formParams.value.accessTimeRange[0];
       formParams.value.accessEndTime = formParams.value.accessTimeRange[1];
@@ -299,33 +299,24 @@
 
   // 格式化审批单图片
   const formatApprovalImage = async (file: File) => {
-    if (!file) return '';
+    if (!file) return file;
     const fileName = file.name;
     const res = await uploadFileApi({ bizType: UPLOAD_BIZ_TYPE.ATTACHMENT, fileName, file });
-    return res.url;
+    return '"' + res.url + '"';
   };
 
   const handleApprovalUploadChange = async () => {
     approvalImages.value = uploadImagesRef.value!.getUploadedImages();
-    if (approvalImages.value && approvalImages.value.length > 0) {
-      const image = approvalImages.value[0]; // 只取第一张图片
-      if (!image.file && image.url) {
-        // 如果已有URL,直接使用
-        formParams.value.approvalFormUrl = image.url;
-      } else if (image.file) {
-        // 如果有新文件,上传后使用新URL
-        const url = await formatApprovalImage(image.file);
-        formParams.value.approvalFormUrl = url;
-      }
-    } else {
-      // 如果没有图片,清空URL
-      formParams.value.approvalFormUrl = '';
-    }
-
-    // 手动触发审批单字段的校验
-    if (formRef.value) {
-      formRef.value.validateField('approvalFormUrl');
-    }
+    const images = await Promise.all(
+      (approvalImages.value || []).map((item) => {
+        if (!item.file && item.url) {
+          return '"' + item.url + '"';
+        } else {
+          return formatApprovalImage(item.file!);
+        }
+      }),
+    );
+    formParams.value.approvalFormUrl = '[' + images.toString() + ']';
   };
 
   // 部门过滤函数
@@ -377,18 +368,13 @@
     () => props.initialData,
     (newData) => {
       if (newData) {
-        formParams.value = { ...newData, accessTimeRange: ['', ''] };
-        // 处理调阅时段
+        formParams.value = { ...newData, accessTimeRange: null };
         if (newData.accessStartTime && newData.accessEndTime) {
           formParams.value.accessTimeRange = [newData.accessStartTime, newData.accessEndTime];
         }
-        // 处理审批单图片 - 直接使用URL字符串
-        // approvalFormUrl 已经是字符串格式,不需要额外处理
-        // 如果有工号,尝试查询用户信息
         if (newData.staffNo) {
           remoteMethod(newData.staffNo);
         }
-        // 编辑模式下,记录人字段保持原有数据,不覆盖
       }
     },
     { immediate: true, deep: true },
@@ -396,7 +382,6 @@
 
   onMounted(() => {
     initDepartmentList();
-    // 只有在添加模式下才初始化记录人为当前登录用户
     if (props.type === 'add') {
       formParams.value.createdByName = realname;
     }

+ 2 - 2
src/views/security-confidentiality/surveillance-management/config/table.ts

@@ -3,8 +3,8 @@
  */
 import type { TableColumnProps } from '@/types/basic-table';
 
-export const SURVEILLANCE_LIST_TABLE_MAX_HEIGHT_DEFAULT = 'calc(70vh - 80px)';
-export const SURVEILLANCE_LIST_TABLE_MAX_HEIGHT_PERMISSION = 'calc(70vh - 130px)';
+export const SURVEILLANCE_LIST_TABLE_MAX_HEIGHT_DEFAULT = 'calc(70vh - 130px)';
+export const SURVEILLANCE_LIST_TABLE_MAX_HEIGHT_PERMISSION = 'calc(70vh - 180px)';
 
 // 基础表格样式配置
 const TABLE_OPTIONS = {