Browse Source

修改核算,新增预算外开支

余思翰 3 months ago
parent
commit
11e43c832c

+ 2
- 2
oa-back/ruoyi-admin/src/main/java/com/ruoyi/web/controller/oa/CmcBudgetOtherController.java View File

90
      */
90
      */
91
     @Log(title = "cmc预算外开支", businessType = BusinessType.DELETE)
91
     @Log(title = "cmc预算外开支", businessType = BusinessType.DELETE)
92
 	@DeleteMapping("/{expenseIds}")
92
 	@DeleteMapping("/{expenseIds}")
93
-    public AjaxResult remove(@PathVariable Long[] expenseIds)
93
+    public AjaxResult remove(@PathVariable String[] budgetId)
94
     {
94
     {
95
-        return success(cmcBudgetOtherService.deleteCmcBudgetOtherByExpenseIds(expenseIds));
95
+        return success(cmcBudgetOtherService.deleteCmcBudgetOtherByExpenseIds(budgetId));
96
     }
96
     }
97
 }
97
 }

+ 2
- 2
oa-back/ruoyi-system/src/main/java/com/ruoyi/oa/mapper/CmcBudgetOtherMapper.java View File

54
     /**
54
     /**
55
      * 批量删除cmc预算外开支
55
      * 批量删除cmc预算外开支
56
      * 
56
      * 
57
-     * @param expenseIds 需要删除的数据主键集合
57
+     * @param budgetId 需要删除的数据主键集合
58
      * @return 结果
58
      * @return 结果
59
      */
59
      */
60
-    public int deleteCmcBudgetOtherByExpenseIds(Long[] expenseIds);
60
+    public int deleteCmcBudgetOtherByExpenseIds(String[] budgetId);
61
 }
61
 }

+ 2
- 2
oa-back/ruoyi-system/src/main/java/com/ruoyi/oa/service/ICmcBudgetOtherService.java View File

46
     /**
46
     /**
47
      * 批量删除cmc预算外开支
47
      * 批量删除cmc预算外开支
48
      * 
48
      * 
49
-     * @param expenseIds 需要删除的cmc预算外开支主键集合
49
+     * @param budgetId 需要删除的cmc预算外开支主键集合
50
      * @return 结果
50
      * @return 结果
51
      */
51
      */
52
-    public int deleteCmcBudgetOtherByExpenseIds(Long[] expenseIds);
52
+    public int deleteCmcBudgetOtherByExpenseIds(String[] budgetId);
53
 
53
 
54
     /**
54
     /**
55
      * 删除cmc预算外开支信息
55
      * 删除cmc预算外开支信息

+ 3
- 3
oa-back/ruoyi-system/src/main/java/com/ruoyi/oa/service/impl/CmcBudgetOtherServiceImpl.java View File

70
     /**
70
     /**
71
      * 批量删除cmc预算外开支
71
      * 批量删除cmc预算外开支
72
      * 
72
      * 
73
-     * @param expenseIds 需要删除的cmc预算外开支主键
73
+     * @param budgetId 需要删除的cmc预算外开支主键
74
      * @return 结果
74
      * @return 结果
75
      */
75
      */
76
     @Override
76
     @Override
77
-    public int deleteCmcBudgetOtherByExpenseIds(Long[] expenseIds)
77
+    public int deleteCmcBudgetOtherByExpenseIds(String[] budgetId)
78
     {
78
     {
79
-        return cmcBudgetOtherMapper.deleteCmcBudgetOtherByExpenseIds(expenseIds);
79
+        return cmcBudgetOtherMapper.deleteCmcBudgetOtherByExpenseIds(budgetId);
80
     }
80
     }
81
 
81
 
82
     /**
82
     /**

+ 3
- 3
oa-back/ruoyi-system/src/main/resources/mapper/oa/CmcBudgetOtherMapper.xml View File

62
     </delete>
62
     </delete>
63
 
63
 
64
     <delete id="deleteCmcBudgetOtherByExpenseIds" parameterType="String">
64
     <delete id="deleteCmcBudgetOtherByExpenseIds" parameterType="String">
65
-        delete from cmc_budget_other where expense_id in 
66
-        <foreach item="expenseId" collection="array" open="(" separator="," close=")">
67
-            #{expenseId}
65
+        delete from cmc_budget_other where budget_id in 
66
+        <foreach item="budgetId" collection="array" open="(" separator="," close=")">
67
+            #{budgetId}
68
         </foreach>
68
         </foreach>
69
     </delete>
69
     </delete>
70
 </mapper>
70
 </mapper>

+ 50
- 0
oa-ui/src/api/oa/budget/budgetOther.js View File

1
+/*
2
+ * @Author: ysh
3
+ * @Date: 2025-05-16 10:38:45
4
+ * @LastEditors: 
5
+ * @LastEditTime: 2025-05-16 10:39:10
6
+ */
7
+import request from '@/utils/request'
8
+
9
+// 查询cmc预算外开支列表
10
+export function listOther(query) {
11
+  return request({
12
+    url: '/oa/other/list',
13
+    method: 'get',
14
+    params: query
15
+  })
16
+}
17
+
18
+// 查询cmc预算外开支详细
19
+export function getOther(expenseId) {
20
+  return request({
21
+    url: '/oa/other/' + expenseId,
22
+    method: 'get'
23
+  })
24
+}
25
+
26
+// 新增cmc预算外开支
27
+export function addOther(data) {
28
+  return request({
29
+    url: '/oa/other',
30
+    method: 'post',
31
+    data: data
32
+  })
33
+}
34
+
35
+// 修改cmc预算外开支
36
+export function updateOther(data) {
37
+  return request({
38
+    url: '/oa/other',
39
+    method: 'put',
40
+    data: data
41
+  })
42
+}
43
+
44
+// 删除cmc预算外开支
45
+export function delOther(expenseId) {
46
+  return request({
47
+    url: '/oa/other/' + expenseId,
48
+    method: 'delete'
49
+  })
50
+}

+ 3
- 4
oa-ui/src/views/flowable/form/budget/addBudget.vue View File

2
  * @Author: ysh
2
  * @Author: ysh
3
  * @Date: 2024-06-21 18:51:51
3
  * @Date: 2024-06-21 18:51:51
4
  * @LastEditors: Please set LastEditors
4
  * @LastEditors: Please set LastEditors
5
- * @LastEditTime: 2025-05-15 18:12:10
5
+ * @LastEditTime: 2025-05-16 09:43:29
6
 -->
6
 -->
7
 <template>
7
 <template>
8
   <div class="app-container">
8
   <div class="app-container">
130
     <el-divider></el-divider>
130
     <el-divider></el-divider>
131
     <div style="text-align: center">
131
     <div style="text-align: center">
132
       <el-button type="warning" @click="preserve()">保存</el-button>
132
       <el-button type="warning" @click="preserve()">保存</el-button>
133
-      <el-button type="danger" @click="returnOpen = true">退 回</el-button>
133
+      <el-button type="danger" @click="returnOpen = true" v-if="taskName != '预算编制'">退 回</el-button>
134
       <el-button type="success" @click="viewForm()">预览表单</el-button>
134
       <el-button type="success" @click="viewForm()">预览表单</el-button>
135
-      <el-button type="primary" @click="submitNextFlow" v-if="taskName == '预算批准'">提交下一个流程</el-button>
136
-      <el-button type="primary" @click="submitNextFlow" v-else>结算批准</el-button>
135
+      <el-button type="primary" @click="submitNextFlow" v-if="taskName == '预算编制'">提交下一个流程</el-button>
137
     </div>
136
     </div>
138
     <el-dialog title="表单预览" :visible.sync="viewOpen" width="75%" append-to-body>
137
     <el-dialog title="表单预览" :visible.sync="viewOpen" width="75%" append-to-body>
139
       <!-- <budget-info :taskName="taskName" :taskForm="taskForm" @goBack="$emit('goBack')"></budget-info> -->
138
       <!-- <budget-info :taskName="taskName" :taskForm="taskForm" @goBack="$emit('goBack')"></budget-info> -->

+ 46
- 7
oa-ui/src/views/flowable/form/budget/adjust/budgetAdjust.vue View File

2
  * @Author: ysh
2
  * @Author: ysh
3
  * @Date: 2025-05-07 11:01:39
3
  * @Date: 2025-05-07 11:01:39
4
  * @LastEditors: Please set LastEditors
4
  * @LastEditors: Please set LastEditors
5
- * @LastEditTime: 2025-05-15 18:32:55
5
+ * @LastEditTime: 2025-05-16 11:15:36
6
 -->
6
 -->
7
 <template>
7
 <template>
8
   <div class="main" v-loading="loading">
8
   <div class="main" v-loading="loading">
118
         <business-cost :budgetForm.sync="budgetForm" @update:budgetForm="handleBusinessChange"></business-cost>
118
         <business-cost :budgetForm.sync="budgetForm" @update:budgetForm="handleBusinessChange"></business-cost>
119
       </el-descriptions-item>
119
       </el-descriptions-item>
120
       <el-descriptions-item label="预算外开销" :span="3">
120
       <el-descriptions-item label="预算外开销" :span="3">
121
+        <other-cost :otherList.sync="otherList" @update:otherList="handleOtherChange"></other-cost>
122
+      </el-descriptions-item>
123
+      <el-descriptions-item label="分管审核意见" :span="3">
121
 
124
 
122
       </el-descriptions-item>
125
       </el-descriptions-item>
123
     </el-descriptions>
126
     </el-descriptions>
135
 import { listBudgetDevice, updateBudgetDevice, addBudgetDevice, delBudgetDevice } from "@/api/oa/budget/budgetDevice";
138
 import { listBudgetDevice, updateBudgetDevice, addBudgetDevice, delBudgetDevice } from "@/api/oa/budget/budgetDevice";
136
 import { listBudgetSettle, updateBudgetSettle, addBudgetSettle, delBudgetSettle } from "@/api/oa/budget/budgetSettle";
139
 import { listBudgetSettle, updateBudgetSettle, addBudgetSettle, delBudgetSettle } from "@/api/oa/budget/budgetSettle";
137
 import { listBudgetStaff, addBudgetStaff, delBudgetStaff } from "@/api/oa/budget/budgetStaff";
140
 import { listBudgetStaff, addBudgetStaff, delBudgetStaff } from "@/api/oa/budget/budgetStaff";
141
+import { listOther, addOther, updateOther, delOther } from "@/api/oa/budget/budgetOther";
138
 import { listProjectWork } from "@/api/oa/project/projectWork";
142
 import { listProjectWork } from "@/api/oa/project/projectWork";
139
-import { listSite, delSite, addSite } from "@/api/oa/budget/budgetSite";
143
+import { listSite, updateSite, delSite, addSite } from "@/api/oa/budget/budgetSite";
140
 import { getProject } from "@/api/oa/project/project";
144
 import { getProject } from "@/api/oa/project/project";
141
 import InnerStaffCost from './components/InnerStaffCost.vue';
145
 import InnerStaffCost from './components/InnerStaffCost.vue';
142
 import OuterStaffCost from './components/OuterStaffCost.vue';
146
 import OuterStaffCost from './components/OuterStaffCost.vue';
144
 import DeviceCost from './components/DeviceCost.vue';
148
 import DeviceCost from './components/DeviceCost.vue';
145
 import SiteCost from '@/views/flowable/form/budget/adjust/components/SiteCost.vue';
149
 import SiteCost from '@/views/flowable/form/budget/adjust/components/SiteCost.vue';
146
 import BusinessCost from '@/views/flowable/form/budget/adjust/components/businessCost.vue';
150
 import BusinessCost from '@/views/flowable/form/budget/adjust/components/businessCost.vue';
151
+import OtherCost from '@/views/flowable/form/budget/adjust/components/otherCost.vue';
147
 export default {
152
 export default {
148
   components: {
153
   components: {
149
     InnerStaffCost,
154
     InnerStaffCost,
151
     CarCost,
156
     CarCost,
152
     DeviceCost,
157
     DeviceCost,
153
     SiteCost,
158
     SiteCost,
154
-    BusinessCost
159
+    BusinessCost,
160
+    OtherCost
155
   },
161
   },
156
   props: {
162
   props: {
157
     taskForm: {
163
     taskForm: {
176
       outerStaffList: [],
182
       outerStaffList: [],
177
       carList: [],
183
       carList: [],
178
       deviceList: [],
184
       deviceList: [],
179
-      siteList: []
185
+      siteList: [],
186
+      otherList: []
180
     }
187
     }
181
   },
188
   },
182
   created() {
189
   created() {
283
           // 获取现场开支
290
           // 获取现场开支
284
           let siteRes = await listSite({ pageSize: 100, budgetId });
291
           let siteRes = await listSite({ pageSize: 100, budgetId });
285
           this.siteList = siteRes.rows;
292
           this.siteList = siteRes.rows;
293
+
286
           this.siteList = this.siteList.map(site => {
294
           this.siteList = this.siteList.map(site => {
287
             return {
295
             return {
288
               ...site,
296
               ...site,
290
               amountAdjust: site.amountAdjust ? Number(site.amountAdjust).toFixed(2) : 0
298
               amountAdjust: site.amountAdjust ? Number(site.amountAdjust).toFixed(2) : 0
291
             };
299
             };
292
           });
300
           });
301
+
302
+          // 获取预算外开销
303
+          let otherRes = await listOther({ pageSize: 100, budgetId });
304
+          this.otherList = otherRes.rows;
305
+          this.otherList = this.otherList.map(other => {
306
+            return {
307
+              ...other,
308
+              amount: Number(other.amount).toFixed(2),
309
+              amountAdjust: other.amountAdjust ? Number(other.amountAdjust).toFixed(2) : 0
310
+            };
311
+          });
293
         }
312
         }
294
         this.loading = false;
313
         this.loading = false;
295
       }).catch(() => {
314
       }).catch(() => {
307
     // 处理内业人员数据变化
326
     // 处理内业人员数据变化
308
     handleInnerStaffChange(newList) {
327
     handleInnerStaffChange(newList) {
309
       this.innerStaffList = newList;
328
       this.innerStaffList = newList;
310
-      console.log(this.innerStaffList);
311
     },
329
     },
312
 
330
 
313
     // 处理外业人员数据变化
331
     // 处理外业人员数据变化
325
     // 处理现场开支数据变化
343
     // 处理现场开支数据变化
326
     handleSiteChange(newList) {
344
     handleSiteChange(newList) {
327
       this.siteList = newList;
345
       this.siteList = newList;
328
-      console.log(this.siteList);
329
     },
346
     },
330
     // 处理经营相关数据变化
347
     // 处理经营相关数据变化
331
     handleBusinessChange(newData) {
348
     handleBusinessChange(newData) {
332
-
349
+      this.budgetForm.outAdjust = newData.outAdjust;
350
+      this.budgetForm.letterAdjust = newData.letterAdjust;
351
+      this.budgetForm.winAdjust = newData.winAdjust;
352
+      this.budgetForm.taxAdjust = newData.taxAdjust;
353
+      this.budgetForm.travelAdjust = newData.travelAdjust;
354
+    },
355
+    // 处理预算外开销数据变化
356
+    handleOtherChange(newList) {
357
+      this.otherList = newList;
333
     },
358
     },
334
     async preserve() {
359
     async preserve() {
335
       let obj = {
360
       let obj = {
344
       }
369
       }
345
       await updateBudget(this.budgetForm);
370
       await updateBudget(this.budgetForm);
346
       let staffList = this.innerStaffList.concat(this.outerStaffList);
371
       let staffList = this.innerStaffList.concat(this.outerStaffList);
372
+      // 更新人员
347
       delBudgetStaff(this.row.budgetId).then(async res => {
373
       delBudgetStaff(this.row.budgetId).then(async res => {
348
         for (let staff of staffList) {
374
         for (let staff of staffList) {
349
           staff.budgetId = this.row.budgetId;
375
           staff.budgetId = this.row.budgetId;
350
           await addBudgetStaff(staff);
376
           await addBudgetStaff(staff);
351
         }
377
         }
352
       })
378
       })
379
+      // 更新车辆
353
       delBudgetCar(this.row.budgetId).then(async res => {
380
       delBudgetCar(this.row.budgetId).then(async res => {
354
         for (let car of this.carList) {
381
         for (let car of this.carList) {
355
           car.budgetId = this.row.budgetId;
382
           car.budgetId = this.row.budgetId;
356
           await addBudgetCar(car);
383
           await addBudgetCar(car);
357
         }
384
         }
358
       })
385
       })
386
+      // 更新设备
359
       delBudgetDevice(this.row.budgetId).then(async res => {
387
       delBudgetDevice(this.row.budgetId).then(async res => {
360
         for (let device of this.deviceList) {
388
         for (let device of this.deviceList) {
361
           device.budgetId = this.row.budgetId;
389
           device.budgetId = this.row.budgetId;
362
           await addBudgetDevice(device);
390
           await addBudgetDevice(device);
363
         }
391
         }
364
       })
392
       })
393
+      // 更新现场开支
394
+      for (let site of this.siteList) {
395
+        await updateSite(site);
396
+      }
397
+      // 更新预算外开销
398
+      delOther(this.row.budgetId).then(async res => {
399
+        for (let other of this.otherList) {
400
+          other.budgetId = this.row.budgetId;
401
+          await addOther(other);
402
+        }
403
+      })
365
       this.$message.success('保存成功');
404
       this.$message.success('保存成功');
366
     },
405
     },
367
     confirmSucess() {
406
     confirmSucess() {

+ 20
- 10
oa-ui/src/views/flowable/form/budget/adjust/components/DeviceCost.vue View File

27
         <td style="text-align:right;">{{ device.days }}</td>
27
         <td style="text-align:right;">{{ device.days }}</td>
28
         <td style="text-align:right;">{{ device.amount }}</td>
28
         <td style="text-align:right;">{{ device.amount }}</td>
29
         <td style="text-align:right;">
29
         <td style="text-align:right;">
30
-          <el-input-number :controls="false" style="width:100%;" v-model="device.daysAdjust" @change="handleChange(device)"></el-input-number>
30
+          <el-input-number :controls="false" style="width:100%;" v-model="device.daysAdjust"
31
+            @change="handleChange(device)"></el-input-number>
31
         </td>
32
         </td>
32
         <td style="text-align:right;">
33
         <td style="text-align:right;">
33
           {{ device.amountAdjust }}
34
           {{ device.amountAdjust }}
34
         </td>
35
         </td>
35
       </tr>
36
       </tr>
36
-      <!-- <tr>
37
-        <td colspan="4" class="amount">设备成本合计</td>
38
-        <td class="amount" style="text-align:right;">{{deviceList.reduce((sum, device) => sum + (Number(device.device?.dayCost) || 0), 0).toFixed(2)}}</td>
39
-        <td class="amount" style="text-align:right;">{{deviceList.reduce((sum, device) => sum + (Number(device.days) || 0), 0).toFixed(2)}}</td>
40
-        <td class="amount" style="text-align:right;">{{deviceList.reduce((sum, device) => sum + (Number(device.amount) || 0), 0).toFixed(2)}}</td>
41
-        <td class="amount" style="text-align:right;">{{deviceList.reduce((sum, device) => sum + (Number(device.daysAdjust) || 0), 0).toFixed(2)}}</td>
42
-        <td class="amount" style="text-align:right;">{{deviceList.reduce((sum, device) => sum + (Number(device.amountAdjust) || 0), 0).toFixed(2)}}</td>
43
-      </tr> -->
37
+      <tr>
38
+        <td colspan="5" class="amount">设备成本合计</td>
39
+        <td class="amount" style="text-align:right;">{{deviceList.reduce((sum, device) => sum + (Number(device.device ?
40
+          device.device.dayCost : 0) || 0), 0).toFixed(2)}}</td>
41
+        <td class="amount" style="text-align:right;">{{deviceList.reduce((sum, device) => sum + (Number(device.days) ||
42
+          0), 0).toFixed(2)}}</td>
43
+        <td class="amount" style="text-align:right;">{{deviceList.reduce((sum, device) => sum + (Number(device.amount) ||
44
+          0), 0).toFixed(2)}}</td>
45
+        <td class="amount" style="text-align:right;">{{deviceList.reduce((sum, device) => sum +
46
+          (Number(device.daysAdjust) || 0), 0).toFixed(2)}}</td>
47
+        <td class="amount" style="text-align:right;">{{deviceList.reduce((sum, device) => sum +
48
+          (Number(device.amountAdjust) || 0), 0).toFixed(2)}}</td>
49
+      </tr>
44
     </table>
50
     </table>
45
     <div class="mt10">
51
     <div class="mt10">
46
       <el-button type="success" plain icon="el-icon-plus" @click="openDevice" size="mini">新增设备</el-button>
52
       <el-button type="success" plain icon="el-icon-plus" @click="openDevice" size="mini">新增设备</el-button>
123
     text-align: center;
129
     text-align: center;
124
     border-collapse: collapse;
130
     border-collapse: collapse;
125
     margin: 0 auto;
131
     margin: 0 auto;
132
+
126
     td {
133
     td {
127
       padding: 5px;
134
       padding: 5px;
128
     }
135
     }
129
   }
136
   }
137
+
130
   .adjust {
138
   .adjust {
131
     color: #F56C6C;
139
     color: #F56C6C;
132
     width: 120px;
140
     width: 120px;
133
   }
141
   }
142
+
134
   .delete-btn {
143
   .delete-btn {
135
     cursor: pointer;
144
     cursor: pointer;
136
     font-size: 18px;
145
     font-size: 18px;
137
   }
146
   }
147
+
138
   .amount {
148
   .amount {
139
     font-weight: bold;
149
     font-weight: bold;
140
     font-family: Arial, Helvetica, sans-serif;
150
     font-family: Arial, Helvetica, sans-serif;
141
   }
151
   }
142
 }
152
 }
143
-</style> 
153
+</style>

+ 1
- 1
oa-ui/src/views/flowable/form/budget/adjust/components/InnerStaffCost.vue View File

3
     <table border="1" style="width:100%">
3
     <table border="1" style="width:100%">
4
       <tr style="background-color:#f8f8f9">
4
       <tr style="background-color:#f8f8f9">
5
         <td></td>
5
         <td></td>
6
-        <td style="min-width:50px;">序号</td>
6
+        <td style="width:50px;">序号</td>
7
         <td style="min-width:80px;">姓名</td>
7
         <td style="min-width:80px;">姓名</td>
8
         <td style="min-width:80px;">人员成本(天)</td>
8
         <td style="min-width:80px;">人员成本(天)</td>
9
         <td style="min-width:80px;">预算天数</td>
9
         <td style="min-width:80px;">预算天数</td>

+ 12
- 2
oa-ui/src/views/flowable/form/budget/adjust/components/SiteCost.vue View File

1
+<!--
2
+ * @Author: ysh
3
+ * @Date: 2025-05-15 15:30:09
4
+ * @LastEditors: Please set LastEditors
5
+ * @LastEditTime: 2025-05-16 09:59:30
6
+-->
1
 <template>
7
 <template>
2
   <div class="site-cost">
8
   <div class="site-cost">
3
     <table border="1" style="width:100%;">
9
     <table border="1" style="width:100%;">
4
       <tr style="background-color:#f8f8f9">
10
       <tr style="background-color:#f8f8f9">
11
+        <td style="width: 50px;">序号</td>
5
         <td>开支项</td>
12
         <td>开支项</td>
6
         <td>金额</td>
13
         <td>金额</td>
7
         <td class="adjust">核算金额</td>
14
         <td class="adjust">核算金额</td>
15
+        <td>备注</td>
8
       </tr>
16
       </tr>
9
-      <tr v-for="site in siteList" :key="site.id">
17
+      <tr v-for="site, index in siteList" :key="site.id">
18
+        <td>{{ index + 1 }}</td>
10
         <td>{{ site.name }}</td>
19
         <td>{{ site.name }}</td>
11
         <td style="text-align: right;">{{ site.amount }}</td>
20
         <td style="text-align: right;">{{ site.amount }}</td>
12
         <td>
21
         <td>
13
           <el-input-number :controls="false" v-model="site.amountAdjust" placeholder="请输入核算金额"
22
           <el-input-number :controls="false" v-model="site.amountAdjust" placeholder="请输入核算金额"
14
             @change="handleSiteChange(site)" />
23
             @change="handleSiteChange(site)" />
15
         </td>
24
         </td>
25
+        <td style="text-align: left;">{{ site.remark }}</td>
16
       </tr>
26
       </tr>
17
       <tr>
27
       <tr>
18
-        <td class="amount" colspan="1">现场开支合计</td>
28
+        <td class="amount" colspan="2">现场开支合计</td>
19
         <td class="amount" style="text-align: right;">{{siteList.reduce((sum, site) => sum + (Number(site.amount)
29
         <td class="amount" style="text-align: right;">{{siteList.reduce((sum, site) => sum + (Number(site.amount)
20
           || 0), 0).toFixed(2)}}</td>
30
           || 0), 0).toFixed(2)}}</td>
21
         <td class="amount" style="text-align: right;">{{siteList.reduce((sum, site) => sum + (Number(site.amountAdjust)
31
         <td class="amount" style="text-align: right;">{{siteList.reduce((sum, site) => sum + (Number(site.amountAdjust)

+ 12
- 7
oa-ui/src/views/flowable/form/budget/adjust/components/businessCost.vue View File

2
  * @Author: ysh
2
  * @Author: ysh
3
  * @Date: 2025-05-15 18:24:27
3
  * @Date: 2025-05-15 18:24:27
4
  * @LastEditors: Please set LastEditors
4
  * @LastEditors: Please set LastEditors
5
- * @LastEditTime: 2025-05-15 18:37:17
5
+ * @LastEditTime: 2025-05-16 10:33:48
6
 -->
6
 -->
7
 <template>
7
 <template>
8
   <div class="business-cost">
8
   <div class="business-cost">
9
     <table border="1" style="width:100%;">
9
     <table border="1" style="width:100%;">
10
       <tr style="background-color:#f8f8f9">
10
       <tr style="background-color:#f8f8f9">
11
-        <td>序号</td>
11
+        <td style="width: 50px;">序号</td>
12
         <td>名称</td>
12
         <td>名称</td>
13
         <td>金额</td>
13
         <td>金额</td>
14
         <td class="adjust">核算金额</td>
14
         <td class="adjust">核算金额</td>
21
           {{ budgetForm.outExpense }}
21
           {{ budgetForm.outExpense }}
22
         </td>
22
         </td>
23
         <td style="text-align:right;">
23
         <td style="text-align:right;">
24
-          <el-input-number :controls="false" v-model="budgetForm.outExpenseAdjust" :min="0" :step="0.01"
24
+          <el-input-number :controls="false" v-model="budgetForm.outAdjust" :min="0" :step="0.01"
25
             @change="updateTotalJYAmount"></el-input-number>
25
             @change="updateTotalJYAmount"></el-input-number>
26
         </td>
26
         </td>
27
         <td class="remark-cell">{{ budgetForm.outRemark }}</td>
27
         <td class="remark-cell">{{ budgetForm.outRemark }}</td>
33
           {{ budgetForm.letterExpense }}
33
           {{ budgetForm.letterExpense }}
34
         </td>
34
         </td>
35
         <td style="text-align:right;">
35
         <td style="text-align:right;">
36
-          <el-input-number :controls="false" v-model="budgetForm.letterExpenseAdjust" :min="0" :step="0.01"
36
+          <el-input-number :controls="false" v-model="budgetForm.letterAdjust" :min="0" :step="0.01"
37
             @change="updateTotalJYAmount"></el-input-number>
37
             @change="updateTotalJYAmount"></el-input-number>
38
         </td>
38
         </td>
39
         <td class="remark-cell">{{ budgetForm.letterRemark }}</td>
39
         <td class="remark-cell">{{ budgetForm.letterRemark }}</td>
44
         <td style="text-align:right;">
44
         <td style="text-align:right;">
45
           {{ budgetForm.winExpense }}
45
           {{ budgetForm.winExpense }}
46
         </td>
46
         </td>
47
+        <td style="text-align:right;">
48
+          <el-input-number :controls="false" v-model="budgetForm.winAdjust" :min="0" :step="0.01"
49
+            @change="updateTotalJYAmount"></el-input-number>
50
+        </td>
47
         <td class="remark-cell">{{ budgetForm.winRemark }}</td>
51
         <td class="remark-cell">{{ budgetForm.winRemark }}</td>
48
       </tr>
52
       </tr>
49
       <tr>
53
       <tr>
53
           {{ budgetForm.taxExpense }}
57
           {{ budgetForm.taxExpense }}
54
         </td>
58
         </td>
55
         <td style="text-align:right;">
59
         <td style="text-align:right;">
56
-          <el-input-number :controls="false" v-model="budgetForm.taxExpenseAdjust" :min="0" :step="0.01"
60
+          <el-input-number :controls="false" v-model="budgetForm.taxAdjust" :min="0" :step="0.01"
57
             @change="updateTotalJYAmount"></el-input-number>
61
             @change="updateTotalJYAmount"></el-input-number>
58
         </td>
62
         </td>
59
         <td class="remark-cell">{{ budgetForm.taxRemark }}</td>
63
         <td class="remark-cell">{{ budgetForm.taxRemark }}</td>
65
           {{ budgetForm.travelExpense }}
69
           {{ budgetForm.travelExpense }}
66
         </td>
70
         </td>
67
         <td style="text-align:right;">
71
         <td style="text-align:right;">
68
-          <el-input-number :controls="false" v-model="budgetForm.travelExpenseAdjust" :min="0" :step="0.01"
72
+          <el-input-number :controls="false" v-model="budgetForm.travelAdjust" :min="0" :step="0.01"
69
             @change="updateTotalJYAmount"></el-input-number>
73
             @change="updateTotalJYAmount"></el-input-number>
70
         </td>
74
         </td>
71
         <td class="remark-cell">{{ budgetForm.travelRemark }}</td>
75
         <td class="remark-cell">{{ budgetForm.travelRemark }}</td>
99
   },
103
   },
100
   created() {
104
   created() {
101
     this.initTotalJYAmount();
105
     this.initTotalJYAmount();
106
+    this.updateTotalJYAmount();
102
   },
107
   },
103
   methods: {
108
   methods: {
104
     initTotalJYAmount() {
109
     initTotalJYAmount() {
105
       this.totalJYAmount = ((Number(this.budgetForm.outExpense) || 0) + (Number(this.budgetForm.letterExpense) || 0) + (Number(this.budgetForm.winExpense) || 0) + (Number(this.budgetForm.taxExpense) || 0) + (Number(this.budgetForm.travelExpense) || 0)).toFixed(2)
110
       this.totalJYAmount = ((Number(this.budgetForm.outExpense) || 0) + (Number(this.budgetForm.letterExpense) || 0) + (Number(this.budgetForm.winExpense) || 0) + (Number(this.budgetForm.taxExpense) || 0) + (Number(this.budgetForm.travelExpense) || 0)).toFixed(2)
106
     },
111
     },
107
     updateTotalJYAmount() {
112
     updateTotalJYAmount() {
108
-      this.totalJYAmountAdjust = ((Number(this.budgetForm.outExpenseAdjust) || 0) + (Number(this.budgetForm.letterExpenseAdjust) || 0) + (Number(this.budgetForm.winExpenseAdjust) || 0) + (Number(this.budgetForm.taxExpenseAdjust) || 0) + (Number(this.budgetForm.travelExpenseAdjust) || 0)).toFixed(2)
113
+      this.totalJYAmountAdjust = ((Number(this.budgetForm.outAdjust) || 0) + (Number(this.budgetForm.letterAdjust) || 0) + (Number(this.budgetForm.winAdjust) || 0) + (Number(this.budgetForm.taxAdjust) || 0) + (Number(this.budgetForm.travelAdjust) || 0)).toFixed(2)
109
     }
114
     }
110
   }
115
   }
111
 }
116
 }

+ 137
- 0
oa-ui/src/views/flowable/form/budget/adjust/components/otherCost.vue View File

1
+<!--
2
+ * @Author: ysh
3
+ * @Date: 2025-05-16 10:34:57
4
+ * @LastEditors: Please set LastEditors
5
+ * @LastEditTime: 2025-05-16 11:06:49
6
+-->
7
+<template>
8
+  <div class="other-cost">
9
+    <table border="1" style="width:100%;">
10
+      <tr style="background-color:#f8f8f9">
11
+        <td></td>
12
+        <td style="width: 50px;">序号</td>
13
+        <td>名称</td>
14
+        <td class="adjust">核算金额</td>
15
+        <td>备注</td>
16
+      </tr>
17
+      <tr v-for="other, index in otherList" :key="other.id">
18
+        <td>
19
+          <div class="delete-btn" @click="removeOther(other, index)"><i class="el-icon-remove-outline"
20
+              style="color:#F56C6C"></i>
21
+          </div>
22
+        </td>
23
+        <td>{{ index + 1 }}</td>
24
+        <td>
25
+          <el-input v-model="other.name" placeholder="请输入名称" />
26
+        </td>
27
+        <td>
28
+          <el-input-number :controls="false" v-model="other.amountAdjust" placeholder="请输入核算金额"
29
+            @change="handleOtherChange(other)" />
30
+        </td>
31
+        <td>
32
+          <el-input type="textarea" :rows="2" v-model="other.remark" placeholder="请输入备注" />
33
+        </td>
34
+      </tr>
35
+      <tr>
36
+        <td colspan="3" class="amount">预算外开支合计</td>
37
+        <td class="amount" style="text-align: right;">{{otherList.reduce((sum, other) => sum + (Number(other.amountAdjust) || 0), 0).toFixed(2)}}</td>
38
+      </tr>
39
+    </table>
40
+    <div class="add-staff mt10">
41
+      <el-button type="success" plain icon="el-icon-plus" @click="addOther" size="mini">新增项</el-button>
42
+    </div>
43
+  </div>
44
+</template>
45
+
46
+<script>
47
+export default {
48
+  props: {
49
+    otherList: {
50
+      type: Array,
51
+      default: () => [{
52
+        id: Date.now(),
53
+        name: '',
54
+        amountAdjust: null,
55
+        remark: ''
56
+      }]
57
+    }
58
+  },
59
+  watch: {
60
+    otherList: {
61
+      handler(newVal) {
62
+        if (!newVal || newVal.length === 0) {
63
+          this.$emit('update:otherList', [{
64
+            id: Date.now(),
65
+            name: '',
66
+            amountAdjust: null,
67
+            remark: ''
68
+          }]);
69
+        }
70
+      },
71
+      immediate: true
72
+    }
73
+  },
74
+  methods: {
75
+    handleOtherChange(other) {
76
+      this.$emit('update:otherList', this.otherList);
77
+    },
78
+    addOther() {
79
+      this.otherList.push({
80
+        id: Date.now(),
81
+        name: '',
82
+        amountAdjust: null,
83
+        remark: ''
84
+      });
85
+    },
86
+    removeOther(other, index) {
87
+      this.$confirm('确实移除【' + other.name + '】吗', '提示', {
88
+        confirmButtonText: '确定',
89
+        cancelButtonText: '取消',
90
+        type: 'warning'
91
+      }).then(() => {
92
+        let arr = this.otherList;
93
+        if (arr.length == 1) {
94
+          return;
95
+        }
96
+        if (index >= 0 && index < arr.length) {
97
+          arr.splice(index, 1);
98
+        }
99
+        this.$emit('update:otherList', arr);
100
+      });
101
+    }
102
+  }
103
+}
104
+</script>
105
+
106
+<style lang="scss" scoped>
107
+.other-cost {
108
+  .add-staff {
109
+    margin-bottom: 10px;
110
+  }
111
+
112
+  table {
113
+    text-align: center;
114
+    border-collapse: collapse;
115
+    margin: 0 auto;
116
+
117
+    td {
118
+      padding: 5px;
119
+    }
120
+  }
121
+
122
+  .adjust {
123
+    color: #F56C6C;
124
+    width: 120px;
125
+  }
126
+}
127
+
128
+.delete-btn {
129
+  cursor: pointer;
130
+  font-size: 18px;
131
+}
132
+
133
+.amount {
134
+  font-weight: bold;
135
+  font-family: Arial, Helvetica, sans-serif;
136
+}
137
+</style>

+ 66
- 41
oa-ui/src/views/flowable/form/budget/components/calculatePerformance.vue View File

10
         <el-form ref="form" :model="item" label-width="100px">
10
         <el-form ref="form" :model="item" label-width="100px">
11
           <el-row>
11
           <el-row>
12
             <el-col :span="12">
12
             <el-col :span="12">
13
-              <el-form-item label="工作类别">
14
-                <el-select v-model="item.workType" placeholder="请选择工作类别"
15
-                  @change="(val) => handleWorkTypeChange(val, index)">
16
-                  <el-option v-for="type in workTypeList" :key="type.value" :label="type.label" :value="type.value">
13
+              <el-form-item label="工作项目">
14
+                <el-select v-model="item.workItem" placeholder="请选择工作项目"
15
+                  @change="(val) => handleWorkItemChange(val, index)">
16
+                  <el-option v-for="workItem in workItemList" :key="workItem.value" :label="workItem.label"
17
+                    :value="workItem.value">
17
                   </el-option>
18
                   </el-option>
18
                 </el-select>
19
                 </el-select>
19
               </el-form-item>
20
               </el-form-item>
20
             </el-col>
21
             </el-col>
21
             <el-col :span="12">
22
             <el-col :span="12">
22
-              <el-form-item label="工作项目">
23
-                <el-select v-model="item.workItem" placeholder="请选择工作项目"
24
-                  @change="(val) => handleWorkItemChange(val, index)">
25
-                  <el-option v-for="workItem in item.workItemList" :key="workItem.value" :label="workItem.label"
26
-                    :value="workItem.value">
23
+              <el-form-item label="内容细项">
24
+                <el-select v-model="item.subItem" placeholder="请选择内容细项"
25
+                  @change="(val) => handleSubItemChange(val, index)">
26
+                  <el-option v-for="subItem in item.workSelect.subItemList" :key="subItem.value" :label="subItem.label"
27
+                    :value="subItem.value">
27
                   </el-option>
28
                   </el-option>
28
                 </el-select>
29
                 </el-select>
29
               </el-form-item>
30
               </el-form-item>
34
               <el-form-item label="比例尺/等级">
35
               <el-form-item label="比例尺/等级">
35
                 <el-select v-model="item.scaleGrade" placeholder="请选择比例尺/等级"
36
                 <el-select v-model="item.scaleGrade" placeholder="请选择比例尺/等级"
36
                   @change="(val) => handleScaleGradeChange(val, index)">
37
                   @change="(val) => handleScaleGradeChange(val, index)">
37
-                  <el-option v-for="scale in item.scaleGradeList" :key="scale.value" :label="scale.label"
38
+                  <el-option v-for="scale in item.workSelect.scaleGradeList" :key="scale.value" :label="scale.label"
38
                     :value="scale.value">
39
                     :value="scale.value">
39
                   </el-option>
40
                   </el-option>
40
                 </el-select>
41
                 </el-select>
47
                   <el-option key="一般地类" label="一般地类" value="0"></el-option>
48
                   <el-option key="一般地类" label="一般地类" value="0"></el-option>
48
                   <el-option key="复杂地类" label="复杂地类" value="1"></el-option>
49
                   <el-option key="复杂地类" label="复杂地类" value="1"></el-option>
49
                 </el-select>
50
                 </el-select>
50
-              </el-form-item></el-col>
51
+              </el-form-item>
52
+            </el-col>
51
           </el-row>
53
           </el-row>
52
 
54
 
53
           <el-row>
55
           <el-row>
65
               <el-form-item label="工作量">
67
               <el-form-item label="工作量">
66
                 <el-input-number v-model="item.workload" :precision="2" :step="0.1" :min="0"
68
                 <el-input-number v-model="item.workload" :precision="2" :step="0.1" :min="0"
67
                   @change="() => calculateTotal(index)"></el-input-number>
69
                   @change="() => calculateTotal(index)"></el-input-number>
68
-              </el-form-item></el-col>
70
+              </el-form-item>
71
+            </el-col>
69
           </el-row>
72
           </el-row>
70
 
73
 
71
-
72
           <el-form-item label="单价">
74
           <el-form-item label="单价">
73
             <el-tag>{{ item.price }}/ {{ item.unit }}</el-tag>
75
             <el-tag>{{ item.price }}/ {{ item.unit }}</el-tag>
74
           </el-form-item>
76
           </el-form-item>
75
 
77
 
76
-
77
           <el-form-item label="单项总额">
78
           <el-form-item label="单项总额">
78
             <el-tag>{{ item.total }}</el-tag>
79
             <el-tag>{{ item.total }}</el-tag>
79
           </el-form-item>
80
           </el-form-item>
81
+
82
+          <el-form-item label="备注">
83
+            {{ item.remark }}
84
+          </el-form-item>
80
         </el-form>
85
         </el-form>
81
       </div>
86
       </div>
82
     </div>
87
     </div>
98
 </template>
103
 </template>
99
 
104
 
100
 <script>
105
 <script>
101
-import { getWorkTypeList, getWorkItemList, getScaleGradeList, getUnitPrice, getPriceRemarkByWorkType } from '@/api/oa/price/price'
106
+import { getWorkItemList, getSubItemList, getScaleGradeList, getUnitPrice, getPriceRemarkByWorkType } from '@/api/oa/price/checkPrice'
102
 
107
 
103
 export default {
108
 export default {
104
   name: 'CalculatePerformance',
109
   name: 'CalculatePerformance',
105
   data() {
110
   data() {
106
     return {
111
     return {
107
       visible: false,
112
       visible: false,
108
-      workTypeList: [],
113
+      workItemList: [],
109
       performanceList: [this.getDefaultItem()]
114
       performanceList: [this.getDefaultItem()]
110
     }
115
     }
111
   },
116
   },
119
   methods: {
124
   methods: {
120
     getDefaultItem() {
125
     getDefaultItem() {
121
       return {
126
       return {
122
-        workType: '',
123
         workItem: '',
127
         workItem: '',
128
+        subItem: '',
124
         scaleGrade: '',
129
         scaleGrade: '',
125
         groundType: '0',
130
         groundType: '0',
126
         price: 0,
131
         price: 0,
127
         workload: 0,
132
         workload: 0,
128
         coefficient: 1,
133
         coefficient: 1,
129
         total: 0,
134
         total: 0,
130
-        workItemList: [],
131
-        scaleGradeList: []
135
+        remark: '',
136
+        workSelect: {
137
+          subItemList: [],
138
+          scaleGradeList: []
139
+        }
132
       }
140
       }
133
     },
141
     },
134
     open() {
142
     open() {
135
       this.visible = true
143
       this.visible = true
136
       this.resetForm()
144
       this.resetForm()
137
-      this.initWorkTypeList()
145
+      this.initWorkItemList()
138
     },
146
     },
139
     resetForm() {
147
     resetForm() {
140
       this.performanceList = [this.getDefaultItem()]
148
       this.performanceList = [this.getDefaultItem()]
145
     removeItem(index) {
153
     removeItem(index) {
146
       this.performanceList.splice(index, 1)
154
       this.performanceList.splice(index, 1)
147
     },
155
     },
148
-    initWorkTypeList() {
149
-      getWorkTypeList().then(res => {
156
+    initWorkItemList() {
157
+      getWorkItemList({ workType: '内业' }).then(res => {
150
         if (res) {
158
         if (res) {
151
-          this.workTypeList = this.setArray(res)
159
+          this.workItemList = this.setArray(res)
152
         }
160
         }
153
       })
161
       })
154
     },
162
     },
155
-    handleWorkTypeChange(value, index) {
163
+    handleWorkItemChange(value, index) {
156
       const item = this.performanceList[index]
164
       const item = this.performanceList[index]
157
-      item.workItem = ''
165
+      item.subItem = ''
158
       item.scaleGrade = ''
166
       item.scaleGrade = ''
159
       item.price = 0
167
       item.price = 0
160
-      item.workItemList = []
161
-      item.scaleGradeList = []
168
+      item.workSelect.subItemList = []
169
+      item.workSelect.scaleGradeList = []
162
       this.calculateTotal(index)
170
       this.calculateTotal(index)
163
 
171
 
164
       if (value) {
172
       if (value) {
165
-        getWorkItemList({ workType: value }).then(res => {
166
-          if (res) {
167
-            item.workItemList = this.setArray(res)
168
-          }
169
-        })
173
+        this.getWorkSubItemList(item, value)
170
       }
174
       }
171
     },
175
     },
172
-    handleWorkItemChange(value, index) {
176
+    getWorkSubItemList(item, workItem) {
177
+      getSubItemList({ workItem }).then(res => {
178
+        if (res) {
179
+          let subItemList = this.setArray(res)
180
+          item.workSelect.subItemList = subItemList
181
+          if (subItemList.length > 0) {
182
+            item.subItem = subItemList[0].value
183
+            this.handleSubItemChange(item.subItem, this.performanceList.indexOf(item))
184
+          }
185
+        }
186
+      })
187
+    },
188
+    handleSubItemChange(value, index) {
173
       const item = this.performanceList[index]
189
       const item = this.performanceList[index]
174
       item.scaleGrade = ''
190
       item.scaleGrade = ''
175
       item.price = 0
191
       item.price = 0
176
-      item.scaleGradeList = []
192
+      item.workSelect.scaleGradeList = []
177
       this.calculateTotal(index)
193
       this.calculateTotal(index)
178
 
194
 
179
-      if (value) {
180
-        getScaleGradeList({ workItem: value }).then(res => {
195
+      // Set remark based on selected subItem
196
+      const selectedSubItem = item.workSelect.subItemList.find(sub => sub.value === value)
197
+      if (selectedSubItem) {
198
+        item.remark = selectedSubItem.remark || ''
199
+      }
200
+
201
+      if (value && item.workItem) {
202
+        getScaleGradeList({ workItem: item.workItem }).then(res => {
181
           if (res) {
203
           if (res) {
182
-            item.scaleGradeList = this.setArray(res)
183
-            if (item.scaleGradeList.length > 0) {
184
-              item.scaleGrade = item.scaleGradeList[0].value
204
+            let scaleGradeList = this.setArray(res)
205
+            item.workSelect.scaleGradeList = scaleGradeList
206
+            if (scaleGradeList.length > 0) {
207
+              item.scaleGrade = scaleGradeList[0].value
185
               this.handleScaleGradeChange(item.scaleGrade, index)
208
               this.handleScaleGradeChange(item.scaleGrade, index)
186
             }
209
             }
187
           }
210
           }
193
       item.price = 0
216
       item.price = 0
194
       this.calculateTotal(index)
217
       this.calculateTotal(index)
195
 
218
 
196
-      if (value && item.workItem) {
219
+      if (value && item.workItem && item.subItem) {
197
         this.getUnitPrice(index)
220
         this.getUnitPrice(index)
198
       }
221
       }
199
     },
222
     },
202
       item.price = 0
225
       item.price = 0
203
       this.calculateTotal(index)
226
       this.calculateTotal(index)
204
 
227
 
205
-      if (item.scaleGrade && item.workItem) {
228
+      if (item.scaleGrade && item.workItem && item.subItem) {
206
         this.getUnitPrice(index)
229
         this.getUnitPrice(index)
207
       }
230
       }
208
     },
231
     },
210
       const item = this.performanceList[index]
233
       const item = this.performanceList[index]
211
       getUnitPrice({
234
       getUnitPrice({
212
         workItem: item.workItem,
235
         workItem: item.workItem,
236
+        subItem: item.subItem,
213
         scaleGrade: item.scaleGrade,
237
         scaleGrade: item.scaleGrade,
214
         groundType: item.groundType
238
         groundType: item.groundType
215
       }).then(res => {
239
       }).then(res => {
216
         if (res.length != 0) {
240
         if (res.length != 0) {
217
           item.price = res.data.price
241
           item.price = res.data.price
218
           item.unit = res.data.unit
242
           item.unit = res.data.unit
243
+          item.remark = res.data.remark || ''
219
           this.calculateTotal(index)
244
           this.calculateTotal(index)
220
         }
245
         }
221
       })
246
       })

Loading…
Cancel
Save