<!--
 * @Author: ysh
 * @Date: 2024-06-21 18:51:51
 * @LastEditors: wrh
 * @LastEditTime: 2025-12-31 16:41:48
-->
<template>
  <div class="app-container">
    <h2 class="text-center">项目直接生产成本预算表</h2>
    <p style="text-align: center" v-if="taskName == '预算编制'">编制人：{{ $store.getters.name }} | 编制时间：{{ budgetForm.createTime }} </p>
    <p style="text-align: center" v-else>编制人：{{ budgetForm.compilerUser ? budgetForm.compilerUser.nickName : '' }} | 编制时间：{{ budgetForm.createTime }} </p>
    <el-divider></el-divider>
    <div class="mt20 mb20" v-if="showAlter">
      <el-alert title="任务被退回，请修改后重新提交" type="error" :closable="false">
        <return-comment :taskForm="taskForm" @isReturn="isReturn"></return-comment>
      </el-alert>
    </div>
    <el-descriptions title="项目信息" labelClassName="mylabel">
      <el-descriptions-item label="项目编号">{{
        project.projectNumber
      }}</el-descriptions-item>
      <el-descriptions-item label="项目名称">{{
        project.projectName
      }}</el-descriptions-item>
      <el-descriptions-item label="项目负责人">{{
        getUserName(project.projectLeader)
      }}</el-descriptions-item>
      <el-descriptions-item label="项目类型">{{
        project.projectType
      }}</el-descriptions-item>
      <el-descriptions-item label="承担部门">{{
        getDeptNames(project.undertakingDept)
      }}</el-descriptions-item>
      <el-descriptions-item label="甲方单位">{{
        project.partyA ? project.partyA.partyAName : ""
      }}</el-descriptions-item>
    </el-descriptions>
    <!-- <el-divider><b>间接成本</b></el-divider> -->
    <!-- 预结算 -->
    <money-table ref="moneyRef" :projectId="this.taskForm.formId" :budgetId="budgetForm.budgetId"
      @settleExpense="getSettleExpense" @contentList="getContentList"></money-table>
    <!-- 选择人员 -->
    <people-table ref="peopleRef" :budgetId="budgetForm.budgetId" :innerSettleLimit="innerSettleLimit"
      @chooseUser="getChooseUser" @staffCost="getStaffCost"
      @innerSettleExceeded="handleInnerSettleExceeded"></people-table>
    <!-- 选择车辆 -->
    <car-table ref="carRef" :budgetId="budgetForm.budgetId" @chooseCar="getChooseCar" @carCost="getCarCost"></car-table>
    <!-- 选择设备 -->
    <device-table ref="deviceRef" :budgetId="budgetForm.budgetId" @chooseDevice="getChooseDevice"
      @deviceCost="getDeviceCost"></device-table>
    <!-- 分割线 -->
    <!-- <el-divider><b>直接成本</b></el-divider> -->
    <!-- 现场开支 -->
    <site-expenses :budgetId="budgetForm.budgetId" :outer-users="outerUsers" @expensesList="getExpensesList"
      @siteSum="getSiteSum"></site-expenses>
    <!-- 经营相关 -->
    <other-table ref="otherRef" @otherCost="getOtherCost" :budgetForm="budgetForm" :taskName="taskName"></other-table>
    <!-- 预算备注 -->
    <el-form :model="budgetForm" style="padding: 20px 100px 0">
      <el-form-item label="预算表单备注" label-width="100px">
        <el-input type="textarea" v-model="budgetForm.remark" placeholder="请输入预算备注" :rows="4"></el-input>
      </el-form-item>
      <el-form-item label="附件上传" label-width="100px">
        <FileUpload v-if="budgetForm.document == null || budgetForm.document == ''" :disabled="taskName != '预算编制'"
          :limit="1" :filePathName="'预算编制/附件上传'" :fileType="['doc', 'docx', 'xls', 'xlsx', 'pdf', 'rar', 'zip']"
          @input="getDocumentPath"></FileUpload>
        <div v-if="budgetForm.document">
          <el-link type="primary" @click="reviewWord(`${baseUrl}${'/profile/upload' + budgetForm.document}`)">
            {{ getFileName(budgetForm.document) }}
          </el-link>
          <el-link class="ml20" type="warning" :href="`${baseUrl}${'/profile/upload' + budgetForm.document}`"
            :underline="false" target="_blank">
            <span class="el-icon-download">下载文件</span>
          </el-link>
          <el-link class="ml20" type="warning" :underline="false" target="_blank" v-if="taskName == '预算编制'">
            <span class="el-icon-delete" style="color:#F56C6C" @click="budgetForm.document = ''">删除文件</span>
          </el-link>
          <FileUpload v-if="taskName == '预算编制'" :limit="1" :filePathName="'预算编制/附件上传'"
            :fileType="['doc', 'docx', 'xls', 'xlsx', 'pdf', 'rar', 'zip']" @input="getDocumentPath"></FileUpload>
        </div>
      </el-form-item>
      <el-form-item label="统计" label-width="100px">
        <!-- <div style="padding: 0 200px;"> -->
        <table border="1" style="width:600px;" class="budget-summary">
          <tr class="header">
            <td><b>名称</b></td>
            <td><b>金额</b></td>
          </tr>
          <tr>
            <td>人员成本</td>
            <td style="text-align:right;">{{ isNaN(budgetForm.staffCost) ? 0 : budgetForm.staffCost }}</td>
          </tr>
          <tr>
            <td>车辆成本</td>
            <td style="text-align:right;">{{ isNaN(budgetForm.carCost) ? 0 : budgetForm.carCost }}</td>
          </tr>
          <tr>
            <td>设备成本</td>
            <td style="text-align:right;">{{ isNaN(budgetForm.deviceCost) ? 0 : budgetForm.deviceCost }}</td>
          </tr>
          <tr>
            <td>现场开支成本</td>
            <td style="text-align:right;">{{ isNaN(budgetForm.siteSum) ? 0 : budgetForm.siteSum }}</td>
          </tr>
          <tr>
            <td>经营相关成本</td>
            <td style="text-align:right;">{{ Number(this.budgetForm.outExpense) +
              Number(this.budgetForm.letterExpense) +
              Number(this.budgetForm.winExpense) + Number(this.budgetForm.taxExpense)
              + Number(this.budgetForm.travelExpense) }}</td>
          </tr>
          <tr class="total">
            <td><b>预算总成本</b></td>
            <td style="text-align:right;"><b>{{ isNaN(budgetForm.totalBudget) ? 0 : budgetForm.totalBudget }}</b></td>
          </tr>
        </table>
        <!-- </div> -->
      </el-form-item>
    </el-form>
    <!-- <div class="text-center mb10">
      <el-tag class="ml10 mr10" type="primary">
        内业预算绩效总额：{{ isNaN(budgetForm.settleExpense) ? 0 : budgetForm.settleExpense }}
      </el-tag>
    </div> -->

    <div class="mt20 text-center" style="color: #909399; font-size: 12px">
      tips:预览表单，请先保存之后刷新再查看
    </div>
    <el-divider></el-divider>
    <div style="text-align: center">
      <el-button type="warning" @click="preserve()">保存</el-button>
      <el-button type="danger" @click="returnOpen = true" v-if="taskName != '预算编制'">退 回</el-button>
      <el-button type="success" @click="viewForm()">预览表单</el-button>
      <el-button type="primary" @click="submitNextFlow"
        v-if="taskName == '预算编制' || taskName == '部门审核'">提交下一个流程</el-button>
    </div>
    <el-dialog title="表单预览" :visible.sync="viewOpen" width="75%" append-to-body>
      <new-budget-info :taskName="taskName" :taskForm="taskForm"></new-budget-info>
    </el-dialog>
    <el-dialog title="退回" :visible.sync="returnOpen" width="40%" append-to-body>
      <return-btn :taskForm="taskForm" :comment="commentByRole()" @goBack="$emit('goBack')" @saves=""
        @cancel="returnOpen = false"></return-btn>
    </el-dialog>
    <!-- 选择修改有多个预算的项目中的预算 -->
    <el-dialog title="选择要修改的预算" :visible.sync="updateData" :close-on-click-modal="false" :close-on-press-escape="false"
      :show-close="false" width="30%" append-to-body>
      <el-select v-model="selectedBudget" placeholder="请选择" style="width:100%">
        <el-option v-for="item in budgets" :key="item.budgetId" :label="item.project.projectName + '_' + item.createTime"
          :value="item.budgetId">
        </el-option>
      </el-select>
      <div style="text-align: center">
        <el-button type="success" style=" margin-top: 10px;" @click="getBudgeNeesUpdate()">确定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { Snowflake } from "@/utils/snowFlake.js";
import { getProject } from "@/api/oa/project/project";
import { listBudget, addBudget, updateBudget } from "@/api/oa/budget/budget.js";
import { addBudgetCar, delBudgetCar } from "@/api/oa/budget/budgetCar.js";
import { addBudgetStaff, delBudgetStaff } from "@/api/oa/budget/budgetStaff.js";
import { addBudgetDevice, delBudgetDevice } from "@/api/oa/budget/budgetDevice.js";
import { addBudgetSettle, delBudgetSettle } from "@/api/oa/budget/budgetSettle.js";
import { delSite, addSite } from "@/api/oa/budget/budgetSite.js";
import { getUsersDeptLeaderByDept, getUsersManageLeaderByDept, getUsersDeptLeader, getDeptLeadersByDeptId } from "@/api/system/post";
import { complete, getNextFlowNode } from "@/api/flowable/todo";
import budgetInfo from "./budgetInfo.vue";
import ReturnComment from "@/views/flowable/form/components/flowBtn/returnComment.vue";
import ReturnBtn from "@/views/flowable/form/components/flowBtn/returnBtn.vue";
import CarTable from "./carTable.vue";
import MoneyTable from "./moneyTable.vue";
import DeviceTable from "./deviceTable.vue";
import OtherTable from "./otherTable.vue";
import SiteExpenses from "./siteExpenses.vue";
import BudgetAdjust from "./adjust/budgetAdjust.vue";
import NewBudgetInfo from './adjust/newBudgetInfo.vue';
import { toStringHDMS } from 'ol/coordinate';

export default {
  components: {
    ReturnComment,
    ReturnBtn,
    PeopleTable: () => import("./staffTable.vue"),
    CarTable,
    DeviceTable,
    MoneyTable,
    OtherTable,
    budgetInfo,
    SiteExpenses,
    BudgetAdjust,
    NewBudgetInfo
  },
  data() {
    return {
      baseUrl: process.env.VUE_APP_BASE_API,
      budgetForm: {
        budgetId: new Snowflake(1n, 1n, 0n).nextId().toString(),
        projectId: "",
        fixCost: 0,
        directExpense: 0,
        totalBudget: 0,
        procInstId: "",
      },
      flag: false,
      project: {},
      showAlter: true,
      returnOpen: false,
      viewOpen: false,
      innerSettleLimit: 0, // 内业预算绩效合计限制
      outerUsers: [], // 存储外业人员
      updateData: false,
      selectedBudget: "",
      budgets: {},
    };
  },
  props: {
    taskForm: {
      type: Object,
      require: true,
    },
    taskName: {
      type: String,
      require: true,
    },
  },
  watch: {
    budgetForm: {
      handler(newVal) {
        if (newVal) {
          this.getFixCost();
          this.getDirectExpense();
          this.getTotalBudget();
        }
      },
      immediate: true, // 立即生效
      deep: true, //监听对象或数组的时候，要用到深度监听
    },
  },
  created() {
    this.getProjectInfo();
    this.initBudgetForm();
  },
  methods: {
    async initBudgetForm() {
      const params = { pageNum: 1, pageSize: 20, projectId: this.taskForm.formId }
      let res = await listBudget(params)
      if (res.rows[0] && res.rows[0].budgetId) {
        if (this.taskName == '预算编制') {
          // 如项目下已有预算，询问是新建预算还是修改原有预算
          try {
            await this.$confirm('该项目下已有预算，请选择修改已有预算还是创建新预算', '系统提示', {
              distinguishCancelAndClose: true, confirmButtonText: '创建新预算',
              cancelButtonText: '修改已有预算', showClose: false,
              closeOnClickModal: false, closeOnPressEscape: false
            });
            this.flag = false;
            this.budgetForm.projectId = this.taskForm.formId;
            this.budgetForm.budgetId = new Snowflake(1n, 1n, 0n).nextId().toString();
            this.budgetForm.procInstId = this.taskForm.procInsId;
          } catch (action) {
            if (action === 'cancel') {
              this.flag = true;
              this.budgets = res.rows;
              this.updateData = true;
              // this.budgetForm = res.rows[0];
              // this.budgetId = res.rows[0].budgetId;
            }
          }
        }
        else {          
          this.flag = true;
          this.budgetForm = res.rows[0];
          this.budgetId = res.rows[0].budgetId;
        }
      } else {
        this.flag = false;
        this.budgetForm.projectId = this.taskForm.formId;
        this.budgetForm.procInstId = this.taskForm.procInsId;
      }
      // listBudget({ pageNum: 1, pageSize: 20, projectId: this.taskForm.formId }).then(
      //   res => {
      //     if (res.rows[0] && res.rows[0].budgetId) {
      //       this.flag = true;
      //       this.budgetForm = res.rows[0];
      //       this.budgetId = res.rows[0].budgetId;
      //     } else {
      //       this.flag = false;
      //       this.budgetForm.projectId = this.taskForm.formId;
      //     }
      //   }
      // );
    },
    getProjectInfo() {
      getProject(this.taskForm.formId).then(response => {
        this.project = response.data;
      });
    },
    // 保存
    async preserve() {
      let loadingInstance = null;
      try {
        loadingInstance = this.$loading({ fullscreen: true, lock: true, text: '正在保存...', background: 'rgba(0,0,0,0.2)' });
        if (!this.flag) {
          await this.addBudgetForm(this.budgetForm);
          this.flag = true;
        } else {
          await this.updateBudgetForm(this.budgetForm);
        }
      } finally {
        if (loadingInstance) loadingInstance.close();
      }
    },
    viewForm() {
      this.viewOpen = true;
    },
    // 提交下一个流程
    async submitNextFlow() {
      this.$modal.confirm('是否提交到下一个流程？').then(async () => {
        if (this.taskName == "预算编制") {
          this.preserve();
          let deptLeaderRes = await getUsersDeptLeaderByDept({ deptId: this.$store.getters.deptId });
          let deptLeader = deptLeaderRes.data.userId;
          this.$set(this.taskForm.variables, 'approval', deptLeader)
        } else if (this.taskName == '部门审核') {
          this.preserve();
          let jyRes = await getUsersDeptLeaderByDept({ deptId: 105 });
          let jyLeader = jyRes.data.userId;
          this.$set(this.taskForm.variables, 'approval', jyLeader)
        }
        // 提交到下一个流程
        getNextFlowNode({ taskId: this.taskForm.taskId }).then(res => {
          complete(this.taskForm).then(response => {
            this.$modal.msgSuccess(response.msg);
            this.$emit("goBack");
          });
        });
      })
    },
    async addBudgetForm(form) {
      await addBudget(form);
      for (let user of form.chooseUser) {
        user.budgetId = form.budgetId;
        await addBudgetStaff(user);
      }
      for (let car of form.chooseCar) {
        car.budgetId = form.budgetId;
        await addBudgetCar(car);
      }
      for (let device of form.chooseDevice) {
        device.budgetId = form.budgetId;
        await addBudgetDevice(device);
      }
      for (let work of form.contentList) {
        work.budgetId = form.budgetId;
        await addBudgetSettle(work)
      }
      for (let site of form.expensesList) {
        site.budgetId = form.budgetId;
        await addSite(site)
      }
      this.$message.success("预算添加成功");
    },
    async updateBudgetForm(form) {
      await updateBudget(form);
      await delBudgetStaff(form.budgetId);
      for (let user of form.chooseUser) {
        user.budgetId = form.budgetId;
        await addBudgetStaff(user);
      }
      await delBudgetCar(form.budgetId);
      for (let car of form.chooseCar) {
        car.budgetId = form.budgetId;
        await addBudgetCar(car);
      }
      await delBudgetDevice(form.budgetId);
      for (let device of form.chooseDevice) {
        device.budgetId = form.budgetId;
        await addBudgetDevice(device);
      }
      await delSite(form.budgetId);
      for (let site of form.expensesList) {
        site.budgetId = form.budgetId;
        await addSite(site);
      }
      await delBudgetSettle(form.budgetId);
      if (form.contentList && Array.isArray(form.contentList)) {
        for (let work of form.contentList) {
          work.budgetId = form.budgetId;
          await addBudgetSettle(work);
        }
      }
      this.$message.success("预算添加成功");
    },
    getChooseUser(val) {
      this.$set(this.budgetForm, "chooseUser", val);
      // 从选择的人员中筛选出外业人员
      this.outerUsers = val.filter(user => user.type === '外业');
    },
    getStaffCost(val) {
      this.$set(this.budgetForm, "staffCost", val);
    },
    getChooseCar(val) {
      this.$set(this.budgetForm, "chooseCar", val);
    },
    getCarCost(val) {
      this.$set(this.budgetForm, "carCost", val);
    },
    getChooseDevice(val) {
      this.$set(this.budgetForm, "chooseDevice", val);
    },
    getExpensesList(val) {
      this.$set(this.budgetForm, "expensesList", val);
    },
    getSiteSum(val) {
      this.$set(this.budgetForm, "siteSum", val);
    },
    getDeviceCost(val) {
      this.$set(this.budgetForm, "deviceCost", val);
    },
    getContentList(val) {
      this.$set(this.budgetForm, "contentList", val);
    },
    getSettleExpense(val) {
      this.innerSettleLimit = val;
      this.$set(this.budgetForm, "settleExpense", val);
    },
    handleInnerSettleExceeded(data) {
      // this.$message.error(`内业预算绩效总额(${data.current.toFixed(2)})超出限制(${data.limit})`);
    },
    getOtherCost(val) {
      this.$set(this.budgetForm, "outExpense", val.outExpense);
      this.$set(this.budgetForm, "letterExpense", val.letterExpense);
      this.$set(this.budgetForm, "winExpense", val.winExpense);
      this.$set(this.budgetForm, "taxExpense", val.taxExpense);
      this.$set(this.budgetForm, "travelExpense", val.travelExpense);
    },
    getFixCost() {
      const staffCost = this.safeNumber(this.budgetForm.staffCost);
      const carCost = this.safeNumber(this.budgetForm.carCost);
      const deviceCost = this.safeNumber(this.budgetForm.deviceCost);
      const total = staffCost + carCost + deviceCost;
      this.budgetForm.fixCost = total.toFixed(2);
    },
    safeNumber(value) {
      const num = Number(value);
      return isNaN(num) ? 0 : num;
    },
    // 获取直接成本
    getDirectExpense() {
      const settleExpense = this.safeNumber(this.budgetForm.settleExpense);
      const outExpense = this.safeNumber(this.budgetForm.outExpense);
      const letterExpense = this.safeNumber(this.budgetForm.letterExpense);
      const taxExpense = this.safeNumber(this.budgetForm.taxExpense);
      const winExpense = this.safeNumber(this.budgetForm.winExpense);
      const travelExpense = this.safeNumber(this.budgetForm.travelExpense);
      const sum =
        settleExpense +
        outExpense +
        letterExpense +
        taxExpense +
        winExpense +
        travelExpense;
      this.budgetForm.directExpense = sum.toFixed(2);
    },
    getTotalBudget() {
      this.budgetForm.totalBudget = (
        Number(this.budgetForm.staffCost) + Number(this.budgetForm.carCost) + Number(this.budgetForm.deviceCost) + Number(this.budgetForm.siteSum)
        + Number(this.budgetForm.outExpense) + Number(this.budgetForm.letterExpense) + Number(this.budgetForm.winExpense) + Number(this.budgetForm.taxExpense)
        + Number(this.budgetForm.travelExpense)
      ).toFixed(2);
    },
    isReturn(val) {
      this.showAlter = val;
    },
    commentByRole() {
      if (this.taskName == "分管审核") {
        return this.form.managerComment;
      } else if (this.taskName == "总经理审批") {
        return this.form.gmComment;
      }
    },
    getDocumentPath(val) {
      let arr = val.split('/upload')
      this.budgetForm.document = arr[1]
      if (val == "") {
        this.budgetForm.document = ""
      }
    },
    getBudgeNeesUpdate() {
      this.budgetForm = this.budgets.find(item => item.budgetId === this.selectedBudget);
      this.budgetId = this.selectedBudget;
      this.updateData = false;
    }
  },
};
</script>

<style lang="scss" scoped>
@import "@/assets/styles/element-reset.scss";

.mylabel {
  font-weight: bold;
}

table {
  width: 100%;
  /*居中*/
  // margin: 0 auto;
  /*边框*/
  /* border: 1px solid black; */
  text-align: center;
  border-collapse: collapse;
  border: 1px solid #c4c6ca;
}

.budget-summary {
  border-collapse: collapse;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  background: #fff;
}

.budget-summary td {
  padding: 8px 12px;
  border: 1px solid #EBEEF5;
}

.budget-summary .header {
  background-color: #F5F7FA;
  color: #606266;
}

.budget-summary .header td {
  font-weight: 500;
}

.budget-summary .total {
  background-color: #F5F7FA;
  color: #303133;
  font-weight: bold;
}

.budget-summary tr:hover {
  background-color: #F5F7FA;
}
</style>
