| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548 |
- <!--
- * @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>
|