From 6ff219555c53c37d4daae0747751043ea103af1e Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期二, 28 四月 2026 11:32:39 +0800
Subject: [PATCH] 水印签到拜访照片

---
 src/pages/cooperativeOffice/clientVisit/detail.vue |  161 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 158 insertions(+), 3 deletions(-)

diff --git a/src/pages/cooperativeOffice/clientVisit/detail.vue b/src/pages/cooperativeOffice/clientVisit/detail.vue
index 0bab2d7..5fb3677 100644
--- a/src/pages/cooperativeOffice/clientVisit/detail.vue
+++ b/src/pages/cooperativeOffice/clientVisit/detail.vue
@@ -61,6 +61,18 @@
             </template>
           </u-input>
         </u-form-item>
+        <u-form-item label="鎷滆鐓х墖">
+          <AlbumImageUpload
+            v-model="form.storageBlobDTO"
+            @change="onVisitImageChange"
+            :limit="6"
+            :enableWatermark="true"
+            :watermarkText="getVisitWatermarkText"
+            :beforeUpload="beforeUploadVisitImages"
+            action="/file/upload"
+            tipText=""
+          />
+        </u-form-item>
       </u-cell-group>
       <!-- 澶囨敞淇℃伅 -->
       <u-cell-group title="澶囨敞淇℃伅">
@@ -105,6 +117,9 @@
 
   import { ref, onMounted } from "vue";
   import PageHeader from "@/components/PageHeader.vue";
+  import AlbumImageUpload from "@/components/AlbumImageUpload/index.vue";
+  import { normalizeFileUrl } from "@/utils/filePreview";
+  import config from "@/config.js";
   import {
     clientVisitSignIn,
     clientVisitUpdate,
@@ -128,6 +143,12 @@
     longitude: "",
     locationAddress: "",
     remark: "",
+    // 涓存椂鏂囦欢id鍒楄〃锛堟彁浜ょ敤锛�
+    tempFileIds: [],
+    // 姝e紡鏂囦欢鍒楄〃锛堝洖鏄剧敤锛屽悗绔煡璇細杩斿洖锛�
+    commonFileList: [],
+    // 涓婁紶缁勪欢鍥炰紶鐨勬枃浠跺垪琛紙鍚庣鑻ヤ笉鎺ユ敹鍙拷鐣ワ紱鍏堥殢琛ㄥ崟鎻愪氦锛�
+    storageBlobDTO: [],
   });
 
   // 椤甸潰鐘舵��
@@ -275,6 +296,23 @@
       Object.keys(source).forEach(k => {
         submitData[k] = source[k];
       });
+      // 浠庝笂浼犲垪琛ㄦ彁鍙� tempFileIds锛堝吋瀹� tempId / tempFileId / id锛�
+      if (Array.isArray(submitData.storageBlobDTO)) {
+        submitData.tempFileIds = submitData.storageBlobDTO
+          .map(f => f?.tempId ?? f?.tempFileId ?? f?.id)
+          .filter(v => v !== undefined && v !== null && v !== "");
+      } else {
+        submitData.tempFileIds = Array.isArray(submitData.tempFileIds)
+          ? submitData.tempFileIds
+          : [];
+      }
+      // 鍏煎鍚庣鍙帴鏀� URL 瀛楃涓茬殑鍦烘櫙锛氶澶栬ˉ涓�涓� visitImageUrls
+      if (Array.isArray(submitData.storageBlobDTO)) {
+        submitData.visitImageUrls = submitData.storageBlobDTO
+          .map(f => f?.url)
+          .filter(Boolean)
+          .join(",");
+      }
       console.log("submitData", submitData);
       if (isEdit.value) {
         const { code } = await clientVisitUpdate(submitData);
@@ -305,6 +343,72 @@
     }
   };
   const isEdit = ref(false);
+  const getVisitFileKey = file => {
+    return (
+      file?.tempId ??
+      file?.tempFileId ??
+      file?.id ??
+      file?.url ??
+      file?.downloadUrl ??
+      ""
+    );
+  };
+  const onVisitImageChange = list => {
+    const nextList = Array.isArray(list) ? list.slice() : [];
+    form.value.storageBlobDTO = nextList;
+
+    // 鍚屾鎻愪氦鐢� tempFileIds锛岄伩鍏嶅垹闄ゅ悗浠嶆惡甯︽棫 ID
+    form.value.tempFileIds = nextList
+      .map(f => f?.tempId ?? f?.tempFileId ?? f?.id)
+      .filter(v => v !== undefined && v !== null && v !== "");
+
+    // 缂栬緫鍦烘櫙涓嬪悓姝� commonFileList锛岄伩鍏嶆彁浜ゆ椂娈嬬暀宸插垹闄ゆ枃浠�
+    if (Array.isArray(form.value.commonFileList)) {
+      const keepKeys = new Set(nextList.map(getVisitFileKey).filter(Boolean));
+      form.value.commonFileList = form.value.commonFileList.filter(item =>
+        keepKeys.has(getVisitFileKey(item))
+      );
+    }
+  };
+  const isLikelyPathValue = value => {
+    const v = String(value || "").trim();
+    if (!v) return false;
+    if (/^(https?:)?\/\//i.test(v)) return true;
+    if (/^(blob:|data:|wxfile:|file:|content:)/i.test(v)) return true;
+    if (v.includes("/") || v.includes("\\")) return true;
+    if (/\.[a-zA-Z0-9]{2,8}($|\?)/.test(v)) return true;
+    return false;
+  };
+  const buildVisitFilePreviewUrl = file => {
+    const candidates = [
+      file?.link,
+      file?.url,
+      file?.path,
+      file?.filePath,
+      file?.tempPath,
+      file?.urlFull,
+      file?.downloadUrl,
+    ].filter(Boolean);
+
+    for (const raw of candidates) {
+      if (!isLikelyPathValue(raw)) continue;
+      const normalized = normalizeFileUrl(raw);
+      if (normalized) return normalized;
+    }
+
+    for (const raw of candidates) {
+      const value = String(raw || "").trim();
+      if (!value) continue;
+      // 鍏滃簳璧� common/download锛屽吋瀹规煇浜涘悗绔彧杩斿洖鐩稿瀛樺偍璺緞
+      return (
+        (config.baseUrl || "") +
+        "/common/download?fileName=" +
+        encodeURIComponent(value) +
+        "&delete=false"
+      );
+    }
+    return "";
+  };
   onLoad(() => {
     // 缂栬緫鎷滆鏃讹紝浠庢湰鍦板瓨鍌ㄨ幏鍙栨嫓璁胯褰�
     const visit = uni.getStorageSync("clientVisit");
@@ -312,6 +416,35 @@
       form.value = visit;
       isEdit.value = true;
       console.log("form.value", form.value);
+
+      // 鍥炴樉锛氳嫢鍚庣/鍒楄〃椤靛浜� commonFileList锛屽垯杞垚涓婁紶缁勪欢鍙瘑鍒殑 storageBlobDTO
+      const commonFileList = Array.isArray(visit?.commonFileList)
+        ? visit.commonFileList
+        : [];
+      if (commonFileList.length && (!Array.isArray(visit?.storageBlobDTO) || !visit.storageBlobDTO.length)) {
+        form.value.commonFileList = commonFileList;
+        form.value.storageBlobDTO = commonFileList
+          .map(f => {
+            const previewUrl = buildVisitFilePreviewUrl(f);
+            return {
+              ...f,
+              tempId: f?.tempId ?? f?.tempFileId ?? f?.id,
+              id: f?.id ?? f?.tempId ?? f?.tempFileId,
+              url: previewUrl,
+              downloadUrl: previewUrl,
+            };
+          })
+          .filter(x => x?.url);
+      }
+
+      // 缂栬緫鍦烘櫙锛氬悓姝ヤ竴浠� tempFileIds锛屼究浜庡悗绔渶瑕佹椂鐩存帴浣跨敤
+      if (!Array.isArray(form.value.tempFileIds) || !form.value.tempFileIds.length) {
+        form.value.tempFileIds = Array.isArray(form.value.storageBlobDTO)
+          ? form.value.storageBlobDTO
+              .map(f => f?.tempId ?? f?.tempFileId ?? f?.id)
+              .filter(Boolean)
+          : [];
+      }
     } else {
       isEdit.value = false;
     }
@@ -330,21 +463,43 @@
   onMounted(() => {
     initPageData();
   });
+
+  const beforeUploadVisitImages = () => {
+    const name = (form.value.customerName || "").trim();
+    if (!name) {
+      showToast("璇峰厛濉啓瀹㈡埛鍚嶇О鍚庝笂浼�");
+      return false;
+    }
+    const visitTime = (form.value.purposeDate || "").trim();
+    if (!visitTime) {
+      showToast("璇峰厛閫夋嫨鎷滆鏃堕棿鍚庝笂浼�");
+      return false;
+    }
+    return true;
+  };
+
+  const getVisitWatermarkText = () => {
+    const name = (form.value.customerName || "").trim();
+    // 姘村嵃鏃堕棿鏀逛负鈥滄嫓璁挎椂闂粹��
+    const visitTime = (form.value.purposeDate || "").trim();
+    const time = visitTime || dayjs().format("YYYY-MM-DD HH:mm:ss");
+    return name ? `${name}\n${time}` : `\n${time}`;
+  };
 </script>
 
 <style scoped lang="scss">
   @import "@/static/scss/form-common.scss";
-  .client-visit {
+  .client-visit-detail {
     min-height: 100vh;
     background: #f8f9fa;
-    padding-bottom: 5rem;
+    padding-bottom: calc(5rem + env(safe-area-inset-bottom));
   }
 
   .footer-btns {
     position: fixed;
     left: 0;
     right: 0;
-    bottom: 0;
+    bottom: calc(env(safe-area-inset-bottom) + 8px);
     background: #fff;
     display: flex;
     justify-content: space-around;

--
Gitblit v1.9.3