瀏覽代碼

修改预算经营审核、部门审核、分管审核

余思翰 3 週之前
父節點
當前提交
adc0a815f0

+ 30
- 28
oa-ui/src/views/flowable/form/budget/addBudget.vue 查看文件

@@ -2,12 +2,13 @@
2 2
  * @Author: ysh
3 3
  * @Date: 2024-06-21 18:51:51
4 4
  * @LastEditors: Please set LastEditors
5
- * @LastEditTime: 2025-05-12 17:25:07
5
+ * @LastEditTime: 2025-05-13 16:51:36
6 6
 -->
7 7
 <template>
8 8
   <div class="app-container">
9 9
     <h2 class="text-center">项目直接生产成本预算表</h2>
10
-    <p style="text-align: center">编制人:{{ $store.getters.name }}</p>
10
+    <p style="text-align: center" v-if="taskName == '预算编制'">编制人:{{ $store.getters.name }}</p>
11
+    <p style="text-align: center" v-else>编制人:{{ budgetForm.compilerUser ? budgetForm.compilerUser.nickName : '' }}</p>
11 12
     <el-divider></el-divider>
12 13
     <div class="mt20 mb20" v-if="showAlter">
13 14
       <el-alert title="任务被退回,请修改后重新提交" type="error" :closable="false">
@@ -122,7 +123,6 @@
122 123
         内业预算绩效总额:{{ isNaN(budgetForm.settleExpense) ? 0 : budgetForm.settleExpense }}
123 124
       </el-tag>
124 125
     </div> -->
125
-    <!-- 统计 -->
126 126
 
127 127
     <div class="mt20 text-center" style="color: #909399; font-size: 12px">
128 128
       tips:预览表单,请先保存之后刷新再查看
@@ -130,14 +130,19 @@
130 130
     <el-divider></el-divider>
131 131
     <div style="text-align: center">
132 132
       <el-button type="warning" @click="preserve()">保存</el-button>
133
+      <el-button type="danger" @click="returnOpen = true">退 回</el-button>
133 134
       <el-button type="success" @click="viewForm()">预览表单</el-button>
134
-      <el-button type="primary" @click="submitNextFlow" v-if="taskName != '预算批准'">提交下一个流程</el-button>
135
+      <el-button type="primary" @click="submitNextFlow" v-if="taskName == '预算批准'">提交下一个流程</el-button>
135 136
       <el-button type="primary" @click="submitNextFlow" v-else>结算批准</el-button>
136 137
     </div>
137 138
     <el-dialog title="表单预览" :visible.sync="viewOpen" width="70%" append-to-body>
138 139
       <!-- <budget-info :taskName="taskName" :taskForm="taskForm" @goBack="$emit('goBack')"></budget-info> -->
139 140
       <new-budget-info :taskName="taskName" :taskForm="taskForm"></new-budget-info>
140 141
     </el-dialog>
142
+    <el-dialog title="退回" :visible.sync="returnOpen" width="40%" append-to-body>
143
+      <return-btn :taskForm="taskForm" :comment="commentByRole()" @goBack="$emit('goBack')" @saves=""
144
+        @cancel="returnOpen = false"></return-btn>
145
+    </el-dialog>
141 146
   </div>
142 147
 </template>
143 148
 
@@ -150,7 +155,7 @@ import { listBudgetStaff, addBudgetStaff, delBudgetStaff } from "@/api/oa/budget
150 155
 import { listBudgetDevice, addBudgetDevice, delBudgetDevice } from "@/api/oa/budget/budgetDevice.js";
151 156
 import { listBudgetSettle, addBudgetSettle, delBudgetSettle } from "@/api/oa/budget/budgetSettle.js";
152 157
 import { listSite, getSite, delSite, addSite, updateSite } from "@/api/oa/budget/budgetSite.js";
153
-import { getUsersDeptLeaderByDept, getUsersManageLeaderByDept } from "@/api/system/post";
158
+import { getUsersDeptLeaderByDept, getUsersManageLeaderByDept, getUsersDeptLeader, getDeptLeadersByDeptId } from "@/api/system/post";
154 159
 import { complete, getNextFlowNode } from "@/api/flowable/todo";
155 160
 import budgetInfo from "./budgetInfo.vue";
156 161
 import ReturnComment from "@/views/flowable/form/components/flowBtn/returnComment.vue";
@@ -245,43 +250,40 @@ export default {
245 250
     },
246 251
     // 保存
247 252
     preserve() {
248
-      console.log(this.budgetForm)
249 253
       if (!this.flag) {
250 254
         this.addBudgetForm(this.budgetForm);
251 255
         this.flag = true;
252 256
       } else {
253 257
         this.updateBudgetForm(this.budgetForm);
254 258
       }
255
-      this.$message.success("保存成功");
259
+      this.$message.success("正在保存......");
256 260
     },
257 261
     viewForm() {
258 262
       this.viewOpen = true;
259 263
     },
260 264
     // 提交下一个流程
261 265
     async submitNextFlow() {
262
-      if (this.taskName == "预算编制") {
263
-        this.preserve();
264
-      }
265
-      const params = { taskId: this.taskForm.taskId };
266
-      const deptIdsStr = this.project.undertakingDept;
267
-      const deptIdsArr = deptIdsStr.split(",").map(Number);
268
-      let approvalList = [];
269
-      for (let deptId of deptIdsArr) {
270
-        let res = await getUsersManageLeaderByDept({ deptId });
271
-        if (res.code == 200 && res.data) {
272
-          res.data.forEach(element => {
273
-            approvalList.push(element.userId);
274
-          });
266
+      this.$modal.confirm('是否提交到下一个流程?').then(async () => {
267
+        if (this.taskName == "预算编制") {
268
+          this.preserve();
269
+          let curUser = this.$store.getters.name;
270
+          let deptLeaderRes = await getUsersDeptLeader(curUser);
271
+          let deptLeader = deptLeaderRes.data.userId;
272
+          this.$set(this.taskForm.variables, 'approval', deptLeader)
273
+        } else if (this.taskName == '部门审核') {
274
+          this.preserve();
275
+          let jyRes = await getUsersDeptLeaderByDept({ deptId: 105 });
276
+          let jyLeader = jyRes.data.userId;
277
+          this.$set(this.taskForm.variables, 'approval', jyLeader)
275 278
         }
276
-      }
277
-      this.$set(this.taskForm.variables, "approvalList", approvalList); //得到各部门的分管领导列表
278
-      // 提交到下一个流程
279
-      getNextFlowNode(params).then(res => {
280
-        complete(this.taskForm).then(response => {
281
-          this.$modal.msgSuccess(response.msg);
282
-          this.$emit("goBack");
279
+        // 提交到下一个流程
280
+        getNextFlowNode({ taskId: this.taskForm.taskId }).then(res => {
281
+          complete(this.taskForm).then(response => {
282
+            this.$modal.msgSuccess(response.msg);
283
+            this.$emit("goBack");
284
+          });
283 285
         });
284
-      });
286
+      })
285 287
     },
286 288
     async addBudgetForm(form) {
287 289
       await addBudget(form);

+ 438
- 62
oa-ui/src/views/flowable/form/budget/adjust/newBudgetInfo.vue 查看文件

@@ -2,11 +2,11 @@
2 2
  * @Author: ysh
3 3
  * @Date: 2025-05-07 11:01:39
4 4
  * @LastEditors: Please set LastEditors
5
- * @LastEditTime: 2025-05-12 17:51:37
5
+ * @LastEditTime: 2025-05-13 18:05:08
6 6
 -->
7 7
 <template>
8
-  <div class="main">
9
-    <h2 class="text-center">项目直接生产成本预算—核算表</h2>
8
+  <div class="main" v-loading="loading">
9
+    <h2 class="text-center">项目直接生产成本预算表</h2>
10 10
     <p style="text-align: center">编制人:{{ budgetForm.compilerUser ? budgetForm.compilerUser.nickName : '' }}</p>
11 11
     <el-divider></el-divider>
12 12
     <el-descriptions :column="3" border class="descriptions">
@@ -55,7 +55,7 @@
55 55
               <td>
56 56
                 {{ work.deadline }}
57 57
               </td>
58
-              <td>
58
+              <td class="remark-cell">
59 59
                 {{ work.remark }}
60 60
               </td>
61 61
             </tr>
@@ -81,16 +81,24 @@
81 81
             <td>
82 82
               {{ work.scaleGrade }}
83 83
             </td>
84
-            <td>
84
+            <td v-if="taskName == '分管审核'">
85
+              <el-input-number style="width:80px;" :controls="false" v-model="work.workload" :min="0" :step="0.01"
86
+                @change="(val) => updateSettle(work, val, 'workload')"></el-input-number>
87
+            </td>
88
+            <td v-else>
85 89
               {{ work.workload }}
86 90
             </td>
87 91
             <td>{{ work.price }}</td>
88 92
             <td>{{ work.unit }}</td>
89
-            <td>
93
+            <td v-if="taskName == '分管审核'">
94
+              <el-input-number style="width:80px;" :controls="false" v-model="work.coefficient" :min="0" :step="0.01"
95
+                @change="(val) => updateSettle(work, val, 'coefficient')"></el-input-number>
96
+            </td>
97
+            <td v-else>
90 98
               {{ work.coefficient }}
91 99
             </td>
92 100
             <td style="text-align:right;">{{ work.settle ? work.settle.toFixed(2) : '0.00' }}</td>
93
-            <td>{{ work.remark ? work.remark : '' }}</td>
101
+            <td class="remark-cell">{{ work.remark ? work.remark : '' }}</td>
94 102
           </tr>
95 103
           <tr>
96 104
             <td :colspan="7" class="head amount">内业绩效额合计</td>
@@ -111,20 +119,37 @@
111 119
             <td>固定成本合计</td>
112 120
             <td>绩效成本合计</td>
113 121
             <td style="width:120px">金额</td>
122
+            <td style="width:120px">备注</td>
114 123
           </tr>
115 124
           <tr v-for="staff, index in innerStaffList" :key="'user' + staff.userId">
116 125
             <td>{{ index + 1 }}</td>
117 126
             <td>{{ staff.user ? staff.user.nickName : '' }}</td>
118 127
             <td>{{ staff.dayCost }}</td>
119
-            <td>{{ staff.days }}</td>
120
-            <td>{{ (Number(staff.dayCost) * Number(staff.days)).toFixed(2) }}</td>
121
-            <td>{{ staff.performance }}</td>
122
-            <td>{{ staff.amount }}</td>
123
-          </tr>
128
+            <td v-if="taskName == '分管审核'">
129
+              <el-input-number style="width:80px;" :controls="false" v-model="staff.days" :min="0"
130
+                :step="0.01" @change="(val) => updateInnerStaffAmount(staff, val, 'days')"></el-input-number>
131
+            </td>
132
+            <td v-else>{{ staff.days }}</td>
133
+            <td style="text-align:right;">{{ staff.staffCost }}</td>
134
+            <td v-if="taskName == '分管审核'">
135
+              <el-input-number style="width:80px;" :controls="false" v-model="staff.performance" :min="0"
136
+                :step="0.01" @change="(val) => updateInnerStaffAmount(staff, val, 'performance')"></el-input-number>
137
+            </td>
138
+            <td v-else style="text-align:right;">{{ staff.performance }}</td>
139
+            <td style="text-align:right;">{{ staff.amount }}</td>
140
+            <td class="remark-cell">{{ staff.remark }}</td>
141
+          </tr> 
124 142
           <tr>
125
-            <td colspan="5" class="head amount">内业人员成本合计</td>
126
-            <td class="head amount">{{ innerStaffList.reduce((sum, staff) => sum + (Number(staff.performance) || 0), 0).toFixed(2) }}</td>
127
-            <td class="head amount">{{ innerStaffList.reduce((sum, staff) => sum + (Number(staff.amount) || 0), 0).toFixed(2) }}</td>
143
+            <td colspan="4" class="head amount">内业人员成本合计</td>
144
+            <td class="head amount" style="text-align:right;">{{innerStaffList.reduce((sum, staff) => sum +
145
+              (Number(staff.staffCost) || 0),
146
+              0).toFixed(2)}}</td>
147
+            <td class="head amount" style="text-align:right;">{{innerStaffList.reduce((sum, staff) => sum +
148
+              (Number(staff.performance) || 0),
149
+              0).toFixed(2)}}</td>
150
+            <td class="head amount" style="text-align:right;">{{innerStaffList.reduce((sum, staff) => sum +
151
+              (Number(staff.amount) || 0),
152
+              0).toFixed(2)}}</td>
128 153
           </tr>
129 154
         </table>
130 155
       </el-descriptions-item>
@@ -140,21 +165,39 @@
140 165
             <td>固定成本合计</td>
141 166
             <td>绩效成本合计</td>
142 167
             <td style="width:120px">金额</td>
168
+            <td style="width:120px">备注</td>
143 169
           </tr>
144 170
           <tr v-for="staff, index in outerStaffList" :key="'user' + staff.userId">
145 171
             <td>{{ index + 1 }}</td>
146 172
             <td>{{ staff.user ? staff.user.nickName : '' }}</td>
147 173
             <td>{{ staff.dayCost }}</td>
148 174
             <td>200</td>
149
-            <td>{{ staff.days }}</td>
150
-            <td>{{ staff.coefficient }}</td>
151
-            <td>{{ (Number(staff.dayCost) * Number(staff.days)).toFixed(2) }}</td>
152
-            <td>{{ staff.performance }}</td>
153
-            <td>{{ staff.amount }}</td>
175
+            <td v-if="taskName == '分管审核'">
176
+              <el-input-number style="width:80px;" :controls="false" v-model="staff.days" :min="0"
177
+                :step="0.01" @change="(val) => updateOuterStaffAmount(staff, val, 'days')"></el-input-number>
178
+            </td>
179
+            <td v-else>{{ staff.days }}</td>
180
+            <td v-if="taskName == '分管审核'">
181
+              <el-input-number style="width:80px;" :controls="false" v-model="staff.coefficient" :min="0"
182
+                :step="0.01" @change="(val) => updateOuterStaffAmount(staff, val, 'coefficient')"></el-input-number>
183
+            </td>
184
+            <td v-else>{{ staff.coefficient }}</td>
185
+            <td style="text-align:right;">{{ staff.staffCost }}</td>
186
+            <td style="text-align:right;">{{ staff.performance }}</td>
187
+            <td style="text-align:right;">{{ staff.amount }}</td>
188
+            <td class="remark-cell">{{ staff.remark }}</td>
154 189
           </tr>
155 190
           <tr>
156
-            <td colspan="8" class="head amount">外业人员成本合计</td>
157
-            <td class="head amount">{{ outerStaffList.reduce((sum, staff) => sum + (Number(staff.amount) || 0), 0).toFixed(2) }}</td>
191
+            <td colspan="6" class="head amount">外业人员成本合计</td>
192
+            <td class="head amount" style="text-align:right;">{{outerStaffList.reduce((sum, staff) => sum +
193
+              (Number(staff.staffCost) || 0),
194
+              0).toFixed(2)}}</td>
195
+            <td class="head amount" style="text-align:right;">{{outerStaffList.reduce((sum, staff) => sum +
196
+              (Number(staff.performance) || 0),
197
+              0).toFixed(2)}}</td>
198
+            <td class="head amount" style="text-align:right;">{{outerStaffList.reduce((sum, staff) => sum +
199
+              (Number(staff.amount) || 0),
200
+              0).toFixed(2)}}</td>
158 201
           </tr>
159 202
         </table>
160 203
       </el-descriptions-item>
@@ -171,12 +214,18 @@
171 214
             <td>{{ index + 1 }}</td>
172 215
             <td>{{ car.car ? car.car.licensePlate : '' }}</td>
173 216
             <td>{{ car.car ? car.car.dayCost : '' }}</td>
174
-            <td>{{ car.days }}</td>
175
-            <td>{{ car.amount }}</td>
217
+            <td v-if="taskName == '分管审核'">
218
+              <el-input-number style="width:80px;" :controls="false" v-model="car.days" :min="0"
219
+                :step="0.01" @change="(val) => updateCarAmount(car, val)"></el-input-number>
220
+            </td>
221
+            <td v-else>{{ car.days }}</td>
222
+            <td style="text-align:right;">{{ car.amount }}</td>
176 223
           </tr>
177 224
           <tr>
178 225
             <td colspan="4" class="head amount">车辆成本合计</td>
179
-            <td class="head amount">{{ carList.reduce((sum, car) => sum + (Number(car.amount) || 0), 0).toFixed(2) }}</td>
226
+            <td class="head amount" style="text-align:right;">{{carList.reduce((sum, car) => sum + (Number(car.amount)
227
+              || 0), 0).toFixed(2)}}
228
+            </td>
180 229
           </tr>
181 230
         </table>
182 231
       </el-descriptions-item>
@@ -197,12 +246,18 @@
197 246
             <td>{{ device.device ? device.device.series : '' }}</td>
198 247
             <td>{{ device.device ? device.device.brand : '' }}</td>
199 248
             <td>{{ device.device ? device.device.dayCost : '' }}</td>
200
-            <td>{{ device.days }}</td>
201
-            <td>{{ device.amount }}</td>
249
+            <td v-if="taskName == '分管审核'">
250
+              <el-input-number style="width:80px;" :controls="false" v-model="device.days" :min="0"
251
+                :step="0.01" @change="(val) => updateDeviceAmount(device, val)"></el-input-number>
252
+            </td>
253
+            <td v-else>{{ device.days }}</td>
254
+            <td style="text-align:right;">{{ device.amount }}</td>
202 255
           </tr>
203 256
           <tr>
204 257
             <td colspan="6" class="head amount">设备成本合计</td>
205
-            <td class="head amount">{{ deviceList.reduce((sum, device) => sum + (Number(device.amount) || 0), 0).toFixed(2) }}</td>
258
+            <td class="head amount" style="text-align:right;">{{deviceList.reduce((sum, device) => sum +
259
+              (Number(device.amount) || 0),
260
+              0).toFixed(2)}}</td>
206 261
           </tr>
207 262
         </table>
208 263
       </el-descriptions-item>
@@ -217,20 +272,160 @@
217 272
           <tr v-for="site, index in siteList" :key="'site' + site.expenseId">
218 273
             <td>{{ index + 1 }}</td>
219 274
             <td>{{ site.name }}</td>
220
-            <td>{{ site.amount }}</td>
221
-            <td>{{ site.remark }}</td>
275
+            <td style="text-align:right;">{{ site.amount }}</td>
276
+            <td class="remark-cell">{{ site.remark }}</td>
222 277
           </tr>
223 278
           <tr>
224 279
             <td colspan="2" class="head amount">现场开支合计</td>
225
-            <td class="head amount">{{ siteList.reduce((sum, site) => sum + (Number(site.amount) || 0), 0).toFixed(2) }}</td>
280
+            <td class="head amount" style="text-align:right;">{{siteList.reduce((sum, site) => sum +
281
+              (Number(site.amount) || 0), 0).toFixed(2)}}
282
+            </td>
226 283
             <td></td>
227 284
           </tr>
228 285
         </table>
229 286
       </el-descriptions-item>
230 287
       <el-descriptions-item label="经营相关" :span="3">
231
-
288
+        <div v-if="taskName == '经营审核'" class="alert alert-warning"
289
+          style="padding: 10px; border: 1px solid #f0ad4e; background-color: #fcf8e3; color: #8a6d3b;">
290
+          请填写以下内容
291
+        </div>
292
+        <table border="1" style="width:100%;" :class="{ 'business-section': taskName == '经营审核' }">
293
+          <tr style="background-color:#f8f8f9">
294
+            <td>序号</td>
295
+            <td>名称</td>
296
+            <td>金额</td>
297
+            <td>备注</td>
298
+          </tr>
299
+          <tr>
300
+            <td>{{ 1 }}</td>
301
+            <td>外协费用</td>
302
+            <td v-if="taskName == '经营审核'">
303
+              <el-input-number style="width:100%;" :controls="false" v-model="budgetForm.outExpense" :min="0"
304
+                :step="0.01" @change="updateTotalJYAmount"></el-input-number>
305
+            </td>
306
+            <td v-else style="text-align:right;">{{ budgetForm.outExpense }}</td>
307
+            <td class="remark-cell">{{ budgetForm.outRemark }}</td>
308
+          </tr>
309
+          <tr>
310
+            <td>{{ 2 }}</td>
311
+            <td>保函费用</td>
312
+            <td v-if="taskName == '经营审核'">
313
+              <el-input-number style="width:100%;" :controls="false" v-model="budgetForm.letterExpense" :min="0"
314
+                :step="0.01" @change="updateTotalJYAmount"></el-input-number>
315
+            </td>
316
+            <td v-else style="text-align:right;">{{ budgetForm.letterExpense }}</td>
317
+            <td class="remark-cell">{{ budgetForm.letterRemark }}</td>
318
+          </tr>
319
+          <tr>
320
+            <td>{{ 3 }}</td>
321
+            <td>中标服务费</td>
322
+            <td v-if="taskName == '经营审核'">
323
+              <el-input-number style="width:100%;" :controls="false" v-model="budgetForm.winExpense" :min="0"
324
+                :step="0.01" @change="updateTotalJYAmount"></el-input-number>
325
+            </td>
326
+            <td v-else style="text-align:right;">{{ budgetForm.winExpense }}</td>
327
+            <td class="remark-cell">{{ budgetForm.winRemark }}</td>
328
+          </tr>
329
+          <tr>
330
+            <td>{{ 4 }}</td>
331
+            <td>税费</td>
332
+            <td v-if="taskName == '经营审核'">
333
+              <el-input-number style="width:100%;" :controls="false" v-model="budgetForm.taxExpense" :min="0"
334
+                :step="0.01" @change="updateTotalJYAmount"></el-input-number>
335
+            </td>
336
+            <td v-else style="text-align:right;">{{ budgetForm.taxExpense }}</td>
337
+            <td class="remark-cell">{{ budgetForm.taxRemark }}</td>
338
+          </tr>
339
+          <tr>
340
+            <td>{{ 5 }}</td>
341
+            <td>管理出差</td>
342
+            <td v-if="taskName == '经营审核'">
343
+              <el-input-number style="width:100%;" :controls="false" v-model="budgetForm.travelExpense" :min="0"
344
+                :step="0.01" @change="updateTotalJYAmount"></el-input-number>
345
+            </td>
346
+            <td v-else style="text-align:right;">{{ budgetForm.travelExpense }}</td>
347
+            <td class="remark-cell">{{ budgetForm.travelRemark }}</td>
348
+          </tr>
349
+          <tr>
350
+            <td colspan="2" class="head amount">经营相关合计</td>
351
+            <td class="head amount" style="text-align:right;">{{ totalJYAmount.toFixed(2) }}
352
+            </td>
353
+            <td></td>
354
+          </tr>
355
+        </table>
356
+      </el-descriptions-item>
357
+      <el-descriptions-item label="预算总额" :span="3">
358
+        <table border="1" style="width:100%;" class="budget-summary">
359
+          <tr class="header">
360
+            <td><b>名称</b></td>
361
+            <td><b>金额</b></td>
362
+          </tr>
363
+          <tr>
364
+            <td>人员成本</td>
365
+            <td style="text-align:right;">{{ isNaN(budgetForm.staffCost) ? 0 : Number(budgetForm.staffCost).toFixed(2) }}</td>
366
+          </tr>
367
+          <tr>
368
+            <td>车辆成本</td>
369
+            <td style="text-align:right;">{{ isNaN(budgetForm.carCost) ? 0 : Number(budgetForm.carCost).toFixed(2) }}</td>
370
+          </tr>
371
+          <tr>
372
+            <td>设备成本</td>
373
+            <td style="text-align:right;">{{ isNaN(budgetForm.deviceCost) ? 0 : Number(budgetForm.deviceCost).toFixed(2) }}</td>
374
+          </tr>
375
+          <tr>
376
+            <td>现场开支成本</td>
377
+            <td style="text-align:right;">{{ isNaN(budgetForm.siteSum) ? 0 : Number(budgetForm.siteSum).toFixed(2) }}</td>
378
+          </tr> 
379
+          <tr>
380
+            <td>经营相关成本</td>
381
+            <td style="text-align:right;">{{ isNaN(totalJYAmount) ? 0 : Number(totalJYAmount).toFixed(2) }}</td>
382
+          </tr>
383
+          <tr class="total-budget">
384
+            <td><b>预算总成本</b></td>
385
+            <td style="text-align:right;"><b>{{ isNaN(budgetForm.totalBudget) ? 0 : budgetForm.totalBudget }}</b></td>
386
+          </tr>
387
+        </table>
388
+      </el-descriptions-item>
389
+      <el-descriptions-item label="分管领导审核意见" :span="3">
390
+        <div v-if="taskName == '分管审核' && !budgetForm.managerComment" class="alert alert-warning"
391
+          style="padding: 10px; border: 1px solid #f0ad4e; background-color: #fcf8e3; color: #8a6d3b;">
392
+          请填写以下内容
393
+        </div>
394
+        <div :class="{ 'business-section': taskName == '分管审核' && !budgetForm.managerComment }">
395
+          <el-input :disabled="taskName != '分管审核'" type="textarea" placeholder="请输入审核意见"
396
+            v-model="budgetForm.managerComment" :autosize="{ minRows: 4 }"></el-input>
397
+          <div class="sign mt10" v-if="budgetForm.manager">
398
+            <div class="mr20">签名:<span class="auditor">{{ getUserName(budgetForm.manager) }}</span>
399
+            </div>
400
+            <div class="ml20"><span>审核时间:{{ budgetForm.managerTime }}</span></div>
401
+          </div>
402
+        </div>
403
+      </el-descriptions-item>
404
+      <el-descriptions-item label="总经理审核意见" :span="3">
405
+        <div v-if="taskName == '总经理审核'" class="alert alert-warning"
406
+          style="padding: 10px; border: 1px solid #f0ad4e; background-color: #fcf8e3; color: #8a6d3b;">
407
+          请填写以下内容
408
+        </div>
409
+        <div :class="{ 'business-section': taskName == '总经理审核' }">
410
+          <el-input :disabled="taskName != '总经理审核'" type="textarea" placeholder="请输入审核意见"
411
+            v-model="budgetForm.zjlComment" :autosize="{ minRows: 4 }"></el-input>
412
+          <div class="sign mt10" v-if="budgetForm.auditor">
413
+            <div class="mr20">签名:<span class="auditor">{{ getUserName(budgetForm.auditor) }}</span>
414
+            </div>
415
+            <div class="ml20"><span>审核时间:{{ budgetForm.zjlTime }}</span></div>
416
+          </div>
417
+        </div>
232 418
       </el-descriptions-item>
233 419
     </el-descriptions>
420
+    <div class="text-center mt20 mb20">
421
+      <el-button type="danger" @click="returnOpen = true">退 回</el-button>
422
+      <el-button type="warning" @click="preserve()">保 存</el-button>
423
+      <el-button type="success" @click="confirmSucess()">提交下一个流程</el-button>
424
+    </div>
425
+    <el-dialog title="退回" :visible.sync="returnOpen" width="40%" append-to-body>
426
+      <return-btn :taskForm="taskForm" :comment="commentByRole()" @goBack="$emit('goBack')"
427
+        @cancel="returnOpen = false"></return-btn>
428
+    </el-dialog>
234 429
   </div>
235 430
 </template>
236 431
 
@@ -243,17 +438,23 @@ import { listBudgetStaff } from "@/api/oa/budget/budgetStaff";
243 438
 import { listProjectWork } from "@/api/oa/project/projectWork";
244 439
 import { listSite } from "@/api/oa/budget/budgetSite.js";
245 440
 import { getProject } from "@/api/oa/project/project";
441
+import { getUsersManageLeader, getUserByPost } from "@/api/system/post";
442
+import { complete, getNextFlowNode } from "@/api/flowable/todo";
246 443
 import InnerStaffCost from './components/InnerStaffCost.vue';
247 444
 import OuterStaffCost from './components/OuterStaffCost.vue';
248 445
 import CarCost from './components/CarCost.vue';
249 446
 import DeviceCost from './components/DeviceCost.vue';
447
+import ReturnComment from '@/views/flowable/form/components/flowBtn/returnComment.vue';
448
+import ReturnBtn from '@/views/flowable/form/components/flowBtn/returnBtn.vue';
250 449
 
251 450
 export default {
252 451
   components: {
253 452
     InnerStaffCost,
254 453
     OuterStaffCost,
255 454
     CarCost,
256
-    DeviceCost
455
+    DeviceCost,
456
+    ReturnComment,
457
+    ReturnBtn
257 458
   },
258 459
   props: {
259 460
     taskForm: {
@@ -276,6 +477,8 @@ export default {
276 477
       carList: [],
277 478
       deviceList: [],
278 479
       siteList: [],
480
+      totalJYAmount: 0,
481
+      returnOpen: false,
279 482
     }
280 483
   },
281 484
   created() {
@@ -288,22 +491,63 @@ export default {
288 491
       listBudget({ pageNum: 1, pageSize: 20, projectId: this.taskForm.formId }).then(async res => {
289 492
         this.budgetForm = res.rows[0];
290 493
         if (this.budgetForm) {
494
+          this.budgetForm.outExpense = Number(this.budgetForm.outExpense).toFixed(2);
495
+          this.budgetForm.letterExpense = Number(this.budgetForm.letterExpense).toFixed(2);
496
+          this.budgetForm.winExpense = Number(this.budgetForm.winExpense).toFixed(2);
497
+          this.budgetForm.taxExpense = Number(this.budgetForm.taxExpense).toFixed(2);
498
+          this.budgetForm.travelExpense = Number(this.budgetForm.travelExpense).toFixed(2);
499
+          this.budgetForm.totalBudget = Number(this.budgetForm.totalBudget).toFixed(2);
500
+          this.totalJYAmount = Number(this.budgetForm.outExpense || 0) +
501
+            Number(this.budgetForm.letterExpense || 0) +
502
+            Number(this.budgetForm.winExpense || 0) +
503
+            Number(this.budgetForm.taxExpense || 0) +
504
+            Number(this.budgetForm.travelExpense || 0);
291 505
           const budgetId = this.budgetForm.budgetId;
292 506
           // 获取设备数据
293 507
           let deviceRes = await listBudgetDevice({ pageSize: 100, budgetId });
294 508
           this.deviceList = deviceRes.rows;
509
+          this.deviceList = this.deviceList.map(device => {
510
+            return {
511
+              ...device,
512
+              amount: Number(device.amount).toFixed(2),
513
+            };
514
+          });
295 515
 
296 516
           // 获取车辆数据
297 517
           let carRes = await listBudgetCar({ pageSize: 100, budgetId });
298 518
           this.carList = carRes.rows;
519
+          this.carList = this.carList.map(car => {
520
+            return {
521
+              ...car,
522
+              amount: Number(car.amount).toFixed(2),
523
+            };
524
+          });
299 525
 
300 526
           // 获取内业人员数据
301 527
           let innerStaffRes = await listBudgetStaff({ pageSize: 100, budgetId, type: '内业' });
302 528
           this.innerStaffList = innerStaffRes.rows;
529
+          this.innerStaffList = this.innerStaffList.map(staff => {
530
+            return {
531
+              ...staff,
532
+              dayCost: Number(staff.dayCost).toFixed(2),
533
+              performance: Number(staff.performance).toFixed(2),
534
+              amount: Number(staff.amount).toFixed(2),
535
+              staffCost: Number(staff.staffCost).toFixed(2)
536
+            };
537
+          });
303 538
 
304 539
           // 获取外业人员数据
305 540
           let outerStaffRes = await listBudgetStaff({ pageSize: 100, budgetId, type: '外业' });
306 541
           this.outerStaffList = outerStaffRes.rows;
542
+          this.outerStaffList = this.outerStaffList.map(staff => {
543
+            return {
544
+              ...staff,
545
+              dayCost: Number(staff.dayCost).toFixed(2),
546
+              performance: Number(staff.performance).toFixed(2),
547
+              amount: Number(staff.amount).toFixed(2),
548
+              staffCost: Number(staff.staffCost).toFixed(2)
549
+            };
550
+          });
307 551
 
308 552
           // 获取内业绩效额数据
309 553
           let settleRes = await listBudgetSettle({ pageSize: 100, budgetId });
@@ -322,12 +566,17 @@ export default {
322 566
           // 获取现场开支
323 567
           let siteRes = await listSite({ pageSize: 100, budgetId });
324 568
           this.siteList = siteRes.rows;
569
+          this.budgetForm.siteSum = this.siteList.reduce((sum, site) => sum + (Number(site.amount) || 0), 0);
325 570
         }
326 571
         this.loading = false;
327 572
       }).catch(() => {
328 573
         this.loading = false;
329 574
       });
330 575
     },
576
+    safeNumber(value) {
577
+      const num = Number(value);
578
+      return isNaN(num) ? 0 : num;
579
+    },
331 580
     getProjectWorkList() {
332 581
       getProject(this.taskForm.formId).then(res => {
333 582
         this.project = res.data;
@@ -336,38 +585,109 @@ export default {
336 585
         this.workContentList = res.rows;
337 586
       })
338 587
     },
339
-    // 处理内业人员数据变化
340
-    handleInnerStaffChange(newList) {
341
-      this.innerStaffList = newList;
342
-      console.log(newList)
343
-      // 计算内业人员总成本
344
-      const totalAmount = this.innerStaffList.reduce((sum, staff) => {
345
-        return sum + (staff.amountAdjust || 0);
346
-      }, 0);
347
-
348
-      // 更新预算表单中的内业人员成本
349
-      if (this.budgetForm) {
350
-        this.budgetForm.innerStaffAmount = totalAmount;
351
-        // 可以在这里调用API保存数据
352
-        // updateBudget(this.budgetForm);
588
+    async preserve() {
589
+      if (this.taskName == '分管审核') {
590
+        this.budgetForm.manager = this.$store.getters.userId;
591
+        this.budgetForm.managerTime = this.parseTime(new Date(), '{y}-{m}-{d}');
592
+      } else if (this.taskName == '总经理审核') {
593
+        this.budgetForm.auditor = this.$store.getters.userId;
594
+        this.budgetForm.zjlTime = this.parseTime(new Date(), '{y}-{m}-{d}');
353 595
       }
596
+      await updateBudget(this.budgetForm)
597
+      this.$message.success('保存成功');
354 598
     },
355
-
356
-    // 处理外业人员数据变化
357
-    handleOuterStaffChange(newList) {
358
-      this.outerStaffList = newList;
359
-      // 计算外业人员总成本
360
-      const totalAmount = this.outerStaffList.reduce((sum, staff) => {
361
-        return sum + (staff.amountAdjust || 0);
362
-      }, 0);
363
-
364
-      // 更新预算表单中的外业人员成本
365
-      if (this.budgetForm) {
366
-        this.budgetForm.outerStaffAmount = totalAmount;
367
-        // 可以在这里调用API保存数据
368
-        // updateBudget(this.budgetForm);
599
+    confirmSucess() {
600
+      this.preserve();
601
+      this.$modal.confirm('是否提交到下一个流程?').then(async () => {
602
+        if (this.taskName == '经营审核') {
603
+          let managerLeaderRes = await getUsersManageLeader({ userId: this.budgetForm.compiler });
604
+          let managerLeader = managerLeaderRes.data;
605
+          let managerList = managerLeader.map(item => item.userId);
606
+          this.$set(this.taskForm.variables, 'approvalList', managerList);
607
+        }
608
+        else if (this.taskName == '分管审核') {
609
+          if (!this.budgetForm.managerComment) {
610
+            this.$message.error('请填写审核意见')
611
+            return
612
+          }
613
+          let zjlRes = await getUserByPost({ postName: '总经理' });
614
+          let zjlUserId = zjlRes.data.userId;
615
+          this.$set(this.taskForm.variables, 'approval', zjlUserId);
616
+        }
617
+        return
618
+        //提交到下一个流程
619
+        getNextFlowNode({ taskId: this.taskForm.taskId }).then(res => {
620
+          complete(this.taskForm).then(response => {
621
+            this.$modal.msgSuccess(response.msg);
622
+            this.$emit("goBack");
623
+          });
624
+        });
625
+      })
626
+    },
627
+    updateTotalJYAmount() {
628
+      this.totalJYAmount = Number(this.budgetForm.outExpense || 0) +
629
+        Number(this.budgetForm.letterExpense || 0) +
630
+        Number(this.budgetForm.winExpense || 0) +
631
+        Number(this.budgetForm.taxExpense || 0) +
632
+        Number(this.budgetForm.travelExpense || 0);
633
+      // Calculate total budget by adding all components
634
+      const innerStaffTotal = this.innerStaffList.reduce((sum, staff) => sum + (Number(staff.amount) || 0), 0);
635
+      const outerStaffTotal = this.outerStaffList.reduce((sum, staff) => sum + (Number(staff.amount) || 0), 0);
636
+      const carTotal = this.carList.reduce((sum, car) => sum + (Number(car.amount) || 0), 0);
637
+      const deviceTotal = this.deviceList.reduce((sum, device) => sum + (Number(device.amount) || 0), 0);
638
+      const siteTotal = this.siteList.reduce((sum, site) => sum + (Number(site.amount) || 0), 0);
639
+      this.budgetForm.totalBudget = (innerStaffTotal +
640
+        outerStaffTotal +
641
+        carTotal +
642
+        deviceTotal +
643
+        siteTotal +
644
+        this.totalJYAmount).toFixed(2);
645
+    },
646
+    commentByRole() {
647
+      if (this.taskName == '分管审核') {
648
+        return this.budgetForm.managerComment
649
+      } else if (this.taskName == '总经理审核') {
650
+        return this.budgetForm.zjlComment
651
+      } else if (this.taskName == '董事长批准') {
652
+        return this.budgetForm.dszComment
369 653
       }
370 654
     },
655
+    updateSettle(work, value, field) {
656
+      work[field] = value;
657
+      work.settle = (Number(work.workload) * Number(work.price) * Number(work.coefficient)).toFixed(2);
658
+      this.budgetForm.settleExpense = this.workList.reduce((sum, work) => {
659
+        return sum + (Number(work.settle) || 0);
660
+      }, 0);
661
+      this.updateTotalJYAmount();
662
+    },
663
+    updateInnerStaffAmount(staff, value, field) {
664
+      staff[field] = value;
665
+      staff.staffCost = (Number(staff.days) * Number(staff.dayCost)).toFixed(2);
666
+      staff.amount = (Number(staff.staffCost) + Number(staff.performance)).toFixed(2);
667
+      let innerStaffTotal = this.innerStaffList.reduce((sum, staff) => sum + (Number(staff.amount) || 0), 0);
668
+      let outerStaffTotal = this.outerStaffList.reduce((sum, staff) => sum + (Number(staff.amount) || 0), 0);
669
+      this.budgetForm.staffCost = (innerStaffTotal + outerStaffTotal).toFixed(2);
670
+      this.updateTotalJYAmount();
671
+    },
672
+    updateOuterStaffAmount(staff, value, field) {
673
+      staff[field] = value;
674
+      staff.performance = (200 * Number(staff.days) * Number(staff.coefficient)).toFixed(2);
675
+      staff.amount = (Number(staff.staffCost) + Number(staff.performance)).toFixed(2);
676
+      let innerStaffTotal = this.innerStaffList.reduce((sum, staff) => sum + (Number(staff.amount) || 0), 0);
677
+      let outerStaffTotal = this.outerStaffList.reduce((sum, staff) => sum + (Number(staff.amount) || 0), 0);
678
+      this.budgetForm.staffCost = (innerStaffTotal + outerStaffTotal).toFixed(2);
679
+      this.updateTotalJYAmount();
680
+    },
681
+    updateCarAmount(car, value) {
682
+      car.days = value;
683
+      car.amount = (Number(car.car.dayCost) * Number(car.days)).toFixed(2);
684
+      this.updateTotalJYAmount();
685
+    },
686
+    updateDeviceAmount(device, value) {
687
+      device.days = value;
688
+      device.amount = (Number(device.device.dayCost) * Number(device.days)).toFixed(2);
689
+      this.updateTotalJYAmount();
690
+    },
371 691
   },
372 692
 }
373 693
 </script>
@@ -390,7 +710,7 @@ export default {
390 710
 
391 711
 .amount {
392 712
   font-weight: bold;
393
-  font-family:Arial, Helvetica, sans-serif;
713
+  font-family: Arial, Helvetica, sans-serif;
394 714
 }
395 715
 
396 716
 table {
@@ -405,11 +725,26 @@ table {
405 725
   }
406 726
 }
407 727
 
728
+.remark-cell {
729
+  text-align: left;
730
+}
731
+
408 732
 .adjust {
409 733
   color: #F56C6C;
410 734
   width: 120px;
411 735
 }
412 736
 
737
+.total-budget {
738
+  font-size: 1.5em;
739
+  font-weight: bold;
740
+  color: #4CAF50;
741
+  text-align: center;
742
+  padding: 10px;
743
+  border: 2px solid #4CAF50;
744
+  border-radius: 5px;
745
+  background-color: #f0f8f5;
746
+}
747
+
413 748
 ::v-deep .el-descriptions .is-bordered .el-descriptions-item__cell {
414 749
   border: 1px solid #838894;
415 750
 }
@@ -418,4 +753,45 @@ table {
418 753
   color: #434141;
419 754
   background: #eaeaea;
420 755
 }
756
+
757
+.business-section {
758
+  border: 2px solid #E6A23C !important;
759
+  box-shadow: 0 0 10px rgba(64, 158, 255, 0.2);
760
+
761
+  tr {
762
+    background-color: #f0f7ff;
763
+
764
+    &:hover {
765
+      background-color: #e6f1ff;
766
+    }
767
+  }
768
+
769
+  .el-input-number {
770
+    .el-input__inner {
771
+      background-color: #fff;
772
+      border: 1px solid #E6A23C;
773
+
774
+      &:focus {
775
+        border-color: #e2af62;
776
+        box-shadow: 0 0 5px rgba(64, 158, 255, 0.3);
777
+      }
778
+    }
779
+  }
780
+
781
+  .head.amount {
782
+    background-color: #ecf5ff;
783
+    color: #E6A23C;
784
+    font-weight: bold;
785
+  }
786
+}
787
+
788
+
789
+.sign {
790
+  display: flex;
791
+  justify-content: flex-end;
792
+  align-items: center;
793
+  padding-right: 80px;
794
+  line-height: 30px;
795
+  /* 如果需要垂直居中 */
796
+}
421 797
 </style>

+ 9
- 4
oa-ui/src/views/flowable/form/budget/budget.vue 查看文件

@@ -2,18 +2,22 @@
2 2
  * @Author: ysh
3 3
  * @Date: 2024-04-08 16:08:33
4 4
  * @LastEditors: Please set LastEditors
5
- * @LastEditTime: 2024-12-16 09:20:14
5
+ * @LastEditTime: 2025-05-13 16:54:30
6 6
 -->
7 7
 <template>
8 8
   <div>
9
-    <add-budget :taskName="taskName" :taskForm="taskForm" @goBack="goBack" v-if="taskName == '预算编制'"></add-budget>
10
-    <budget-info :taskName="taskName" :taskForm="taskForm" @goBack="goBack" v-if="taskName == '分管审核' || taskName == '总经理审核' || taskName == '预算批准'"></budget-info>
9
+    <add-budget :taskName="taskName" :taskForm="taskForm" @goBack="goBack"
10
+      v-if="taskName == '预算编制' || taskName == '部门审核'"></add-budget>
11
+    <new-budget-info :taskName="taskName" :taskForm="taskForm" @goBack="goBack" v-else></new-budget-info>
12
+    <!-- <budget-info :taskName="taskName" :taskForm="taskForm" @goBack="goBack"
13
+      v-if="taskName == '分管审核' || taskName == '总经理审核' || taskName == '预算批准'"></budget-info> -->
11 14
   </div>
12 15
 </template>
13 16
 
14 17
 <script>
15 18
 import AddBudget from '@/views/flowable/form/budget/addBudget.vue';
16 19
 import BudgetInfo from './budgetInfo.vue';
20
+import NewBudgetInfo from './adjust/newBudgetInfo.vue';
17 21
 export default {
18 22
   props: {
19 23
     taskName: {
@@ -27,7 +31,8 @@ export default {
27 31
   },
28 32
   components: {
29 33
     AddBudget,
30
-    BudgetInfo
34
+    BudgetInfo,
35
+    NewBudgetInfo
31 36
   },
32 37
   methods: {
33 38
     goBack() {

+ 2
- 0
oa-ui/src/views/flowable/form/budget/deviceTable.vue 查看文件

@@ -117,10 +117,12 @@ export default {
117 117
     getChooseDevice(val) {
118 118
       this.chooseDevice = val;
119 119
       this.openDevice = false;
120
+      this.chooseDevice.depreciation = val.device.dayCost;
120 121
       this.recalculateCost(val, 'amount', 'deviceCost');
121 122
     },
122 123
     calculateDeviceTotal(device) {
123 124
       let total = Number(device.depreciation) * Number(device.days);
125
+      total = isNaN(total) ? 0 : total
124 126
       this.$set(device, "amount", total.toFixed(2));
125 127
       this.getCost("amount", "deviceCost", this.chooseDevice);
126 128
     },

+ 4
- 4
oa-ui/src/views/flowable/form/budget/otherTable.vue 查看文件

@@ -2,7 +2,7 @@
2 2
  * @Author: ysh
3 3
  * @Date: 2024-12-11 17:21:00
4 4
  * @LastEditors: Please set LastEditors
5
- * @LastEditTime: 2025-05-12 16:16:45
5
+ * @LastEditTime: 2025-05-13 10:07:18
6 6
 -->
7 7
 <template>
8 8
   <div>
@@ -31,7 +31,7 @@
31 31
                 @blur="computedDirectExpense()"></el-input-number>
32 32
             </td>
33 33
             <td>
34
-              <el-input type="textarea" v-model="form.rentRemark"></el-input>
34
+              <el-input type="textarea" v-model="form.letterRemark"></el-input>
35 35
             </td>
36 36
           </tr>
37 37
           <tr>
@@ -41,7 +41,7 @@
41 41
                 @blur="computedDirectExpense()"></el-input-number>
42 42
             </td>
43 43
             <td>
44
-              <el-input type="textarea" v-model="form.otherRemark"></el-input>
44
+              <el-input type="textarea" v-model="form.winRemark"></el-input>
45 45
             </td>
46 46
           </tr>
47 47
           <tr>
@@ -61,7 +61,7 @@
61 61
                 @blur="computedDirectExpense()"></el-input-number>
62 62
             </td>
63 63
             <td>
64
-              <el-input type="textarea" v-model="form.businessRemark"></el-input>
64
+              <el-input type="textarea" v-model="form.travelRemark"></el-input>
65 65
             </td>
66 66
           </tr>
67 67
           <tr>

+ 4
- 10
oa-ui/src/views/flowable/form/budget/staffTable.vue 查看文件

@@ -311,27 +311,21 @@ export default {
311 311
         user.coefficient = 1; // 默认值改为1
312 312
       }
313 313
       let total = 0;
314
-      if (user.type === '内业') {
315
-        // 内业人员计算方式不变
316
-        // if (user.dayCost) {
317
-        // } else {
318
-        //   user.dayCost = parseFloat(((user.salary.salary + 1780) * 12) / 365).toFixed(2)
319
-        // }
320
-        // total = user.dayCost * Number(user.days) + Number(user.performance);
321
-      } else {
314
+      if (user.type === '外业') {
322 315
         // 外业人员计算方式
323 316
         user.performance = 200 * Number(user.days) * Number(user.coefficient);
324 317
       }
325
-      if (user.dayCost) {
326
-      } else {
318
+      if (!user.dayCost) {
327 319
         user.dayCost = parseFloat(((user.salary.salary + 1780) * 12) / 365).toFixed(2)
328 320
       }
321
+      let staffCost = Number(user.dayCost) * Number(user.days)
329 322
       total = user.dayCost * Number(user.days) + Number(user.performance);
330 323
 
331 324
       if (isNaN(total)) {
332 325
         total = 0
333 326
       }
334 327
       this.$set(user, "amount", total.toFixed(2));
328
+      this.$set(user, "staffCost", staffCost.toFixed(2));
335 329
       this.updateStaffCosts();
336 330
     },
337 331
     openCalculatePerformance(user) {

Loading…
取消
儲存