yxh
6 天以前 e1dd822239ce5b1fd85462c95b264b300153a4cf
src/views/project/fund/applyDetail0/index.vue
@@ -12,7 +12,7 @@
                style="width: 100%"
                v-model="form.createTime"
                type="date" format="yyyy-MM-dd"
                value-format="yyyy-MM-dd"
                value-format="yyyy-MM-dd HH:mm:ss"
                placeholder="申请日期"
              >
              </el-date-picker>
@@ -1034,8 +1034,21 @@
      :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>
      <div class="pdfimg">
        <div class="box-pdf">
          <div>
@@ -1125,16 +1138,7 @@
          </div> -->
        </div>
        <div v-if="this.previewpdf" class="pdfimgmin">
          <!-- <img :src="pdfimg" /> -->
          <el-image
            style="width: 95%; height: 90%"
            :src="pdfimg"
            :preview-src-list="pdfimgsrcList"
          >
          </el-image>
        </div>
        <div v-else class="pdfimgmins">{{ hintitle }}</div>
        <attachment-preview-pane :file="embeddedFile" style="flex: 1; min-width: 0;" />
      </div>
    </el-dialog>
    <el-dialog title="提示" :visible.sync="Savereminder" width="30%">
@@ -1228,6 +1232,7 @@
import OrgSelecter from "@/views/project/components/orgselect";
import { getToken } from "@/utils/auth";
import { moneySum, moneyAdd, moneySub, moneyMul, moneyRound } from "@/utils/money";
import { checkFileName, checkDetails } from "@/utils/fileNameCheck";
export default {
  //import引入的组件需要注入到对象中才能使用
@@ -1551,15 +1556,8 @@
    },
    // 获取请求头
    Getnetworkheader() {
      let string = window.location.href;
      if (string.includes("9091")) {
        const index = string.indexOf("9091");
        this.Networkheader = string.slice(0, index + 4); // 截取9091及其前部字符
        // console.log(this.Networkheader);
      } else {
        const index = string.indexOf("8032");
        this.Networkheader = string.slice(0, index + 4); // 截取8032及其前部字符
      }
      // 以当前页面 origin 为准,兼容 80/8032/9091 及后续端口调整
      this.Networkheader = window.location.origin;
    },
    /** 通过参数获取业务类型 */
    getroute() {
@@ -1845,6 +1843,11 @@
    },
    /** 提交按钮 */
    submitForm: debounce(function() {
      // 2026-10-15:保存前附件文件名规范校验(仅新增单据;老单据的历史附件由后端按"只校验本次变更"放行)
      if (!this.checkDetailFileNames()) {
        return;
      }
      if (!this.randomnumber) {
        this.randomnumber = this.generateRandomString(9);
        this.form.randomnumber = this.randomnumber;
@@ -2523,6 +2526,11 @@
    },
    // 接受提醒立刻保存
    Savenow() {
      // 2026-10-15:保存前附件文件名规范校验(仅新增单据;老单据的历史附件由后端按"只校验本次变更"放行)
      if (!this.checkDetailFileNames()) {
        return;
      }
      if (!this.randomnumber) {
        this.randomnumber = this.generateRandomString(9);
        this.form.randomnumber = this.randomnumber;
@@ -2998,7 +3006,43 @@
    //     console.log(response.msg);
    //   }
    // },
    /**
     * 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:保存前校验整单明细附件文件名(含同一行内重名)。
     * 口径(业务确认):只校验"本次变更"的附件——老单据里已存在的不合规附件名不能把保存卡死
     * (否则老单据改一个金额都存不进去)。后端按 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;
      //获取票据信息位置
@@ -3009,9 +3053,15 @@
        this.fileListto.push({ name: file.name, url: response.fileName });
        // this.fileListto.push({ name: file.name, url: response.url });
        this.pdfimgsrcList.push(
          this.Networkheader + "/prod-api" + response.fileName
          this.Networkheader + process.env.VUE_APP_BASE_API + response.fileName
        );
        this.pdfimg = this.Networkheader + "/prod-api" + response.fileName;
        this.pdfimg = this.Networkheader + process.env.VUE_APP_BASE_API + response.fileName;
        const localUrl = URL.createObjectURL(file.raw);
        this.embeddedFile = {
          name: file.name,
          url: localUrl,
          type: /\.pdf$/i.test(file.name) ? "pdf" : "image"
        };
        this.rbDetails[this.atpresent].annexfilesList = this.fileListto;
      } else {
@@ -3026,11 +3076,11 @@
      if (this.rbDetails[index].annexfilesList) {
        this.previewpdf = true;
        this.fileListto = this.rbDetails[index].annexfilesList;
        this.pdfimg = this.Networkheader + "/prod-api" + this.fileListto[0].url;
        this.pdfimg = this.Networkheader + process.env.VUE_APP_BASE_API + this.fileListto[0].url;
        // this.pdfimg = this.fileListto[0].url;
        this.pdfimgsrcList = [];
        this.fileListto.forEach(item => {
          this.pdfimgsrcList.push(this.Networkheader + "/prod-api" + item.url);
          this.pdfimgsrcList.push(this.Networkheader + process.env.VUE_APP_BASE_API + item.url);
        });
        console.log(this.pdfimgsrcList);
        console.log(this.pdfimg);
@@ -3041,34 +3091,31 @@
      }
    },
    // 点击已上传文件
    // 点击已上传文件:在附件弹窗右侧内嵌预览
    downFile(item) {
      console.log(item);
      this.pdftitle = 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.pdfimg = this.Networkheader + "/prod-api" + item.url;
          // if (!this.pdfimgsrcList.includes(this.pdfimg)) {
          //   this.pdfimgsrcList.push(this.pdfimg);
          //   console.log("加入");
          // }
          console.log(this.pdfimg);
          console.log(this.pdfimgsrcList, "imglist");
        } else {
          this.pdfimg = this.Networkheader + "/prod-api" + item.url;
        }
      } else {
        this.hintitle = "当前文件暂不支持预览";
        this.$modal.msgWarning("当前文件暂不支持预览");
        this.previewpdf = false;
      if (this.operationType == "detail") {
        const list = (this.fileListto || []).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;
      }
      this.embeddedFile = {
        name: item.name,
        url: item.url,
        type: ext === "pdf" ? "pdf" : "image"
      };
      this.pdftitle = item.name;
      this.pdfVisible = true;
    },
    getIndexInArray(arr, obj) {
      return arr.indexOf(obj);
@@ -3079,7 +3126,7 @@
      console.log(row);
      const indexlist = this.getIndexInArray(
        this.pdfimgsrcList,
        this.Networkheader + "/prod-api" + row.url
        this.Networkheader + process.env.VUE_APP_BASE_API + row.url
      );
      console.log(indexlist);
      this.pdfimgsrcList.splice(indexlist, 1);