sinake
5 天以前 df97bab9fcb3e6044ad736cd7483498f61f0feb4
src/views/project/fund/applyDetail0/index.vue
@@ -11,7 +11,7 @@
                clearable
                style="width: 100%"
                v-model="form.createTime"
                type="date"
                type="date" format="yyyy-MM-dd"
                value-format="yyyy-MM-dd HH:mm:ss"
                placeholder="申请日期"
              >
@@ -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%">
@@ -1227,6 +1231,8 @@
import Li_area_select from "@/components/Address";
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引入的组件需要注入到对象中才能使用
@@ -1550,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() {
@@ -1844,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;
@@ -2103,11 +2107,7 @@
          this.$store.dispatch("tagsView/delView", this.$route);
          this.$router.go(-1);
        } else {
          if (res.msg) {
            this.$modal.msgError("操作失误");
          } else {
            this.$modal.msgError(res.msg);
          }
          this.$modal.msgError(res.msg || "操作失败");
        }
      });
    },
@@ -2526,6 +2526,11 @@
    },
    // 接受提醒立刻保存
    Savenow() {
      // 2026-10-15:保存前附件文件名规范校验(仅新增单据;老单据的历史附件由后端按"只校验本次变更"放行)
      if (!this.checkDetailFileNames()) {
        return;
      }
      if (!this.randomnumber) {
        this.randomnumber = this.generateRandomString(9);
        this.form.randomnumber = this.randomnumber;
@@ -2876,32 +2881,28 @@
      }
    },
    //计算总金额
    //计算总金额(金额一律走精确运算)
    sumTotalFee(row) {
      let allSum = 0;
      const detailsArr = [];
      if (this.form.applytype != null) {
        for (let i = 0; i < this.rbDetails.length; i++) {
          const detail = this.rbDetails[i];
          let totalFee = 0;
          let taxFee = 0;
          if (this.form.applytype == 1 || this.form.applytype == 2) {
            //计算当前报销内容费用合计
            if (!isNaN(parseFloat(this.rbDetails[i].amount))) {
              totalFee += parseFloat(this.rbDetails[i].amount);
              taxFee += parseFloat(this.rbDetails[i].amount);
            //计算当前报销内容费用合计:税前 - 扣税
            if (!isNaN(parseFloat(detail.amount))) {
              totalFee = moneyAdd(totalFee, detail.amount);
            }
            if (!isNaN(parseFloat(this.rbDetails[i].taxamount))) {
              totalFee -= parseFloat(this.rbDetails[i].taxamount);
              taxFee -= parseFloat(this.rbDetails[i].taxamount);
            if (!isNaN(parseFloat(detail.taxamount))) {
              totalFee = moneySub(totalFee, detail.taxamount);
            }
          } else if (this.form.applytype == 3 || this.form.applytype == 4) {
            //单价*数量=税前金额
            if (
              !isNaN(parseFloat(this.rbDetails[i].price)) &&
              !isNaN(parseFloat(this.rbDetails[i].quantity))
              !isNaN(parseFloat(detail.price)) &&
              !isNaN(parseFloat(detail.quantity))
            ) {
              totalFee +=
                parseFloat(this.rbDetails[i].price) *
                parseFloat(this.rbDetails[i].quantity);
              totalFee = moneyMul(detail.price, detail.quantity);
              this.rbDetails[i].amount = totalFee;
            }
          }
@@ -2911,10 +2912,10 @@
          //   this.rbDetails[i].taxedamount = taxFee.toFixed(2);
          // }
          allSum += totalFee;
          detailsArr.push(totalFee);
        }
      }
      // this.form.amountrequested = allSum.toFixed(2);
      // this.form.amountrequested = moneyRound(moneySum(detailsArr)).toFixed(2);
      // this.$forceUpdate();
    },
@@ -3005,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;
      //获取票据信息位置
@@ -3016,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 {
@@ -3033,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);
@@ -3048,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);
@@ -3086,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);
@@ -3279,13 +3319,13 @@
  //生命周期 - 挂载完成(可以访问DOM元素)
  mounted() {
    window.addEventListener("beforeunload", e => this.beforeunloadHandler(e));
    // 存住同一个引用,否则 removeEventListener 传新箭头函数无法真正移除,会泄漏监听器
    this._beforeUnloadHandler = e => this.beforeunloadHandler(e);
    window.addEventListener("beforeunload", this._beforeUnloadHandler);
    this.getUserList();
    this.getUserProfile();
    let apifunddetailForm = this.funddetailForm;
    let apiform = this.form;
    console.log(apiform);
    console.log(apifunddetailForm);
    // this.getFeeUnitList();
  },
@@ -3294,7 +3334,12 @@
  beforeMount() {}, //生命周期 - 挂载之前
  beforeUpdate() {}, //生命周期 - 更新之前
  updated() {}, //生命周期 - 更新之后
  beforeDestroy() {}, //生命周期 - 销毁之前
  beforeDestroy() {
    if (this._beforeUnloadHandler) {
      window.removeEventListener("beforeunload", this._beforeUnloadHandler);
      this._beforeUnloadHandler = null;
    }
  }, //生命周期 - 销毁之前
  destroyed() {}, //生命周期 - 销毁完成
  activated() {} //如果页面有keep-alive缓存功能,这个函数会触发
};