yxh
2026-09-30 d21d7dd23f15a0ca395a4c9d1b3bb31330ff56c0
src/views/project/fund/applyDetail/index.vue
@@ -69,6 +69,14 @@
              <el-input :disabled="true" v-model="form.donorname" placeholder="请输入捐献者姓名" />
            </el-form-item>
          </el-col>
          <el-col :span="4">
            <div style="margin-left: 10px;">
              <dict-tag
                :options="dict.type.sys_DonationStatus"
                :value="form.invoicecount"
              />
            </div>
          </el-col>
          <el-col :span="10">
            <el-form-item label="申请说明" prop="remark">
              <el-input v-model="form.remark" placeholder="申请说明" />
@@ -221,8 +229,9 @@
              v-if="businessType == '1' || businessType == '2'">
              <template slot-scope="scope">
                <el-form-item label-width="0">
                  <el-input :disabled="userprofile.nickName != '陈慕华'" v-model.number="scope.row.idcardno"
                    @input="tableParValueChange1(scope.row)" placeholder="身份证号" />
                  <el-input :disabled="userprofile.nickName != '陈慕华' || scope.row.isunit == 1"
                    :placeholder="scope.row.isunit == 1 ? '单位无需填写' : '身份证号'"
                    v-model.number="scope.row.idcardno" @input="tableParValueChange1(scope.row)" />
                </el-form-item>
              </template>
            </el-table-column>
@@ -682,13 +691,19 @@
    </el-dialog>
    <!-- 批量选取 -->
    <el-dialog title="批量生成明细信息" :visible.sync="batchdialogVisible" width="30%">
    <el-dialog title="批量生成明细信息" :visible.sync="batchdialogVisible" width="35%">
      <div style="margin-bottom: 12px">
        <el-input v-model="personKeyword" clearable size="small" prefix-icon="el-icon-search"
          placeholder="输入 姓名 / 单位 / 工号 / 身份证后4位 筛查" style="width: 330px" />
        <span style="margin-left: 10px; color: #909399; font-size: 12px">共 {{ filteredCityOptions.length }} 人</span>
      </div>
      <div style="max-height: 300px; overflow-y: auto">
        <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
        <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全选(当前筛查结果)</el-checkbox>
        <div style="margin: 15px 0;"></div>
        <el-checkbox-group v-model="checkedCities" @change="handleCheckedCitiesChange">
          <el-checkbox border v-for="city in cityOptions" :label="city" :key="city.reportNo">{{ city.reportName
          }}</el-checkbox>
          <el-checkbox border v-for="city in filteredCityOptions" :label="city"
            :key="city.reportNo + '_' + city.reportName">{{ city.reportName
            }}{{ city.unitname ? " · " + city.unitname : "" }}</el-checkbox>
        </el-checkbox-group>
      </div>
@@ -727,7 +742,9 @@
  getdownloadBX,
  addorupdateFund,
  ManualCalculation,
  getdetailsByItemId
  getdetailsByItemId,
  validateExpertFee,
  listbypower
} from "@/api/project/fund";
import {
@@ -777,6 +794,7 @@
import Li_area_select from "@/components/Address";
import OrgSelecter from "@/views/project/components/orgselect";
import { getToken } from "@/utils/auth";
import { moneySum, moneyMul, moneySub, moneyRound } from "@/utils/money";
import CustomImageViewer from "@/components/CustomImageViewer"; // 根据你的路径调整
export default {
@@ -800,11 +818,12 @@
    //"sys_finsubject",
    //"sys_financeitemtype",
    //"sys_expensetype",
    'sys_DonationStatus',
    "sys_recordstatus",
    "sys_professionaltitle"
  ],
  data() {
  data() {
    // 自定义身份证号校验器
    const validateIdCard = (rule, value, callback) => {
      // 1. 如果为空,交给 required 规则去处理,这里直接放行
@@ -871,6 +890,8 @@
      // 网络请求头
      Networkheader: null,
      batchdialogVisible: false,
      //批量录入弹框的筛查关键字
      personKeyword: "",
      itemlist: [],
      cityOptions: [],
      checkAll: false,
@@ -953,7 +974,19 @@
        ],
        unitTaxNo: [{ required: true, message: "请输入税号", trigger: "blur" }],
        idcardno: [
          { required: true, message: '请输入身份证号', trigger: 'blur' },
          {
            // 账户类型选择"单位机构"时不需要身份证号
            validator: (rule, value, callback) => {
              if (this.hasUserType(this.accountselectform.usertype, "org")) {
                return callback();
              }
              if (!value || !String(value).trim()) {
                return callback(new Error("请输入身份证号"));
              }
              return callback();
            },
            trigger: "blur"
          },
          // 添加自定义校验规则
          { validator: validateIdCard, trigger: 'blur' }
        ],
@@ -1020,6 +1053,8 @@
        flowconclusion: null,
        fundid: null
      },
      // 连续审批:待审批单据列表
      pendingList: [],
      // 查询参数
      queryParams: {
@@ -1113,7 +1148,16 @@
  },
  //监听属性 类似于data概念
  computed: {},
  computed: {
    //批量录入弹框:按关键字(姓名/单位/工号/身份证后4位)筛查后的候选人
    filteredCityOptions() {
      const kw = (this.personKeyword || "").trim().toLowerCase();
      if (!kw) {
        return this.cityOptions;
      }
      return this.cityOptions.filter(item => this.personMatchKeyword(item, kw));
    }
  },
  //监控data中的数据变化
  watch: {},
  //方法集合
@@ -1268,9 +1312,12 @@
        this.businessType == "2" ||
        this.businessType == "3"
      ) {
        console.log(this.curCase,'this.curCase');
        this.form.infoid = this.curCase.id;
        this.form.donorname = this.curCase.name;
        this.form.donorno = this.curCase.donorno;
        this.form.invoicecount = this.curCase.recordstate;
      }
      //初始化明细
@@ -1373,6 +1420,14 @@
    handleCheck() {
      this.isopen = 0;
      this.reset();
      // 重置审批信息,避免上一单的审批结果带入下一单
      this.checkObj = {
        flowlevelone: null,
        flowconclusion: null,
        fundid: null
      };
      // 连续审批:加载当前业务类型下的待审批列表
      this.getPendingList();
      getFund(this.curId).then(response => {
        this.form = response.data;
@@ -1515,6 +1570,31 @@
        if (valid) {
          this.formData = this.form;
          // 专家劳务费专用:9 条费用控制规则校验(校验不通过不允许保存)
          if (this.businessType == "1") {
            this.$modal.loading("正在校验专家劳务费用,请稍候!");
            this.checkExpertFeeRules("保存").then((allowed) => {
              this.$modal.closeLoading();
              if (allowed) {
                this.doSubmitForm();
              }
            });
            return;
          }
          this.doSubmitForm();
        }
      });
    }, 500),
    /**
     * 保存申请单的实际落库逻辑。
     *
     * 从 submitForm 中拆出,便于在专家劳务费规则校验通过后再执行;
     * 其他业务类型由 submitForm 直接调用,行为与拆分前一致。
     */
    doSubmitForm() {
          //保存前校验数据
          for (let k = 0; k < this.rbDetails.length; k++) {
            let tempDetail = this.rbDetails[k];
@@ -1584,7 +1664,7 @@
              let tempDetail = this.rbDetails[j];
              if (
                isNaN(parseFloat(tempDetail.amount)) ||
                parseFloat(tempDetail.amount) == 0
                moneyRound(tempDetail.amount) == 0
              ) {
                this.$modal.msgWarning(
                  "服务项目表中,第" +
@@ -1599,7 +1679,7 @@
              let tempDetail = this.rbDetails[j];
              if (
                isNaN(parseFloat(tempDetail.amount)) ||
                parseFloat(tempDetail.amount) == 0
                moneyRound(tempDetail.amount) == 0
              ) {
                this.$modal.msgWarning(
                  "服务项目表中,第" +
@@ -1610,7 +1690,7 @@
              }
              if (
                isNaN(parseFloat(tempDetail.taxamount)) ||
                parseFloat(tempDetail.taxamount) == 0
                moneyRound(tempDetail.taxamount) == 0
              ) {
                tempDetail.taxedamount = parseFloat(tempDetail.amount);
              } else {
@@ -1712,9 +1792,84 @@
          //关闭窗口
          this.loading = false;
          // this.getfundList();
        }
    },
    /**
     * 专家劳务费 9 条费用控制规则校验(提交前拦截)。
     *
     * 适用范围:businessType === '1'(专家劳务费申请单),与后端 applytype === '1' 对应。
     * 其他业务类型(伦理专家费、医学成本、办公费用)不校验,直接放行。
     *
     * 校验口径(同一捐献案例 infoid 下累计)由后端统一实现:
     *   errors   阻断型:提示违反的具体规则,不允许继续保存/审核
     *   warnings 提示型:仅提醒经办人处理(规则 5、6),需二次确认后才继续
     *
     * @param {string} action 当前动作,用于拼接提示文案(如“保存”“提交审核”)
     * @returns {Promise<boolean>} true 允许继续,false 阻止继续
     */
    checkExpertFeeRules(action) {
      if (this.businessType != "1") {
        return Promise.resolve(true);
      }
      // 后端按「案例内已有单据 + 本次提交明细」合并计算,确保尚未落库的明细也参与校验
      const payload = Object.assign({}, this.form, {
        applytype: this.form.applytype || "1",
        serviceFunddetails: this.rbDetails,
      });
    }, 500),
      // 排查用:能直接从控制台看到到底送了什么,以及后端判定了什么
      console.log("[专家费校验] 提交校验", action, {
        businessType: this.businessType,
        applytype: payload.applytype,
        infoid: payload.infoid,
        fundId: payload.id,
        明细: (this.rbDetails || []).map((d) => ({
          itemid: d.itemid,
          amount: d.amount,
          taxedamount: d.taxedamount,
          场景: d.servicesscopename,
        })),
      });
      return validateExpertFee(payload)
        .then((res) => {
          const errors = (res && res.errors) || [];
          const warnings = (res && res.warnings) || [];
          console.log("[专家费校验] 后端返回", { errors, warnings });
          // 1) 阻断型:列出违反的具体规则,不允许继续
          //    用弹窗而非轻提示:错误可能有多条,轻提示会挤成一行且很快消失
          if (errors.length > 0) {
            this.$modal.alertError(
              "专家劳务费用不符合以下规定,无法" +
                action +
                ":\n\n" +
                errors.map((msg, i) => i + 1 + ". " + msg).join("\n\n")
            );
            return false;
          }
          // 2) 提示型:需经办人确认后才能继续(当前规则 5、6 已改为硬拦截,此分支保留备用)
          if (warnings.length > 0) {
            const confirmText =
              "专家劳务费用存在以下问题,请确认是否继续" +
              action +
              "?\n\n" +
              warnings.map((msg, i) => i + 1 + ". " + msg).join("\n\n");
            return this.$modal
              .confirm(confirmText)
              .then(() => true)
              .catch(() => false);
          }
          return true;
        })
        .catch((err) => {
          // 接口异常时按“不阻断”处理,避免校验服务不可用导致完全无法报销;
          // 后端 addOrUpdateNew / checkFund 仍有同样的硬拦截兜底。
          console.error("专家劳务费规则校验接口调用失败", err);
          return true;
        });
    },
    checksubmit() {
      //检查是否收到纸质材料
@@ -1746,8 +1901,79 @@
        return;
      }
      this.Savenow();
      console.log("保存并审批");
      // 专家劳务费专用:9 条费用控制规则校验(仅审核通过时拦截)
      const needExpertFeeCheck = this.checkObj.flowlevelone == 1;
      const expertFeePromise = needExpertFeeCheck
        ? this.checkExpertFeeRules("提交审核")
        : Promise.resolve(true);
      expertFeePromise.then((allowed) => {
        if (!allowed) {
          return;
        }
        this.Savenow();
        console.log("保存并审批");
      });
    },
    // 连续审批:获取当前业务类型下的待审批列表
    getPendingList() {
      return listbypower({
        pageNum: 1,
        pageSize: 1000,
        CHECKFLAG: 1,
        APPLYTYPE: this.businessType
      })
        .then(res => {
          this.pendingList = res.rows || [];
        })
        .catch(() => {
          this.pendingList = [];
        });
    },
    // 连续审批:审批完成后询问是否继续审批下一单
    continueOrExit() {
      // 重新拉取待审批列表(当前单据已审批完成被移出列表)
      this.getPendingList().then(() => {
        const list = this.pendingList || [];
        const next = list[0] || null;
        if (next) {
          this.$confirm("审批已完成,是否继续审批下一张待审批单据?", "提示", {
            confirmButtonText: "继续审批",
            cancelButtonText: "返回列表",
            type: "info"
          })
            .then(() => {
              // 在当前页面直接加载下一张待审批单据
              this.curId = next.id;
              this.handleCheck();
              // 同步更新地址栏,避免刷新后回到上一单
              this.$router
                .replace({
                  path: this.$route.path,
                  query: {
                    id: next.id,
                    businessType: this.businessType,
                    operationType: "check"
                  }
                })
                .catch(() => {});
            })
            .catch(() => {
              this.exitToPage();
            });
        } else {
          this.$modal.msgSuccess("已无待审批单据,返回列表");
          this.exitToPage();
        }
      });
    },
    // 返回列表页
    exitToPage() {
      this.$store.dispatch("tagsView/delView", this.$route);
      this.$router.go(-1);
    },
    // 取消按钮
@@ -1796,6 +2022,19 @@
      });
    },
    /** 人员类型(多值,逗号分隔)是否包含指定类型;org = 单位机构 */
    hasUserType(usertype, code) {
      if (!usertype) {
        return false;
      }
      return (
        String(usertype)
          .split(",")
          .map(t => t.trim())
          .indexOf(code) > -1
      );
    },
    /** 受益人/账户是否为"单位"(人员类型含 org) */
    //获取专家、单位机构的账户列表
    getAccountList() {
      listExternalperson().then(res => {
@@ -1804,7 +2043,7 @@
        for (let j = 0; j < res.rows.length; j++) {
          //单位账号列表
          if (res.rows[j].userstatus == "1") {
            if (res.rows[j].usertype == "org") {
            if (this.hasUserType(res.rows[j].usertype, "org")) {
              this.accountlist.push({
                id: res.rows[j].id,
                userno: res.rows[j].userno,
@@ -1815,6 +2054,7 @@
                bankcardno: res.rows[j].bankcardno,
                unitno: res.rows[j].unitno,
                unitname: res.rows[j].unitname,
                usertype: res.rows[j].usertype,
                userid:
                  res.rows[j].username + "(" + res.rows[j].bankcardno + ")"
              });
@@ -1829,6 +2069,7 @@
                bankcardno: res.rows[j].bankcardno,
                unitno: res.rows[j].unitno,
                unitname: res.rows[j].unitname,
                usertype: res.rows[j].usertype,
                userid:
                  res.rows[j].username + "(" + res.rows[j].idcardno + ")"
              });
@@ -2022,14 +2263,13 @@
    //计算个税:type(A:已知税前金额,计算税后金额;B:已知税后金额,计算税前金额)
    calculateTax(row, type) {
      let targetValue = 0;
      for (let i = 0; i < this.rbDetails.length; i++) {
        if (!this.rbDetails[i].amount) {
          this.rbDetails[i].amount = 0;
        }
        targetValue += parseFloat(this.rbDetails[i].amount); // 假设每个对象中的特定值存储在'specificValue'属性下
      }
      this.form.pretaxcost = targetValue;
      // 合计金额必须精确累加,否则会写入 form.pretaxcost 并落库
      this.form.pretaxcost = moneySum(this.rbDetails, "amount");
    },
    //导入所有项目
@@ -2110,192 +2350,202 @@
      this.Savereminder = false;
      this.Reminderquantity = 0;
      this.totalquantity = 0;
      this.$refs["form"].validate(valid => {
        if (valid) {
          this.formData = this.form;
          //保存前校验数据
          for (let k = 0; k < this.rbDetails.length; k++) {
            let tempDetail = this.rbDetails[k];
            if (tempDetail.itemid == null) {
              this.$modal.msgWarning(
                "服务项目表中,第" +
                (k + 1).toString() +
                "行的服务项目未选择,请先选择服务项目后再提交保存!"
              );
              return;
            }
            if (this.businessType == "1") {
              if (tempDetail.servicesscope == null) {
                this.$modal.msgWarning(
                  "服务项目表中,第" +
                  (k + 1).toString() +
                  "行的费用说明未选择,请选择费用说明后再提交保存!"
                );
                return;
              }
              if (tempDetail.beneficiaryno == null) {
                this.$modal.msgWarning(
                  "服务项目表中,第" +
                  (k + 1).toString() +
                  "行的人员姓名为空,请选择人员后再提交保存!"
                );
                return;
              }
              if (tempDetail.unitname == null) {
                this.$modal.msgWarning(
                  "服务项目表中,第" +
                  (k + 1).toString() +
                  "行的专家单位为空,请选择单位后再提交保存!"
                );
                return;
              }
            }
          }
          //处理明细
          for (let i = 0; i < this.rbDetails.length; i++) {
            let tempDetail = this.rbDetails[i];
            //获取服务项目明细
            let tempitemlist = tempDetail.itemlist;
            let itemIndex = tempitemlist.findIndex(
              item => tempDetail.itemid == item.id
            );
            if (itemIndex > -1) {
              tempDetail.itemname = tempitemlist[itemIndex].itemName;
              tempDetail.itemid = tempitemlist[itemIndex].id;
            }
            //获取applytypename、服务费用大类
            let applytypeIndex = this.rowfeeItemTypes.findIndex(
              item => tempDetail.applytype == item.value
            );
            if (applytypeIndex > -1) {
              tempDetail.applytypename = this.rowfeeItemTypes[
                applytypeIndex
              ].label;
              tempDetail.subjecttype = this.rowfeeItemTypes[
                applytypeIndex
              ].subjecttype;
              tempDetail.subjecttypename = this.rowfeeItemTypes[
                applytypeIndex
              ].subjecttypename;
            }
            this.rbDetails[i] = tempDetail;
          }
          //计算当前行报销内容费用合计,税前金额(amount)、扣税金额(taxamount)、税后金额(taxedamount)
          if (this.businessType == "2") {
            for (let j = 0; j < this.rbDetails.length; j++) {
              let tempDetail = this.rbDetails[j];
              if (
                isNaN(parseFloat(tempDetail.amount)) ||
                parseFloat(tempDetail.amount) == 0
              ) {
                this.$modal.msgWarning(
                  "服务项目表中,第" +
                  (j + 1).toString() +
                  "行的金额未输入,请先输入金额后再提交保存!"
                );
                return;
              }
            }
          } else if (this.businessType == "3" || this.businessType == "4") {
            for (let j = 0; j < this.rbDetails.length; j++) {
              let tempDetail = this.rbDetails[j];
              if (
                isNaN(parseFloat(tempDetail.amount)) ||
                parseFloat(tempDetail.amount) == 0
              ) {
                this.$modal.msgWarning(
                  "服务项目表中,第" +
                  (j + 1).toString() +
                  "行的金额未输入,请先输入金额后再提交保存!"
                );
                return;
              }
              if (
                isNaN(parseFloat(tempDetail.taxamount)) ||
                parseFloat(tempDetail.taxamount) == 0
              ) {
                tempDetail.taxedamount = parseFloat(tempDetail.amount);
              } else {
                tempDetail.taxedamount =
                  parseFloat(tempDetail.amount) +
                  parseFloat(tempDetail.taxamount);
              }
            }
          }
          //保存数据
          this.loading = true;
          this.form.serviceFunddetails = 0;
          this.rbDetails.map(item => {
            this.form.serviceFunddetails += item.amount;
          });
          this.form.serviceFunddetails = this.rbDetails;
          if (this.form.id != null) {
          } else {
            this.form.recordstatus = -1;
          }
          addorupdateFund(this.form).then(response => {
            if (response.code === 200) {
              this.$modal.msgSuccess("申请单保存成功!");
              // 非提醒状态下执行审批解决异步调用延迟问题
              if (!this.Savereminder) {
                let checkFundObj = {
                  // fundid: this.checkObj.fundid,
                  fundid: this.curId,
                  flowconclusion: this.checkObj.flowlevelone,
                  flowcontent: this.checkObj.flowconclusion
                };
                this.$modal.loading("正在提交审核,请稍候!");
                checkfund(checkFundObj).then(res => {
                  if (res.code == 200) {
                    //关闭窗口
                    this.$modal.closeLoading();
                    this.$modal.msgSuccess("审核完成!");
                    this.$store.dispatch("tagsView/delView", this.$route);
                    this.$router.go(-1);
                  } else {
                    this.$modal.closeLoading();
                    if (res.msg) {
                      this.$modal.msgError("操作失误");
                    } else {
                      this.$modal.msgError(res.msg);
                    }
                  }
                });
              }
              this.Getnetworkheader();
              this.getroute();
              this.getAccountList();
              this.getUserList();
              this.getUserProfile();
            } else {
              this.$modal.msgError("申请单保存失败:" + response.msg);
            }
          });
          //关闭窗口
          this.loading = false;
          // this.getfundList();
      // 专家劳务费专用:9 条费用控制规则校验(校验不通过不允许落库)
      this.checkExpertFeeRules("保存").then((allowed) => {
        if (!allowed) {
          return;
        }
        this.$refs["form"].validate(valid => {
          if (valid) {
            this.formData = this.form;
            //保存前校验数据
            for (let k = 0; k < this.rbDetails.length; k++) {
              let tempDetail = this.rbDetails[k];
              if (tempDetail.itemid == null) {
                this.$modal.msgWarning(
                  "服务项目表中,第" +
                  (k + 1).toString() +
                  "行的服务项目未选择,请先选择服务项目后再提交保存!"
                );
                return;
              }
              if (this.businessType == "1") {
                if (tempDetail.servicesscope == null) {
                  this.$modal.msgWarning(
                    "服务项目表中,第" +
                    (k + 1).toString() +
                    "行的费用说明未选择,请选择费用说明后再提交保存!"
                  );
                  return;
                }
                if (tempDetail.beneficiaryno == null) {
                  this.$modal.msgWarning(
                    "服务项目表中,第" +
                    (k + 1).toString() +
                    "行的人员姓名为空,请选择人员后再提交保存!"
                  );
                  return;
                }
                if (tempDetail.unitname == null) {
                  this.$modal.msgWarning(
                    "服务项目表中,第" +
                    (k + 1).toString() +
                    "行的专家单位为空,请选择单位后再提交保存!"
                  );
                  return;
                }
              }
            }
            //处理明细
            for (let i = 0; i < this.rbDetails.length; i++) {
              let tempDetail = this.rbDetails[i];
              //获取服务项目明细
              let tempitemlist = tempDetail.itemlist;
              let itemIndex = tempitemlist.findIndex(
                item => tempDetail.itemid == item.id
              );
              if (itemIndex > -1) {
                tempDetail.itemname = tempitemlist[itemIndex].itemName;
                tempDetail.itemid = tempitemlist[itemIndex].id;
              }
              //获取applytypename、服务费用大类
              let applytypeIndex = this.rowfeeItemTypes.findIndex(
                item => tempDetail.applytype == item.value
              );
              if (applytypeIndex > -1) {
                tempDetail.applytypename = this.rowfeeItemTypes[
                  applytypeIndex
                ].label;
                tempDetail.subjecttype = this.rowfeeItemTypes[
                  applytypeIndex
                ].subjecttype;
                tempDetail.subjecttypename = this.rowfeeItemTypes[
                  applytypeIndex
                ].subjecttypename;
              }
              this.rbDetails[i] = tempDetail;
            }
            //计算当前行报销内容费用合计,税前金额(amount)、扣税金额(taxamount)、税后金额(taxedamount)
            if (this.businessType == "2") {
              for (let j = 0; j < this.rbDetails.length; j++) {
                let tempDetail = this.rbDetails[j];
                if (
                  isNaN(parseFloat(tempDetail.amount)) ||
                  moneyRound(tempDetail.amount) == 0
                ) {
                  this.$modal.msgWarning(
                    "服务项目表中,第" +
                    (j + 1).toString() +
                    "行的金额未输入,请先输入金额后再提交保存!"
                  );
                  return;
                }
              }
            } else if (this.businessType == "3" || this.businessType == "4") {
              for (let j = 0; j < this.rbDetails.length; j++) {
                let tempDetail = this.rbDetails[j];
                if (
                  isNaN(parseFloat(tempDetail.amount)) ||
                  moneyRound(tempDetail.amount) == 0
                ) {
                  this.$modal.msgWarning(
                    "服务项目表中,第" +
                    (j + 1).toString() +
                    "行的金额未输入,请先输入金额后再提交保存!"
                  );
                  return;
                }
                if (
                  isNaN(parseFloat(tempDetail.taxamount)) ||
                  moneyRound(tempDetail.taxamount) == 0
                ) {
                  tempDetail.taxedamount = parseFloat(tempDetail.amount);
                } else {
                  tempDetail.taxedamount =
                    parseFloat(tempDetail.amount) +
                    parseFloat(tempDetail.taxamount);
                }
              }
            }
            //保存数据
            this.loading = true;
            this.form.serviceFunddetails = 0;
            this.rbDetails.map(item => {
              this.form.serviceFunddetails += item.amount;
            });
            this.form.serviceFunddetails = this.rbDetails;
            if (this.form.id != null) {
            } else {
              this.form.recordstatus = -1;
            }
            addorupdateFund(this.form).then(response => {
              if (response.code === 200) {
                this.$modal.msgSuccess("申请单保存成功!");
                // 非提醒状态下执行审批解决异步调用延迟问题
                if (!this.Savereminder) {
                  let checkFundObj = {
                    // fundid: this.checkObj.fundid,
                    fundid: this.curId,
                    flowconclusion: this.checkObj.flowlevelone,
                    flowcontent: this.checkObj.flowconclusion
                  };
                  this.$modal.loading("正在提交审核,请稍候!");
                  checkfund(checkFundObj).then(res => {
                    if (res.code == 200) {
                      //关闭窗口
                      this.$modal.closeLoading();
                      this.$modal.msgSuccess("审核完成!");
                      // 连续审批:询问是否继续审批下一单
                      this.continueOrExit();
                    } else {
                      this.$modal.closeLoading();
                      if (res.msg) {
                        this.$modal.msgError("操作失误");
                      } else {
                        this.$modal.msgError(res.msg);
                      }
                    }
                  });
                }
                this.Getnetworkheader();
                this.getroute();
                this.getAccountList();
                this.getUserList();
                this.getUserProfile();
              } else {
                this.$modal.msgError("申请单保存失败:" + response.msg);
              }
            });
            //关闭窗口
            this.loading = false;
            // this.getfundList();
          }
        });
      });
    },
    handleCheckAllChange(val) {
      this.checkedCities = val ? this.cityOptions : [];
      this.checkedCities = val ? this.filteredCityOptions.slice() : [];
      this.isIndeterminate = false;
    },
    handleCheckedCitiesChange(value) {
      let checkedCount = value.length;
      this.checkAll = checkedCount === this.cityOptions.length;
      this.checkAll =
        this.filteredCityOptions.length > 0 &&
        checkedCount === this.filteredCityOptions.length;
      this.isIndeterminate =
        checkedCount > 0 && checkedCount < this.cityOptions.length;
        checkedCount > 0 && checkedCount < this.filteredCityOptions.length;
    },
    // 手动计算
    Manualcalculationfn() {
@@ -2331,19 +2581,57 @@
    // 批量录入点击
    Batchentry() {
      // ethical
      this.personKeyword = "";
      this.checkedCities = [];
      this.checkAll = false;
      this.isIndeterminate = false;
      listReportname("ethical").then(res => {
        this.cityOptions = res.data;
      });
      this.batchdialogVisible = true;
    },
    /** 批量录入弹框:姓名/单位/工号/身份证后4位 命中判断 */
    personMatchKeyword(item, kw) {
      const idcard = String(item.idcrad || "");
      return (
        String(item.reportName || "")
          .toLowerCase()
          .indexOf(kw) > -1 ||
        String(item.unitname || "")
          .toLowerCase()
          .indexOf(kw) > -1 ||
        String(item.reportNo || "")
          .toLowerCase()
          .indexOf(kw) > -1 ||
        (idcard.length >= 4 && idcard.slice(-4).indexOf(kw) > -1)
      );
    },
    // 确认录入
    BatchentryFn() {
      // 明细中已有的人员姓名,用于重复提醒
      const existed = {};
      this.rbDetails.forEach(row => {
        if (row.beneficiaryname) {
          existed[String(row.beneficiaryname).trim()] = true;
        }
      });
      const duplicated = [];
      this.checkedCities.forEach(item => {
        const nameKey = String(item.reportName || "").trim();
        if (nameKey && existed[nameKey]) {
          duplicated.push(item.reportName);
          return;
        }
        if (nameKey) {
          existed[nameKey] = true;
        }
        let rowData = {
          orderno: null,
          fundid: null,
          beneficiaryname: item.reportName,
          beneficiaryno: item.reportNo,
          isunit: 0,
          unitname: item.unitname,
          unitno: null,
          uintuserno: null,
@@ -2388,11 +2676,17 @@
        this.rbDetails.push(rowData);
      });
      for (let i = 0; i < this.checkedCities.length + 1; i++) {
      for (let i = 0; i < this.rbDetails.length; i++) {
        this.rbDetails[i].orderno = i + 1;
      }
      this.calculateTax();
      this.batchdialogVisible = false;
      this.checkedCities = [];
      if (duplicated.length) {
        this.$modal.msgWarning(
          "以下人员在明细中已存在,已跳过重复添加:" + duplicated.join("、")
        );
      }
    },
    //新增一行
    addRow(rowIndex) {
@@ -2402,6 +2696,7 @@
        fundid: null,
        beneficiaryname: null,
        beneficiaryno: null,
        isunit: 0,
        unitname: null,
        itemdescribe: null,
        unitno: null,
@@ -2498,33 +2793,32 @@
        });
      //全部删除后添加一条新行
    },
    //计算总金额
    //计算总金额(金额一律走精确运算,禁止 parseFloat 累加)
    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 = moneySub(totalFee, -parseFloat(detail.amount));
              taxFee = moneySub(taxFee, -parseFloat(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);
              taxFee = moneySub(taxFee, 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);
              this.rbDetails[i].amount = totalFee;
              totalFee = moneyMul(detail.price, detail.quantity);
              detail.amount = totalFee;
            }
          }
@@ -2533,9 +2827,10 @@
          //   this.rbDetails[i].taxedamount = taxFee.toFixed(2);
          // }
          allSum += totalFee;
          detailsArr.push(totalFee);
        }
      }
      const allSum = moneyRound(moneySum(detailsArr));
      // this.form.amountrequested = allSum.toFixed(2);
      // this.$forceUpdate();
    },
@@ -3038,11 +3333,13 @@
                  this.rbDetails[tempIndex].phone = res.telephone;
                  if (res.usertype == "org") {
                    this.$set(this.rbDetails[tempIndex], "isunit", 1);
                    this.rbDetails[tempIndex].idcardno = "";
                    this.rbDetails[tempIndex].title = "";
                    this.rbDetails[tempIndex].unitno = "";
                    this.rbDetails[tempIndex].unitname = "";
                  } else {
                    this.$set(this.rbDetails[tempIndex], "isunit", 0);
                    this.rbDetails[tempIndex].idcardno = res.idcardno;
                    this.rbDetails[tempIndex].title = res.title;
                    this.rbDetails[tempIndex].unitno = parseInt(res.unitno);
@@ -3148,12 +3445,14 @@
                      this.rbDetails[tempIndex].bankcardno = res.bankcardno;
                      this.rbDetails[tempIndex].phone = res.telephone;
                      if (res.usertype == "org") {
                      if (this.hasUserType(res.usertype, "org")) {
                        this.$set(this.rbDetails[tempIndex], "isunit", 1);
                        this.rbDetails[tempIndex].idcardno = "";
                        this.rbDetails[tempIndex].title = "";
                        this.rbDetails[tempIndex].unitno = "";
                        this.rbDetails[tempIndex].unitname = "";
                      } else {
                        this.$set(this.rbDetails[tempIndex], "isunit", 0);
                        this.rbDetails[tempIndex].idcardno = res.idcardno;
                        this.rbDetails[tempIndex].title = res.title;
                        this.rbDetails[tempIndex].unitno = parseInt(res.unitno);
@@ -3238,7 +3537,9 @@
  //生命周期 - 挂载完成(可以访问DOM元素)
  mounted() {
    window.addEventListener("beforeunload", e => this.beforeunloadHandler(e));
    // 存住同一个引用,否则 removeEventListener 传新箭头函数无法真正移除,会泄漏监听器
    this._beforeUnloadHandler = e => this.beforeunloadHandler(e);
    window.addEventListener("beforeunload", this._beforeUnloadHandler);
    this.getUserList();
    let apiaccountselectform = this.accountselectform;
    let apiform = this.form;
@@ -3254,7 +3555,10 @@
  updated() { }, //生命周期 - 更新之后
  beforeDestroy() { }, //生命周期 - 销毁之前
  destroyed() {
    window.removeEventListener("beforeunload", e => this.beforeunloadFn(e));
    if (this._beforeUnloadHandler) {
      window.removeEventListener("beforeunload", this._beforeUnloadHandler);
      this._beforeUnloadHandler = null;
    }
  }, //生命周期 - 销毁完成
  activated() { } //如果页面有keep-alive缓存功能,这个函数会触发
};