|
@@ -1,388 +1,390 @@
|
1
|
|
-<!--
|
2
|
|
- * @Author: ysh
|
3
|
|
- * @Date: 2024-06-21 18:51:51
|
4
|
|
- * @LastEditors: Please set LastEditors
|
5
|
|
- * @LastEditTime: 2025-04-21 09:34:14
|
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="项目编号">{{
|
19
|
|
- project.projectNumber
|
20
|
|
- }}</el-descriptions-item>
|
21
|
|
- <el-descriptions-item label="项目名称">{{
|
22
|
|
- project.projectName
|
23
|
|
- }}</el-descriptions-item>
|
24
|
|
- <el-descriptions-item label="项目负责人">{{
|
25
|
|
- getUserName(project.projectLeader)
|
26
|
|
- }}</el-descriptions-item>
|
27
|
|
- <el-descriptions-item label="项目类型">{{
|
28
|
|
- project.projectType
|
29
|
|
- }}</el-descriptions-item>
|
30
|
|
- <el-descriptions-item label="承担部门">{{
|
31
|
|
- getDeptNames(project.undertakingDept)
|
32
|
|
- }}</el-descriptions-item>
|
33
|
|
- <el-descriptions-item label="甲方单位">{{
|
34
|
|
- project.partyA ? project.partyA.partyAName : ""
|
35
|
|
- }}</el-descriptions-item>
|
36
|
|
- </el-descriptions>
|
37
|
|
- <el-divider><b>间接成本</b></el-divider>
|
38
|
|
- <!-- 选择人员 -->
|
39
|
|
- <people-table ref="peopleRef" :budgetId="budgetForm.budgetId" @chooseUser="getChooseUser"
|
40
|
|
- @staffCost="getStaffCost"></people-table>
|
41
|
|
- <!-- 选择车辆 -->
|
42
|
|
- <car-table ref="carRef" :budgetId="budgetForm.budgetId" @chooseCar="getChooseCar" @carCost="getCarCost"></car-table>
|
43
|
|
- <!-- 选择设备 -->
|
44
|
|
- <device-table ref="deviceRef" :budgetId="budgetForm.budgetId" @chooseDevice="getChooseDevice"
|
45
|
|
- @deviceCost="getDeviceCost"></device-table>
|
46
|
|
- <!-- 分割线 -->
|
47
|
|
- <el-divider><b>直接成本</b></el-divider>
|
48
|
|
- <!-- 预结算 -->
|
49
|
|
- <money-table ref="moneyRef" :projectId="this.taskForm.formId" :budgetId="budgetForm.budgetId"
|
50
|
|
- @settleExpense="getSettleExpense" @contentList="getContentList"></money-table>
|
51
|
|
- <!-- 其他成本 -->
|
52
|
|
- <other-table ref="otherRef" @otherCost="getOtherCost" :budgetForm="budgetForm"></other-table>
|
53
|
|
- <!-- 预算备注 -->
|
54
|
|
- <el-form :model="budgetForm" style="padding: 20px 100px 0">
|
55
|
|
- <el-form-item label="预算表单备注" label-width="100px">
|
56
|
|
- <el-input type="textarea" v-model="budgetForm.remark" placeholder="请输入预算备注" :rows="4"></el-input>
|
57
|
|
- </el-form-item>
|
58
|
|
- <el-form-item label="附件上传" label-width="100px">
|
59
|
|
- <FileUpload v-if="budgetForm.document == null || budgetForm.document == ''" :disabled="taskName != '预算编制'"
|
60
|
|
- :limit="1" :filePathName="'预算编制/附件上传'" :fileType="['doc', 'docx', 'xls', 'xlsx', 'pdf', 'rar', 'zip']"
|
61
|
|
- @input="getDocumentPath"></FileUpload>
|
62
|
|
- <div v-if="budgetForm.document">
|
63
|
|
- <el-link type="primary" @click="reviewWord(`${baseUrl}${'/profile/upload' + budgetForm.document}`)">
|
64
|
|
- {{ getFileName(budgetForm.document) }}
|
65
|
|
- </el-link>
|
66
|
|
- <el-link class="ml20" type="warning" :href="`${baseUrl}${'/profile/upload' + budgetForm.document}`"
|
67
|
|
- :underline="false" target="_blank">
|
68
|
|
- <span class="el-icon-download">下载文件</span>
|
69
|
|
- </el-link>
|
70
|
|
- <FileUpload v-if="taskName == '预算编制'" :limit="1" :filePathName="'预算编制/附件上传'"
|
71
|
|
- :fileType="['doc', 'docx', 'xls', 'xlsx', 'pdf', 'rar', 'zip']" @input="getDocumentPath"></FileUpload>
|
72
|
|
- </div>
|
73
|
|
- </el-form-item>
|
74
|
|
- </el-form>
|
75
|
|
- <!-- 统计 -->
|
76
|
|
- <div class="text-center">
|
77
|
|
- <el-tag class="ml10 mr10" type="success">间接成本:{{ isNaN(budgetForm.fixCost) ? 0 : budgetForm.fixCost }}</el-tag>
|
78
|
|
- <el-tag class="ml10 mr10">直接成本:{{
|
79
|
|
- isNaN(budgetForm.directExpense) ? 0 : budgetForm.directExpense
|
80
|
|
- }}</el-tag>
|
81
|
|
- <el-tag class="ml10 mr10" type="danger">预算总成本:{{
|
82
|
|
- isNaN(budgetForm.totalBudget) ? 0 : budgetForm.totalBudget
|
83
|
|
- }}</el-tag>
|
84
|
|
- </div>
|
85
|
|
- <div class="mt20 text-center" style="color: #909399; font-size: 12px">
|
86
|
|
- tips:预览表单,请先保存之后刷新再查看
|
87
|
|
- </div>
|
88
|
|
- <el-divider></el-divider>
|
89
|
|
- <div style="text-align: center">
|
90
|
|
- <el-button type="warning" @click="preserve()">保存</el-button>
|
91
|
|
- <el-button type="success" @click="viewForm()">预览表单</el-button>
|
92
|
|
- <el-button type="primary" @click="submitNextFlow" v-if="taskName != '预算批准'">提交下一个流程</el-button>
|
93
|
|
- <el-button type="primary" @click="submitNextFlow" v-else>结算批准</el-button>
|
94
|
|
- </div>
|
95
|
|
- <el-dialog title="表单预览" :visible.sync="viewOpen" width="70%" append-to-body>
|
96
|
|
- <budget-info :taskName="taskName" :taskForm="taskForm" @goBack="$emit('goBack')"></budget-info>
|
97
|
|
- </el-dialog>
|
98
|
|
- </div>
|
99
|
|
-</template>
|
100
|
|
-
|
101
|
|
-<script>
|
102
|
|
-import { Snowflake } from "@/utils/snowFlake.js";
|
103
|
|
-import { getProject } from "@/api/oa/project/project";
|
104
|
|
-import {
|
105
|
|
- listBudget,
|
106
|
|
- addBudget,
|
107
|
|
- updateBudget,
|
108
|
|
- delBudget,
|
109
|
|
-} from "@/api/oa/budget/budget.js";
|
110
|
|
-import { listBudgetCar, addBudgetCar, delBudgetCar } from "@/api/oa/budget/budgetCar.js";
|
111
|
|
-import {
|
112
|
|
- listBudgetStaff,
|
113
|
|
- addBudgetStaff,
|
114
|
|
- delBudgetStaff,
|
115
|
|
-} from "@/api/oa/budget/budgetStaff.js";
|
116
|
|
-import {
|
117
|
|
- listBudgetDevice,
|
118
|
|
- addBudgetDevice,
|
119
|
|
- delBudgetDevice,
|
120
|
|
-} from "@/api/oa/budget/budgetDevice.js";
|
121
|
|
-import {
|
122
|
|
- listBudgetSettle,
|
123
|
|
- addBudgetSettle,
|
124
|
|
- delBudgetSettle,
|
125
|
|
-} from "@/api/oa/budget/budgetSettle.js";
|
126
|
|
-import { getUsersDeptLeaderByDept, getUsersManageLeaderByDept } from "@/api/system/post";
|
127
|
|
-import { complete, getNextFlowNode } from "@/api/flowable/todo";
|
128
|
|
-import budgetInfo from "./budgetInfo.vue";
|
129
|
|
-import ReturnComment from "@/views/flowable/form/components/flowBtn/returnComment.vue";
|
130
|
|
-import ReturnBtn from "@/views/flowable/form/components/flowBtn/returnBtn.vue";
|
131
|
|
-import CarTable from "./carTable.vue";
|
132
|
|
-import MoneyTable from "./moneyTable.vue";
|
133
|
|
-import PeopleTable from "./staffTable.vue";
|
134
|
|
-import DeviceTable from "./deviceTable.vue";
|
135
|
|
-import OtherTable from "./otherTable.vue";
|
136
|
|
-export default {
|
137
|
|
- components: {
|
138
|
|
- ReturnComment,
|
139
|
|
- ReturnBtn,
|
140
|
|
- PeopleTable,
|
141
|
|
- CarTable,
|
142
|
|
- DeviceTable,
|
143
|
|
- MoneyTable,
|
144
|
|
- OtherTable,
|
145
|
|
- budgetInfo,
|
146
|
|
- },
|
147
|
|
- data() {
|
148
|
|
- return {
|
149
|
|
- baseUrl: process.env.VUE_APP_BASE_API,
|
150
|
|
- budgetForm: {
|
151
|
|
- budgetId: new Snowflake(1n, 1n, 0n).nextId().toString(),
|
152
|
|
- projectId: "",
|
153
|
|
- fixCost: 0,
|
154
|
|
- directExpense: 0,
|
155
|
|
- totalBudget: 0,
|
156
|
|
- },
|
157
|
|
- flag: false,
|
158
|
|
- project: {},
|
159
|
|
- showAlter: true,
|
160
|
|
- returnOpen: false,
|
161
|
|
- viewOpen: false,
|
162
|
|
- };
|
163
|
|
- },
|
164
|
|
- props: {
|
165
|
|
- taskForm: {
|
166
|
|
- type: Object,
|
167
|
|
- require: true,
|
168
|
|
- },
|
169
|
|
- taskName: {
|
170
|
|
- type: String,
|
171
|
|
- require: true,
|
172
|
|
- },
|
173
|
|
- },
|
174
|
|
- watch: {
|
175
|
|
- budgetForm: {
|
176
|
|
- handler(newVal) {
|
177
|
|
- if (newVal) {
|
178
|
|
- this.getFixCost();
|
179
|
|
- this.getDirectExpense();
|
180
|
|
- this.getTotalBudget();
|
181
|
|
- }
|
182
|
|
- },
|
183
|
|
- immediate: true, // 立即生效
|
184
|
|
- deep: true, //监听对象或数组的时候,要用到深度监听
|
185
|
|
- },
|
186
|
|
- },
|
187
|
|
- created() {
|
188
|
|
- this.getProjectInfo();
|
189
|
|
- this.initBudgetForm();
|
190
|
|
- },
|
191
|
|
- methods: {
|
192
|
|
- initBudgetForm() {
|
193
|
|
- listBudget({ pageNum: 1, pageSize: 20, projectId: this.taskForm.formId }).then(
|
194
|
|
- res => {
|
195
|
|
- if (res.rows[0] && res.rows[0].budgetId) {
|
196
|
|
- this.flag = true;
|
197
|
|
- this.budgetForm = res.rows[0];
|
198
|
|
- this.budgetId = res.rows[0].budgetId;
|
199
|
|
- } else {
|
200
|
|
- this.flag = false;
|
201
|
|
- this.budgetForm.projectId = this.taskForm.formId;
|
202
|
|
- }
|
203
|
|
- }
|
204
|
|
- );
|
205
|
|
- },
|
206
|
|
- getProjectInfo() {
|
207
|
|
- getProject(this.taskForm.formId).then(response => {
|
208
|
|
- this.project = response.data;
|
209
|
|
- });
|
210
|
|
- },
|
211
|
|
- // 保存
|
212
|
|
- preserve() {
|
213
|
|
- if (!this.flag) {
|
214
|
|
- this.addBudgetForm(this.budgetForm);
|
215
|
|
- this.flag = true;
|
216
|
|
- } else {
|
217
|
|
- this.updateBudgetForm(this.budgetForm);
|
218
|
|
- }
|
219
|
|
- this.$message.success("保存成功");
|
220
|
|
- },
|
221
|
|
- viewForm() {
|
222
|
|
- this.viewOpen = true;
|
223
|
|
- },
|
224
|
|
- // 提交下一个流程
|
225
|
|
- async submitNextFlow() {
|
226
|
|
- if (this.taskName == "预算编制") {
|
227
|
|
- this.preserve();
|
228
|
|
- }
|
229
|
|
- const params = { taskId: this.taskForm.taskId };
|
230
|
|
- const deptIdsStr = this.project.undertakingDept;
|
231
|
|
- const deptIdsArr = deptIdsStr.split(",").map(Number);
|
232
|
|
- let approvalList = [];
|
233
|
|
- for (let deptId of deptIdsArr) {
|
234
|
|
- let res = await getUsersManageLeaderByDept({ deptId });
|
235
|
|
- if (res.code == 200 && res.data) {
|
236
|
|
- res.data.forEach(element => {
|
237
|
|
- approvalList.push(element.userId);
|
238
|
|
- });
|
239
|
|
- }
|
240
|
|
- }
|
241
|
|
- this.$set(this.taskForm.variables, "approvalList", approvalList); //得到各部门的分管领导列表
|
242
|
|
- // 提交到下一个流程
|
243
|
|
- getNextFlowNode(params).then(res => {
|
244
|
|
- complete(this.taskForm).then(response => {
|
245
|
|
- this.$modal.msgSuccess(response.msg);
|
246
|
|
- this.$emit("goBack");
|
247
|
|
- });
|
248
|
|
- });
|
249
|
|
- },
|
250
|
|
- addBudgetForm(form) {
|
251
|
|
- addBudget(form);
|
252
|
|
- for (let user of form.chooseUser) {
|
253
|
|
- user.budgetId = form.budgetId;
|
254
|
|
- addBudgetStaff(user);
|
255
|
|
- }
|
256
|
|
- for (let car of form.chooseCar) {
|
257
|
|
- car.budgetId = form.budgetId;
|
258
|
|
- addBudgetCar(car);
|
259
|
|
- }
|
260
|
|
- for (let device of form.chooseDevice) {
|
261
|
|
- device.budgetId = form.budgetId;
|
262
|
|
- addBudgetDevice(device);
|
263
|
|
- }
|
264
|
|
- for (let work of form.contentList) {
|
265
|
|
- work.budgetId = form.budgetId;
|
266
|
|
- addBudgetSettle(work).then(res => {
|
267
|
|
- this.$message.success("预算添加成功");
|
268
|
|
- });
|
269
|
|
- }
|
270
|
|
- },
|
271
|
|
- updateBudgetForm(form) {
|
272
|
|
- updateBudget(form);
|
273
|
|
- delBudgetStaff(form.budgetId).then(res => {
|
274
|
|
- for (let user of form.chooseUser) {
|
275
|
|
- user.budgetId = form.budgetId;
|
276
|
|
- addBudgetStaff(user);
|
277
|
|
- }
|
278
|
|
- });
|
279
|
|
- delBudgetCar(form.budgetId).then(res => {
|
280
|
|
- for (let car of form.chooseCar) {
|
281
|
|
- car.budgetId = form.budgetId;
|
282
|
|
- addBudgetCar(car);
|
283
|
|
- }
|
284
|
|
- });
|
285
|
|
- delBudgetDevice(form.budgetId).then(res => {
|
286
|
|
- for (let device of form.chooseDevice) {
|
287
|
|
- device.budgetId = form.budgetId;
|
288
|
|
- addBudgetDevice(device);
|
289
|
|
- }
|
290
|
|
- });
|
291
|
|
- delBudgetSettle(form.budgetId).then(res => {
|
292
|
|
- for (let work of form.contentList) {
|
293
|
|
- work.budgetId = form.budgetId;
|
294
|
|
- addBudgetSettle(work);
|
295
|
|
- }
|
296
|
|
- this.$message.success("预算添加成功");
|
297
|
|
- });
|
298
|
|
- },
|
299
|
|
- getChooseUser(val) {
|
300
|
|
- this.$set(this.budgetForm, "chooseUser", val);
|
301
|
|
- },
|
302
|
|
- getStaffCost(val) {
|
303
|
|
- this.$set(this.budgetForm, "staffCost", val);
|
304
|
|
- },
|
305
|
|
- getChooseCar(val) {
|
306
|
|
- this.$set(this.budgetForm, "chooseCar", val);
|
307
|
|
- },
|
308
|
|
- getCarCost(val) {
|
309
|
|
- this.$set(this.budgetForm, "carCost", val);
|
310
|
|
- },
|
311
|
|
- getChooseDevice(val) {
|
312
|
|
- this.$set(this.budgetForm, "chooseDevice", val);
|
313
|
|
- },
|
314
|
|
- getDeviceCost(val) {
|
315
|
|
- this.$set(this.budgetForm, "deviceCost", val);
|
316
|
|
- },
|
317
|
|
- getContentList(val) {
|
318
|
|
- this.$set(this.budgetForm, "contentList", val);
|
319
|
|
- },
|
320
|
|
- getSettleExpense(val) {
|
321
|
|
- this.$set(this.budgetForm, "settleExpense", val);
|
322
|
|
- },
|
323
|
|
- getOtherCost(val) {
|
324
|
|
- this.$set(this.budgetForm, "outExpense", val.outExpense);
|
325
|
|
- this.$set(this.budgetForm, "rentExpense", val.rentExpense);
|
326
|
|
- this.$set(this.budgetForm, "otherExpense", val.otherExpense);
|
327
|
|
- this.$set(this.budgetForm, "taxExpense", val.taxExpense);
|
328
|
|
- this.$set(this.budgetForm, "businessExpense", val.businessExpense);
|
329
|
|
- },
|
330
|
|
- getFixCost() {
|
331
|
|
- const staffCost = this.safeNumber(this.budgetForm.staffCost);
|
332
|
|
- const carCost = this.safeNumber(this.budgetForm.carCost);
|
333
|
|
- const deviceCost = this.safeNumber(this.budgetForm.deviceCost);
|
334
|
|
- const total = staffCost + carCost + deviceCost;
|
335
|
|
- this.budgetForm.fixCost = total.toFixed(2);
|
336
|
|
- },
|
337
|
|
- safeNumber(value) {
|
338
|
|
- const num = Number(value);
|
339
|
|
- return isNaN(num) ? 0 : num;
|
340
|
|
- },
|
341
|
|
- // 获取直接成本
|
342
|
|
- getDirectExpense() {
|
343
|
|
- const settleExpense = this.safeNumber(this.budgetForm.settleExpense);
|
344
|
|
- const outExpense = this.safeNumber(this.budgetForm.outExpense);
|
345
|
|
- const rentExpense = this.safeNumber(this.budgetForm.rentExpense);
|
346
|
|
- const taxExpense = this.safeNumber(this.budgetForm.taxExpense);
|
347
|
|
- const businessExpense = this.safeNumber(this.budgetForm.businessExpense);
|
348
|
|
- const otherExpense = this.safeNumber(this.budgetForm.otherExpense);
|
349
|
|
- const sum =
|
350
|
|
- settleExpense +
|
351
|
|
- outExpense +
|
352
|
|
- rentExpense +
|
353
|
|
- taxExpense +
|
354
|
|
- businessExpense +
|
355
|
|
- otherExpense;
|
356
|
|
- this.budgetForm.directExpense = sum.toFixed(2);
|
357
|
|
- },
|
358
|
|
- getTotalBudget() {
|
359
|
|
- this.budgetForm.totalBudget = (
|
360
|
|
- Number(this.budgetForm.fixCost) + Number(this.budgetForm.directExpense)
|
361
|
|
- ).toFixed(2);
|
362
|
|
- },
|
363
|
|
- isReturn(val) {
|
364
|
|
- this.showAlter = val;
|
365
|
|
- },
|
366
|
|
- commentByRole() {
|
367
|
|
- if (this.taskName == "分管审核") {
|
368
|
|
- return this.form.managerComment;
|
369
|
|
- } else if (this.taskName == "总经理审批") {
|
370
|
|
- return this.form.gmComment;
|
371
|
|
- }
|
372
|
|
- },
|
373
|
|
- getDocumentPath(val) {
|
374
|
|
- let arr = val.split('/upload')
|
375
|
|
- this.budgetForm.document = arr[1]
|
376
|
|
- if (val == "") {
|
377
|
|
- this.budgetForm.document = ""
|
378
|
|
- }
|
379
|
|
- }
|
380
|
|
- },
|
381
|
|
-};
|
382
|
|
-</script>
|
383
|
|
-
|
384
|
|
-<style lang="scss" scoped>
|
385
|
|
-.mylabel {
|
386
|
|
- font-weight: bold;
|
387
|
|
-}
|
388
|
|
-</style>
|
|
1
|
+<!--
|
|
2
|
+ * @Author: ysh
|
|
3
|
+ * @Date: 2024-06-21 18:51:51
|
|
4
|
+ * @LastEditors: Please set LastEditors
|
|
5
|
+ * @LastEditTime: 2025-05-09 17:29:35
|
|
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="项目编号">{{
|
|
19
|
+ project.projectNumber
|
|
20
|
+ }}</el-descriptions-item>
|
|
21
|
+ <el-descriptions-item label="项目名称">{{
|
|
22
|
+ project.projectName
|
|
23
|
+ }}</el-descriptions-item>
|
|
24
|
+ <el-descriptions-item label="项目负责人">{{
|
|
25
|
+ getUserName(project.projectLeader)
|
|
26
|
+ }}</el-descriptions-item>
|
|
27
|
+ <el-descriptions-item label="项目类型">{{
|
|
28
|
+ project.projectType
|
|
29
|
+ }}</el-descriptions-item>
|
|
30
|
+ <el-descriptions-item label="承担部门">{{
|
|
31
|
+ getDeptNames(project.undertakingDept)
|
|
32
|
+ }}</el-descriptions-item>
|
|
33
|
+ <el-descriptions-item label="甲方单位">{{
|
|
34
|
+ project.partyA ? project.partyA.partyAName : ""
|
|
35
|
+ }}</el-descriptions-item>
|
|
36
|
+ </el-descriptions>
|
|
37
|
+ <!-- <el-divider><b>间接成本</b></el-divider> -->
|
|
38
|
+ <!-- 预结算 -->
|
|
39
|
+ <money-table ref="moneyRef" :projectId="this.taskForm.formId" :budgetId="budgetForm.budgetId"
|
|
40
|
+ @settleExpense="getSettleExpense" @contentList="getContentList"></money-table>
|
|
41
|
+ <!-- 选择人员 -->
|
|
42
|
+ <people-table ref="peopleRef" :budgetId="budgetForm.budgetId" :innerSettleLimit="innerSettleLimit"
|
|
43
|
+ @chooseUser="getChooseUser" @staffCost="getStaffCost"
|
|
44
|
+ @innerSettleExceeded="handleInnerSettleExceeded"></people-table>
|
|
45
|
+ <!-- 选择车辆 -->
|
|
46
|
+ <car-table ref="carRef" :budgetId="budgetForm.budgetId" @chooseCar="getChooseCar" @carCost="getCarCost"></car-table>
|
|
47
|
+ <!-- 选择设备 -->
|
|
48
|
+ <device-table ref="deviceRef" :budgetId="budgetForm.budgetId" @chooseDevice="getChooseDevice"
|
|
49
|
+ @deviceCost="getDeviceCost"></device-table>
|
|
50
|
+ <!-- 分割线 -->
|
|
51
|
+ <!-- <el-divider><b>直接成本</b></el-divider> -->
|
|
52
|
+ <!-- 现场开支 -->
|
|
53
|
+ <site-expenses :outer-users="outerUsers" @expensesList="getExpensesList"></site-expenses>
|
|
54
|
+ <!-- 经营填写 -->
|
|
55
|
+
|
|
56
|
+ <!-- 其他成本 -->
|
|
57
|
+ <other-table ref="otherRef" @otherCost="getOtherCost" :budgetForm="budgetForm"></other-table>
|
|
58
|
+ <!-- 预算备注 -->
|
|
59
|
+ <el-form :model="budgetForm" style="padding: 20px 100px 0">
|
|
60
|
+ <el-form-item label="预算表单备注" label-width="100px">
|
|
61
|
+ <el-input type="textarea" v-model="budgetForm.remark" placeholder="请输入预算备注" :rows="4"></el-input>
|
|
62
|
+ </el-form-item>
|
|
63
|
+ <el-form-item label="附件上传" label-width="100px">
|
|
64
|
+ <FileUpload v-if="budgetForm.document == null || budgetForm.document == ''" :disabled="taskName != '预算编制'"
|
|
65
|
+ :limit="1" :filePathName="'预算编制/附件上传'" :fileType="['doc', 'docx', 'xls', 'xlsx', 'pdf', 'rar', 'zip']"
|
|
66
|
+ @input="getDocumentPath"></FileUpload>
|
|
67
|
+ <div v-if="budgetForm.document">
|
|
68
|
+ <el-link type="primary" @click="reviewWord(`${baseUrl}${'/profile/upload' + budgetForm.document}`)">
|
|
69
|
+ {{ getFileName(budgetForm.document) }}
|
|
70
|
+ </el-link>
|
|
71
|
+ <el-link class="ml20" type="warning" :href="`${baseUrl}${'/profile/upload' + budgetForm.document}`"
|
|
72
|
+ :underline="false" target="_blank">
|
|
73
|
+ <span class="el-icon-download">下载文件</span>
|
|
74
|
+ </el-link>
|
|
75
|
+ <FileUpload v-if="taskName == '预算编制'" :limit="1" :filePathName="'预算编制/附件上传'"
|
|
76
|
+ :fileType="['doc', 'docx', 'xls', 'xlsx', 'pdf', 'rar', 'zip']" @input="getDocumentPath"></FileUpload>
|
|
77
|
+ </div>
|
|
78
|
+ </el-form-item>
|
|
79
|
+ </el-form>
|
|
80
|
+ <!-- 统计 -->
|
|
81
|
+ <div class="text-center">
|
|
82
|
+ <el-tag class="ml10 mr10" type="success">间接成本:{{ isNaN(budgetForm.fixCost) ? 0 : budgetForm.fixCost }}</el-tag>
|
|
83
|
+ <el-tag class="ml10 mr10">直接成本:{{
|
|
84
|
+ isNaN(budgetForm.directExpense) ? 0 : budgetForm.directExpense
|
|
85
|
+ }}</el-tag>
|
|
86
|
+ <el-tag class="ml10 mr10" type="danger">预算总成本:{{
|
|
87
|
+ isNaN(budgetForm.totalBudget) ? 0 : budgetForm.totalBudget
|
|
88
|
+ }}</el-tag>
|
|
89
|
+ </div>
|
|
90
|
+ <div class="mt20 text-center" style="color: #909399; font-size: 12px">
|
|
91
|
+ tips:预览表单,请先保存之后刷新再查看
|
|
92
|
+ </div>
|
|
93
|
+ <el-divider></el-divider>
|
|
94
|
+ <div style="text-align: center">
|
|
95
|
+ <el-button type="warning" @click="preserve()">保存</el-button>
|
|
96
|
+ <el-button type="success" @click="viewForm()">预览表单</el-button>
|
|
97
|
+ <el-button type="primary" @click="submitNextFlow" v-if="taskName != '预算批准'">提交下一个流程</el-button>
|
|
98
|
+ <el-button type="primary" @click="submitNextFlow" v-else>结算批准</el-button>
|
|
99
|
+ </div>
|
|
100
|
+ <el-dialog title="表单预览" :visible.sync="viewOpen" width="70%" append-to-body>
|
|
101
|
+ <budget-info :taskName="taskName" :taskForm="taskForm" @goBack="$emit('goBack')"></budget-info>
|
|
102
|
+ </el-dialog>
|
|
103
|
+ </div>
|
|
104
|
+</template>
|
|
105
|
+
|
|
106
|
+<script>
|
|
107
|
+import { Snowflake } from "@/utils/snowFlake.js";
|
|
108
|
+import { getProject } from "@/api/oa/project/project";
|
|
109
|
+import { listBudget, addBudget, updateBudget, delBudget } from "@/api/oa/budget/budget.js";
|
|
110
|
+import { listBudgetCar, addBudgetCar, delBudgetCar } from "@/api/oa/budget/budgetCar.js";
|
|
111
|
+import { listBudgetStaff, addBudgetStaff, delBudgetStaff } from "@/api/oa/budget/budgetStaff.js";
|
|
112
|
+import { listBudgetDevice, addBudgetDevice, delBudgetDevice } from "@/api/oa/budget/budgetDevice.js";
|
|
113
|
+import { listBudgetSettle, addBudgetSettle, delBudgetSettle } from "@/api/oa/budget/budgetSettle.js";
|
|
114
|
+import { getUsersDeptLeaderByDept, getUsersManageLeaderByDept } from "@/api/system/post";
|
|
115
|
+import { complete, getNextFlowNode } from "@/api/flowable/todo";
|
|
116
|
+import budgetInfo from "./budgetInfo.vue";
|
|
117
|
+import ReturnComment from "@/views/flowable/form/components/flowBtn/returnComment.vue";
|
|
118
|
+import ReturnBtn from "@/views/flowable/form/components/flowBtn/returnBtn.vue";
|
|
119
|
+import CarTable from "./carTable.vue";
|
|
120
|
+import MoneyTable from "./moneyTable.vue";
|
|
121
|
+import PeopleTable from "./staffTable.vue";
|
|
122
|
+import DeviceTable from "./deviceTable.vue";
|
|
123
|
+import OtherTable from "./otherTable.vue";
|
|
124
|
+import SiteExpenses from "./siteExpenses.vue";
|
|
125
|
+export default {
|
|
126
|
+ components: {
|
|
127
|
+ ReturnComment,
|
|
128
|
+ ReturnBtn,
|
|
129
|
+ PeopleTable,
|
|
130
|
+ CarTable,
|
|
131
|
+ DeviceTable,
|
|
132
|
+ MoneyTable,
|
|
133
|
+ OtherTable,
|
|
134
|
+ budgetInfo,
|
|
135
|
+ SiteExpenses
|
|
136
|
+ },
|
|
137
|
+ data() {
|
|
138
|
+ return {
|
|
139
|
+ baseUrl: process.env.VUE_APP_BASE_API,
|
|
140
|
+ budgetForm: {
|
|
141
|
+ budgetId: new Snowflake(1n, 1n, 0n).nextId().toString(),
|
|
142
|
+ projectId: "",
|
|
143
|
+ fixCost: 0,
|
|
144
|
+ directExpense: 0,
|
|
145
|
+ totalBudget: 0,
|
|
146
|
+ },
|
|
147
|
+ flag: false,
|
|
148
|
+ project: {},
|
|
149
|
+ showAlter: true,
|
|
150
|
+ returnOpen: false,
|
|
151
|
+ viewOpen: false,
|
|
152
|
+ innerSettleLimit: 0, // 内业预算绩效合计限制
|
|
153
|
+ outerUsers: [], // 存储外业人员
|
|
154
|
+ };
|
|
155
|
+ },
|
|
156
|
+ props: {
|
|
157
|
+ taskForm: {
|
|
158
|
+ type: Object,
|
|
159
|
+ require: true,
|
|
160
|
+ },
|
|
161
|
+ taskName: {
|
|
162
|
+ type: String,
|
|
163
|
+ require: true,
|
|
164
|
+ },
|
|
165
|
+ },
|
|
166
|
+ watch: {
|
|
167
|
+ budgetForm: {
|
|
168
|
+ handler(newVal) {
|
|
169
|
+ if (newVal) {
|
|
170
|
+ this.getFixCost();
|
|
171
|
+ this.getDirectExpense();
|
|
172
|
+ this.getTotalBudget();
|
|
173
|
+ }
|
|
174
|
+ },
|
|
175
|
+ immediate: true, // 立即生效
|
|
176
|
+ deep: true, //监听对象或数组的时候,要用到深度监听
|
|
177
|
+ },
|
|
178
|
+ },
|
|
179
|
+ created() {
|
|
180
|
+ this.getProjectInfo();
|
|
181
|
+ this.initBudgetForm();
|
|
182
|
+ },
|
|
183
|
+ methods: {
|
|
184
|
+ initBudgetForm() {
|
|
185
|
+ listBudget({ pageNum: 1, pageSize: 20, projectId: this.taskForm.formId }).then(
|
|
186
|
+ res => {
|
|
187
|
+ if (res.rows[0] && res.rows[0].budgetId) {
|
|
188
|
+ this.flag = true;
|
|
189
|
+ this.budgetForm = res.rows[0];
|
|
190
|
+ this.budgetId = res.rows[0].budgetId;
|
|
191
|
+ } else {
|
|
192
|
+ this.flag = false;
|
|
193
|
+ this.budgetForm.projectId = this.taskForm.formId;
|
|
194
|
+ }
|
|
195
|
+ }
|
|
196
|
+ );
|
|
197
|
+ },
|
|
198
|
+ getProjectInfo() {
|
|
199
|
+ getProject(this.taskForm.formId).then(response => {
|
|
200
|
+ this.project = response.data;
|
|
201
|
+ });
|
|
202
|
+ },
|
|
203
|
+ // 保存
|
|
204
|
+ preserve() {
|
|
205
|
+ console.log(this.budgetForm)
|
|
206
|
+ return
|
|
207
|
+ if (!this.flag) {
|
|
208
|
+ this.addBudgetForm(this.budgetForm);
|
|
209
|
+ this.flag = true;
|
|
210
|
+ } else {
|
|
211
|
+ this.updateBudgetForm(this.budgetForm);
|
|
212
|
+ }
|
|
213
|
+ this.$message.success("保存成功");
|
|
214
|
+ },
|
|
215
|
+ viewForm() {
|
|
216
|
+ this.viewOpen = true;
|
|
217
|
+ },
|
|
218
|
+ // 提交下一个流程
|
|
219
|
+ async submitNextFlow() {
|
|
220
|
+ if (this.taskName == "预算编制") {
|
|
221
|
+ this.preserve();
|
|
222
|
+ }
|
|
223
|
+ const params = { taskId: this.taskForm.taskId };
|
|
224
|
+ const deptIdsStr = this.project.undertakingDept;
|
|
225
|
+ const deptIdsArr = deptIdsStr.split(",").map(Number);
|
|
226
|
+ let approvalList = [];
|
|
227
|
+ for (let deptId of deptIdsArr) {
|
|
228
|
+ let res = await getUsersManageLeaderByDept({ deptId });
|
|
229
|
+ if (res.code == 200 && res.data) {
|
|
230
|
+ res.data.forEach(element => {
|
|
231
|
+ approvalList.push(element.userId);
|
|
232
|
+ });
|
|
233
|
+ }
|
|
234
|
+ }
|
|
235
|
+ this.$set(this.taskForm.variables, "approvalList", approvalList); //得到各部门的分管领导列表
|
|
236
|
+ // 提交到下一个流程
|
|
237
|
+ getNextFlowNode(params).then(res => {
|
|
238
|
+ complete(this.taskForm).then(response => {
|
|
239
|
+ this.$modal.msgSuccess(response.msg);
|
|
240
|
+ this.$emit("goBack");
|
|
241
|
+ });
|
|
242
|
+ });
|
|
243
|
+ },
|
|
244
|
+ addBudgetForm(form) {
|
|
245
|
+ addBudget(form);
|
|
246
|
+ for (let user of form.chooseUser) {
|
|
247
|
+ user.budgetId = form.budgetId;
|
|
248
|
+ addBudgetStaff(user);
|
|
249
|
+ }
|
|
250
|
+ for (let car of form.chooseCar) {
|
|
251
|
+ car.budgetId = form.budgetId;
|
|
252
|
+ addBudgetCar(car);
|
|
253
|
+ }
|
|
254
|
+ for (let device of form.chooseDevice) {
|
|
255
|
+ device.budgetId = form.budgetId;
|
|
256
|
+ addBudgetDevice(device);
|
|
257
|
+ }
|
|
258
|
+ for (let work of form.contentList) {
|
|
259
|
+ work.budgetId = form.budgetId;
|
|
260
|
+ addBudgetSettle(work).then(res => {
|
|
261
|
+ this.$message.success("预算添加成功");
|
|
262
|
+ });
|
|
263
|
+ }
|
|
264
|
+ },
|
|
265
|
+ updateBudgetForm(form) {
|
|
266
|
+ updateBudget(form);
|
|
267
|
+ delBudgetStaff(form.budgetId).then(res => {
|
|
268
|
+ for (let user of form.chooseUser) {
|
|
269
|
+ user.budgetId = form.budgetId;
|
|
270
|
+ addBudgetStaff(user);
|
|
271
|
+ }
|
|
272
|
+ });
|
|
273
|
+ delBudgetCar(form.budgetId).then(res => {
|
|
274
|
+ for (let car of form.chooseCar) {
|
|
275
|
+ car.budgetId = form.budgetId;
|
|
276
|
+ addBudgetCar(car);
|
|
277
|
+ }
|
|
278
|
+ });
|
|
279
|
+ delBudgetDevice(form.budgetId).then(res => {
|
|
280
|
+ for (let device of form.chooseDevice) {
|
|
281
|
+ device.budgetId = form.budgetId;
|
|
282
|
+ addBudgetDevice(device);
|
|
283
|
+ }
|
|
284
|
+ });
|
|
285
|
+ delBudgetSettle(form.budgetId).then(res => {
|
|
286
|
+ for (let work of form.contentList) {
|
|
287
|
+ work.budgetId = form.budgetId;
|
|
288
|
+ addBudgetSettle(work);
|
|
289
|
+ }
|
|
290
|
+ this.$message.success("预算添加成功");
|
|
291
|
+ });
|
|
292
|
+ },
|
|
293
|
+ getChooseUser(val) {
|
|
294
|
+ this.$set(this.budgetForm, "chooseUser", val);
|
|
295
|
+ // 从选择的人员中筛选出外业人员
|
|
296
|
+ this.outerUsers = val.filter(user => user.type === '外业');
|
|
297
|
+ },
|
|
298
|
+ getStaffCost(val) {
|
|
299
|
+ this.$set(this.budgetForm, "staffCost", val);
|
|
300
|
+ },
|
|
301
|
+ getChooseCar(val) {
|
|
302
|
+ this.$set(this.budgetForm, "chooseCar", val);
|
|
303
|
+ },
|
|
304
|
+ getCarCost(val) {
|
|
305
|
+ this.$set(this.budgetForm, "carCost", val);
|
|
306
|
+ },
|
|
307
|
+ getChooseDevice(val) {
|
|
308
|
+ this.$set(this.budgetForm, "chooseDevice", val);
|
|
309
|
+ },
|
|
310
|
+ getExpensesList(val) {
|
|
311
|
+ this.$set(this.budgetForm, "expensesList", val);
|
|
312
|
+ },
|
|
313
|
+ getDeviceCost(val) {
|
|
314
|
+ this.$set(this.budgetForm, "deviceCost", val);
|
|
315
|
+ },
|
|
316
|
+ getContentList(val) {
|
|
317
|
+ this.$set(this.budgetForm, "contentList", val);
|
|
318
|
+ },
|
|
319
|
+ getSettleExpense(val) {
|
|
320
|
+ this.innerSettleLimit = val;
|
|
321
|
+ },
|
|
322
|
+ handleInnerSettleExceeded(data) {
|
|
323
|
+ // this.$message.error(`内业预算绩效总额(${data.current.toFixed(2)})超出限制(${data.limit})`);
|
|
324
|
+ },
|
|
325
|
+ getOtherCost(val) {
|
|
326
|
+ this.$set(this.budgetForm, "outExpense", val.outExpense);
|
|
327
|
+ this.$set(this.budgetForm, "letterExpense", val.letterExpense);
|
|
328
|
+ this.$set(this.budgetForm, "winExpense", val.winExpense);
|
|
329
|
+ this.$set(this.budgetForm, "taxExpense", val.taxExpense);
|
|
330
|
+ this.$set(this.budgetForm, "travelExpense", val.travelExpense);
|
|
331
|
+ },
|
|
332
|
+ getFixCost() {
|
|
333
|
+ const staffCost = this.safeNumber(this.budgetForm.staffCost);
|
|
334
|
+ const carCost = this.safeNumber(this.budgetForm.carCost);
|
|
335
|
+ const deviceCost = this.safeNumber(this.budgetForm.deviceCost);
|
|
336
|
+ const total = staffCost + carCost + deviceCost;
|
|
337
|
+ this.budgetForm.fixCost = total.toFixed(2);
|
|
338
|
+ },
|
|
339
|
+ safeNumber(value) {
|
|
340
|
+ const num = Number(value);
|
|
341
|
+ return isNaN(num) ? 0 : num;
|
|
342
|
+ },
|
|
343
|
+ // 获取直接成本
|
|
344
|
+ getDirectExpense() {
|
|
345
|
+ const settleExpense = this.safeNumber(this.budgetForm.settleExpense);
|
|
346
|
+ const outExpense = this.safeNumber(this.budgetForm.outExpense);
|
|
347
|
+ const letterExpense = this.safeNumber(this.budgetForm.letterExpense);
|
|
348
|
+ const taxExpense = this.safeNumber(this.budgetForm.taxExpense);
|
|
349
|
+ const winExpense = this.safeNumber(this.budgetForm.winExpense);
|
|
350
|
+ const travelExpense = this.safeNumber(this.budgetForm.travelExpense);
|
|
351
|
+ const sum =
|
|
352
|
+ settleExpense +
|
|
353
|
+ outExpense +
|
|
354
|
+ letterExpense +
|
|
355
|
+ taxExpense +
|
|
356
|
+ winExpense +
|
|
357
|
+ travelExpense;
|
|
358
|
+ this.budgetForm.directExpense = sum.toFixed(2);
|
|
359
|
+ },
|
|
360
|
+ getTotalBudget() {
|
|
361
|
+ this.budgetForm.totalBudget = (
|
|
362
|
+ Number(this.budgetForm.fixCost) + Number(this.budgetForm.directExpense)
|
|
363
|
+ ).toFixed(2);
|
|
364
|
+ },
|
|
365
|
+ isReturn(val) {
|
|
366
|
+ this.showAlter = val;
|
|
367
|
+ },
|
|
368
|
+ commentByRole() {
|
|
369
|
+ if (this.taskName == "分管审核") {
|
|
370
|
+ return this.form.managerComment;
|
|
371
|
+ } else if (this.taskName == "总经理审批") {
|
|
372
|
+ return this.form.gmComment;
|
|
373
|
+ }
|
|
374
|
+ },
|
|
375
|
+ getDocumentPath(val) {
|
|
376
|
+ let arr = val.split('/upload')
|
|
377
|
+ this.budgetForm.document = arr[1]
|
|
378
|
+ if (val == "") {
|
|
379
|
+ this.budgetForm.document = ""
|
|
380
|
+ }
|
|
381
|
+ }
|
|
382
|
+ },
|
|
383
|
+};
|
|
384
|
+</script>
|
|
385
|
+
|
|
386
|
+<style lang="scss" scoped>
|
|
387
|
+.mylabel {
|
|
388
|
+ font-weight: bold;
|
|
389
|
+}
|
|
390
|
+</style>
|