123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898 |
- <!--
- * @Author: ysh
- * @Date: 2025-05-07 11:01:39
- * @LastEditors: Please set LastEditors
- * @LastEditTime: 2025-05-14 14:18:45
- -->
- <template>
- <div class="main" v-loading="loading">
- <h2 class="text-center">项目直接生产成本预算表</h2>
- <p style="text-align: center">编制人:{{ budgetForm.compilerUser ? budgetForm.compilerUser.nickName : '' }}</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 :column="3" border class="descriptions">
- <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="承担部门">
- {{ getDeptNames(project.undertakingDept) }}
- </el-descriptions-item>
- <el-descriptions-item label="项目备注" :span="3">
- {{ project.remark }}
- </el-descriptions-item>
- <el-descriptions-item label="预算表单备注" :span="5">
- {{ budgetForm.remark }}
- </el-descriptions-item>
- <el-descriptions-item label="项目计划工作量" :span="3">
- <div>
- <table border="1" style="width: 100%;">
- <tr style="background-color:#f8f8f9">
- <td style="width: 250px">工作内容</td>
- <td style="width: 100px">比例尺/等级</td>
- <td style="width: 100px">单位</td>
- <td style="width: 100px">工作量</td>
- <td style="width: 100px">要求完成时间</td>
- <td style="width: 200px">备注</td>
- </tr>
- <tr v-for="(work, index) in workContentList" :key="index">
- <td>{{ work.content }}</td>
- <td>{{ work.scale }} </td>
- <td>{{ work.unit }}</td>
- <td>{{ work.workload }}</td>
- <td>{{ work.deadline }}</td>
- <td class="remark-cell">{{ work.remark }}
- </td>
- </tr>
- </table>
- </div>
- </el-descriptions-item>
- <el-descriptions-item label="内业绩效额" :span="3">
- <table border="1" style="width:100%">
- <tr style="background-color:#f8f8f9" v-if="workList.length != 0">
- <td style="min-width:50px">工作简述</td>
- <td style="min-width:50px">工作内容</td>
- <td style="min-width:50px">比例尺/等级</td>
- <td style="min-width:50px">数量</td>
- <td style="min-width:50px">单价</td>
- <td style="min-width:50px">单位</td>
- <td style="min-width:50px">系数</td>
- <td style="min-width:80px">金额</td>
- <td style="min-width: 150px;">备注</td>
- </tr>
- <tr v-for="work in workList">
- <td>{{ work.content }}</td>
- <td>{{ work.cmcPrice ? work.cmcPrice.workItem : '' }}</td>
- <td>
- {{ work.scaleGrade }}
- </td>
- <td v-if="taskName == '分管审核'">
- <el-input-number style="width:80px;" :controls="false" v-model="work.workload" :min="0" :step="0.01"
- @change="(val) => updateSettle(work, val, 'workload')"></el-input-number>
- </td>
- <td v-else>
- {{ work.workload }}
- </td>
- <td>{{ work.price }}</td>
- <td>{{ work.unit }}</td>
- <td v-if="taskName == '分管审核'">
- <el-input-number style="width:80px;" :controls="false" v-model="work.coefficient" :min="0" :step="0.01"
- @change="(val) => updateSettle(work, val, 'coefficient')"></el-input-number>
- </td>
- <td v-else>
- {{ work.coefficient }}
- </td>
- <td style="text-align:right;">{{ work.settle ? Number(work.settle).toFixed(2) : '0.00' }}</td>
- <td class="remark-cell">{{ work.remark ? work.remark : '' }}</td>
- </tr>
- <tr>
- <td :colspan="7" class="head amount">内业绩效额合计</td>
- <td :colspan="1" class="head amount" :class="{ 'performance-error': isPerformanceExceeded() }"
- style="text-align:right;">
- {{ budgetForm.settleExpense ? budgetForm.settleExpense.toFixed(2) : '0.00' }}
- </td>
- <td></td>
- </tr>
- </table>
- </el-descriptions-item>
- <el-descriptions-item label="内业人员成本" :span="3" v-if="innerStaffList.length > 0">
- <table border="1" style="width:100%">
- <tr style="background-color:#f8f8f9">
- <td>序号</td>
- <td>姓名</td>
- <td>固定成本(天)</td>
- <td style="width:120px">预算天数</td>
- <td>固定成本合计</td>
- <td>绩效成本合计</td>
- <td style="width:120px">金额</td>
- <td style="width:120px">备注</td>
- </tr>
- <tr v-for="staff, index in innerStaffList" :key="'user' + staff.userId">
- <td>{{ index + 1 }}</td>
- <td>{{ staff.user ? staff.user.nickName : '' }}</td>
- <td>{{ staff.dayCost }}</td>
- <td v-if="taskName == '分管审核'">
- <el-input-number style="width:80px;" :controls="false" v-model="staff.days" :min="0" :step="0.01"
- @change="(val) => updateInnerStaffAmount(staff, val, 'days')"></el-input-number>
- </td>
- <td v-else>{{ staff.days }}</td>
- <td style="text-align:right;">{{ staff.staffCost }}</td>
- <td v-if="taskName == '分管审核'">
- <el-input-number style="width:80px;" :controls="false" v-model="staff.performance" :min="0" :step="0.01"
- @change="(val) => updateInnerStaffAmount(staff, val, 'performance')"></el-input-number>
- </td>
- <td v-else>{{ staff.performance }}</td>
- <td style="text-align:right;">{{ staff.amount }}</td>
- <td class="remark-cell">{{ staff.remark }}</td>
- </tr>
- <tr>
- <td colspan="4" class="head amount">内业人员成本合计</td>
- <td class="head amount" style="text-align:right;">{{innerStaffList.reduce((sum, staff) => sum +
- (Number(staff.staffCost) || 0),
- 0).toFixed(2)}}</td>
- <td class="head amount" :class="{ 'performance-error': isPerformanceExceeded() }" style="text-align:right;">
- {{innerStaffList.reduce((sum, staff) => sum +
- (Number(staff.performance) || 0),
- 0).toFixed(2)}}</td>
- <td class="head amount" style="text-align:right;">{{innerStaffList.reduce((sum, staff) => sum +
- (Number(staff.amount) || 0),
- 0).toFixed(2)}}</td>
- </tr>
- </table>
- </el-descriptions-item>
- <el-descriptions-item label="外业人员成本" :span="3" v-if="outerStaffList.length > 0">
- <table border="1" style="width:100%">
- <tr style="background-color:#f8f8f9">
- <td>序号</td>
- <td>姓名</td>
- <td>固定成本(天)</td>
- <td>单价</td>
- <td style="width:120px">预算天数</td>
- <td>预算系数</td>
- <td>固定成本合计</td>
- <td>绩效成本合计</td>
- <td style="width:120px">金额</td>
- <td style="width:120px">备注</td>
- </tr>
- <tr v-for="staff, index in outerStaffList" :key="'user' + staff.userId">
- <td>{{ index + 1 }}</td>
- <td>{{ staff.user ? staff.user.nickName : '' }}</td>
- <td>{{ staff.dayCost }}</td>
- <td>200</td>
- <td v-if="taskName == '分管审核'">
- <el-input-number style="width:80px;" :controls="false" v-model="staff.days" :min="0" :step="0.01"
- @change="(val) => updateOuterStaffAmount(staff, val, 'days')"></el-input-number>
- </td>
- <td v-else>{{ staff.days }}</td>
- <td v-if="taskName == '分管审核'">
- <el-input-number style="width:80px;" :controls="false" v-model="staff.coefficient" :min="0" :step="0.01"
- @change="(val) => updateOuterStaffAmount(staff, val, 'coefficient')"></el-input-number>
- </td>
- <td v-else>{{ staff.coefficient }}</td>
- <td style="text-align:right;">{{ staff.staffCost }}</td>
- <td style="text-align:right;">{{ staff.performance }}</td>
- <td style="text-align:right;">{{ staff.amount }}</td>
- <td class="remark-cell">{{ staff.remark }}</td>
- </tr>
- <tr>
- <td colspan="6" class="head amount">外业人员成本合计</td>
- <td class="head amount" style="text-align:right;">{{outerStaffList.reduce((sum, staff) => sum +
- (Number(staff.staffCost) || 0),
- 0).toFixed(2)}}</td>
- <td class="head amount" style="text-align:right;">{{outerStaffList.reduce((sum, staff) => sum +
- (Number(staff.performance) || 0),
- 0).toFixed(2)}}</td>
- <td class="head amount" style="text-align:right;">{{outerStaffList.reduce((sum, staff) => sum +
- (Number(staff.amount) || 0),
- 0).toFixed(2)}}</td>
- </tr>
- </table>
- </el-descriptions-item>
- <el-descriptions-item label="车辆成本" :span="3" v-if="carList.length > 0">
- <table border="1" style="width:100%;">
- <tr style="background-color:#f8f8f9">
- <td>序号</td>
- <td>车牌号</td>
- <td>折旧成本(天)</td>
- <td>预算天数</td>
- <td>金额</td>
- </tr>
- <tr v-for="car, index in carList" :key="'car' + car.carId">
- <td>{{ index + 1 }}</td>
- <td>{{ car.car ? car.car.licensePlate : '' }}</td>
- <td>{{ car.car ? car.car.dayCost : '' }}</td>
- <td v-if="taskName == '分管审核'">
- <el-input-number style="width:80px;" :controls="false" v-model="car.days" :min="0" :step="0.01"
- @change="(val) => updateCarAmount(car, val)"></el-input-number>
- </td>
- <td v-else>{{ car.days }}</td>
- <td style="text-align:right;">{{ car.amount }}</td>
- </tr>
- <tr>
- <td colspan="4" class="head amount">车辆成本合计</td>
- <td class="head amount" style="text-align:right;">{{carList.reduce((sum, car) => sum + (Number(car.amount)
- || 0), 0).toFixed(2)}}
- </td>
- </tr>
- </table>
- </el-descriptions-item>
- <el-descriptions-item label="设备成本" :span="3" v-if="deviceList.length > 0">
- <table border="1" style="width:100%;">
- <tr style="background-color:#f8f8f9">
- <td>序号</td>
- <td>设备名称</td>
- <td>规格型号</td>
- <td>品牌</td>
- <td>折旧成本(天)</td>
- <td>预算天数</td>
- <td>金额</td>
- </tr>
- <tr v-for="device, index in deviceList" :key="'device' + device.deviceId">
- <td>{{ index + 1 }}</td>
- <td>{{ device.device ? device.device.name : '' }}</td>
- <td>{{ device.device ? device.device.series : '' }}</td>
- <td>{{ device.device ? device.device.brand : '' }}</td>
- <td>{{ device.device ? device.device.dayCost : '' }}</td>
- <td v-if="taskName == '分管审核'">
- <el-input-number style="width:80px;" :controls="false" v-model="device.days" :min="0" :step="0.01"
- @change="(val) => updateDeviceAmount(device, val)"></el-input-number>
- </td>
- <td v-else>{{ device.days }}</td>
- <td style="text-align:right;">{{ device.amount }}</td>
- </tr>
- <tr>
- <td colspan="6" class="head amount">设备成本合计</td>
- <td class="head amount" style="text-align:right;">{{deviceList.reduce((sum, device) => sum +
- (Number(device.amount) || 0),
- 0).toFixed(2)}}</td>
- </tr>
- </table>
- </el-descriptions-item>
- <el-descriptions-item label="现场开支" :span="3">
- <table border="1" style="width:100%;">
- <tr style="background-color:#f8f8f9">
- <td>序号</td>
- <td>开支项</td>
- <td style="min-width:120px">金额</td>
- <td>备注</td>
- </tr>
- <tr v-for="site, index in siteList" :key="'site' + site.expenseId">
- <td>{{ index + 1 }}</td>
- <td>{{ site.name }}</td>
- <td v-if="taskName == '分管审核'">
- <el-input-number style="width:100%;" :controls="false" v-model="site.amount" :min="0" :step="0.01"
- @change="(val) => updateSiteAmount(site, val)"></el-input-number>
- </td>
- <td v-else style="text-align:right;">{{ site.amount }}</td>
- <td class="remark-cell">{{ site.remark }}</td>
- </tr>
- <tr>
- <td colspan="2" class="head amount">现场开支合计</td>
- <td class="head amount" style="text-align:right;">{{siteList.reduce((sum, site) => sum +
- (Number(site.amount) || 0), 0).toFixed(2)}}
- </td>
- <td></td>
- </tr>
- </table>
- </el-descriptions-item>
- <el-descriptions-item label="经营相关" :span="3">
- <div v-if="taskName == '经营审核'" class="alert alert-warning"
- style="padding: 10px; border: 1px solid #f0ad4e; background-color: #fcf8e3; color: #8a6d3b;">
- 请填写以下内容
- </div>
- <table border="1" style="width:100%;" :class="{ 'business-section': taskName == '经营审核' }">
- <tr style="background-color:#f8f8f9">
- <td>序号</td>
- <td>名称</td>
- <td>金额</td>
- <td>备注</td>
- </tr>
- <tr>
- <td>{{ 1 }}</td>
- <td>外协费用</td>
- <td v-if="taskName == '经营审核'">
- <el-input-number style="width:100%;" :controls="false" v-model="budgetForm.outExpense" :min="0"
- :step="0.01" @change="updateTotalJYAmount"></el-input-number>
- </td>
- <td v-else style="text-align:right;">{{ budgetForm.outExpense }}</td>
- <td class="remark-cell">{{ budgetForm.outRemark }}</td>
- </tr>
- <tr>
- <td>{{ 2 }}</td>
- <td>保函费用</td>
- <td v-if="taskName == '经营审核'">
- <el-input-number style="width:100%;" :controls="false" v-model="budgetForm.letterExpense" :min="0"
- :step="0.01" @change="updateTotalJYAmount"></el-input-number>
- </td>
- <td v-else style="text-align:right;">{{ budgetForm.letterExpense }}</td>
- <td class="remark-cell">{{ budgetForm.letterRemark }}</td>
- </tr>
- <tr>
- <td>{{ 3 }}</td>
- <td>中标服务费</td>
- <td v-if="taskName == '经营审核'">
- <el-input-number style="width:100%;" :controls="false" v-model="budgetForm.winExpense" :min="0"
- :step="0.01" @change="updateTotalJYAmount"></el-input-number>
- </td>
- <td v-else style="text-align:right;">{{ budgetForm.winExpense }}</td>
- <td class="remark-cell">{{ budgetForm.winRemark }}</td>
- </tr>
- <tr>
- <td>{{ 4 }}</td>
- <td>税费</td>
- <td v-if="taskName == '经营审核'">
- <el-input-number style="width:100%;" :controls="false" v-model="budgetForm.taxExpense" :min="0"
- :step="0.01" @change="updateTotalJYAmount"></el-input-number>
- </td>
- <td v-else style="text-align:right;">{{ budgetForm.taxExpense }}</td>
- <td class="remark-cell">{{ budgetForm.taxRemark }}</td>
- </tr>
- <tr>
- <td>{{ 5 }}</td>
- <td>管理出差</td>
- <td v-if="taskName == '经营审核'">
- <el-input-number style="width:100%;" :controls="false" v-model="budgetForm.travelExpense" :min="0"
- :step="0.01" @change="updateTotalJYAmount"></el-input-number>
- </td>
- <td v-else style="text-align:right;">{{ budgetForm.travelExpense }}</td>
- <td class="remark-cell">{{ budgetForm.travelRemark }}</td>
- </tr>
- <tr>
- <td colspan="2" class="head amount">经营相关合计</td>
- <td class="head amount" style="text-align:right;">{{ totalJYAmount.toFixed(2) }}
- </td>
- <td></td>
- </tr>
- </table>
- </el-descriptions-item>
- <el-descriptions-item label="预算总额" :span="3">
- <table border="1" style="width:100%;" 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 : Number(budgetForm.staffCost).toFixed(2)
- }}</td>
- </tr>
- <tr>
- <td>车辆成本</td>
- <td style="text-align:right;">{{ isNaN(budgetForm.carCost) ? 0 : Number(budgetForm.carCost).toFixed(2) }}
- </td>
- </tr>
- <tr>
- <td>设备成本</td>
- <td style="text-align:right;">{{ isNaN(budgetForm.deviceCost) ? 0 : Number(budgetForm.deviceCost).toFixed(2)
- }}</td>
- </tr>
- <tr>
- <td>现场开支成本</td>
- <td style="text-align:right;">{{ isNaN(budgetForm.siteSum) ? 0 : Number(budgetForm.siteSum).toFixed(2) }}
- </td>
- </tr>
- <tr>
- <td>经营相关成本</td>
- <td style="text-align:right;">{{ isNaN(totalJYAmount) ? 0 : Number(totalJYAmount).toFixed(2) }}</td>
- </tr>
- <tr class="total-budget">
- <td><b>预算总成本</b></td>
- <td style="text-align:right;"><b>{{ isNaN(budgetForm.totalBudget) ? 0 : budgetForm.totalBudget }}</b></td>
- </tr>
- </table>
- </el-descriptions-item>
- <el-descriptions-item label="合同总价" :span="3" v-if="$store.getters.roles.includes('leader')">
- <table border="1" style="width:100%;">
- <tr style="background-color:#f8f8f9">
- <td>序号</td>
- <td>合同名称</td>
- <td>合同总价</td>
- </tr>
- <tr v-for="contract, index in contractList" :key="contract.contractId">
- <td>{{ index + 1 }}</td>
- <td>{{ contract.contractName }}</td>
- <td>{{ contract.amount }}</td>
- </tr>
- </table>
- </el-descriptions-item>
- <el-descriptions-item label="分管领导审核意见" :span="3">
- <div v-if="taskName == '分管审核' && !budgetForm.managerComment" class="alert alert-warning"
- style="padding: 10px; border: 1px solid #f0ad4e; background-color: #fcf8e3; color: #8a6d3b;">
- 请填写以下内容
- </div>
- <div :class="{ 'business-section': taskName == '分管审核' && !budgetForm.managerComment }">
- <el-input :disabled="taskName != '分管审核'" type="textarea" placeholder="请输入审核意见"
- v-model="budgetForm.managerComment" :autosize="{ minRows: 4 }"></el-input>
- <div class="sign mt10" v-if="budgetForm.manager">
- <div class="mr20">签名:<span class="auditor">{{ getUserName(budgetForm.manager) }}</span>
- </div>
- <div class="ml20"><span>审核时间:{{ budgetForm.managerTime }}</span></div>
- </div>
- </div>
- </el-descriptions-item>
- <el-descriptions-item label="总经理审核意见" :span="3">
- <div v-if="taskName == '总经理审核'" class="alert alert-warning"
- style="padding: 10px; border: 1px solid #f0ad4e; background-color: #fcf8e3; color: #8a6d3b;">
- 请填写以下内容
- </div>
- <div :class="{ 'business-section': taskName == '总经理审核' }">
- <el-input :disabled="taskName != '总经理审核'" type="textarea" placeholder="请输入审核意见"
- v-model="budgetForm.zjlComment" :autosize="{ minRows: 4 }"></el-input>
- <div class="sign mt10" v-if="budgetForm.auditor">
- <div class="mr20">签名:<span class="auditor">{{ getUserName(budgetForm.auditor) }}</span>
- </div>
- <div class="ml20"><span>审核时间:{{ budgetForm.zjlTime }}</span></div>
- </div>
- </div>
- </el-descriptions-item>
- </el-descriptions>
- <div class="text-center mt20 mb20">
- <el-button type="danger" @click="returnOpen = true">退 回</el-button>
- <el-button type="warning" @click="preserve()">保 存</el-button>
- <el-button type="success" @click="confirmSucess()">提交下一个流程</el-button>
- </div>
- <el-dialog title="退回" :visible.sync="returnOpen" width="40%" append-to-body>
- <return-btn :taskForm="taskForm" :comment="commentByRole()" @goBack="$emit('goBack')"
- @cancel="returnOpen = false"></return-btn>
- </el-dialog>
- </div>
- </template>
-
- <script>
- import { listBudget, updateBudget } from "@/api/oa/budget/budget";
- import { listBudgetCar, updateBudgetCar } from "@/api/oa/budget/budgetCar";
- import { listBudgetDevice, updateBudgetDevice } from "@/api/oa/budget/budgetDevice";
- import { listBudgetSettle, updateBudgetSettle } from "@/api/oa/budget/budgetSettle";
- import { listBudgetStaff, updateBudgetStaff } from "@/api/oa/budget/budgetStaff";
- import { listProjectWork } from "@/api/oa/project/projectWork";
- import { listSite, updateSite } from "@/api/oa/budget/budgetSite.js";
- import { getProject } from "@/api/oa/project/project";
- import { getUsersManageLeader, getUserByPost } from "@/api/system/post";
- import { complete, getNextFlowNode } from "@/api/flowable/todo";
- import { listProjectContract } from "@/api/oa/contract/projectContract";
- import { getContract } from "@/api/oa/contract/contract";
- import InnerStaffCost from './components/InnerStaffCost.vue';
- import OuterStaffCost from './components/OuterStaffCost.vue';
- import CarCost from './components/CarCost.vue';
- import DeviceCost from './components/DeviceCost.vue';
- import ReturnComment from '@/views/flowable/form/components/flowBtn/returnComment.vue';
- import ReturnBtn from '@/views/flowable/form/components/flowBtn/returnBtn.vue';
-
- export default {
- components: {
- InnerStaffCost,
- OuterStaffCost,
- CarCost,
- DeviceCost,
- ReturnComment,
- ReturnBtn
- },
- props: {
- taskForm: {
- type: Object,
- require: true
- },
- taskName: {
- type: String,
- }
- },
- data() {
- return {
- loading: true,
- budgetForm: {},
- project: {},
- workContentList: [],
- workList: [],
- innerStaffList: [],
- outerStaffList: [],
- carList: [],
- deviceList: [],
- siteList: [],
- totalJYAmount: 0,
- returnOpen: false,
- contractList: [],
- showAlter: true,
- }
- },
- created() {
- this.initBudgetForm();
- this.getProjectWorkList();
- this.getContractInfo();
- },
- methods: {
- initBudgetForm() {
- this.loading = true;
- listBudget({ pageNum: 1, pageSize: 20, projectId: this.taskForm.formId }).then(async res => {
- this.budgetForm = res.rows[0];
- if (this.budgetForm) {
- this.budgetForm.outExpense = Number(this.budgetForm.outExpense).toFixed(2);
- this.budgetForm.letterExpense = Number(this.budgetForm.letterExpense).toFixed(2);
- this.budgetForm.winExpense = Number(this.budgetForm.winExpense).toFixed(2);
- this.budgetForm.taxExpense = Number(this.budgetForm.taxExpense).toFixed(2);
- this.budgetForm.travelExpense = Number(this.budgetForm.travelExpense).toFixed(2);
- this.budgetForm.totalBudget = Number(this.budgetForm.totalBudget).toFixed(2);
- this.totalJYAmount = Number(this.budgetForm.outExpense || 0) +
- Number(this.budgetForm.letterExpense || 0) +
- Number(this.budgetForm.winExpense || 0) +
- Number(this.budgetForm.taxExpense || 0) +
- Number(this.budgetForm.travelExpense || 0);
- const budgetId = this.budgetForm.budgetId;
- // 获取设备数据
- let deviceRes = await listBudgetDevice({ pageSize: 100, budgetId });
- this.deviceList = deviceRes.rows;
- this.deviceList = this.deviceList.map(device => {
- return {
- ...device,
- amount: Number(device.amount).toFixed(2),
- };
- });
-
- // 获取车辆数据
- let carRes = await listBudgetCar({ pageSize: 100, budgetId });
- this.carList = carRes.rows;
- this.carList = this.carList.map(car => {
- return {
- ...car,
- amount: Number(car.amount).toFixed(2),
- };
- });
-
- // 获取内业人员数据
- let innerStaffRes = await listBudgetStaff({ pageSize: 100, budgetId, type: '内业' });
- this.innerStaffList = innerStaffRes.rows;
- this.innerStaffList = this.innerStaffList.map(staff => {
- return {
- ...staff,
- dayCost: Number(staff.dayCost).toFixed(2),
- performance: Number(staff.performance).toFixed(2),
- amount: Number(staff.amount).toFixed(2),
- staffCost: Number(staff.staffCost).toFixed(2)
- };
- });
-
- // 获取外业人员数据
- let outerStaffRes = await listBudgetStaff({ pageSize: 100, budgetId, type: '外业' });
- this.outerStaffList = outerStaffRes.rows;
- this.outerStaffList = this.outerStaffList.map(staff => {
- return {
- ...staff,
- dayCost: Number(staff.dayCost).toFixed(2),
- performance: Number(staff.performance).toFixed(2),
- amount: Number(staff.amount).toFixed(2),
- staffCost: Number(staff.staffCost).toFixed(2)
- };
- });
-
- // 获取内业绩效额数据
- let settleRes = await listBudgetSettle({ pageSize: 100, budgetId });
- this.workList = settleRes.rows;
- for (let work of this.workList) {
- if (work.groundType == '0') {
- work.price = work.cmcPrice.commonPrice
- work.scaleGrade = work.cmcPrice.scaleGrade
- work.unit = work.cmcPrice.unit
- } else {
- work.price = work.cmcPrice.complexPrice
- work.scaleGrade = work.cmcPrice.scaleGrade
- work.unit = work.cmcPrice.unit
- }
- }
- // 获取现场开支
- let siteRes = await listSite({ pageSize: 100, budgetId });
- this.siteList = siteRes.rows;
- this.budgetForm.siteSum = this.siteList.reduce((sum, site) => sum + (Number(site.amount) || 0), 0);
-
- // 检查内业人员绩效总额是否超过内业绩效总额
- const totalPerformance = this.innerStaffList.reduce((sum, staff) => sum + (Number(staff.performance) || 0), 0);
- if (totalPerformance > Number(this.budgetForm.settleExpense)) {
- this.$message.warning('内业人员绩效总额超过内业绩效总额,请检查');
- }
- }
- this.loading = false;
- }).catch(() => {
- this.loading = false;
- });
- },
- getContractInfo() {
- listProjectContract({ projectId: this.taskForm.formId }).then(res => {
- let contractIds = res.rows;
- this.contractList = [];
- for (let contractId of contractIds) {
- getContract(contractId.contractId).then(response => {
- this.contractList.push(response.data);
- })
- }
- })
- },
- safeNumber(value) {
- const num = Number(value);
- return isNaN(num) ? 0 : num;
- },
- getProjectWorkList() {
- getProject(this.taskForm.formId).then(res => {
- this.project = res.data;
- })
- listProjectWork({ pageSize: 999, projectId: this.taskForm.formId }).then(res => {
- this.workContentList = res.rows;
- })
- },
- async preserve() {
- this.$message.warning('正在保存,请勿关闭页面');
- if (this.taskName == '分管审核') {
- this.budgetForm.manager = this.$store.getters.userId;
- this.budgetForm.managerTime = this.parseTime(new Date(), '{y}-{m}-{d}');
- } else if (this.taskName == '总经理审核') {
- this.budgetForm.auditor = this.$store.getters.userId;
- this.budgetForm.zjlTime = this.parseTime(new Date(), '{y}-{m}-{d}');
- }
- if (this.taskName != '经营审核') {
- await Promise.all([
- ...this.carList.map(car => updateBudgetCar(car)),
- ...this.deviceList.map(device => updateBudgetDevice(device)),
- ...this.innerStaffList.map(staff => updateBudgetStaff(staff)),
- ...this.outerStaffList.map(staff => updateBudgetStaff(staff)),
- ...this.workList.map(work => updateBudgetSettle(work)),
- ...this.siteList.map(site => updateSite(site))
- ]);
- }
- await updateBudget(this.budgetForm)
- this.$message.success('保存成功');
- },
- confirmSucess() {
- this.preserve();
- this.$modal.confirm('是否提交到下一个流程?').then(async () => {
- if (this.taskName == '经营审核') {
- let managerLeaderRes = await getUsersManageLeader({ userId: this.budgetForm.compiler });
- let managerLeader = managerLeaderRes.data;
- let managerList = managerLeader.map(item => item.userId);
- this.$set(this.taskForm.variables, 'approvalList', managerList);
- }
- else if (this.taskName == '分管审核') {
- if (!this.budgetForm.managerComment) {
- this.$message.error('请填写审核意见')
- return
- }
- let zjlRes = await getUserByPost({ postName: '总经理' });
- let zjlUserId = zjlRes.data[0].userId;
- this.$set(this.taskForm.variables, 'approval', zjlUserId);
- }
- else if (this.taskName == '总经理审核') {
- if (!this.budgetForm.zjlComment) {
- this.$message.error('请填写审核意见')
- return
- }
- let dszRes = await getUserByPost({ postName: '董事长' });
- let dszUserId = dszRes.data[0].userId;
- this.$set(this.taskForm.variables, 'approval', dszUserId);
- this.$set(this.taskForm.variables, "skip", true);
- }
- //提交到下一个流程
- getNextFlowNode({ taskId: this.taskForm.taskId }).then(res => {
- complete(this.taskForm).then(response => {
- this.$modal.msgSuccess(response.msg);
- this.$emit("goBack");
- });
- });
- })
- },
- updateTotalJYAmount() {
- this.totalJYAmount = Number(this.budgetForm.outExpense || 0) +
- Number(this.budgetForm.letterExpense || 0) +
- Number(this.budgetForm.winExpense || 0) +
- Number(this.budgetForm.taxExpense || 0) +
- Number(this.budgetForm.travelExpense || 0);
- const innerStaffTotal = this.innerStaffList.reduce((sum, staff) => sum + (Number(staff.amount) || 0), 0);
- const outerStaffTotal = this.outerStaffList.reduce((sum, staff) => sum + (Number(staff.amount) || 0), 0);
- const carTotal = this.carList.reduce((sum, car) => sum + (Number(car.amount) || 0), 0);
- const deviceTotal = this.deviceList.reduce((sum, device) => sum + (Number(device.amount) || 0), 0);
- const siteTotal = this.siteList.reduce((sum, site) => sum + (Number(site.amount) || 0), 0);
- this.budgetForm.totalBudget = (innerStaffTotal +
- outerStaffTotal +
- carTotal +
- deviceTotal +
- siteTotal +
- this.totalJYAmount).toFixed(2);
- },
- commentByRole() {
- if (this.taskName == '分管审核') {
- return this.budgetForm.managerComment
- } else if (this.taskName == '总经理审核') {
- return this.budgetForm.zjlComment
- } else if (this.taskName == '董事长批准') {
- return this.budgetForm.dszComment
- }
- },
- updateSettle(work, value, field) {
- work[field] = value;
- work.settle = (Number(work.workload) * Number(work.price) * Number(work.coefficient)).toFixed(2);
- this.budgetForm.settleExpense = this.workList.reduce((sum, work) => {
- return sum + (Number(work.settle) || 0);
- }, 0);
- this.updateTotalJYAmount();
- },
- updateInnerStaffAmount(staff, value, field) {
- staff[field] = value;
- staff.staffCost = (Number(staff.days) * Number(staff.dayCost)).toFixed(2);
- staff.amount = (Number(staff.staffCost) + Number(staff.performance)).toFixed(2);
- let innerStaffTotal = this.innerStaffList.reduce((sum, staff) => sum + (Number(staff.amount) || 0), 0);
- let outerStaffTotal = this.outerStaffList.reduce((sum, staff) => sum + (Number(staff.amount) || 0), 0);
- let innerStaffPerformance = this.innerStaffList.reduce((sum, staff) => sum + (Number(staff.performance) || 0), 0);
- this.budgetForm.staffCost = (innerStaffTotal + outerStaffTotal).toFixed(2);
- this.updateTotalJYAmount();
- if (innerStaffPerformance > this.budgetForm.settleExpense) {
- this.$message.error('内业人员成本超过内业绩效总额,请修改');
- return;
- }
- },
- updateOuterStaffAmount(staff, value, field) {
- staff[field] = value;
- staff.performance = (200 * Number(staff.days) * Number(staff.coefficient)).toFixed(2);
- staff.amount = (Number(staff.staffCost) + Number(staff.performance)).toFixed(2);
- let innerStaffTotal = this.innerStaffList.reduce((sum, staff) => sum + (Number(staff.amount) || 0), 0);
- let outerStaffTotal = this.outerStaffList.reduce((sum, staff) => sum + (Number(staff.amount) || 0), 0);
- this.budgetForm.staffCost = (innerStaffTotal + outerStaffTotal).toFixed(2);
- this.updateTotalJYAmount();
- },
- updateCarAmount(car, value) {
- car.days = value;
- car.amount = (Number(car.car.dayCost) * Number(car.days)).toFixed(2);
- let carTotal = this.carList.reduce((sum, car) => sum + (Number(car.amount) || 0), 0);
- this.budgetForm.carCost = carTotal.toFixed(2);
- this.updateTotalJYAmount();
- },
- updateDeviceAmount(device, value) {
- device.days = value;
- device.amount = (Number(device.device.dayCost) * Number(device.days)).toFixed(2);
- let deviceTotal = this.deviceList.reduce((sum, device) => sum + (Number(device.amount) || 0), 0);
- this.budgetForm.deviceCost = deviceTotal.toFixed(2);
- this.updateTotalJYAmount();
- },
- updateSiteAmount(site, value) {
- site.amount = value;
- let siteTotal = this.siteList.reduce((sum, site) => sum + (Number(site.amount) || 0), 0);
- this.budgetForm.siteSum = siteTotal.toFixed(2);
- this.updateTotalJYAmount();
- },
- isPerformanceExceeded() {
- const totalPerformance = this.innerStaffList.reduce((sum, staff) => sum + (Number(staff.performance) || 0), 0);
- return totalPerformance > Number(this.budgetForm.settleExpense);
- },
- isReturn(val) {
- this.showAlter = val;
- },
- },
- }
- </script>
-
- <style lang="scss" scoped>
- @import "@/assets/styles/element-reset.scss";
-
- .mylabel {
- font-weight: bold;
- }
-
- .main {
- width: 85%;
- margin: 0 auto;
- text-align: center;
- }
-
- .descriptions {
- width: 100%;
- margin: 0 auto;
- }
-
- .amount {
- font-weight: bold;
- font-family: Arial, Helvetica, sans-serif;
- }
-
- table {
- text-align: center;
- border-collapse: collapse;
- margin: 0 auto;
-
- /*设置背景颜色*/
- /* background-color: #bfa; */
- td {
- padding: 5px;
- }
- }
-
- .remark-cell {
- text-align: left;
- }
-
- .adjust {
- color: #F56C6C;
- width: 120px;
- }
-
- .total-budget {
- font-size: 1.5em;
- font-weight: bold;
- color: #4CAF50;
- text-align: center;
- padding: 10px;
- border: 2px solid #4CAF50;
- border-radius: 5px;
- background-color: #f0f8f5;
- }
-
- ::v-deep .el-descriptions .is-bordered .el-descriptions-item__cell {
- border: 1px solid #838894;
- }
-
- ::v-deep .el-descriptions-item__label.is-bordered-label {
- color: #434141;
- background: #eaeaea;
- }
-
- .business-section {
- border: 2px solid #E6A23C !important;
- box-shadow: 0 0 10px rgba(64, 158, 255, 0.2);
-
- tr {
- background-color: #f0f7ff;
-
- &:hover {
- background-color: #e6f1ff;
- }
- }
-
- .el-input-number {
- .el-input__inner {
- background-color: #fff;
- border: 1px solid #E6A23C;
-
- &:focus {
- border-color: #e2af62;
- box-shadow: 0 0 5px rgba(64, 158, 255, 0.3);
- }
- }
- }
-
- .head.amount {
- background-color: #ecf5ff;
- color: #E6A23C;
- font-weight: bold;
- }
- }
-
-
- .sign {
- display: flex;
- justify-content: flex-end;
- align-items: center;
- padding-right: 80px;
- line-height: 30px;
- /* 如果需要垂直居中 */
- }
-
- .performance-error {
- background-color: #fef0f0 !important;
- color: #f56c6c !important;
- border: 1px solid #fbc4c4 !important;
- }
-
- .performance-error:hover {
- background-color: #fde2e2 !important;
- }
-
- .performance-error .el-input-number {
- .el-input__inner {
- background-color: #fef0f0;
- border-color: #f56c6c;
- color: #f56c6c;
- }
- }
- </style>
|