综合办公系统
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

budgetInfo.vue 27KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. <!--
  2. * @Author: ysh
  3. * @Date: 2024-04-03 16:28:09
  4. * @LastEditors: Please set LastEditors
  5. * @LastEditTime: 2024-07-16 16:18:22
  6. -->
  7. <template>
  8. <div class="main">
  9. <div>
  10. <h2 class="text-center">项目直接生产成本预算表</h2>
  11. <p style="text-align: center;">编制人:{{ budgetForm.compilerUser ? budgetForm.compilerUser.nickName : '' }}</p>
  12. <el-descriptions :column="3" border class="descriptions">
  13. <el-descriptions-item label="项目编号">
  14. {{ projectForm.projectNumber }}
  15. </el-descriptions-item>
  16. <el-descriptions-item label="项目名称">
  17. {{ projectForm.projectName }}
  18. </el-descriptions-item>
  19. <el-descriptions-item label="项目负责人">
  20. {{ getUserName(projectForm.projectLeader) }}
  21. </el-descriptions-item>
  22. <el-descriptions-item label="承担部门">
  23. {{ getDeptNames(projectForm.undertakingDept) }}
  24. </el-descriptions-item>
  25. <el-descriptions-item label="项目备注" :span="3">
  26. {{ projectForm.remark }}
  27. </el-descriptions-item>
  28. <el-descriptions-item label="项目概况" :span="3">
  29. <div>
  30. <table border="1" style="width: 100%;">
  31. <tr style="background-color:#f8f8f9">
  32. <td style="width: 250px">工作内容</td>
  33. <td style="width: 100px">等级或比例尺</td>
  34. <td style="width: 100px">单位</td>
  35. <td style="width: 100px">工作量</td>
  36. <td style="width: 100px">要求完成时间</td>
  37. <td style="width: 200px">备注</td>
  38. </tr>
  39. <tr v-for="(work, index) in workContentList" :key="index">
  40. <td>
  41. {{ work.content }}
  42. </td>
  43. <td>
  44. {{ work.scale }}
  45. </td>
  46. <td>
  47. {{ work.unit }}
  48. </td>
  49. <td>
  50. {{ work.workload }}
  51. </td>
  52. <td>
  53. {{ work.deadline }}
  54. </td>
  55. <td>
  56. {{ work.remark }}
  57. </td>
  58. </tr>
  59. </table>
  60. </div>
  61. </el-descriptions-item>
  62. <el-descriptions-item label="直接成本" :span="3">
  63. <table border="1" style="width:100%">
  64. <tr style="background-color:#f8f8f9" v-if="workList.length != 0">
  65. <td>工作简述</td>
  66. <td>工作内容</td>
  67. <td>数量</td>
  68. <td>单价</td>
  69. <td>单位</td>
  70. <td>系数</td>
  71. <td>金额</td>
  72. <td style="min-width: 150px;">备注</td>
  73. </tr>
  74. <tr v-for="work in workList">
  75. <td>{{ work.content }}</td>
  76. <td>{{ work.cmcPrice ? work.cmcPrice.workItem : '' }}</td>
  77. <td v-if="taskName == '分管审核' || taskName == '总经理审核'">
  78. <el-input-number :controls="false" style="width:100px;" v-model="work.workload"
  79. @change="computeWorkSettle(work)"></el-input-number>
  80. </td>
  81. <td v-else>
  82. {{ work.workload }}
  83. </td>
  84. <td>{{ work.price }}</td>
  85. <td>{{ work.unit }}</td>
  86. <td v-if="taskName == '分管审核' || taskName == '总经理审核'">
  87. <el-input-number :controls="false" style="width:100px;" v-model="work.coefficient"
  88. @change="computeWorkSettle(work)"></el-input-number>
  89. <el-button type="text" @click="getCoefficientRemark(work)">系数备注</el-button>
  90. </td>
  91. <td v-else>
  92. {{ work.coefficient }}
  93. </td>
  94. <td>{{ work.settle }}</td>
  95. <td>{{ work.remark ? work.remark : '' }}</td>
  96. </tr>
  97. <tr>
  98. <td :colspan="6" class="head">直接成本合计</td>
  99. <td :colspan="1" class="head">{{ budgetForm.settleExpense }}</td>
  100. <td></td>
  101. </tr>
  102. </table>
  103. </el-descriptions-item>
  104. <el-descriptions-item label="间接成本" :span="3">
  105. <table border="1" style="width:100%">
  106. <tr v-if="userLen != 1" style="background-color:#f8f8f9">
  107. <td :rowspan="userLen">人员</td>
  108. <td>姓名</td>
  109. <td>基本工资</td>
  110. <td>岗位工资</td>
  111. <td>人员成本(天)</td>
  112. <td>预算天数</td>
  113. <td>金额</td>
  114. <td>备注</td>
  115. </tr>
  116. <tr v-for="user in chooseUser" :key="'user' + user.userId">
  117. <td>{{ user.user ? user.user.nickName : '' }}</td>
  118. <td>1780</td>
  119. <td>{{ user.salary.salary }}</td>
  120. <td>{{ parseFloat((user.salary.salary + 1780) / 21.75).toFixed(2) }}</td>
  121. <td v-if="taskName == '分管审核' || taskName == '总经理审核'">
  122. <el-input-number :controls="false" style="width:100px;" v-model="user.days"
  123. @blur="computedFixCostSettle(user, 'user')"></el-input-number>
  124. </td>
  125. <td v-else>
  126. {{ user.days }}
  127. </td>
  128. <td>{{ user.staffCost }}</td>
  129. <td></td>
  130. </tr>
  131. <tr v-if="carLen != 1" style="background-color:#f8f8f9">
  132. <td :rowspan="carLen">车辆</td>
  133. <td>车牌号</td>
  134. <td>油耗</td>
  135. <td>总里程</td>
  136. <td>折旧成本(天)</td>
  137. <td>预算天数</td>
  138. <td>金额</td>
  139. </tr>
  140. <tr v-for="car in chooseCar" :key="'car' + car.carId">
  141. <td>{{ car.car ? car.car.licensePlate : '' }}</td>
  142. <td>{{ car.mileage }}</td>
  143. <td v-if="taskName == '分管审核' || taskName == '总经理审核'">
  144. <el-input-number :controls="false" style="width:100px;" v-model="car.distance"
  145. @blur="computedFixCostSettle(car, 'car')"></el-input-number>
  146. </td>
  147. <td v-else>
  148. {{ car.distance }}
  149. </td>
  150. <td>{{ car.car ? car.car.dayCost : '' }}</td>
  151. <td v-if="taskName == '分管审核' || taskName == '总经理审核'">
  152. <el-input-number :controls="false" style="width:100px;" v-model="car.days"
  153. @blur="computedFixCostSettle(car, 'car')"></el-input-number>
  154. </td>
  155. <td v-else>
  156. {{ car.days }}
  157. </td>
  158. <td>{{ car.expense }}</td>
  159. <td></td>
  160. </tr>
  161. <tr v-if="deviceLen != 1" style="background-color:#f8f8f9">
  162. <td :rowspan="deviceLen">设备</td>
  163. <td>设备名称</td>
  164. <td>规格型号</td>
  165. <td>品牌</td>
  166. <td>折旧成本(天)</td>
  167. <td>预算天数</td>
  168. <td>金额</td>
  169. </tr>
  170. <tr v-for="device in chooseDevice" :key="'device' + device.deviceId">
  171. <td>{{ device.device ? device.device.name : '' }}</td>
  172. <td>{{ device.device ? device.device.series : '' }}</td>
  173. <td>{{ device.device ? device.device.brand : '' }}</td>
  174. <td>{{ device.device ? device.device.dayCost : '' }}</td>
  175. <td v-if="taskName == '分管审核' || taskName == '总经理审核'">
  176. <el-input-number :controls="false" style="width:100px;" v-model="device.days"
  177. @blur="computedFixCostSettle(device, 'device')"></el-input-number>
  178. </td>
  179. <td v-else>
  180. {{ device.days }}
  181. </td>
  182. <td>{{ device.depreciation }}</td>
  183. <td></td>
  184. </tr>
  185. <tr>
  186. <td :colspan="6" class="head">间接成本合计</td>
  187. <td :colspan="1" class="head">{{ budgetForm.fixCost }}</td>
  188. <td></td>
  189. </tr>
  190. </table>
  191. </el-descriptions-item>
  192. <el-descriptions-item label="外协费用" :span="2">
  193. <div v-if="taskName == '分管审核' || taskName == '总经理审核'">
  194. <el-input-number :controls="false" style="width:100%;" v-model="budgetForm.outExpense"
  195. @blur="computedDirectExpense()"></el-input-number>
  196. </div>
  197. <div v-else class="text-center">
  198. {{ budgetForm.outExpense }}
  199. </div>
  200. </el-descriptions-item>
  201. <el-descriptions-item label="备注" :span="1">
  202. {{ budgetForm.outRemark }}
  203. </el-descriptions-item>
  204. <el-descriptions-item label="车船租赁" :span="2">
  205. <div v-if="taskName == '分管审核' || taskName == '总经理审核'">
  206. <el-input-number :controls="false" style="width:100%;" v-model="budgetForm.rentExpense"
  207. @blur="computedDirectExpense()"></el-input-number>
  208. </div>
  209. <div v-else class="text-center">
  210. {{ budgetForm.rentExpense }}
  211. </div>
  212. </el-descriptions-item>
  213. <el-descriptions-item label="备注" :span="1">
  214. {{ budgetForm.rentRemark }}
  215. </el-descriptions-item>
  216. <el-descriptions-item label="其他费用" :span="2">
  217. <div v-if="taskName == '分管审核' || taskName == '总经理审核'">
  218. <el-input-number :controls="false" style="width:100%;" v-model="budgetForm.otherExpense"
  219. @blur="computedDirectExpense()"></el-input-number>
  220. </div>
  221. <div v-else class="text-center">
  222. {{ budgetForm.otherExpense }}
  223. </div>
  224. </el-descriptions-item>
  225. <el-descriptions-item label="备注" :span="1">
  226. {{ budgetForm.otherRemark }}
  227. </el-descriptions-item>
  228. <el-descriptions-item label="税费成本" :span="2">
  229. <div v-if="taskName == '分管审核' || taskName == '总经理审核'">
  230. <el-input-number :controls="false" style="width:100%;" v-model="budgetForm.taxExpense"
  231. @blur="computedDirectExpense()"></el-input-number>
  232. </div>
  233. <div v-else class="text-center">
  234. {{ budgetForm.taxExpense }}
  235. </div>
  236. </el-descriptions-item>
  237. <el-descriptions-item label="备注" :span="1">
  238. {{ budgetForm.taxRemark }}
  239. </el-descriptions-item>
  240. <el-descriptions-item label="经营管理费用" :span="2">
  241. <div v-if="taskName == '分管审核' || taskName == '总经理审核'">
  242. <el-input-number :controls="false" style="width:100%;" v-model="budgetForm.businessExpense"
  243. @blur="computedDirectExpense()"></el-input-number>
  244. </div>
  245. <div v-else class="text-center">
  246. {{ budgetForm.businessExpense }}
  247. </div>
  248. </el-descriptions-item>
  249. <el-descriptions-item label="备注" :span="1">
  250. {{ budgetForm.businessRemark }}
  251. </el-descriptions-item>
  252. <el-descriptions-item label="预算成本合计" :span="3">
  253. <div class="text-center" style="font-weight:bold;font-size:18px;color:orange">
  254. {{ budgetForm.totalBudget }}
  255. </div>
  256. <div class="text-center">
  257. (简写:{{ (budgetForm.totalBudget / 10000).toFixed(4) + '万' }})
  258. </div>
  259. </el-descriptions-item>
  260. <el-descriptions-item label="合同总价约" :span="3"
  261. v-if="taskName == '分管审核' || taskName == '总经理审核' || taskName == '预算批准'">
  262. <div class="text-center" style="font-weight:bold;font-size:18px;color:#409EFF">
  263. {{ contract.contractId ? contract.amount : '' }}
  264. </div>
  265. <div class="text-center">
  266. (简写:{{ contract.contractId ? (contract.amount / 10000).toFixed(4) + '万' : '' }})
  267. </div>
  268. </el-descriptions-item>
  269. <el-descriptions-item label="利润" :span="3"
  270. v-if="taskName == '分管审核' || taskName == '总经理审核' || taskName == '预算批准'">
  271. <div class="text-center" style="font-weight:bold;font-size:18px;color:#67C23A">
  272. {{ profit.toFixed(2) }}
  273. </div>
  274. <div class="text-center">
  275. (简写:{{ (profit / 10000).toFixed(4) + '万' }})
  276. </div>
  277. </el-descriptions-item>
  278. <el-descriptions-item label="分管审核意见" :span="3">
  279. <div>
  280. <el-input :disabled="taskName != '分管审核'" type="textarea" placeholder="请输入审核意见"
  281. v-model="budgetForm.managerComment" :autosize="{ minRows: 4 }"></el-input>
  282. <div class="sign mt10">
  283. <div class="mr20">签名:<span class="auditor">{{ getUserName(budgetForm.manager) }}</span>
  284. </div>
  285. <div class="ml20"><span>审核时间:{{ budgetForm.managerTime }}</span></div>
  286. </div>
  287. </div>
  288. </el-descriptions-item>
  289. <el-descriptions-item label="总经理审核意见" :span="3">
  290. <div>
  291. <el-input :disabled="taskName != '总经理审核'" type="textarea" placeholder="请输入审核意见"
  292. v-model="budgetForm.zjlComment" :autosize="{ minRows: 4 }"></el-input>
  293. <div class="sign mt10">
  294. <div class="mr20">签名:<span class="auditor">{{ getUserName(budgetForm.auditor) }}</span>
  295. </div>
  296. <div class="ml20"><span>审核时间:{{ budgetForm.zjlTime }}</span></div>
  297. </div>
  298. </div>
  299. </el-descriptions-item>
  300. <el-descriptions-item label="董事长批准意见" :span="3">
  301. <div>
  302. <el-input :disabled="taskName != '预算批准'" type="textarea" placeholder="请输入审核意见"
  303. v-model="budgetForm.dszComment" :autosize="{ minRows: 4 }"></el-input>
  304. <div class="sign mt10">
  305. <div class="mr20">签名:<span class="auditor">{{ getUserName(budgetForm.approver) }}</span>
  306. </div>
  307. <div class="ml20"><span>审核时间:{{ budgetForm.dszTime }}</span></div>
  308. </div>
  309. </div>
  310. </el-descriptions-item>
  311. </el-descriptions>
  312. </div>
  313. <el-row v-if="taskName == '分管审核' || taskName == '总经理审核' || taskName == '预算批准'" class="text-center mt20 mb20">
  314. <el-button type="success" @click="confirmSucess(taskName)">提 交</el-button>
  315. </el-row>
  316. </div>
  317. </template>
  318. <script>
  319. import { listBudget, updateBudget } from "@/api/oa/budget/budget";
  320. import { listBudgetCar, updateBudgetCar } from "@/api/oa/budget/budgetCar";
  321. import { listBudgetDevice, updateBudgetDevice } from "@/api/oa/budget/budgetDevice";
  322. import { listBudgetSettle, updateBudgetSettle } from "@/api/oa/budget/budgetSettle";
  323. import { listBudgetStaff, updateBudgetStaff } from "@/api/oa/budget/budgetStaff";
  324. import { listProjectWork } from "@/api/oa/project/projectWork";
  325. import { mapGetters } from 'vuex';
  326. import { getProject } from "@/api/oa/project/project";
  327. import { listProjectContract, addProjectContract } from "@/api/oa/contract/projectContract";
  328. import { listContract, getContract, delContract, addContract, updateContract } from "@/api/oa/contract/contract";
  329. import { complete, rejectTask, returnList, returnTask, getNextFlowNode, delegate, flowTaskForm } from "@/api/flowable/todo";
  330. import { getUser } from '@/api/system/user'
  331. import { getUsersManageLeaderByDept } from '@/api/system/post'
  332. import { getPriceRemarkByWorkType } from '@/api/oa/price/price'
  333. import { getUserByPost } from "@/api/system/post";
  334. export default {
  335. computed: {
  336. ...mapGetters(["name", "userId"]),
  337. },
  338. props: {
  339. taskForm: {
  340. type: Object,
  341. require: true
  342. },
  343. taskName: {
  344. type: String,
  345. }
  346. },
  347. watch: {
  348. 'taskForm.formId'() {
  349. this.initBudgetForm();
  350. }
  351. },
  352. data() {
  353. return {
  354. projectId: '',
  355. managerList: [],
  356. budgetForm: {
  357. },
  358. projectForm: {
  359. projectRegistrantUser: {
  360. nickName: ''
  361. }
  362. },
  363. userLen: 1,
  364. carLen: 1,
  365. deviceLen: 1,
  366. workLen: 1,
  367. chooseCar: [],
  368. chooseDevice: [],
  369. chooseUser: [],
  370. workList: [],
  371. workContentList: [],
  372. contract: {},
  373. profit: 0
  374. };
  375. },
  376. created() {
  377. this.initBudgetForm();
  378. },
  379. methods: {
  380. initBudgetForm() {
  381. listBudget({ pageNum: 1, pageSize: 20, projectId: this.taskForm.formId }).then(res => {
  382. this.budgetForm = res.rows[0];
  383. this.setSignName();
  384. if (this.budgetForm) {
  385. listBudgetDevice({ budgetId: this.budgetForm.budgetId }).then(res => {
  386. this.chooseDevice = res.rows;
  387. this.deviceLen = res.rows.length + 1;
  388. })
  389. listBudgetStaff({ budgetId: this.budgetForm.budgetId }).then(res => {
  390. this.chooseUser = res.rows;
  391. this.userLen = res.rows.length + 1;
  392. let days = 0;
  393. for (let d of this.chooseUser) {
  394. days = days + d.days
  395. }
  396. this.budgetForm.inOutPriceSum = Number(days) * Number(this.chooseUser[0].inOutPrice)
  397. })
  398. listBudgetCar({ budgetId: this.budgetForm.budgetId }).then(res => {
  399. this.chooseCar = res.rows;
  400. this.carLen = res.rows.length + 1;
  401. })
  402. listBudgetSettle({ budgetId: this.budgetForm.budgetId }).then(res => {
  403. this.workList = res.rows;
  404. this.workLen = res.rows.length;
  405. for (let work of this.workList) {
  406. if (work.groundType == '0') {
  407. work.price = work.cmcPrice.commonPrice
  408. work.scaleGrade = work.cmcPrice.scaleGrade
  409. work.unit = work.cmcPrice.unit
  410. } else {
  411. work.price = work.cmcPrice.complexPrice
  412. work.scaleGrade = work.cmcPrice.scaleGrade
  413. work.unit = work.cmcPrice.unit
  414. }
  415. }
  416. this.getProjectWorkList();
  417. })
  418. this.getProjectList();
  419. listProjectContract({ projectId: this.taskForm.formId }).then(res => {
  420. if (res.total == 1) {
  421. getContract(res.rows[0].contractId).then(response => {
  422. this.contract = response.data;
  423. this.profit = Number(this.contract.amount) - Number(this.budgetForm.totalBudget)
  424. })
  425. }
  426. })
  427. }
  428. });
  429. },
  430. setSignName() {
  431. const signUser = this.$store.getters.userId
  432. const times = this.parseTime(new Date(), '{y}-{m}-{d}')
  433. if (this.taskName == '分管审核') {
  434. this.budgetForm.manager = signUser
  435. this.budgetForm.managerTime = times
  436. } else if (this.taskName == '总经理审核') {
  437. this.budgetForm.auditor = signUser
  438. this.budgetForm.zjlTime = times
  439. } else if (this.taskName == '预算批准') {
  440. this.budgetForm.approver = signUser
  441. this.budgetForm.dszTime = times
  442. }
  443. },
  444. // 查询项目列表
  445. getProjectList() {
  446. getProject(this.taskForm.formId).then(response => {
  447. this.projectForm = response.data;
  448. });
  449. },
  450. getProjectWorkList() {
  451. listProjectWork({ projectId: this.taskForm.formId }).then(res => {
  452. this.workContentList = res.rows;
  453. })
  454. },
  455. confirmSucess(taskName) {
  456. const params = { taskId: this.taskForm.taskId };
  457. if (taskName == '分管审核') {
  458. this.updateBudgetForm();
  459. getNextFlowNode(params).then(res => {
  460. getUserByPost({ postName: "总经理" }).then(res => {
  461. const userId = res.data[0].userId;
  462. this.$set(this.taskForm.variables, "approval", userId);
  463. complete(this.taskForm).then(response => {
  464. this.$modal.msgSuccess(response.msg);
  465. this.$emit("goBack");
  466. });
  467. })
  468. })
  469. } else if (taskName == '总经理审核') {
  470. this.updateBudgetForm();
  471. getNextFlowNode(params).then(res => {
  472. getUserByPost({ postName: "董事长" }).then(res => {
  473. const userId = res.data[0].userId;
  474. this.$set(this.taskForm.variables, "approval", userId);
  475. complete(this.taskForm).then(response => {
  476. this.$modal.msgSuccess(response.msg);
  477. this.$emit("goBack");
  478. });
  479. })
  480. })
  481. } else {
  482. this.updateBudgetForm();
  483. getNextFlowNode(params).then(res => {
  484. complete(this.taskForm).then(response => {
  485. this.$modal.msgSuccess(response.msg);
  486. this.$emit("goBack");
  487. });
  488. })
  489. }
  490. },
  491. updateBudgetForm() {
  492. updateBudget(this.budgetForm).then(res => {
  493. this.updateBudgetSubItem(this.chooseCar, updateBudgetCar);
  494. this.updateBudgetSubItem(this.chooseDevice, updateBudgetDevice);
  495. this.updateBudgetSubItem(this.chooseUser, updateBudgetStaff);
  496. this.updateBudgetSubItem(this.workList, updateBudgetSettle, this.showSuccessMessage);
  497. });
  498. },
  499. updateBudgetSubItem(items, updateFunction, onSuccess) {
  500. // 假设所有更新都成功
  501. let allUpdatesSuccessful = true;
  502. // 遍历项目数组,并对每个项目调用更新函数
  503. for (let item of items) {
  504. try {
  505. updateFunction(item);
  506. } catch (error) {
  507. // 如果有任何更新失败,设置标志并可能记录错误
  508. allUpdatesSuccessful = false;
  509. console.error('更新失败:', error);
  510. }
  511. }
  512. // 如果所有更新都成功,调用onSuccess回调函数
  513. if (allUpdatesSuccessful && typeof onSuccess === 'function') {
  514. onSuccess();
  515. }
  516. },
  517. showSuccessMessage() {
  518. this.$message.success('预算更新成功!')
  519. },
  520. // 计算作业结算金额
  521. computeWorkSettle(work) {
  522. let workload = Number(work.workload);
  523. let price = Number(work.price);
  524. let coefficient = Number(work.coefficient);
  525. if (!isNaN(workload) && !isNaN(price) && !isNaN(coefficient)) {
  526. let result = workload * price * coefficient;
  527. if (result < 600) {
  528. result = 600
  529. this.$message.warning('不足600,按600算')
  530. }
  531. this.$set(work, 'settle', result.toFixed(2));
  532. this.computedSettleExpense();
  533. this.computedDirectExpense();
  534. } else {
  535. this.$message.error('请确保参与计算的值都为数字')
  536. }
  537. },
  538. computedFixCostSettle(item, type) {
  539. if (type == 'user') {
  540. let salaryPerDay = (Number(item.salary.salary) + 1780 || 0) / 21.75; // 转换为每天的薪资,或默认为0
  541. let totalDays = Number(item.days) || 0; // 转换为天数,或默认为0
  542. // 计算总薪资
  543. let total = (salaryPerDay * totalDays).toFixed(2);
  544. this.$set(item, 'staffCost', total);
  545. this.getCost("staffCost", "staffCost", this.chooseUser);
  546. } else if (type == 'car') {
  547. let total1 = (Number(item.mileage) || 0) * (Number(item.distance) || 0);
  548. let total2 = (Number(item.car.dayCost) || 0) * (Number(item.days) || 0);
  549. this.$set(item, "depreciation", total2);
  550. let sum = (total1 + total2).toFixed(2); // sum 是一个字符串
  551. this.$set(item, "expense", sum); // expense 将是一个字符串,包含两位小数的总和
  552. this.getCost("expense", "carCost", this.chooseCar);
  553. } else {
  554. let total = (Number(item.device.dayCost) || 0) * (Number(item.days) || 0);
  555. this.$set(item, "depreciation", total.toFixed(2));
  556. this.getCost("depreciation", "deviceCost", this.chooseDevice);
  557. }
  558. this.getFixCost();
  559. this.computedTotalBudget();
  560. },
  561. getCost(name1, name2, list) {
  562. let sum = 0;
  563. for (let user of list) {
  564. sum = sum + Number(user[name1]);
  565. }
  566. this.budgetForm[name2] = sum.toFixed(2);
  567. },
  568. getFixCost() {
  569. let total =
  570. Number(this.budgetForm.staffCost) +
  571. Number(this.budgetForm.carCost) +
  572. Number(this.budgetForm.deviceCost);
  573. this.budgetForm.fixCost = total.toFixed(2);
  574. },
  575. computedSettleExpense() {
  576. let sum = this.workList.reduce((accumulator, work) => {
  577. const settleValue = Number(work.settle);
  578. // 如果settleValue不是NaN(即它可以被转换为数字)
  579. if (!isNaN(settleValue)) {
  580. return accumulator + settleValue;
  581. }
  582. return accumulator;
  583. }, 0); // 初始累加器值为0
  584. this.$set(this.budgetForm, 'settleExpense', sum.toFixed(2))
  585. },
  586. computedDirectExpense() {
  587. const { settleExpense, outExpense, businessExpense, taxExpense, rentExpense, otherExpense } = this.budgetForm;
  588. const expenses = [settleExpense, outExpense, businessExpense, taxExpense, rentExpense, otherExpense];
  589. // 使用 reduce 函数计算总和
  590. let sum = expenses.reduce((acc, curr) => {
  591. // 确保每个当前值都是数字(如果不是,则默认为0)
  592. const num = Number(curr) || 0;
  593. return acc + num;
  594. }, 0);
  595. this.$set(this.budgetForm, 'directExpense', `${sum.toFixed(2)}`);
  596. this.computedTotalBudget();
  597. },
  598. computedTotalBudget() {
  599. const { fixCost, directExpense } = this.budgetForm;
  600. // 确保 fixCost 和 directExpense 是数字,如果不是则默认为 0
  601. const totalBudget = (Number(fixCost) || 0) + (Number(directExpense) || 0);
  602. this.$set(this.budgetForm, 'totalBudget', totalBudget.toFixed(2));
  603. this.profit = (Number(this.contract.amount) || 0) - (Number(totalBudget) || 0);
  604. },
  605. getCoefficientRemark(work) {
  606. let workType = work.cmcPrice.workType
  607. getPriceRemarkByWorkType({ workType }).then(res => {
  608. if (res.code == 200) {
  609. if (workType != undefined)
  610. this.$notify({
  611. title: workType,
  612. dangerouslyUseHTMLString: true,
  613. message: res.msg,
  614. duration: 0
  615. });
  616. }
  617. })
  618. },
  619. },
  620. };
  621. </script>
  622. <style lang="scss" scoped>
  623. @import "@/assets/styles/element-reset.scss";
  624. .main {
  625. width: 100%;
  626. margin: 0 auto;
  627. text-align: center;
  628. }
  629. table {
  630. text-align: center;
  631. border-collapse: collapse;
  632. margin: 0 auto;
  633. /*设置背景颜色*/
  634. /* background-color: #bfa; */
  635. td {
  636. padding: 5px;
  637. }
  638. }
  639. .descriptions {
  640. width: 100%;
  641. margin: 0 auto;
  642. }
  643. .head {
  644. line-height: 35px;
  645. font-weight: bold;
  646. }
  647. .sign {
  648. display: flex;
  649. justify-content: flex-end;
  650. align-items: center;
  651. padding-right: 80px;
  652. line-height: 30px;
  653. /* 如果需要垂直居中 */
  654. }
  655. ::v-deep .el-descriptions-item__label.is-bordered-label {
  656. color: #5a5757;
  657. background: rgba($color: #a9adb3, $alpha: 0.1);
  658. width: 120px;
  659. text-align: center;
  660. min-width: 120px;
  661. }
  662. ::v-deep .el-descriptions .is-bordered .el-descriptions-item__cell {
  663. border: 1px solid #cdd0d3;
  664. }
  665. </style>