Jelajahi Sumber

fix: 修复添加/编辑监控调阅记录审批单图片时异常复制闪烁问题

bxy 6 bulan lalu
induk
melakukan
3079cf47c1

+ 76 - 38
src/views/security-confidentiality/surveillance-management/components/ManageDrawer.vue

@@ -5,17 +5,24 @@
     :title="props.type === 'add' ? '添加监控调阅记录' : '编辑监控调阅记录'"
     @close="handleCloseDrawer"
   >
-    <el-form ref="formRef" :model="formParams" :rules="rules" label-placement="left" :label-width="95">
+    <el-form
+      v-loading="loading"
+      ref="formRef"
+      :model="formParams"
+      :rules="rules"
+      :label-width="95"
+      label-placement="left"
+    >
       <el-form-item label="工号" prop="staffNo" style="margin-bottom: 18px">
-        <el-input placeholder="请输入工号" v-model="formParams.staffNo" v-if="staffNoHtmlType === 'INPUT'" />
+        <el-input v-model="formParams.staffNo" v-if="staffNoHtmlType === 'INPUT'" placeholder="请输入工号" />
         <el-tree-select
           v-model="formParams.staffNo"
-          check-strictly
+          v-else
           placeholder="请输入工号进行搜索"
-          class="protocal-select"
           filterable
           remote
           clearable
+          class="protocal-select"
           :loading="loading"
           :data="staffNoOptions"
           :render-after-expand="false"
@@ -23,7 +30,6 @@
           :remote-method="debouncedRemoteMethod"
           @clear="handleClearStaffNo"
           @change="handleChangeStaffNo"
-          v-else
         />
         <el-text class="text-mode" type="primary" @click="handleChangeStaff">{{
           `切换为工号${staffNoHtmlType === 'INPUT' ? '选择' : '输入'}方式`
@@ -31,34 +37,31 @@
       </el-form-item>
       <el-form-item label="姓名" prop="userName">
         <el-input
-          :placeholder="staffNoHtmlType === 'INPUT' ? '请输入姓名' : '请选择工号,此项自动填充'"
           v-model="formParams.userName"
           :disabled="staffNoHtmlType === 'SELECT'"
+          :placeholder="staffNoHtmlType === 'INPUT' ? '请输入姓名' : '请选择工号,此项自动填充'"
         />
       </el-form-item>
       <el-form-item label="所属部门" prop="deptId">
         <el-tree-select
           v-model="formParams.deptId"
+          filterable
+          clearable
+          placement="left"
+          class="protocal-select"
           :data="departmentArr"
-          :render-after-expand="false"
           :default-expand-all="true"
-          :placeholder="staffNoHtmlType === 'INPUT' ? '请选择部门' : '请选择工号,此项自动填充'"
-          class="protocal-select"
+          :render-after-expand="false"
           :filter-node-method="filterDept"
-          filterable
-          clearable
           :disabled="staffNoHtmlType === 'SELECT'"
+          :placeholder="staffNoHtmlType === 'INPUT' ? '请选择部门' : '请选择工号,此项自动填充'"
           @change="handleChangeDept"
-        >
-          <template #default>
-            {{ formParams.deptName }}
-          </template>
-        </el-tree-select>
+        />
       </el-form-item>
       <el-form-item label="调阅位置" prop="accessLocation">
         <el-input
-          placeholder="请输入调阅位置"
           v-model="formParams.accessLocation"
+          placeholder="请输入调阅位置"
           maxlength="50"
           show-word-limit
           clearable
@@ -99,7 +102,7 @@
         />
       </el-form-item>
       <el-form-item label="记录人" prop="createdByName">
-        <el-input placeholder="记录人" v-model="formParams.createdByName" disabled />
+        <el-input v-model="formParams.createdByName" placeholder="记录人" disabled />
       </el-form-item>
     </el-form>
     <template #footer>
@@ -115,25 +118,25 @@
   import { ref, reactive, watch, computed, onMounted } from 'vue';
   import { ElMessage, type FormInstance, type FormRules } from 'element-plus';
   import { debounce } from 'lodash-es';
-  import { getAllDepartments } from '@/api/auth/dept';
-  import { queryOrganizationUserTree } from '@/api/system/user';
+  import { ImageItem } from '@/types/disaster-control';
+  import { useUserInfoHook } from '@/hooks/useUserInfoHook';
   import { OrganizationUserTree } from '@/views/system/user/types';
-  import { calculateTreeData } from '@/utils';
   import UploadImages from '@/views/disaster/disaster-control/src/components/UploadImages.vue';
-  import { ImageItem } from '@/types/disaster-control';
-  import { UPLOAD_BIZ_TYPE, uploadFileApi } from '@/api/minio';
   import {
     findUserByWorkNo,
     transformTreeData,
     TransformedTreeNode,
     findOrgCodeByWorkNo,
   } from '@/utils/findUserByWorkNo';
+  import { calculateTreeData } from '@/utils';
+  import { getAllDepartments } from '@/api/auth/dept';
+  import { queryOrganizationUserTree } from '@/api/system/user';
+  import { UPLOAD_BIZ_TYPE, uploadFileApi } from '@/api/minio';
   import {
     SurveillanceInfoStruct,
     addSurveillanceInfo,
     updateSurveillanceInfo,
   } from '@/api/security-confidentiality-surveillance';
-  import { useUserInfoHook } from '@/hooks/useUserInfoHook';
 
   const props = defineProps<{
     type: string; // add or edit
@@ -206,7 +209,13 @@
 
   const approvalImageList = computed(() => {
     if (!formParams.value.approvalFormUrl) return [];
-    return JSON.parse(formParams.value.approvalFormUrl);
+    // 如果是临时标记值,返回空数组
+    if (formParams.value.approvalFormUrl === 'temp') return [];
+    try {
+      return JSON.parse(formParams.value.approvalFormUrl);
+    } catch (e) {
+      return [];
+    }
   });
 
   // 通过工号查询组织结构树
@@ -307,6 +316,16 @@
 
   const handleApprovalUploadChange = async () => {
     approvalImages.value = uploadImagesRef.value!.getUploadedImages();
+    // 根据是否有图片,更新审批单字段的值
+    if (approvalImages.value && approvalImages.value.length > 0) {
+      formParams.value.approvalFormUrl = 'temp'; // 设置非空值,表示已上传
+    } else {
+      formParams.value.approvalFormUrl = ''; // 设置空值
+    }
+    // 手动触发审批单字段的校验
+    if (formRef.value) {
+      formRef.value.validateField('approvalFormUrl');
+    }
   };
 
   // 部门过滤函数
@@ -337,27 +356,46 @@
       formParams.value.accessEndTime = formParams.value.accessTimeRange[1];
     }
 
-    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() + ']';
+    // 先更新审批单数据,用于校验
+    approvalImages.value = uploadImagesRef.value!.getUploadedImages();
 
-    await formEl.validate((valid) => {
+    // 临时设置审批单字段,用于校验
+    if (approvalImages.value && approvalImages.value.length > 0) {
+      formParams.value.approvalFormUrl = 'temp'; // 设置非空值用于校验
+    } else {
+      formParams.value.approvalFormUrl = ''; // 设置空值触发必填校验
+    }
+
+    // 先进行表单校验
+    await formEl.validate(async (valid) => {
       if (!valid) return;
 
+      // 校验通过后,处理审批单图片上传
+      const images = await Promise.all(
+        (approvalImages.value || []).map((item) => {
+          if (!item.file && item.url) {
+            return '"' + item.url + '"';
+          } else {
+            return formatApprovalImage(item.file!);
+          }
+        }),
+      );
+      const approvalFormUrlValue = '[' + images.toString() + ']';
+
+      // 创建提交数据对象,不直接修改 formParams.value.approvalFormUrl
+      // 避免触发 approvalImageList 计算属性变化,进而触发 UploadImages 的 watch
+      const submitData = {
+        ...formParams.value,
+        approvalFormUrl: approvalFormUrlValue,
+      };
+
       if (props.type === 'add') {
-        addSurveillanceInfo(formParams.value).then(() => {
+        addSurveillanceInfo(submitData).then(() => {
           ElMessage.success('添加成功');
           handleCloseDrawer();
         });
       } else {
-        updateSurveillanceInfo(formParams.value).then(() => {
+        updateSurveillanceInfo(submitData).then(() => {
           ElMessage.success('编辑成功');
           handleCloseDrawer();
         });