From 5743e533414c608a12f9323f17a7c86721c7f54c Mon Sep 17 00:00:00 2001
From: yxh <172933527@qq.com>
Date: 星期五, 06 十一月 2026 00:13:43 +0800
Subject: [PATCH] organfee

---
 src/views/project/fund/performancedetails/index.vue |  327 +++++++++++++++++++++++++++++++++---------------------
 1 files changed, 199 insertions(+), 128 deletions(-)

diff --git a/src/views/project/fund/performancedetails/index.vue b/src/views/project/fund/performancedetails/index.vue
index 6cfb93d..14e574c 100644
--- a/src/views/project/fund/performancedetails/index.vue
+++ b/src/views/project/fund/performancedetails/index.vue
@@ -11,7 +11,7 @@
                 clearable
                 style="width: 100%"
                 v-model="form.applyTime"
-                type="date"
+                type="date" format="yyyy-MM-dd"
                 value-format="yyyy-MM-dd HH:mm:ss"
                 placeholder="鐢宠鏃ユ湡"
                 :disabled="true"
@@ -59,9 +59,17 @@
           </el-col>
         </el-row>
         <el-row>
-          <el-col :span="5">
-            <el-form-item label="鑱旂郴鐢佃瘽" prop="phone">
-              <el-input v-model="form.phone" placeholder="璇疯緭鍏ヨ仈绯荤數璇�" />
+           <el-col :span="5">
+            <el-form-item label="缁╂晥鏃ユ湡" prop="jxrq">
+              <el-date-picker
+                clearable
+                style="width: 100%"
+                v-model="form.jxrq"
+                type="date" format="yyyy-MM-dd"
+                value-format="yyyy-MM-dd HH:mm:ss"
+                placeholder="缁╂晥鏃ユ湡"
+              >
+              </el-date-picker>
             </el-form-item>
           </el-col>
           <el-col :span="5">
@@ -90,9 +98,14 @@
               </el-select>
             </el-form-item>
           </el-col>
+          <el-col :span="5">
+            <el-form-item label="鑱旂郴鐢佃瘽" prop="phone">
+              <el-input v-model="form.phone" placeholder="璇疯緭鍏ヨ仈绯荤數璇�" />
+            </el-form-item>
+          </el-col>
         </el-row>
         <el-row style="text-align: left">
-          <el-col :span="8">
+          <el-col :span="12">
             <el-form-item label="鐢宠璇存槑" prop="remark">
               <el-input v-model="form.remark" placeholder="鐢宠璇存槑" />
             </el-form-item>
@@ -280,6 +293,31 @@
                       : "鐐瑰嚮閫夋嫨"
                   }}</el-button
                 >
+              </template>
+            </el-table-column>
+            <el-table-column
+              prop="deptName"
+              align="center"
+              label="缁╂晥绉戝"
+              width="160"
+            >
+              <template slot-scope="scope">
+                <el-select
+                  v-model="scope.row.deptId"
+                  size="mini"
+                  clearable
+                  filterable
+                  placeholder="璇烽�夋嫨缁╂晥绉戝"
+                  style="width: 100%"
+                  @change="value => handleRowDeptChange(scope.row, value)"
+                >
+                  <el-option
+                    v-for="dept in deptList"
+                    :key="dept.deptId"
+                    :label="dept.deptName"
+                    :value="dept.deptId"
+                  />
+                </el-select>
               </template>
             </el-table-column>
             <el-table-column
@@ -558,8 +596,28 @@
       :close-on-click-modal="false"
       :title="pdftitle"
       :visible.sync="pdfVisible"
+      :fullscreen="pdfFullscreen"
       width="60%"
+      custom-class="pdf-resize-dialog"
+      @closed="pdfFullscreen = false"
     >
+      <template slot="title">
+        <span>{{ pdftitle }}</span>
+        <el-button class="pdf-fullscreen-btn" size="mini"
+          :icon="pdfFullscreen ? 'el-icon-close' : 'el-icon-full-screen'"
+          @click="pdfFullscreen = !pdfFullscreen">{{ pdfFullscreen ? "杩樺師" : "鍏ㄥ睆" }}</el-button>
+      </template>
+      <el-alert
+        :title="
+          activeName == 2
+            ? '褰撳墠姝e湪鎿嶄綔锛氬彂绁ㄦ枃浠讹紙璇风‘璁ょエ鎹睘浜庡彂绁級'
+            : '褰撳墠姝e湪鎿嶄綔锛氭櫘閫氶檮浠讹紙璇峰嬁鍦ㄦ涓婁紶鍙戠エ锛�'
+        "
+        :type="activeName == 2 ? 'success' : 'warning'"
+        :closable="false"
+        show-icon
+        style="margin-bottom: 10px;"
+      />
       <div style="margin-bottom: 10px;">
         <el-table :data="tableDatatop" style="width: 100%">
           <el-table-column
@@ -686,24 +744,7 @@
               </div>
             </div>
 
-            <div
-              v-if="this.previewpdf && pdfimgsrcList.length"
-              class="pdfimgmin"
-            >
-              <el-image
-                style="width: 95%; height: 90%"
-                :src="pdfimg"
-                @click="handleImageClick(0)"
-              />
-              <custom-image-viewer
-                :url-list="pdfimgsrcList"
-                :initial-index="currentIndex"
-                :visible="viewerVisible"
-                @update:visible="viewerVisible = $event"
-                @close="handleViewerClose"
-              />
-            </div>
-            <div v-else class="pdfimgmins">{{ hintitle }}</div>
+            <attachment-preview-pane :file="embeddedFile" style="flex: 1; min-width: 0;" />
           </div>
         </el-tab-pane>
         <el-tab-pane label="鍙戠エ鏂囦欢" :name="2">
@@ -791,24 +832,7 @@
               </div>
             </div>
 
-            <div
-              v-if="this.previewpdf && invoicepdfimgsrcList.length"
-              class="pdfimgmin"
-            >
-              <el-image
-                style="width: 95%; height: 90%"
-                :src="invoicepdfimg"
-                @click="invoiceHandleImageClick(0)"
-              />
-              <custom-image-viewer
-                :url-list="invoicepdfimgsrcList"
-                :initial-index="invoiceCurrentIndex"
-                :visible="invoiceViewerVisible"
-                @update:visible="invoiceViewerVisible = $event"
-                @close="invoiceHandleViewerClose"
-              />
-            </div>
-            <div v-else class="pdfimgmins">{{ hintitle }}</div>
+            <attachment-preview-pane :file="invoiceEmbeddedFile" style="flex: 1; min-width: 0;" />
           </div>
         </el-tab-pane>
       </el-tabs>
@@ -858,7 +882,8 @@
             :label="city"
             :key="city.id"
             >{{ city.username }}{{ city.isUnitPerson ? "锛堝崟浣嶏級" : ""
-            }}{{ city.unitname ? " 路 " + city.unitname : "" }}</el-checkbox
+            }}{{ city.unitname ? " 路 " + city.unitname : ""
+            }}{{ city.deptName ? " 路 绉戝锛�" + city.deptName : "" }}</el-checkbox
           >
         </el-checkbox-group>
       </div>
@@ -915,10 +940,12 @@
 import { listItemexpense } from "@/api/project/itemexpense";
 
 import { getUserProfile } from "@/api/system/user";
+import { listDept } from "@/api/system/dept";
 import Li_area_select from "@/components/Address";
 import OrgSelecter from "@/views/project/components/orgselect";
 import { getToken } from "@/utils/auth";
 import { moneySum, moneyAdd, moneySub, moneyRound } from "@/utils/money";
+import { checkFileName, checkDetails } from "@/utils/fileNameCheck";
 import CustomImageViewer from "@/components/CustomImageViewer";
 
 export default {
@@ -969,6 +996,8 @@
       expertlist: [],
       //鍖荤枟鏈烘瀯鍒楄〃
       unitList: [],
+      //缁╂晥绉戝鍒楄〃
+      deptList: [],
       //璐圭敤鎶ラ攢鏈烘瀯鍒楄〃
       feeUnitList: [],
       batchdialogVisible: false,
@@ -1218,7 +1247,7 @@
       invoicefileListto: [],
       invoicepdfimg: "",
       invoicepdfimgsrcList: [],
-      activeName: 1, //鏂囦欢绫诲瀷
+      activeName: 2, //鏂囦欢绫诲瀷锛氶粯璁ゅ彂绁ㄦ枃浠�
       //涓婁紶闄勪欢璺緞
       uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload",
       //鏂囦欢涓婁紶token
@@ -1228,6 +1257,7 @@
       //绁ㄦ嵁鏂囦欢
       pdftitle: "",
       pdfimg: "",
+      invoiceEmbeddedFile: null,
       pdfimgsrcList: [],
       pdfVisible: false,
       previewpdf: false,
@@ -1660,6 +1690,11 @@
     },
     /** 鎻愪氦鎸夐挳 */
     submitForm: debounce(function() {
+      // 2026-10-15锛氫繚瀛樺墠闄勪欢鏂囦欢鍚嶈鑼冩牎楠岋紙浠呮柊澧炲崟鎹紱鑰佸崟鎹殑鍘嗗彶闄勪欢鐢卞悗绔寜"鍙牎楠屾湰娆″彉鏇�"鏀捐锛�
+      if (!this.checkDetailFileNames()) {
+        return;
+      }
+
       if (!this.randomnumber) {
         this.randomnumber = this.generateRandomString(9);
         this.form.randomnumber = this.randomnumber;
@@ -1885,11 +1920,7 @@
           this.$router.go(-1);
         } else {
           this.$modal.closeLoading();
-          if (res.msg) {
-            this.$modal.msgError("鎿嶄綔澶辫");
-          } else {
-            this.$modal.msgError(res.msg);
-          }
+          this.$modal.msgError(res.msg || "鎿嶄綔澶辫触");
         }
       });
     },
@@ -1998,6 +2029,25 @@
         this.feeUnitList = res.data;
         console.log(this.feeUnitList);
       });
+    },
+
+    /** 缁╂晥绉戝鍒楄〃 */
+    getDeptList() {
+      listDept({}).then(res => {
+        this.deptList = res.data || [];
+      });
+    },
+
+    /** 琛ㄦ牸鍐呯洿鎺ヤ慨鏀圭哗鏁堢瀹わ細鍚屾鍚嶇О */
+    handleRowDeptChange(row, deptId) {
+      if (deptId === null || deptId === undefined || deptId === "") {
+        this.$set(row, "deptName", null);
+        return;
+      }
+      const dept = this.deptList.find(
+        item => String(item.deptId) === String(deptId)
+      );
+      this.$set(row, "deptName", dept ? dept.deptName : null);
     },
 
     //鑾峰彇鍖荤枟鏈烘瀯鍒楄〃
@@ -2182,6 +2232,11 @@
     },
     // 鎺ュ彈鎻愰啋绔嬪埢淇濆瓨
     Savenow() {
+      // 2026-10-15锛氫繚瀛樺墠闄勪欢鏂囦欢鍚嶈鑼冩牎楠岋紙浠呮柊澧炲崟鎹紱鑰佸崟鎹殑鍘嗗彶闄勪欢鐢卞悗绔寜"鍙牎楠屾湰娆″彉鏇�"鏀捐锛�
+      if (!this.checkDetailFileNames()) {
+        return;
+      }
+
       if (!this.randomnumber) {
         this.randomnumber = this.generateRandomString(9);
         this.form.randomnumber = this.randomnumber;
@@ -2502,6 +2557,8 @@
           isunit: isunit ? 1 : 0,
           unitname: item.unitname,
           unitno: item.unitno,
+          deptId: item.deptId,
+          deptName: item.deptName,
           uintuserno: null,
           title: item.title,
           idcardtype: null,
@@ -2727,6 +2784,8 @@
         singleDetail.title = person.title;
         singleDetail.unitname = person.unitname;
         singleDetail.unitno = person.unitno;
+        singleDetail.deptId = person.deptId;
+        singleDetail.deptName = person.deptName;
       } else {
         // 鎵嬪伐杈撳叆鐨勪汉鍛橈細鍙啓濮撳悕锛岃韩浠借瘉鍙�/閾惰璐﹀彿鐢辩粡鍔炰汉濉啓
         singleDetail.beneficiaryname = String(key);
@@ -2754,41 +2813,67 @@
     },
     // 鑾峰彇璇锋眰澶�
     Getnetworkheader() {
-      let string = window.location.href;
-      if (string.includes("9091")) {
-        const index = string.indexOf("9091");
-        this.Networkheader = string.slice(0, index + 4); // 鎴彇9091鍙婂叾鍓嶉儴瀛楃
-      } else {
-        const index = string.indexOf("8032");
-        this.Networkheader = string.slice(0, index + 4); // 鎴彇8032鍙婂叾鍓嶉儴瀛楃
-      }
+      // 浠ュ綋鍓嶉〉闈� origin 涓哄噯锛屽吋瀹� 80/8032/9091 鍙婂悗缁鍙h皟鏁�
+      this.Networkheader = window.location.origin;
     },
+    /**
+     * 2026-10-15锛氫笂浼犳椂鏍¢獙闄勪欢鏂囦欢鍚嶏紙涓氬姟瑕佹眰锛氫笉鍚堟牸绔嬪嵆鎻愮ず涓斾笉鍔犲叆鍒楄〃锛夈��
+     * 瑙勫垯涓庡悗绔� AttachmentNameValidator 鍚屽彛寰勶細涓嶅己鍒跺惈涓枃 / 鍘绘帀鎵╁睍鍚嶅悗涓诲共 鈮�20 瀛� /
+     * 涓嶅惈绌烘牸鍙� / \ : * ? " < > | # % 绛夌壒娈婂瓧绗︺��
+     */
+    checkUploadFileName(file) {
+      const raw = file && file.raw ? file.raw.name : file && file.name;
+      const r = checkFileName(raw);
+      if (!r.ok) {
+        this.$modal.msgError(r.msg);
+        return false;
+      }
+      return true;
+    },
+
+    /**
+     * 2026-10-15锛氫繚瀛樺墠鏍¢獙鏁村崟鏄庣粏闄勪欢鏂囦欢鍚嶏紙鍚悓涓�琛屽唴閲嶅悕锛夈��
+     * 鍙e緞锛堜笟鍔$‘璁わ級锛氬彧鏍¢獙"鏈鍙樻洿"鐨勯檮浠垛�斺�旇�佸崟鎹噷宸插瓨鍦ㄧ殑涓嶅悎瑙勯檮浠跺悕涓嶈兘鎶婁繚瀛樺崱姝�
+     * 锛堝惁鍒欒�佸崟鎹敼涓�涓噾棰濋兘瀛樹笉杩涘幓锛夈�傚悗绔寜 id 璇绘棫璁板綍鏀捐鍘嗗彶闄勪欢锛涘墠绔嬁涓嶅埌"鍝簺鏄巻鍙�"
+     * 鐨勬潈濞佷俊鎭紝鍥犳**浠呮柊澧炲崟鎹�**鍋氫繚瀛樺墠鎷︽埅锛岀紪杈戣�佸崟鎹椂鏂板鐨勪笉鍚堣闄勪欢鐢卞悗绔簩娆℃牎楠屾嫤涓嬨��
+     */
+    checkDetailFileNames() {
+      if (this.form && this.form.id) {
+        return true;
+      }
+      const c = checkDetails(this.rbDetails);
+      if (!c.ok) {
+        this.$modal.msgError(c.msg);
+        return false;
+      }
+      return true;
+    },
+
     uploadSccess(response, file, fileList) {
+      if (!this.checkUploadFileName(file)) {
+        return;
+      }
       this.rbDetails;
       const config = {
         headers: { Authorization: "Bearer " + this.ICDtoken }
       };
-      const pdfimg = this.Networkheader + "/prod-api" + response.fileName;
+      const pdfimg = this.Networkheader + process.env.VUE_APP_BASE_API + response.fileName;
       //鑾峰彇绁ㄦ嵁淇℃伅浣嶇疆
       if (this.activeName == 1) {
         if (response.code == 200) {
           this.previewpdf = true;
-
-          fetch(pdfimg, config)
-            .then(response => response.blob())
-            .then(blob => {
-              // 灏嗚幏鍙栫殑鏁版嵁娴佽浆鎹负URL
-              this.pdfimg = URL.createObjectURL(blob);
-              this.pdfimgsrcList.push(URL.createObjectURL(blob));
-              this.fileListto.push({
-                name: file.name,
-                url: URL.createObjectURL(blob)
-              });
-            })
-            .catch(error => {
-              console.error("Error loading image", error);
-              return;
-            });
+          const localUrl = URL.createObjectURL(file.raw);
+          this.pdfimg = localUrl;
+          this.embeddedFile = {
+            name: file.name,
+            url: localUrl,
+            type: /\.pdf$/i.test(file.name) ? "pdf" : "image"
+          };
+          this.pdfimgsrcList.push(localUrl);
+          this.fileListto.push({
+            name: file.name,
+            url: localUrl
+          });
 
           this.$modal.msgSuccess(response.msg);
 
@@ -2807,21 +2892,18 @@
       } else {
         if (response.code == 200) {
           this.previewpdf = true;
-          fetch(pdfimg, config)
-            .then(response => response.blob())
-            .then(blob => {
-              // 灏嗚幏鍙栫殑鏁版嵁娴佽浆鎹负URL
-              this.invoicepdfimg = URL.createObjectURL(blob);
-              this.invoicepdfimgsrcList.push(URL.createObjectURL(blob));
-              this.invoicefileListto.push({
-                name: file.name,
-                url: URL.createObjectURL(blob)
-              });
-            })
-            .catch(error => {
-              console.error("Error loading image", error);
-              return;
-            });
+          const localUrl = URL.createObjectURL(file.raw);
+          this.invoicepdfimg = localUrl;
+          this.invoiceEmbeddedFile = {
+            name: file.name,
+            url: localUrl,
+            type: /\.pdf$/i.test(file.name) ? "pdf" : "image"
+          };
+          this.invoicepdfimgsrcList.push(localUrl);
+          this.invoicefileListto.push({
+            name: file.name,
+            url: localUrl
+          });
 
           this.$modal.msgSuccess(response.msg);
 
@@ -2858,7 +2940,7 @@
       if (this.rbDetails[index].annexfilesList) {
         const fetchPromises = this.rbDetails[index].annexfilesList.map(
           (value, indexson) => {
-            const pdfimg = this.Networkheader + "/prod-api" + value.url;
+            const pdfimg = this.Networkheader + process.env.VUE_APP_BASE_API + value.url;
             return fetch(pdfimg, config)
               .then(response => response.blob())
               .then(blob => {
@@ -2891,7 +2973,7 @@
       if (this.rbDetails[index].invoicefilesList) {
         const fetchPromises = this.rbDetails[index].invoicefilesList.map(
           (value, indexson) => {
-            const pdfimg = this.Networkheader + "/prod-api" + value.url;
+            const pdfimg = this.Networkheader + process.env.VUE_APP_BASE_API + value.url;
             return fetch(pdfimg, config)
               .then(response => response.blob())
               .then(blob => {
@@ -2925,7 +3007,7 @@
         this.pdftitle = "";
       }
 
-      if (this.activeName == "common") {
+      if (this.activeName == 1) {
         this.pdftitle = "鍏�" + this.pdfimgsrcList.length + "椤�";
       } else {
         this.pdftitle = "鍏�" + this.invoicepdfimgsrcList.length + "椤�";
@@ -2934,50 +3016,38 @@
       console.log(this.rbDetails[index].annexfilesList, "annexfilesList");
     },
 
-    // 鐐瑰嚮宸蹭笂浼犳枃浠�
+    // 鐐瑰嚮宸蹭笂浼犳枃浠讹細鍦ㄩ檮浠跺脊绐楀彸渚у唴宓岄瑙�
     downFile(item) {
+      if (this.operationType == "detail") {
+        const source =
+          this.activeName == 1 ? this.fileListto : this.invoicefileListto;
+        const list = (source || []).map(f => ({ name: f.name, url: f.url }));
+        const index = list.findIndex(f => f.url === item.url);
+        this.$previewFile(list, index > -1 ? index : 0);
+        return;
+      }
+      const ext = String(item.name || "").toLowerCase().split(".").pop();
+      const isImage = ["jpg", "jpeg", "png", "gif", "bmp", "webp"].includes(ext);
+      if (ext !== "pdf" && !isImage) {
+        this.hintitle = "褰撳墠鏂囦欢鏆備笉鏀寔棰勮";
+        this.$modal.msgWarning("褰撳墠鏂囦欢鏆備笉鏀寔棰勮");
+        return;
+      }
+      const file = {
+        name: item.name,
+        url: item.url,
+        type: ext === "pdf" ? "pdf" : "image"
+      };
       if (this.activeName == 1) {
+        this.embeddedFile = file;
         this.pdftitle =
           "鍏�" + this.pdfimgsrcList.length + "椤癸紝褰撳墠閫変腑" + item.name;
-        let name = item.name.split(".");
-        if (name[1] == "pdf") {
-          this.$modal.msgWarning("褰撳墠鏂囦欢鏆備笉鏀寔棰勮");
-          this.previewpdf = false;
-          this.hintitle = "褰撳墠鏂囦欢鏆備笉鏀寔棰勮";
-        } else if (name[1] == "jpg" || "png") {
-          console.log(item, "灞曠ず");
-          this.previewpdf = true;
-          if (item.url) {
-            this.pdfimg = item.url;
-          } else {
-            this.pdfimg = "";
-          }
-        } else {
-          this.hintitle = "褰撳墠鏂囦欢鏆備笉鏀寔棰勮";
-          this.$modal.msgWarning("褰撳墠鏂囦欢鏆備笉鏀寔棰勮");
-          this.previewpdf = false;
-        }
       } else {
+        this.invoiceEmbeddedFile = file;
         this.pdftitle =
           "鍏�" + this.invoicepdfimgsrcList.length + "椤癸紝褰撳墠閫変腑" + item.name;
-        let name = item.name.split(".");
-        if (name[1] == "pdf") {
-          this.$modal.msgWarning("褰撳墠鏂囦欢鏆備笉鏀寔棰勮");
-          this.previewpdf = false;
-          this.hintitle = "褰撳墠鏂囦欢鏆備笉鏀寔棰勮";
-        } else if (name[1] == "jpg" || "png") {
-          this.previewpdf = true;
-          if (item.url) {
-            this.invoicepdfimg = item.url;
-          } else {
-            this.invoicepdfimg = "";
-          }
-        } else {
-          this.hintitle = "褰撳墠鏂囦欢鏆備笉鏀寔棰勮";
-          this.$modal.msgWarning("褰撳墠鏂囦欢鏆備笉鏀寔棰勮");
-          this.previewpdf = false;
-        }
       }
+      this.pdfVisible = true;
     },
     getIndexInArray(arr, obj) {
       return arr.indexOf(obj);
@@ -3065,7 +3135,7 @@
     },
     Downloadfile(row) {
       console.log(row);
-      window.location.href = this.Networkheader + "/prod-api" + row.url;
+      window.location.href = this.Networkheader + process.env.VUE_APP_BASE_API + row.url;
     },
     //琛ㄦ牸鍚堣
     getSummaries(param) {
@@ -3119,6 +3189,7 @@
     this.getExternalList();
     this.getFeeUnitList();
     this.listperformance();
+    this.getDeptList();
   },
 
   //鐢熷懡鍛ㄦ湡 - 鎸傝浇瀹屾垚锛堝彲浠ヨ闂瓺OM鍏冪礌锛�

--
Gitblit v1.9.3