综合办公系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

addBudget.vue 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. <!--
  2. * @Author: ysh
  3. * @Date: 2024-06-21 18:51:51
  4. * @LastEditors: Please set LastEditors
  5. * @LastEditTime: 2025-01-23 14:02:18
  6. -->
  7. <template>
  8. <div class="app-container">
  9. <h2 class="text-center">项目直接生产成本预算表</h2>
  10. <p style="text-align: center;">编制人:{{ $store.getters.name }}</p>
  11. <el-divider></el-divider>
  12. <div class="mt20 mb20" v-if="showAlter">
  13. <el-alert title="任务被退回,请修改后重新提交" type="error" :closable="false">
  14. <return-comment :taskForm="taskForm" @isReturn="isReturn"></return-comment>
  15. </el-alert>
  16. </div>
  17. <el-descriptions title="项目信息" labelClassName="mylabel">
  18. <el-descriptions-item label="项目编号">{{ project.projectNumber }}</el-descriptions-item>
  19. <el-descriptions-item label="项目名称">{{ project.projectName }}</el-descriptions-item>
  20. <el-descriptions-item label="项目负责人">{{ getUserName(project.projectLeader) }}</el-descriptions-item>
  21. <el-descriptions-item label="项目类型">{{ project.projectType }}</el-descriptions-item>
  22. <el-descriptions-item label="承担部门">{{ getDeptNames(project.undertakingDept) }}</el-descriptions-item>
  23. <el-descriptions-item label="甲方单位">{{ project.partyA ? project.partyA.partyAName : "" }}</el-descriptions-item>
  24. </el-descriptions>
  25. <el-divider><b>间接成本</b></el-divider>
  26. <!-- 选择人员 -->
  27. <people-table ref="peopleRef" :budgetId="budgetForm.budgetId" @chooseUser="getChooseUser"
  28. @staffCost="getStaffCost"></people-table>
  29. <!-- 选择车辆 -->
  30. <car-table ref="carRef" :budgetId="budgetForm.budgetId" @chooseCar="getChooseCar" @carCost="getCarCost"></car-table>
  31. <!-- 选择设备 -->
  32. <device-table ref="deviceRef" :budgetId="budgetForm.budgetId" @chooseDevice="getChooseDevice"
  33. @deviceCost="getDeviceCost"></device-table>
  34. <!-- 分割线 -->
  35. <el-divider><b>直接成本</b></el-divider>
  36. <!-- 预结算 -->
  37. <money-table ref="moneyRef" :projectId="this.taskForm.formId" :budgetId="budgetForm.budgetId"
  38. @settleExpense="getSettleExpense" @contentList="getContentList"></money-table>
  39. <!-- 其他成本 -->
  40. <other-table ref="otherRef" @otherCost="getOtherCost" :budgetForm="budgetForm"></other-table>
  41. <!-- 预算备注 -->
  42. <el-form :model="budgetForm" style="padding: 20px 100px 0">
  43. <el-form-item label="预算表单备注" label-width="100px">
  44. <el-input type="textarea" v-model="budgetForm.remark" placeholder="请输入预算备注" :rows="4"></el-input>
  45. </el-form-item>
  46. </el-form>
  47. <!-- 统计 -->
  48. <div class="text-center">
  49. <el-tag class="ml10 mr10" type="success">间接成本:{{ isNaN(budgetForm.fixCost) ? 0 : budgetForm.fixCost }}</el-tag>
  50. <el-tag class="ml10 mr10">直接成本:{{ isNaN(budgetForm.directExpense) ? 0 : budgetForm.directExpense }}</el-tag>
  51. <el-tag class="ml10 mr10" type="danger">预算总成本:{{ isNaN(budgetForm.totalBudget) ? 0 : budgetForm.totalBudget
  52. }}</el-tag>
  53. </div>
  54. <div class="mt20 text-center" style="color:#909399;font-size:12px;">
  55. tips:预览表单,请先保存之后刷新再查看
  56. </div>
  57. <el-divider></el-divider>
  58. <div style="text-align: center">
  59. <el-button type="warning" @click="preserve()">保存</el-button>
  60. <el-button type="success" @click="viewForm()">预览表单</el-button>
  61. <el-button type="primary" @click="submitNextFlow" v-if="taskName != '预算批准'">提交下一个流程</el-button>
  62. <el-button type="primary" @click="submitNextFlow" v-else>结算批准</el-button>
  63. </div>
  64. <el-dialog title="表单预览" :visible.sync="viewOpen" width="60%" append-to-body>
  65. <budget-info :taskName="taskName" :taskForm="taskForm" @goBack="$emit('goBack')"></budget-info>
  66. </el-dialog>
  67. </div>
  68. </template>
  69. <script>
  70. import { Snowflake } from "@/utils/snowFlake.js";
  71. import { getProject } from "@/api/oa/project/project";
  72. import { listBudget, addBudget, updateBudget, delBudget } from "@/api/oa/budget/budget.js";
  73. import { listBudgetCar, addBudgetCar, delBudgetCar } from "@/api/oa/budget/budgetCar.js";
  74. import { listBudgetStaff, addBudgetStaff, delBudgetStaff } from "@/api/oa/budget/budgetStaff.js";
  75. import { listBudgetDevice, addBudgetDevice, delBudgetDevice } from "@/api/oa/budget/budgetDevice.js";
  76. import { listBudgetSettle, addBudgetSettle, delBudgetSettle } from "@/api/oa/budget/budgetSettle.js";
  77. import { getUsersDeptLeaderByDept, getUsersManageLeaderByDept } from "@/api/system/post";
  78. import { complete, getNextFlowNode } from "@/api/flowable/todo";
  79. import budgetInfo from "./budgetInfo.vue";
  80. import ReturnComment from '@/views/flowable/form/components/flowBtn/returnComment.vue';
  81. import ReturnBtn from '@/views/flowable/form/components/flowBtn/returnBtn.vue';
  82. import CarTable from './carTable.vue';
  83. import MoneyTable from './moneyTable.vue';
  84. import PeopleTable from "./staffTable.vue";
  85. import DeviceTable from './deviceTable.vue';
  86. import OtherTable from './otherTable.vue';
  87. export default {
  88. components: {
  89. ReturnComment,
  90. ReturnBtn,
  91. PeopleTable,
  92. CarTable,
  93. DeviceTable,
  94. MoneyTable,
  95. OtherTable,
  96. budgetInfo
  97. },
  98. data() {
  99. return {
  100. budgetForm: {
  101. budgetId: new Snowflake(1n, 1n, 0n).nextId().toString(),
  102. projectId: '',
  103. fixCost: 0,
  104. directExpense: 0,
  105. totalBudget: 0,
  106. },
  107. flag: false,
  108. project: {},
  109. showAlter: true,
  110. returnOpen: false,
  111. viewOpen: false,
  112. }
  113. },
  114. props: {
  115. taskForm: {
  116. type: Object,
  117. require: true,
  118. },
  119. taskName: {
  120. type: String,
  121. require: true,
  122. },
  123. },
  124. watch: {
  125. budgetForm: {
  126. handler(newVal) {
  127. if (newVal) {
  128. this.getFixCost();
  129. this.getDirectExpense();
  130. this.getTotalBudget();
  131. }
  132. },
  133. immediate: true, // 立即生效
  134. deep: true //监听对象或数组的时候,要用到深度监听
  135. }
  136. },
  137. created() {
  138. this.getProjectInfo();
  139. this.initBudgetForm();
  140. },
  141. methods: {
  142. initBudgetForm() {
  143. listBudget({ pageNum: 1, pageSize: 20, projectId: this.taskForm.formId }).then(res => {
  144. if (res.rows[0] && res.rows[0].budgetId) {
  145. this.flag = true
  146. this.budgetForm = res.rows[0];
  147. this.budgetId = res.rows[0].budgetId
  148. } else {
  149. this.flag = false
  150. this.budgetForm.projectId = this.taskForm.formId
  151. }
  152. })
  153. },
  154. getProjectInfo() {
  155. getProject(this.taskForm.formId).then(response => {
  156. this.project = response.data;
  157. });
  158. },
  159. // 保存
  160. preserve() {
  161. if (!this.flag) {
  162. this.addBudgetForm(this.budgetForm)
  163. this.flag = true;
  164. } else {
  165. this.updateBudgetForm(this.budgetForm)
  166. }
  167. },
  168. viewForm() {
  169. this.viewOpen = true;
  170. },
  171. // 提交下一个流程
  172. async submitNextFlow() {
  173. if (this.taskName == '预算编制') {
  174. this.preserve();
  175. }
  176. const params = { taskId: this.taskForm.taskId };
  177. const deptIdsStr = this.project.undertakingDept;
  178. const deptIdsArr = (deptIdsStr.split(',')).map(Number);
  179. let approvalList = []
  180. for (let deptId of deptIdsArr) {
  181. let res = await getUsersManageLeaderByDept({ deptId })
  182. if (res.code == 200 && res.data) {
  183. res.data.forEach(element => {
  184. approvalList.push(element.userId)
  185. });
  186. }
  187. }
  188. this.$set(this.taskForm.variables, "approvalList", approvalList); //得到各部门的分管领导列表
  189. // 提交到下一个流程
  190. getNextFlowNode(params).then(res => {
  191. complete(this.taskForm).then(response => {
  192. this.$modal.msgSuccess(response.msg);
  193. this.$emit("goBack");
  194. });
  195. });
  196. },
  197. addBudgetForm(form) {
  198. addBudget(form);
  199. for (let user of form.chooseUser) {
  200. user.budgetId = form.budgetId;
  201. addBudgetStaff(user);
  202. }
  203. for (let car of form.chooseCar) {
  204. car.budgetId = form.budgetId;
  205. addBudgetCar(car);
  206. }
  207. for (let device of form.chooseDevice) {
  208. device.budgetId = form.budgetId;
  209. addBudgetDevice(device);
  210. }
  211. for (let work of form.contentList) {
  212. work.budgetId = form.budgetId;
  213. addBudgetSettle(work).then(res => {
  214. this.$message.success('预算添加成功')
  215. })
  216. }
  217. },
  218. updateBudgetForm(form) {
  219. updateBudget(form);
  220. delBudgetStaff(form.budgetId).then(res => {
  221. for (let user of form.chooseUser) {
  222. user.budgetId = form.budgetId;
  223. addBudgetStaff(user);
  224. }
  225. });
  226. delBudgetCar(form.budgetId).then(res => {
  227. for (let car of form.chooseCar) {
  228. car.budgetId = form.budgetId;
  229. addBudgetCar(car);
  230. }
  231. })
  232. delBudgetDevice(form.budgetId).then(res => {
  233. for (let device of form.chooseDevice) {
  234. device.budgetId = form.budgetId;
  235. addBudgetDevice(device);
  236. }
  237. })
  238. delBudgetSettle(form.budgetId).then(res => {
  239. for (let work of form.contentList) {
  240. work.budgetId = form.budgetId;
  241. addBudgetSettle(work)
  242. }
  243. this.$message.success('预算添加成功')
  244. })
  245. },
  246. getChooseUser(val) {
  247. this.$set(this.budgetForm, 'chooseUser', val);
  248. },
  249. getStaffCost(val) {
  250. this.$set(this.budgetForm, 'staffCost', val);
  251. },
  252. getChooseCar(val) {
  253. this.$set(this.budgetForm, 'chooseCar', val);
  254. },
  255. getCarCost(val) {
  256. this.$set(this.budgetForm, 'carCost', val);
  257. },
  258. getChooseDevice(val) {
  259. this.$set(this.budgetForm, 'chooseDevice', val);
  260. },
  261. getDeviceCost(val) {
  262. this.$set(this.budgetForm, 'deviceCost', val);
  263. },
  264. getContentList(val) {
  265. this.$set(this.budgetForm, 'contentList', val);
  266. },
  267. getSettleExpense(val) {
  268. this.$set(this.budgetForm, 'settleExpense', val);
  269. },
  270. getOtherCost(val) {
  271. this.$set(this.budgetForm, 'outExpense', val.outExpense);
  272. this.$set(this.budgetForm, 'rentExpense', val.rentExpense);
  273. this.$set(this.budgetForm, 'otherExpense', val.otherExpense);
  274. this.$set(this.budgetForm, 'taxExpense', val.taxExpense);
  275. this.$set(this.budgetForm, 'businessExpense', val.businessExpense);
  276. },
  277. getFixCost() {
  278. const staffCost = this.safeNumber(this.budgetForm.staffCost);
  279. const carCost = this.safeNumber(this.budgetForm.carCost);
  280. const deviceCost = this.safeNumber(this.budgetForm.deviceCost);
  281. const total = staffCost + carCost + deviceCost;
  282. this.budgetForm.fixCost = total.toFixed(2);
  283. },
  284. safeNumber(value) {
  285. const num = Number(value);
  286. return isNaN(num) ? 0 : num;
  287. },
  288. // 获取直接成本
  289. getDirectExpense() {
  290. const settleExpense = this.safeNumber(this.budgetForm.settleExpense);
  291. const outExpense = this.safeNumber(this.budgetForm.outExpense);
  292. const rentExpense = this.safeNumber(this.budgetForm.rentExpense);
  293. const taxExpense = this.safeNumber(this.budgetForm.taxExpense);
  294. const businessExpense = this.safeNumber(this.budgetForm.businessExpense);
  295. const otherExpense = this.safeNumber(this.budgetForm.otherExpense);
  296. const sum = settleExpense + outExpense + rentExpense + taxExpense + businessExpense + otherExpense;
  297. this.budgetForm.directExpense = sum.toFixed(2);
  298. },
  299. getTotalBudget() {
  300. this.budgetForm.totalBudget = (Number(this.budgetForm.fixCost) + Number(this.budgetForm.directExpense)).toFixed(2);
  301. },
  302. isReturn(val) {
  303. this.showAlter = val
  304. },
  305. commentByRole() {
  306. if (this.taskName == '分管审核') {
  307. return this.form.managerComment
  308. } else if (this.taskName == '总经理审批') {
  309. return this.form.gmComment
  310. }
  311. }
  312. },
  313. }
  314. </script>
  315. <style lang="scss" scoped>
  316. .mylabel {
  317. font-weight: bold;
  318. }
  319. </style>