ソースを参照

更新核算编制,修改预算、核算的内业绩效额

余思翰 3週間前
コミット
5f5ab25298

+ 1
- 0
oa-back/ruoyi-admin/src/main/java/com/ruoyi/web/controller/oa/CmcCheckPriceController.java ファイルの表示

@@ -131,6 +131,7 @@ public class CmcCheckPriceController extends BaseController
131 131
         JSONObject price = new JSONObject();
132 132
         price.put("id", cmcCheckPriceList.get(0).getId());
133 133
         price.put("unit", cmcCheckPriceList.get(0).getUnit());
134
+        price.put("remark", cmcCheckPriceList.get(0).getRemark());
134 135
         if (groundType.equals("0"))
135 136
             price.put("price", cmcCheckPriceList.get(0).getCommonPrice());
136 137
         else

+ 1
- 1
oa-back/ruoyi-system/src/main/java/com/ruoyi/oa/domain/CmcWage.java ファイルの表示

@@ -71,7 +71,7 @@ public class CmcWage extends BaseEntity
71 71
     private BigDecimal payableWage;
72 72
 
73 73
     /** 公积金 */
74
-    @Excel(name = "公积金")
74
+    @Excel(name = "公积金单位部分")
75 75
     private BigDecimal houseFund;
76 76
 
77 77
     /** 养老保险 */

+ 17
- 1
oa-back/ruoyi-system/src/main/resources/mapper/oa/CmcBudgetSettleMapper.xml ファイルの表示

@@ -16,6 +16,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
16 16
         <result property="settle"    column="settle"    />
17 17
         <result property="remark"    column="remark"    />
18 18
         <association property="cmcPrice"    javaType="CmcPrice"         resultMap="CmcPriceResult" />
19
+        <association property="cmcCheckPrice"    javaType="CmcCheckPrice"         resultMap="CmcCheckPriceResult" />
19 20
     </resultMap>
20 21
 
21 22
     <resultMap type="CmcPrice" id="CmcPriceResult">
@@ -29,8 +30,23 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
29 30
         <result property="complexPrice"    column="complex_price"    />
30 31
     </resultMap>
31 32
 
33
+    <resultMap type="CmcCheckPrice" id="CmcCheckPriceResult">
34
+        <result property="id"    column="id"    />
35
+        <result property="workType"    column="check_work_type"    />
36
+        <result property="workItem"    column="check_work_item"    />
37
+        <result property="subItem"    column="check_sub_item"    />
38
+        <result property="scaleGrade"    column="check_scale_grade"    />
39
+        <result property="unit"    column="check_unit"    />
40
+        <result property="commonPrice"    column="check_common_price"    />
41
+        <result property="complexPrice"    column="check_complex_price"    />
42
+        <result property="remark"    column="check_remark"    />
43
+    </resultMap>
44
+
32 45
     <sql id="selectCmcBudgetSettleVo">
33
-        select bs.budget_settle_id, bs.budget_id, bs.content, bs.price_id, bs.check_price_id, p.work_type, p.work_item, p.sub_item, p.scale_grade, p.unit, p.common_price, p.complex_price, bs.workload, bs.coefficient, bs.ground_type, bs.settle , bs.remark from cmc_budget_settle as bs
46
+        select bs.budget_settle_id, bs.budget_id, bs.content, bs.price_id, bs.check_price_id, p.work_type, p.work_item, p.sub_item, p.scale_grade, p.unit, 
47
+        p.common_price, p.complex_price, cp.work_type as check_work_type, cp.work_item as check_work_item, cp.sub_item as check_sub_item, cp.scale_grade as check_scale_grade, 
48
+        cp.unit as check_unit, cp.common_price as check_common_price, cp.complex_price as check_complex_price, cp.remark as check_remark, bs.workload, bs.coefficient, 
49
+        bs.ground_type, bs.settle , bs.remark from cmc_budget_settle as bs
34 50
         left join cmc_price as p on p.id = bs.price_id
35 51
         left join cmc_check_price as cp on cp.id = bs.check_price_id
36 52
     </sql>

+ 11
- 2
oa-ui/src/api/oa/wage/wage.js ファイルの表示

@@ -1,8 +1,8 @@
1 1
 /*
2 2
  * @Author: wrh
3 3
  * @Date: 2024-09-19 16:09:52
4
- * @LastEditors: wrh
5
- * @LastEditTime: 2024-09-27 11:21:46
4
+ * @LastEditors: Please set LastEditors
5
+ * @LastEditTime: 2025-05-15 10:26:51
6 6
  */
7 7
 import request from '@/utils/request'
8 8
 
@@ -22,6 +22,15 @@ export function getWage(wageId) {
22 22
     method: 'get'
23 23
   })
24 24
 }
25
+// 查询员工工资详细
26
+export function getUserDayValue(query) {
27
+  return request({
28
+    url: '/oa/wage/userDayValue',
29
+    method: 'get',
30
+    params: query
31
+  })
32
+}
33
+
25 34
 
26 35
 // 新增员工工资
27 36
 export function addWage(data) {

+ 4
- 4
oa-ui/src/views/flowable/form/budget/addBudget.vue ファイルの表示

@@ -2,7 +2,7 @@
2 2
  * @Author: ysh
3 3
  * @Date: 2024-06-21 18:51:51
4 4
  * @LastEditors: Please set LastEditors
5
- * @LastEditTime: 2025-05-13 16:51:36
5
+ * @LastEditTime: 2025-05-15 18:12:10
6 6
 -->
7 7
 <template>
8 8
   <div class="app-container">
@@ -135,7 +135,7 @@
135 135
       <el-button type="primary" @click="submitNextFlow" v-if="taskName == '预算批准'">提交下一个流程</el-button>
136 136
       <el-button type="primary" @click="submitNextFlow" v-else>结算批准</el-button>
137 137
     </div>
138
-    <el-dialog title="表单预览" :visible.sync="viewOpen" width="70%" append-to-body>
138
+    <el-dialog title="表单预览" :visible.sync="viewOpen" width="75%" append-to-body>
139 139
       <!-- <budget-info :taskName="taskName" :taskForm="taskForm" @goBack="$emit('goBack')"></budget-info> -->
140 140
       <new-budget-info :taskName="taskName" :taskForm="taskForm"></new-budget-info>
141 141
     </el-dialog>
@@ -162,17 +162,17 @@ import ReturnComment from "@/views/flowable/form/components/flowBtn/returnCommen
162 162
 import ReturnBtn from "@/views/flowable/form/components/flowBtn/returnBtn.vue";
163 163
 import CarTable from "./carTable.vue";
164 164
 import MoneyTable from "./moneyTable.vue";
165
-import PeopleTable from "./staffTable.vue";
166 165
 import DeviceTable from "./deviceTable.vue";
167 166
 import OtherTable from "./otherTable.vue";
168 167
 import SiteExpenses from "./siteExpenses.vue";
169 168
 import BudgetAdjust from "./adjust/budgetAdjust.vue";
170 169
 import NewBudgetInfo from './adjust/newBudgetInfo.vue';
170
+
171 171
 export default {
172 172
   components: {
173 173
     ReturnComment,
174 174
     ReturnBtn,
175
-    PeopleTable,
175
+    PeopleTable: () => import("./staffTable.vue"),
176 176
     CarTable,
177 177
     DeviceTable,
178 178
     MoneyTable,

+ 104
- 65
oa-ui/src/views/flowable/form/budget/adjust/budgetAdjust.vue ファイルの表示

@@ -2,7 +2,7 @@
2 2
  * @Author: ysh
3 3
  * @Date: 2025-05-07 11:01:39
4 4
  * @LastEditors: Please set LastEditors
5
- * @LastEditTime: 2025-05-14 18:27:04
5
+ * @LastEditTime: 2025-05-15 18:32:55
6 6
 -->
7 7
 <template>
8 8
   <div class="main" v-loading="loading">
@@ -40,24 +40,12 @@
40 40
               <td style="width: 200px">备注</td>
41 41
             </tr>
42 42
             <tr v-for="(work, index) in workContentList" :key="index">
43
-              <td>
44
-                {{ work.content }}
45
-              </td>
46
-              <td>
47
-                {{ work.scale }}
48
-              </td>
49
-              <td>
50
-                {{ work.unit }}
51
-              </td>
52
-              <td>
53
-                {{ work.workload }}
54
-              </td>
55
-              <td>
56
-                {{ work.deadline }}
57
-              </td>
58
-              <td>
59
-                {{ work.remark }}
60
-              </td>
43
+              <td>{{ work.content }}</td>
44
+              <td>{{ work.scale }}</td>
45
+              <td>{{ work.unit }}</td>
46
+              <td>{{ work.workload }}</td>
47
+              <td>{{ work.deadline }}</td>
48
+              <td style="text-align:left;">{{ work.remark }}</td>
61 49
             </tr>
62 50
           </table>
63 51
         </div>
@@ -67,6 +55,7 @@
67 55
           <tr style="background-color:#f8f8f9" v-if="workList.length != 0">
68 56
             <td style="min-width:50px">工作简述</td>
69 57
             <td style="min-width:50px">工作内容</td>
58
+            <td style="min-width:50px">内容细项</td>
70 59
             <td style="min-width:50px">比例尺/等级</td>
71 60
             <td style="min-width:50px">数量</td>
72 61
             <td style="min-width:50px">单价</td>
@@ -77,7 +66,8 @@
77 66
           </tr>
78 67
           <tr v-for="work in workList">
79 68
             <td>{{ work.content }}</td>
80
-            <td>{{ work.cmcPrice ? work.cmcPrice.workItem : '' }}</td>
69
+            <td>{{ work.workItem }}</td>
70
+            <td>{{ work.subItem }}</td>
81 71
             <td>
82 72
               {{ work.scaleGrade }}
83 73
             </td>
@@ -93,14 +83,14 @@
93 83
             <td>{{ work.remark ? work.remark : '' }}</td>
94 84
           </tr>
95 85
           <tr>
96
-            <td :colspan="7" class="head">内业绩效额合计</td>
86
+            <td :colspan="8" class="head">内业绩效额合计</td>
97 87
             <td :colspan="1" class="head" style="text-align:right;">
98 88
               {{ budgetForm.settleExpense ? budgetForm.settleExpense.toFixed(2) : '0.00' }}
99 89
             </td>
100 90
             <td></td>
101 91
           </tr>
102 92
           <tr style="color:#F56C6C">
103
-            <td :colspan="7" class="head">内业核算绩效额</td>
93
+            <td :colspan="8" class="head">内业核算绩效额</td>
104 94
             <td :colspan="1" class="head">
105 95
               <el-input-number v-model="budgetForm.settleAdjust" :controls="false" style="width:100%"></el-input-number>
106 96
             </td>
@@ -109,32 +99,23 @@
109 99
       </el-descriptions-item>
110 100
       <el-descriptions-item label="内业人员成本" :span="3" v-if="innerStaffList.length > 0">
111 101
         <inner-staff-cost :staffList.sync="innerStaffList" :settleExpense="budgetForm.settleExpense"
112
-          @update:staffList="handleInnerStaffChange"></inner-staff-cost>
102
+          :settleAdjust="budgetForm.settleAdjust" @update:staffList="handleInnerStaffChange"></inner-staff-cost>
113 103
       </el-descriptions-item>
114 104
       <el-descriptions-item label="外业人员成本" :span="3" v-if="outerStaffList.length > 0">
115 105
         <outer-staff-cost :staffList.sync="outerStaffList"
116 106
           @update:staffList="handleOuterStaffChange"></outer-staff-cost>
117 107
       </el-descriptions-item>
118 108
       <el-descriptions-item label="车辆成本" :span="3" v-if="carList.length > 0">
119
-        <car-cost :carList.sync="carList"></car-cost>
109
+        <car-cost :carList.sync="carList" @update:carList="handleCarChange"></car-cost>
120 110
       </el-descriptions-item>
121 111
       <el-descriptions-item label="设备成本" :span="3" v-if="deviceList.length > 0">
122
-        <device-cost :deviceList.sync="deviceList"></device-cost>
112
+        <device-cost :deviceList.sync="deviceList" @update:deviceList="handleDeviceChange"></device-cost>
123 113
       </el-descriptions-item>
124 114
       <el-descriptions-item label="现场开支" :span="3">
125
-        <table border="1" style="width:100%;">
126
-          <tr style="background-color:#f8f8f9">
127
-            <td>开支项</td>
128
-            <td>金额</td>
129
-            <td class="adjust">核算金额</td>
130
-          </tr>
131
-          <tr>
132
-
133
-          </tr>
134
-        </table>
115
+        <site-cost :siteList.sync="siteList" @update:siteList="handleSiteChange"></site-cost>
135 116
       </el-descriptions-item>
136 117
       <el-descriptions-item label="经营相关" :span="3">
137
-
118
+        <business-cost :budgetForm.sync="budgetForm" @update:budgetForm="handleBusinessChange"></business-cost>
138 119
       </el-descriptions-item>
139 120
       <el-descriptions-item label="预算外开销" :span="3">
140 121
 
@@ -161,13 +142,16 @@ import InnerStaffCost from './components/InnerStaffCost.vue';
161 142
 import OuterStaffCost from './components/OuterStaffCost.vue';
162 143
 import CarCost from './components/CarCost.vue';
163 144
 import DeviceCost from './components/DeviceCost.vue';
164
-
145
+import SiteCost from '@/views/flowable/form/budget/adjust/components/SiteCost.vue';
146
+import BusinessCost from '@/views/flowable/form/budget/adjust/components/businessCost.vue';
165 147
 export default {
166 148
   components: {
167 149
     InnerStaffCost,
168 150
     OuterStaffCost,
169 151
     CarCost,
170
-    DeviceCost
152
+    DeviceCost,
153
+    SiteCost,
154
+    BusinessCost
171 155
   },
172 156
   props: {
173 157
     taskForm: {
@@ -192,6 +176,7 @@ export default {
192 176
       outerStaffList: [],
193 177
       carList: [],
194 178
       deviceList: [],
179
+      siteList: []
195 180
     }
196 181
   },
197 182
   created() {
@@ -205,13 +190,34 @@ export default {
205 190
         this.budgetForm = res.rows[0];
206 191
         if (this.budgetForm) {
207 192
           const budgetId = this.budgetForm.budgetId;
193
+          this.budgetForm.outExpense = Number(this.budgetForm.outExpense).toFixed(2);
194
+          this.budgetForm.letterExpense = Number(this.budgetForm.letterExpense).toFixed(2);
195
+          this.budgetForm.winExpense = Number(this.budgetForm.winExpense).toFixed(2);
196
+          this.budgetForm.taxExpense = Number(this.budgetForm.taxExpense).toFixed(2);
197
+          this.budgetForm.travelExpense = Number(this.budgetForm.travelExpense).toFixed(2);
198
+          this.budgetForm.totalBudget = Number(this.budgetForm.totalBudget).toFixed(2);
208 199
           // 获取设备数据
209 200
           let deviceRes = await listBudgetDevice({ pageSize: 100, budgetId });
210 201
           this.deviceList = deviceRes.rows;
211
-
202
+          this.deviceList = this.deviceList.map(device => {
203
+            return {
204
+              ...device,
205
+              depreciation: Number(device.depreciation).toFixed(2),
206
+              amount: Number(device.amount).toFixed(2),
207
+              amountAdjust: device.amountAdjust ? Number(device.amountAdjust).toFixed(2) : 0
208
+            };
209
+          });
212 210
           // 获取车辆数据
213 211
           let carRes = await listBudgetCar({ pageSize: 100, budgetId });
214 212
           this.carList = carRes.rows;
213
+          this.carList = this.carList.map(car => {
214
+            return {
215
+              ...car,
216
+              depreciation: Number(car.depreciation).toFixed(2),
217
+              amount: Number(car.amount).toFixed(2),
218
+              amountAdjust: car.amountAdjust ? Number(car.amountAdjust).toFixed(2) : 0
219
+            };
220
+          });
215 221
 
216 222
           // 获取内业人员数据
217 223
           let innerStaffRes = await listBudgetStaff({ pageSize: 100, budgetId, type: '内业' });
@@ -249,16 +255,41 @@ export default {
249 255
           let settleRes = await listBudgetSettle({ pageSize: 100, budgetId });
250 256
           this.workList = settleRes.rows;
251 257
           for (let work of this.workList) {
252
-            if (work.groundType == '0') {
253
-              work.price = work.cmcPrice.commonPrice
254
-              work.scaleGrade = work.cmcPrice.scaleGrade
255
-              work.unit = work.cmcPrice.unit
258
+            if (work.checkPriceId) {
259
+              work.workType = work.cmcCheckPrice.workType
260
+              work.workItem = work.cmcCheckPrice.workItem
261
+              work.subItem = work.cmcCheckPrice.subItem
262
+              work.scaleGrade = work.cmcCheckPrice.scaleGrade
263
+              work.unit = work.cmcCheckPrice.unit
264
+              if (work.groundType == '0') {
265
+                work.price = work.cmcCheckPrice.commonPrice
266
+              } else {
267
+                work.price = work.cmcCheckPrice.complexPrice
268
+              }
256 269
             } else {
257
-              work.price = work.cmcPrice.complexPrice
270
+              work.workType = work.cmcPrice.workType
271
+              work.workItem = work.cmcPrice.workItem
272
+              work.subItem = work.cmcPrice.subItem
258 273
               work.scaleGrade = work.cmcPrice.scaleGrade
259 274
               work.unit = work.cmcPrice.unit
275
+              if (work.groundType == '0') {
276
+                work.price = work.cmcPrice.commonPrice
277
+              } else {
278
+                work.price = work.cmcPrice.complexPrice
279
+              }
260 280
             }
261 281
           }
282
+
283
+          // 获取现场开支
284
+          let siteRes = await listSite({ pageSize: 100, budgetId });
285
+          this.siteList = siteRes.rows;
286
+          this.siteList = this.siteList.map(site => {
287
+            return {
288
+              ...site,
289
+              amount: Number(site.amount).toFixed(2),
290
+              amountAdjust: site.amountAdjust ? Number(site.amountAdjust).toFixed(2) : 0
291
+            };
292
+          });
262 293
         }
263 294
         this.loading = false;
264 295
       }).catch(() => {
@@ -276,33 +307,29 @@ export default {
276 307
     // 处理内业人员数据变化
277 308
     handleInnerStaffChange(newList) {
278 309
       this.innerStaffList = newList;
279
-      // 计算内业人员总成本
280
-      const totalAmount = this.innerStaffList.reduce((sum, staff) => {
281
-        return sum + (staff.amountAdjust || 0);
282
-      }, 0);
283
-
284
-      // 更新预算表单中的内业人员成本
285
-      if (this.budgetForm) {
286
-        this.budgetForm.innerStaffAmount = totalAmount;
287
-        // 可以在这里调用API保存数据
288
-        // updateBudget(this.budgetForm);
289
-      }
310
+      console.log(this.innerStaffList);
290 311
     },
291 312
 
292 313
     // 处理外业人员数据变化
293 314
     handleOuterStaffChange(newList) {
294 315
       this.outerStaffList = newList;
295
-      // 计算外业人员总成本
296
-      const totalAmount = this.outerStaffList.reduce((sum, staff) => {
297
-        return sum + (staff.amountAdjust || 0);
298
-      }, 0);
316
+    },
317
+    // 处理车辆数据变化
318
+    handleCarChange(newList) {
319
+      this.carList = newList;
320
+    },
321
+    // 处理设备数据变化
322
+    handleDeviceChange(newList) {
323
+      this.deviceList = newList;
324
+    },
325
+    // 处理现场开支数据变化
326
+    handleSiteChange(newList) {
327
+      this.siteList = newList;
328
+      console.log(this.siteList);
329
+    },
330
+    // 处理经营相关数据变化
331
+    handleBusinessChange(newData) {
299 332
 
300
-      // 更新预算表单中的外业人员成本
301
-      if (this.budgetForm) {
302
-        this.budgetForm.outerStaffAmount = totalAmount;
303
-        // 可以在这里调用API保存数据
304
-        // updateBudget(this.budgetForm);
305
-      }
306 333
     },
307 334
     async preserve() {
308 335
       let obj = {
@@ -323,6 +350,18 @@ export default {
323 350
           await addBudgetStaff(staff);
324 351
         }
325 352
       })
353
+      delBudgetCar(this.row.budgetId).then(async res => {
354
+        for (let car of this.carList) {
355
+          car.budgetId = this.row.budgetId;
356
+          await addBudgetCar(car);
357
+        }
358
+      })
359
+      delBudgetDevice(this.row.budgetId).then(async res => {
360
+        for (let device of this.deviceList) {
361
+          device.budgetId = this.row.budgetId;
362
+          await addBudgetDevice(device);
363
+        }
364
+      })
326 365
       this.$message.success('保存成功');
327 366
     },
328 367
     confirmSucess() {

+ 103
- 10
oa-ui/src/views/flowable/form/budget/adjust/components/CarCost.vue ファイルの表示

@@ -1,7 +1,14 @@
1
+<!--
2
+ * @Author: ysh
3
+ * @Date: 2025-05-08 14:18:15
4
+ * @LastEditors: Please set LastEditors
5
+ * @LastEditTime: 2025-05-15 14:55:55
6
+-->
1 7
 <template>
2 8
   <div class="car-cost">
3 9
     <table border="1" style="width:100%;">
4 10
       <tr style="background-color:#f8f8f9">
11
+        <td></td>
5 12
         <td>车牌号</td>
6 13
         <td>折旧成本(天)</td>
7 14
         <td>预算天数</td>
@@ -9,33 +16,107 @@
9 16
         <td class="adjust">核算天数</td>
10 17
         <td class="adjust">核算金额</td>
11 18
       </tr>
12
-      <tr v-for="car in carList" :key="'car' + car.carId">
13
-        <td>{{ car.car ? car.car.licensePlate : '' }}</td>
14
-        <td>{{ car.car ? car.car.dayCost : '' }}</td>
15
-        <td>{{ car.days }}</td>
16
-        <td>{{ car.amount }}</td>
19
+      <tr v-for="car, index in carList" :key="'car' + car.carId">
17 20
         <td>
18
-          <el-input-number :controls="false" style="width:100%;" v-model="car.daysAdjust" @change="handleChange"></el-input-number>
21
+          <div class="delete-btn" @click="removeCar(car, index)"><i class="el-icon-remove-outline"
22
+              style="color:#F56C6C"></i>
23
+          </div>
19 24
         </td>
20
-        <td>
21
-          <el-input-number :controls="false" style="width:100%;" v-model="car.amountAdjust" @change="handleChange"></el-input-number>
25
+        <td>{{ car.car ? car.car.licensePlate : '' }}</td>
26
+        <td style="text-align:right;">{{ car.car ? car.car.dayCost : '' }}</td>
27
+        <td style="text-align:right;">{{ car.days }}</td>
28
+        <td style="text-align:right;">{{ car.amount }}</td>
29
+        <td style="text-align:right;">
30
+          <el-input-number :controls="false" style="width:100%;" v-model="car.daysAdjust"
31
+            @change="handleChange(car)"></el-input-number>
32
+        </td>
33
+        <td style="text-align:right;">
34
+          {{ car.amountAdjust }}
22 35
         </td>
23 36
       </tr>
37
+      <tr>
38
+        <td colspan="2" class="amount">车辆成本合计</td>
39
+        <td class="amount" style="text-align:right;">{{carList.reduce((sum, car) => sum +
40
+          (Number(car.depreciation) || 0), 0).toFixed(2)}}</td>
41
+        <td class="amount" style="text-align:right;">{{carList.reduce((sum, car) => sum +
42
+          (Number(car.days) || 0), 0).toFixed(2)}}</td>
43
+        <td class="amount" style="text-align:right;">{{carList.reduce((sum, car) => sum +
44
+          (Number(car.amount) || 0), 0).toFixed(2)}}</td>
45
+        <td class="amount" style="text-align:right;">{{carList.reduce((sum, car) => sum +
46
+          (Number(car.daysAdjust) || 0), 0).toFixed(2)}}</td>
47
+        <td class="amount" style="text-align:right;">{{carList.reduce((sum, car) => sum +
48
+          (Number(car.amountAdjust) || 0), 0).toFixed(2)}}</td>
49
+      </tr>
24 50
     </table>
51
+    <div class="mt10">
52
+      <el-button type="success" plain icon="el-icon-plus" @click="openCar" size="mini">新增车辆</el-button>
53
+    </div>
54
+    <!-- 选择车辆对话框 -->
55
+    <el-dialog title="选择车辆" :visible.sync="isOpenCar" width="700px" append-to-body>
56
+      <choose-car @chooseList="getChooseCar"></choose-car>
57
+    </el-dialog>
25 58
   </div>
26 59
 </template>
27 60
 
28 61
 <script>
62
+import ChooseCar from '../../components/chooseCar.vue'
63
+
29 64
 export default {
30 65
   name: 'CarCost',
66
+  components: {
67
+    ChooseCar
68
+  },
31 69
   props: {
32 70
     carList: {
33 71
       type: Array,
34 72
       default: () => []
35 73
     }
36 74
   },
75
+  data() {
76
+    return {
77
+      isOpenCar: false
78
+    }
79
+  },
37 80
   methods: {
38
-    handleChange() {
81
+    handleChange(car) {
82
+      car.amountAdjust = (Number(car.car.dayCost) * Number(car.daysAdjust)).toFixed(2);
83
+      this.$emit('update:carList', this.carList);
84
+    },
85
+    openCar() {
86
+      this.isOpenCar = true;
87
+    },
88
+    removeCar(car, index) {
89
+      this.$confirm('确实移除【' + car.car.licensePlate + '】吗', '提示', {
90
+        confirmButtonText: '确定',
91
+        cancelButtonText: '取消',
92
+        type: 'warning'
93
+      }).then(() => {
94
+        let arr = this.carList;
95
+        if (arr.length == 1) {
96
+          return;
97
+        }
98
+        if (index >= 0 && index < arr.length) {
99
+          arr.splice(index, 1);
100
+        }
101
+        this.$emit('update:carList', this.carList);
102
+      }).catch(() => { });
103
+    },
104
+    getChooseCar(val) {
105
+      let arr = [];
106
+      for (let car of val) {
107
+        let obj = {
108
+          carId: car.carId,
109
+          car: car,
110
+          days: 0,
111
+          depreciation: car.dayCost,
112
+          amount: 0,
113
+          daysAdjust: 0,
114
+          amountAdjust: 0,
115
+        }
116
+        arr.push(obj);
117
+      }
118
+      this.carList.push(...arr);
119
+      this.isOpenCar = false;
39 120
       this.$emit('update:carList', this.carList);
40 121
     }
41 122
   }
@@ -48,13 +129,25 @@ export default {
48 129
     text-align: center;
49 130
     border-collapse: collapse;
50 131
     margin: 0 auto;
132
+
51 133
     td {
52 134
       padding: 5px;
53 135
     }
54 136
   }
137
+
55 138
   .adjust {
56 139
     color: #F56C6C;
57 140
     width: 120px;
58 141
   }
59 142
 }
60
-</style> 
143
+
144
+.delete-btn {
145
+  cursor: pointer;
146
+  font-size: 18px;
147
+}
148
+
149
+.amount {
150
+  font-weight: bold;
151
+  font-family: Arial, Helvetica, sans-serif;
152
+}
153
+</style>

+ 93
- 14
oa-ui/src/views/flowable/form/budget/adjust/components/DeviceCost.vue ファイルの表示

@@ -2,44 +2,115 @@
2 2
   <div class="device-cost">
3 3
     <table border="1" style="width:100%;">
4 4
       <tr style="background-color:#f8f8f9">
5
+        <td></td>
5 6
         <td>设备名称</td>
7
+        <td>出厂编号</td>
6 8
         <td>规格型号</td>
7 9
         <td>品牌</td>
8
-        <td>折旧成本(天)</td>
9
-        <td>预算天数</td>
10
-        <td>金额</td>
11
-        <td class="adjust">核算天数</td>
12
-        <td class="adjust">核算金额</td>
10
+        <td style="min-width: 120px;">折旧成本(天)</td>
11
+        <td style="min-width: 80px;">预算天数</td>
12
+        <td style="min-width: 80px;">金额</td>
13
+        <td style="min-width: 80px;" class="adjust">核算天数</td>
14
+        <td style="min-width: 80px;" class="adjust">核算金额</td>
13 15
       </tr>
14
-      <tr v-for="device in deviceList" :key="'device' + device.deviceId">
16
+      <tr v-for="device, index in deviceList" :key="'device' + device.deviceId">
17
+        <td>
18
+          <div class="delete-btn" @click="removeDevice(device, index)">
19
+            <i class="el-icon-remove-outline" style="color:#F56C6C"></i>
20
+          </div>
21
+        </td>
15 22
         <td>{{ device.device ? device.device.name : '' }}</td>
23
+        <td>{{ device.device ? device.device.code : '' }}</td>
16 24
         <td>{{ device.device ? device.device.series : '' }}</td>
17 25
         <td>{{ device.device ? device.device.brand : '' }}</td>
18
-        <td>{{ device.device ? device.device.dayCost : '' }}</td>
19
-        <td>{{ device.days }}</td>
20
-        <td>{{ device.amount }}</td>
21
-        <td>
22
-          <el-input-number :controls="false" style="width:100%;" v-model="device.daysAdjust" @change="handleChange"></el-input-number>
26
+        <td style="text-align:right;">{{ device.device ? device.device.dayCost : '' }}</td>
27
+        <td style="text-align:right;">{{ device.days }}</td>
28
+        <td style="text-align:right;">{{ device.amount }}</td>
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>
23 31
         </td>
24
-        <td>
25
-          <el-input-number :controls="false" style="width:100%;" v-model="device.amountAdjust" @change="handleChange"></el-input-number>
32
+        <td style="text-align:right;">
33
+          {{ device.amountAdjust }}
26 34
         </td>
27 35
       </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> -->
28 44
     </table>
45
+    <div class="mt10">
46
+      <el-button type="success" plain icon="el-icon-plus" @click="openDevice" size="mini">新增设备</el-button>
47
+    </div>
48
+    <!-- 选择设备对话框 -->
49
+    <el-dialog title="选择设备" :visible.sync="isOpenDevice" width="700px" append-to-body>
50
+      <choose-device @chooseList="getChooseDevice"></choose-device>
51
+    </el-dialog>
29 52
   </div>
30 53
 </template>
31 54
 
32 55
 <script>
56
+import ChooseDevice from '../../components/chooseDevice.vue'
57
+
33 58
 export default {
34 59
   name: 'DeviceCost',
60
+  components: {
61
+    ChooseDevice
62
+  },
35 63
   props: {
36 64
     deviceList: {
37 65
       type: Array,
38 66
       default: () => []
39 67
     }
40 68
   },
69
+  data() {
70
+    return {
71
+      isOpenDevice: false
72
+    }
73
+  },
41 74
   methods: {
42
-    handleChange() {
75
+    handleChange(device) {
76
+      device.amountAdjust = (Number(device.device.dayCost) * Number(device.daysAdjust)).toFixed(2);
77
+      this.$emit('update:deviceList', this.deviceList);
78
+    },
79
+    openDevice() {
80
+      this.isOpenDevice = true;
81
+    },
82
+    removeDevice(device, index) {
83
+      this.$confirm('确实移除【' + device.device.name + '】吗', '提示', {
84
+        confirmButtonText: '确定',
85
+        cancelButtonText: '取消',
86
+        type: 'warning'
87
+      }).then(() => {
88
+        let arr = this.deviceList;
89
+        if (arr.length == 1) {
90
+          return;
91
+        }
92
+        if (index >= 0 && index < arr.length) {
93
+          arr.splice(index, 1);
94
+        }
95
+        this.$emit('update:deviceList', this.deviceList);
96
+      }).catch(() => { });
97
+    },
98
+    getChooseDevice(val) {
99
+      let arr = [];
100
+      for (let device of val) {
101
+        let obj = {
102
+          deviceId: device.deviceId,
103
+          device: device,
104
+          days: 0,
105
+          depreciation: device.dayCost,
106
+          amount: 0,
107
+          daysAdjust: 0,
108
+          amountAdjust: 0,
109
+        }
110
+        arr.push(obj);
111
+      }
112
+      this.deviceList.push(...arr);
113
+      this.isOpenDevice = false;
43 114
       this.$emit('update:deviceList', this.deviceList);
44 115
     }
45 116
   }
@@ -60,5 +131,13 @@ export default {
60 131
     color: #F56C6C;
61 132
     width: 120px;
62 133
   }
134
+  .delete-btn {
135
+    cursor: pointer;
136
+    font-size: 18px;
137
+  }
138
+  .amount {
139
+    font-weight: bold;
140
+    font-family: Arial, Helvetica, sans-serif;
141
+  }
63 142
 }
64 143
 </style> 

+ 44
- 31
oa-ui/src/views/flowable/form/budget/adjust/components/InnerStaffCost.vue ファイルの表示

@@ -3,22 +3,22 @@
3 3
     <table border="1" style="width:100%">
4 4
       <tr style="background-color:#f8f8f9">
5 5
         <td></td>
6
-        <td>序号</td>
7
-        <td>姓名</td>
8
-        <td>人员成本(天)</td>
9
-        <td style="width:120px">预算天数</td>
10
-        <td>固定成本合计</td>
11
-        <td>绩效成本合计</td>
12
-        <td style="width:120px">预算金额</td>
13
-        <td class="adjust" style="width:120px">核算固定成本</td>
14
-        <td class="adjust" style="width:120px">核算天数</td>
15
-        <td class="adjust" style="width:120px">核算绩效</td>
16
-        <td class="adjust" style="width:120px">核算金额</td>
6
+        <td style="min-width:50px;">序号</td>
7
+        <td style="min-width:80px;">姓名</td>
8
+        <td style="min-width:80px;">人员成本(天)</td>
9
+        <td style="min-width:80px;">预算天数</td>
10
+        <td style="min-width:80px;">固定成本合计</td>
11
+        <td style="min-width:80px;">绩效成本合计</td>
12
+        <td style="width:120px;min-width:80px;">预算金额</td>
13
+        <td class="adjust" style="width:120px;min-width:80px;">核算固定成本</td>
14
+        <td class="adjust" style="width:120px;min-width:80px;">核算天数</td>
15
+        <td class="adjust" style="width:120px;min-width:80px;">核算绩效</td>
16
+        <td class="adjust" style="width:120px;min-width:80px;">核算金额</td>
17 17
       </tr>
18 18
       <tr v-for="staff, index in staffList" :key="'user' + index">
19 19
         <td>
20 20
           <!-- <el-button type="danger" icon="el-icon-minus" circle plain></el-button> -->
21
-          <div class="delete-btn" v-if="index + 1 > lens" @click="removeStaff(index)"><i class="el-icon-remove-outline"
21
+          <div class="delete-btn" @click="removeStaff(staff, index)"><i class="el-icon-remove-outline"
22 22
               style="color:#F56C6C"></i>
23 23
           </div>
24 24
         </td>
@@ -46,7 +46,7 @@
46 46
         <td colspan="5" class="head amount">内业人员成本合计</td>
47 47
         <td class="head amount" style="text-align:right;">{{staffList.reduce((sum, staff) => sum +
48 48
           (Number(staff.staffCost) || 0), 0).toFixed(2)}}</td>
49
-        <td class="head amount" style="text-align:right;">{{staffList.reduce((sum, staff) => sum +
49
+        <td class="head amount"  :class="{ 'performance-error': isPerformanceExceeded() }" style="text-align:right;">{{staffList.reduce((sum, staff) => sum +
50 50
           (Number(staff.performance) || 0), 0).toFixed(2)}}</td>
51 51
         <td class="head amount" style="text-align:right;">{{staffList.reduce((sum, staff) => sum + (Number(staff.amount)
52 52
           || 0), 0).toFixed(2)}}</td>
@@ -54,9 +54,9 @@
54 54
           ((staff.dayCost * staff.daysAdjust)), 0).toFixed(2)}}</td>
55 55
         <td class="head amount" style="text-align:right;">{{staffList.reduce((sum, staff) => sum +
56 56
           (Number(staff.daysAdjust) || 0), 0).toFixed(2)}}</td>
57
-        <td class="head amount" :class="{ 'performance-error': isPerformanceExceeded() }" style="text-align:right;">
57
+        <td class="head amount" :class="{ 'performance-error': isPerformanceAdjustExceeded() }" style="text-align:right;">
58 58
           {{staffList.reduce((sum, staff) => sum + (Number(staff.performanceAdjust) || 0), 0).toFixed(2)}}</td>
59
-        <td class="head amount" :class="{ 'performance-error': isPerformanceExceeded() }" style="text-align:right;">
59
+        <td class="head amount" style="text-align:right;">
60 60
           {{staffList.reduce((sum, staff) => sum + (Number(staff.amountAdjust) || 0), 0).toFixed(2)}}</td>
61 61
       </tr>
62 62
     </table>
@@ -86,19 +86,21 @@ export default {
86 86
     settleExpense: {
87 87
       type: Number,
88 88
       default: 0
89
+    },
90
+    settleAdjust: {
91
+      type: Number,
92
+      default: 0
89 93
     }
90 94
   },
91 95
   data() {
92 96
     return {
93 97
       isOpenPeople: false,
94
-      lens: 0,
95 98
     }
96 99
   },
97 100
   watch: {
98 101
 
99 102
   },
100 103
   mounted() {
101
-    this.lens = this.staffList.length;
102 104
   },
103 105
   methods: {
104 106
     handleChange(staff) {
@@ -109,24 +111,31 @@ export default {
109 111
       this.isOpenPeople = true;
110 112
     },
111 113
     getChooseUser(val) {
114
+      let arr = [];
112 115
       for (let v of val) {
113
-        v.days = 0;
114
-        v.settle = 0;
115
-        v.amount = 0;
116
-        v.user = v;
117
-        v.dayCost = parseFloat(((v.salary.salary + 1780) * 12) / 365).toFixed(2);
118
-        v.staffCost = 0;
119
-        v.performance = 0;
120
-        v.daysAdjust = 0;
121
-        v.performanceAdjust = 0;
122
-        v.amountAdjust = 0;
116
+        let dayCost = (parseFloat(((v.salary.salary + 1780) * 12) / 365) + v.socialSecurityUnit + v.houseFund).toFixed(2);
117
+        let obj = {};
118
+        obj.days = 0;
119
+        obj.settle = 0;
120
+        obj.amount = 0;
121
+        obj.user = v;
122
+        obj.dayCost = dayCost;
123
+        obj.staffCost = 0;
124
+        obj.performance = 0;
125
+        obj.salary = v.salary;
126
+        obj.userId = v.userId;
127
+        this.$set(obj, 'type', '内业');
128
+        this.$set(obj, 'daysAdjust', 0);
129
+        this.$set(obj, 'performanceAdjust', 0);
130
+        this.$set(obj, 'amountAdjust', 0);
131
+        arr.push(obj);
123 132
       }
124
-      this.staffList.push(...val);
133
+      this.staffList.push(...arr);
125 134
       this.isOpenPeople = false;
126 135
       this.$emit('update:staffList', this.staffList);
127 136
     },
128
-    removeStaff(index) {
129
-      this.$confirm('确实移除该人员吗', '提示', {
137
+    removeStaff(staff, index) {
138
+      this.$confirm('确实移除【' + staff.user.nickName + '】吗', '提示', {
130 139
         confirmButtonText: '确定',
131 140
         cancelButtonText: '取消',
132 141
         type: 'warning'
@@ -141,8 +150,12 @@ export default {
141 150
       }).catch(() => { });
142 151
     },
143 152
     isPerformanceExceeded() {
144
-      const totalPerformance = this.staffList.reduce((sum, staff) => sum + (Number(staff.performanceAdjust) || 0), 0);
153
+      const totalPerformance = this.staffList.reduce((sum, staff) => sum + (Number(staff.performance) || 0), 0);
145 154
       return totalPerformance > Number(this.settleExpense);
155
+    },
156
+    isPerformanceAdjustExceeded() {
157
+      const totalPerformanceAdjust = this.staffList.reduce((sum, staff) => sum + (Number(staff.performanceAdjust) || 0), 0);
158
+      return totalPerformanceAdjust > Number(this.settleAdjust);
146 159
     }
147 160
   }
148 161
 }

+ 45
- 26
oa-ui/src/views/flowable/form/budget/adjust/components/OuterStaffCost.vue ファイルの表示

@@ -3,22 +3,23 @@
3 3
     <table border="1" style="width:100%">
4 4
       <tr style="background-color:#f8f8f9">
5 5
         <td></td>
6
-        <td>序号</td>
7
-        <td>姓名</td>
8
-        <td>人员成本(天)</td>
9
-        <td style="width:120px">预算天数</td>
10
-        <td>预算系数</td>
11
-        <td>固定成本合计</td>
12
-        <td>绩效成本合计</td>
13
-        <td style="width:120px">金额</td>
14
-        <td class="adjust" style="width:120px">核算固定成本</td>
15
-        <td class="adjust" style="width:120px">核算天数</td>
16
-        <td class="adjust" style="width:120px">核算系数</td>
17
-        <td class="adjust" style="width:120px">核算金额</td>
6
+        <td style="min-width:50px;">序号</td>
7
+        <td style="min-width:80px;">姓名</td>
8
+        <td style="min-width:80px;">人员成本(天)</td>
9
+        <td style="min-width:80px;">预算天数</td>
10
+        <td style="min-width:80px;">预算系数</td>
11
+        <td style="min-width:100px;">固定成本合计</td>
12
+        <td style="min-width:100px;">绩效成本合计</td>
13
+        <td style="width:120px;min-width:80px;">预算金额</td>
14
+        <td class="adjust" style="width:120px;min-width:80px;">核算固定成本</td>
15
+        <td class="adjust" style="width:120px;min-width:80px;">核算天数</td>
16
+        <td class="adjust" style="width:120px;min-width:80px;">核算系数</td>
17
+        <td class="adjust" style="width:120px;min-width:80px;">核算绩效</td>
18
+        <td class="adjust" style="width:120px;min-width:80px;">核算金额</td>
18 19
       </tr>
19 20
       <tr v-for="staff, index in staffList" :key="'user' + staff.userId">
20 21
         <td>
21
-          <div class="delete-btn" v-if="index + 1 > lens" @click="removeStaff(index)">
22
+          <div class="delete-btn" @click="removeStaff(staff, index)">
22 23
             <i class="el-icon-remove-outline" style="color:#F56C6C"></i>
23 24
           </div>
24 25
         </td>
@@ -39,6 +40,9 @@
39 40
           <el-input-number :controls="false" style="width:100%;" v-model="staff.coefficientAdjust"
40 41
             @change="handleChange(staff)"></el-input-number>
41 42
         </td>
43
+        <td style="text-align:right;">
44
+          {{ staff.performanceAdjust }}
45
+        </td>
42 46
         <td style="text-align:right;">
43 47
           {{ staff.amountAdjust }}
44 48
         </td>
@@ -58,8 +62,11 @@
58 62
           ((staff.dayCost * staff.daysAdjust)), 0).toFixed(2)}}</td>
59 63
         <td class="head amount" style="text-align:right;">{{staffList.reduce((sum, staff) => sum +
60 64
           (Number(staff.daysAdjust) || 0), 0).toFixed(2)}}</td>
65
+        <td class="head amount">
66
+          ——
67
+        </td>
61 68
         <td class="head amount" style="text-align:right;">
62
-         ——
69
+          {{staffList.reduce((sum, staff) => sum + (Number(staff.performanceAdjust) || 0), 0).toFixed(2)}}
63 70
         </td>
64 71
         <td class="head amount" style="text-align:right;">
65 72
           {{staffList.reduce((sum, staff) => sum + (Number(staff.amountAdjust) || 0), 0).toFixed(2)}}</td>
@@ -92,42 +99,54 @@ export default {
92 99
   data() {
93 100
     return {
94 101
       isOpenPeople: false,
95
-      lens: 0
96 102
     }
97 103
   },
98 104
   watch: {
99 105
     staffList(newval, oldval) {
100 106
       if (oldval.length == 0) {
101
-        this.lens = newval.length;
107
+
102 108
       }
103 109
     }
104 110
   },
105 111
   mounted() {
106
-    this.lens = this.staffList.length;
112
+
107 113
   },
108 114
   methods: {
109 115
     handleChange(staff) {
110 116
       // 计算调整后的金额
111
-      staff.amountAdjust = (Number(staff.dayCost) * Number(staff.daysAdjust) + (200 * Number(staff.daysAdjust) * Number(staff.coefficient))).toFixed(2)
117
+      staff.performanceAdjust = (200 * Number(staff.daysAdjust) * Number(staff.coefficientAdjust)).toFixed(2)
118
+      staff.amountAdjust = (Number(staff.dayCost) * Number(staff.daysAdjust) + Number(staff.performanceAdjust)).toFixed(2)
112 119
       this.$emit('update:staffList', this.staffList);
113 120
     },
114 121
     openPeople() {
115 122
       this.isOpenPeople = true;
116 123
     },
117 124
     getChooseUser(val) {
125
+      let arr = [];
118 126
       for (let v of val) {
119
-        v.daysAdjust = 0;
120
-        v.coefficientAdjust = 1;
121
-        v.otherCoefficientAdjust = 1;
122
-        v.amountAdjust = 0;
123
-        v.user = v;
127
+        let dayCost = (parseFloat(((v.salary.salary + 1780) * 12) / 365) + v.socialSecurityUnit + v.houseFund).toFixed(2);
128
+        let obj = {};
129
+        obj.user = v;
130
+        obj.dayCost = dayCost;
131
+        obj.staffCost = 0;
132
+        obj.performance = 0;
133
+        obj.amount = 0;
134
+        obj.days = 0;
135
+        obj.coefficient = 1;
136
+        obj.salary = v.salary;
137
+        obj.userId = v.userId;
138
+        this.$set(obj, 'type', '外业');
139
+        this.$set(obj, 'daysAdjust', 0);
140
+        this.$set(obj, 'coefficientAdjust', 0);
141
+        this.$set(obj, 'amountAdjust', 0);
142
+        arr.push(obj);
124 143
       }
125
-      this.staffList.push(...val);
144
+      this.staffList.push(...arr);
126 145
       this.isOpenPeople = false;
127 146
       this.$emit('update:staffList', this.staffList);
128 147
     },
129
-    removeStaff(index) {
130
-      this.$confirm('确实移除该人员吗', '提示', {
148
+    removeStaff(staff, index) {
149
+      this.$confirm('确实移除【' + staff.user.nickName + '】吗', '提示', {
131 150
         confirmButtonText: '确定',
132 151
         cancelButtonText: '取消',
133 152
         type: 'warning'

+ 70
- 0
oa-ui/src/views/flowable/form/budget/adjust/components/SiteCost.vue ファイルの表示

@@ -0,0 +1,70 @@
1
+<template>
2
+  <div class="site-cost">
3
+    <table border="1" style="width:100%;">
4
+      <tr style="background-color:#f8f8f9">
5
+        <td>开支项</td>
6
+        <td>金额</td>
7
+        <td class="adjust">核算金额</td>
8
+      </tr>
9
+      <tr v-for="site in siteList" :key="site.id">
10
+        <td>{{ site.name }}</td>
11
+        <td style="text-align: right;">{{ site.amount }}</td>
12
+        <td>
13
+          <el-input-number :controls="false" v-model="site.amountAdjust" placeholder="请输入核算金额"
14
+            @change="handleSiteChange(site)" />
15
+        </td>
16
+      </tr>
17
+      <tr>
18
+        <td class="amount" colspan="1">现场开支合计</td>
19
+        <td class="amount" style="text-align: right;">{{siteList.reduce((sum, site) => sum + (Number(site.amount)
20
+          || 0), 0).toFixed(2)}}</td>
21
+        <td class="amount" style="text-align: right;">{{siteList.reduce((sum, site) => sum + (Number(site.amountAdjust)
22
+          || 0), 0).toFixed(2)}}</td>
23
+      </tr>
24
+    </table>
25
+  </div>
26
+</template>
27
+
28
+<script>
29
+export default {
30
+  props: {
31
+    siteList: {
32
+      type: Array,
33
+      default: () => []
34
+    }
35
+  },
36
+  methods: {
37
+    handleSiteChange(site) {
38
+      this.$emit('update:siteList', this.siteList);
39
+    }
40
+  },
41
+}
42
+</script>
43
+
44
+<style lang="scss" scoped>
45
+.site-cost {
46
+  .add-staff {
47
+    margin-bottom: 10px;
48
+  }
49
+
50
+  table {
51
+    text-align: center;
52
+    border-collapse: collapse;
53
+    margin: 0 auto;
54
+
55
+    td {
56
+      padding: 5px;
57
+    }
58
+  }
59
+
60
+  .adjust {
61
+    color: #F56C6C;
62
+    width: 120px;
63
+  }
64
+}
65
+
66
+.amount {
67
+  font-weight: bold;
68
+  font-family: Arial, Helvetica, sans-serif;
69
+}
70
+</style>

+ 144
- 0
oa-ui/src/views/flowable/form/budget/adjust/components/businessCost.vue ファイルの表示

@@ -0,0 +1,144 @@
1
+<!--
2
+ * @Author: ysh
3
+ * @Date: 2025-05-15 18:24:27
4
+ * @LastEditors: Please set LastEditors
5
+ * @LastEditTime: 2025-05-15 18:37:17
6
+-->
7
+<template>
8
+  <div class="business-cost">
9
+    <table border="1" style="width:100%;">
10
+      <tr style="background-color:#f8f8f9">
11
+        <td>序号</td>
12
+        <td>名称</td>
13
+        <td>金额</td>
14
+        <td class="adjust">核算金额</td>
15
+        <td>备注</td>
16
+      </tr>
17
+      <tr>
18
+        <td>{{ 1 }}</td>
19
+        <td>外协费用</td>
20
+        <td style="text-align:right;">
21
+          {{ budgetForm.outExpense }}
22
+        </td>
23
+        <td style="text-align:right;">
24
+          <el-input-number :controls="false" v-model="budgetForm.outExpenseAdjust" :min="0" :step="0.01"
25
+            @change="updateTotalJYAmount"></el-input-number>
26
+        </td>
27
+        <td class="remark-cell">{{ budgetForm.outRemark }}</td>
28
+      </tr>
29
+      <tr>
30
+        <td>{{ 2 }}</td>
31
+        <td>保函费用</td>
32
+        <td style="text-align:right;">
33
+          {{ budgetForm.letterExpense }}
34
+        </td>
35
+        <td style="text-align:right;">
36
+          <el-input-number :controls="false" v-model="budgetForm.letterExpenseAdjust" :min="0" :step="0.01"
37
+            @change="updateTotalJYAmount"></el-input-number>
38
+        </td>
39
+        <td class="remark-cell">{{ budgetForm.letterRemark }}</td>
40
+      </tr>
41
+      <tr>
42
+        <td>{{ 3 }}</td>
43
+        <td>中标服务费</td>
44
+        <td style="text-align:right;">
45
+          {{ budgetForm.winExpense }}
46
+        </td>
47
+        <td class="remark-cell">{{ budgetForm.winRemark }}</td>
48
+      </tr>
49
+      <tr>
50
+        <td>{{ 4 }}</td>
51
+        <td>税费</td>
52
+        <td style="text-align:right;">
53
+          {{ budgetForm.taxExpense }}
54
+        </td>
55
+        <td style="text-align:right;">
56
+          <el-input-number :controls="false" v-model="budgetForm.taxExpenseAdjust" :min="0" :step="0.01"
57
+            @change="updateTotalJYAmount"></el-input-number>
58
+        </td>
59
+        <td class="remark-cell">{{ budgetForm.taxRemark }}</td>
60
+      </tr>
61
+      <tr>
62
+        <td>{{ 5 }}</td>
63
+        <td>差旅费用</td>
64
+        <td style="text-align:right;">
65
+          {{ budgetForm.travelExpense }}
66
+        </td>
67
+        <td style="text-align:right;">
68
+          <el-input-number :controls="false" v-model="budgetForm.travelExpenseAdjust" :min="0" :step="0.01"
69
+            @change="updateTotalJYAmount"></el-input-number>
70
+        </td>
71
+        <td class="remark-cell">{{ budgetForm.travelRemark }}</td>
72
+      </tr>
73
+      <tr>
74
+        <td colspan="2" class="amount">经营相关合计</td>
75
+        <td class="amount" style="text-align:right;">
76
+          {{ totalJYAmount }}
77
+        </td>
78
+        <td class="amount" style="text-align:right;">
79
+          {{ totalJYAmountAdjust }}
80
+        </td>
81
+      </tr>
82
+    </table>
83
+  </div>
84
+</template>
85
+
86
+<script>
87
+export default {
88
+  props: {
89
+    budgetForm: {
90
+      type: Object,
91
+      required: true
92
+    }
93
+  },
94
+  data() {
95
+    return {
96
+      totalJYAmount: 0,
97
+      totalJYAmountAdjust: 0
98
+    }
99
+  },
100
+  created() {
101
+    this.initTotalJYAmount();
102
+  },
103
+  methods: {
104
+    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)
106
+    },
107
+    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)
109
+    }
110
+  }
111
+}
112
+</script>
113
+
114
+<style lang="scss" scoped>
115
+.business-cost {
116
+  .add-staff {
117
+    margin-bottom: 10px;
118
+  }
119
+
120
+  table {
121
+    text-align: center;
122
+    border-collapse: collapse;
123
+    margin: 0 auto;
124
+
125
+    td {
126
+      padding: 5px;
127
+    }
128
+  }
129
+
130
+  .adjust {
131
+    color: #F56C6C;
132
+    width: 120px;
133
+  }
134
+}
135
+
136
+.amount {
137
+  font-weight: bold;
138
+  font-family: Arial, Helvetica, sans-serif;
139
+}
140
+
141
+.remark-cell {
142
+  text-align: left;
143
+}
144
+</style>

+ 25
- 9
oa-ui/src/views/flowable/form/budget/adjust/newBudgetInfo.vue ファイルの表示

@@ -2,7 +2,7 @@
2 2
  * @Author: ysh
3 3
  * @Date: 2025-05-07 11:01:39
4 4
  * @LastEditors: Please set LastEditors
5
- * @LastEditTime: 2025-05-14 14:18:45
5
+ * @LastEditTime: 2025-05-15 17:40:52
6 6
 -->
7 7
 <template>
8 8
   <div class="main" v-loading="loading">
@@ -61,6 +61,7 @@
61 61
           <tr style="background-color:#f8f8f9" v-if="workList.length != 0">
62 62
             <td style="min-width:50px">工作简述</td>
63 63
             <td style="min-width:50px">工作内容</td>
64
+            <td style="min-width:50px">内容细项</td>
64 65
             <td style="min-width:50px">比例尺/等级</td>
65 66
             <td style="min-width:50px">数量</td>
66 67
             <td style="min-width:50px">单价</td>
@@ -71,7 +72,8 @@
71 72
           </tr>
72 73
           <tr v-for="work in workList">
73 74
             <td>{{ work.content }}</td>
74
-            <td>{{ work.cmcPrice ? work.cmcPrice.workItem : '' }}</td>
75
+            <td>{{ work.workItem }}</td>
76
+            <td>{{ work.subItem }}</td>
75 77
             <td>
76 78
               {{ work.scaleGrade }}
77 79
             </td>
@@ -95,7 +97,7 @@
95 97
             <td class="remark-cell">{{ work.remark ? work.remark : '' }}</td>
96 98
           </tr>
97 99
           <tr>
98
-            <td :colspan="7" class="head amount">内业绩效额合计</td>
100
+            <td :colspan="8" class="head amount">内业绩效额合计</td>
99 101
             <td :colspan="1" class="head amount" :class="{ 'performance-error': isPerformanceExceeded() }"
100 102
               style="text-align:right;">
101 103
               {{ budgetForm.settleExpense ? budgetForm.settleExpense.toFixed(2) : '0.00' }}
@@ -130,7 +132,7 @@
130 132
               <el-input-number style="width:80px;" :controls="false" v-model="staff.performance" :min="0" :step="0.01"
131 133
                 @change="(val) => updateInnerStaffAmount(staff, val, 'performance')"></el-input-number>
132 134
             </td>
133
-            <td v-else>{{ staff.performance }}</td>
135
+            <td v-else style="text-align:right;">{{ staff.performance }}</td>
134 136
             <td style="text-align:right;">{{ staff.amount }}</td>
135 137
             <td class="remark-cell">{{ staff.remark }}</td>
136 138
           </tr>
@@ -576,14 +578,28 @@ export default {
576 578
           let settleRes = await listBudgetSettle({ pageSize: 100, budgetId });
577 579
           this.workList = settleRes.rows;
578 580
           for (let work of this.workList) {
579
-            if (work.groundType == '0') {
580
-              work.price = work.cmcPrice.commonPrice
581
-              work.scaleGrade = work.cmcPrice.scaleGrade
582
-              work.unit = work.cmcPrice.unit
581
+            if (work.checkPriceId) {
582
+              work.workType = work.cmcCheckPrice.workType
583
+              work.workItem = work.cmcCheckPrice.workItem
584
+              work.subItem = work.cmcCheckPrice.subItem
585
+              work.scaleGrade = work.cmcCheckPrice.scaleGrade
586
+              work.unit = work.cmcCheckPrice.unit
587
+              if (work.groundType == '0') {
588
+                work.price = work.cmcCheckPrice.commonPrice
589
+              } else {
590
+                work.price = work.cmcCheckPrice.complexPrice
591
+              }
583 592
             } else {
584
-              work.price = work.cmcPrice.complexPrice
593
+              work.workType = work.cmcPrice.workType
594
+              work.workItem = work.cmcPrice.workItem
595
+              work.subItem = work.cmcPrice.subItem
585 596
               work.scaleGrade = work.cmcPrice.scaleGrade
586 597
               work.unit = work.cmcPrice.unit
598
+              if (work.groundType == '0') {
599
+                work.price = work.cmcPrice.commonPrice
600
+              } else {
601
+                work.price = work.cmcPrice.complexPrice
602
+              }
587 603
             }
588 604
           }
589 605
           // 获取现场开支

+ 10
- 0
oa-ui/src/views/flowable/form/budget/components/choosePeople.vue ファイルの表示

@@ -58,6 +58,7 @@
58 58
 <script>
59 59
 import { listUser, deptTreeSelect } from "@/api/system/user";
60 60
 import { listDept } from "@/api/system/dept";
61
+import { getUserDayValue } from "@/api/oa/wage/wage";
61 62
 export default {
62 63
   dicts: ['sys_normal_disable', 'sys_user_sex', 'sys_user_titles', 'sys_user_certificates', 'sys_user_pmlevel', 'sys_user_postlevel', 'sys_user_salarylevel'],
63 64
   props: {
@@ -93,6 +94,15 @@ export default {
93 94
     getList() {
94 95
       listUser(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
95 96
         this.userList = response.rows.filter(item => item.status != '1' && item.status != '2')
97
+        let month = this.parseTime(new Date(), '{y}-{m}')
98
+        this.userList.forEach(item => {
99
+          getUserDayValue({ userId: item.userId, payMonth: month }).then(res => {
100
+            if (res.data) {
101
+              item.socialSecurityUnit = res.data.socialSecurityUnit
102
+              item.houseFund = res.data.houseFund
103
+            }
104
+          })
105
+        })
96 106
         this.total = response.total;
97 107
       });
98 108
     },

+ 77
- 42
oa-ui/src/views/flowable/form/budget/moneyTable.vue ファイルの表示

@@ -16,27 +16,13 @@
16 16
             <td colspan="4">备注</td>
17 17
           </tr>
18 18
           <tr v-for="(work, index) in workList" :key="index">
19
-            <td>
20
-              {{ index + 1 }}
21
-            </td>
22
-            <td colspan="2">
23
-              {{ work.content }}
24
-            </td>
25
-            <td>
26
-              {{ work.scale }}
27
-            </td>
28
-            <td>
29
-              {{ work.unit }}
30
-            </td>
31
-            <td>
32
-              {{ work.workload }}
33
-            </td>
34
-            <td>
35
-              {{ work.deadline }}
36
-            </td>
37
-            <td colspan="4">
38
-              {{ work.remark }}
39
-            </td>
19
+            <td>{{ index + 1 }}</td>
20
+            <td colspan="2">{{ work.content }}</td>
21
+            <td>{{ work.scale }}</td>
22
+            <td>{{ work.unit }}</td>
23
+            <td>{{ work.workload }}</td>
24
+            <td> {{ work.deadline }}</td>
25
+            <td colspan="4">{{ work.remark }}</td>
40 26
           </tr>
41 27
         </table>
42 28
       </el-form-item>
@@ -47,8 +33,9 @@
47 33
           </tr>
48 34
           <tr class="content-head">
49 35
             <td style="width: 100px;">工作简述</td>
50
-            <td style="width: 100px;">工作类别</td>
51
-            <td style="width: 100px;">工作项目</td>
36
+            <!-- <td style="width: 100px;">工作类别</td> -->
37
+            <td style="width: 100px;">工作内容</td>
38
+            <td style="width: 100px;">内容细项</td>
52 39
             <td style="width: 80px;">比例尺/等级</td>
53 40
             <td style="width: 80px;">地类类型</td>
54 41
             <td style="width: 50px;">单价</td>
@@ -67,18 +54,26 @@
67 54
               <el-input type="textarea" v-model="work.content"></el-input>
68 55
             </td>
69 56
             <!-- 选择工作类别 -->
70
-            <td>
57
+            <!-- <td>
71 58
               <el-select v-model="work.workType" :style="{ width: '100%' }"
72 59
                 @change="getWorkItemList(work, work.workType)">
73 60
                 <el-option v-for="item in workTypeList" :key="item.value" :label="item.label" :value="item.value">
74 61
                 </el-option>
75 62
               </el-select>
76
-            </td>
63
+            </td> -->
77 64
             <!-- 选择工作项目 -->
78 65
             <td>
79 66
               <el-select v-model="work.workItem" :style="{ width: '100%' }" :remote="true"
80 67
                 @change="getScaleGradeList(work, work.workItem)">
81
-                <el-option v-for="item in work.workSelect.workItemList" :key="item.value" :label="item.label"
68
+                <el-option v-for="item in workItemList" :key="item.value" :label="item.label" :value="item.value">
69
+                </el-option>
70
+              </el-select>
71
+            </td>
72
+            <!-- 选择内容细项 -->
73
+            <td>
74
+              <el-select v-model="work.subItem" :style="{ width: '100%' }" :remote="true"
75
+                @change="setRemarkBySubItem(work, work.subItem)">
76
+                <el-option v-for="item in work.workSelect.subItemList" :key="item.value" :label="item.label"
82 77
                   :value="item.value">
83 78
                 </el-option>
84 79
               </el-select>
@@ -120,9 +115,9 @@
120 115
               <el-input-number v-model="work.coefficient" :controls="false" :precision="2" :step="0.01" :max="10"
121 116
                 @blur="getTotal(work)" style="width:60px;">
122 117
               </el-input-number>
123
-              <el-tooltip content="系数备注" placement="right-start">
118
+              <!-- <el-tooltip content="系数备注" placement="right-start">
124 119
                 <el-button icon="el-icon-info" type="text" @click="getCoefficientRemark(work.workType)"></el-button>
125
-              </el-tooltip>
120
+              </el-tooltip> -->
126 121
 
127 122
             </td>
128 123
             <!-- 备注 -->
@@ -149,7 +144,8 @@
149 144
 import { listProjectWork } from "@/api/oa/project/projectWork";
150 145
 import { getPriceRemarkByWorkType } from '@/api/oa/price/price'
151 146
 import { listBudgetSettle, addBudgetSettle, delBudgetSettle } from "@/api/oa/budget/budgetSettle.js";
152
-import { getWorkTypeList, getWorkItemList, getSubItemList, getScaleGradeList, getUnitPrice } from '@/api/oa/price/price'
147
+// import { getWorkTypeList, getWorkItemList, getSubItemList, getScaleGradeList, getUnitPrice } from '@/api/oa/price/price'
148
+import { getWorkTypeList, getWorkItemList, getSubItemList, getScaleGradeList, getUnitPrice } from '@/api/oa/price/checkPrice'
153 149
 export default {
154 150
   props: {
155 151
     projectId: {
@@ -166,11 +162,13 @@ export default {
166 162
       form: {},
167 163
       workList: [],//项目概况工作列表
168 164
       workTypeList: [],
165
+      workItemList: [],
169 166
       contentList: [
170 167
         {
171 168
           content: '',
172 169
           workType: '',
173 170
           workItem: '',
171
+          subItem: '',
174 172
           scaleGrade: '',
175 173
           groundType: '0',
176 174
           price: '',
@@ -204,7 +202,7 @@ export default {
204 202
     },
205 203
     contentList: {
206 204
       handler(newVal) {
207
-        let list = newVal.filter(item => item.priceId);
205
+        let list = newVal.filter(item => item.checkPriceId);
208 206
         this.$emit('contentList', list)
209 207
       },
210 208
       immediate: true, // 立即生效
@@ -213,7 +211,8 @@ export default {
213 211
   },
214 212
   created() {
215 213
     this.initTable();
216
-    this.initWorkTypeList();
214
+    // this.initWorkTypeList();
215
+    this.initWorkItemList();
217 216
   },
218 217
   methods: {
219 218
     initTable() {
@@ -249,14 +248,28 @@ export default {
249 248
           subItemLoading: true,
250 249
           scaleGradeLoading: true,
251 250
         })
252
-        this.$set(c, 'workType', c.cmcPrice.workType)
253
-        this.$set(c, 'scaleGrade', c.cmcPrice.scaleGrade)
254
-        this.$set(c, 'workItem', c.cmcPrice.workItem)
255
-        this.$set(c, 'unit', c.cmcPrice.unit)
256
-        if (c.groundType == '0') {
257
-          this.$set(c, 'price', c.cmcPrice.commonPrice)
251
+        if (c.checkPriceId) {
252
+          this.$set(c, 'workType', c.cmcCheckPrice.workType)
253
+          this.$set(c, 'workItem', c.cmcCheckPrice.workItem)
254
+          this.$set(c, 'subItem', c.cmcCheckPrice.subItem)
255
+          this.$set(c, 'scaleGrade', c.cmcCheckPrice.scaleGrade)
256
+          this.$set(c, 'unit', c.cmcCheckPrice.unit)
257
+          if (c.groundType == '0') {
258
+            this.$set(c, 'price', c.cmcCheckPrice.commonPrice)
259
+          } else {
260
+            this.$set(c, 'price', c.cmcCheckPrice.complexPrice)
261
+          }
258 262
         } else {
259
-          this.$set(c, 'price', c.cmcPrice.complexPrice)
263
+          this.$set(c, 'workType', c.cmcPrice.workType)
264
+          this.$set(c, 'scaleGrade', c.cmcPrice.scaleGrade)
265
+          this.$set(c, 'workItem', c.cmcPrice.workItem)
266
+          this.$set(c, 'unit', c.cmcPrice.unit)
267
+          this.$set(c, 'groundType', c.cmcPrice.groundType)
268
+          if (c.groundType == '0') {
269
+            this.$set(c, 'price', c.cmcPrice.commonPrice)
270
+          } else {
271
+            this.$set(c, 'price', c.cmcPrice.complexPrice)
272
+          }
260 273
         }
261 274
         this.getTotal(c)
262 275
       }
@@ -269,6 +282,13 @@ export default {
269 282
         }
270 283
       });
271 284
     },
285
+    initWorkItemList() {
286
+      getWorkItemList({ workType: '内业' }).then(res => {
287
+        if (res) {
288
+          this.workItemList = this.setArray(res);
289
+        }
290
+      })
291
+    },
272 292
     /* 获取工作项目 */
273 293
     getWorkItemList(work, workType) {
274 294
       getWorkItemList({ workType: workType }).then(res => {
@@ -281,8 +301,24 @@ export default {
281 301
         }
282 302
       })
283 303
     },
304
+    // 获取内容细项
305
+    getWorkSubItemList(work, workItem) {
306
+      getSubItemList({ workItem }).then(res => {
307
+        if (res) {
308
+          let subItemList = this.setArray(res);
309
+          work.workSelect.subItemList = subItemList;
310
+          this.$set(work, 'subItem', subItemList[0].label);
311
+          this.$set(work, 'remark', subItemList[0].remark);
312
+        }
313
+      })
314
+    },
315
+    // 设置备注
316
+    setRemarkBySubItem(work) {
317
+      this.getUnitPrice(work, work.workItem, work.subItem, work.scaleGrade, work.groundType);
318
+    },
284 319
     /* 获取比例尺 */
285 320
     getScaleGradeList(work, workItem) {
321
+      this.getWorkSubItemList(work, workItem);
286 322
       if (work.scale) {
287 323
         this.$set(work, 'scaleGrade', work.scale);
288 324
         if (work.groundType == undefined) {
@@ -295,8 +331,7 @@ export default {
295 331
             let scaleGradeList = this.setArray(res);
296 332
             work.workSelect.scaleGradeLoading = false;
297 333
             work.workSelect.scaleGradeList = scaleGradeList;
298
-            this.$set(work, 'scaleGrade', scaleGradeList[0].label)
299
-            // work.scaleGrade = scaleGradeList[0].label;
334
+            this.$set(work, 'scaleGrade', scaleGradeList[0].label);
300 335
             if (work.scaleGrade == undefined) {
301 336
               this.$set(work, 'scaleGrade', '无');
302 337
             }
@@ -312,12 +347,12 @@ export default {
312 347
     getUnitPrice(work, workItem, subItem, scaleGrade, groundType) {
313 348
       getUnitPrice({ workItem, subItem, scaleGrade, groundType: groundType }).then(res => {
314 349
         if (res.length != 0) {
315
-          work.priceId = res.data.id;
350
+          work.checkPriceId = res.data.id;
316 351
           this.$set(work, 'price', res.data.price)
317 352
           this.$set(work, 'unit', res.data.unit)
318 353
           this.$set(work, 'coefficient', 1)
354
+          this.$set(work, 'remark', res.data.remark)
319 355
           if (work.workload != undefined || work.workload != '') {
320
-
321 356
             this.getTotal(work);
322 357
           }
323 358
         }

+ 3
- 2
oa-ui/src/views/flowable/form/budget/staffTable.vue ファイルの表示

@@ -280,12 +280,13 @@ export default {
280 280
         if (v.deptId === 115) {
281 281
           v.salary = { salary: 7898.75 }
282 282
         }
283
+        let dayCost = (parseFloat(((v.salary.salary + 1780) * 12) / 365) + v.socialSecurityUnit + v.houseFund).toFixed(2);
283 284
         v.type = this.currentType === 'inner' ? '内业' : '外业';
284 285
         v.days = 0; // 初始化天数为0
285 286
         v.staffCost = 0; // 初始化成本为0
286 287
         v.coefficient = 1; // 初始化系数为1
287 288
         v.otherCoefficient = 1; // 初始化其他系数为1
288
-        v.userDays = parseFloat(((v.salary.salary + 1780) * 12) / 365).toFixed(2);
289
+        v.dayCost = dayCost;
289 290
       }
290 291
       if (this.currentType === 'inner') {
291 292
         this.innerUsers = val;
@@ -316,7 +317,7 @@ export default {
316 317
         user.performance = 200 * Number(user.days) * Number(user.coefficient);
317 318
       }
318 319
       if (!user.dayCost) {
319
-        user.dayCost = parseFloat(((user.salary.salary + 1780) * 12) / 365).toFixed(2)
320
+        user.dayCost = (parseFloat(((user.salary.salary + 1780) * 12) / 365) + user.socialSecurityUnit + user.houseFund).toFixed(2);
320 321
       }
321 322
       let staffCost = Number(user.dayCost) * Number(user.days)
322 323
       total = user.dayCost * Number(user.days) + Number(user.performance);

+ 91
- 16
oa-ui/src/views/oa/wage/index.vue ファイルの表示

@@ -8,13 +8,8 @@
8 8
           </el-option>
9 9
         </el-select>
10 10
       </el-form-item>
11
-      <el-form-item label="发放日期" prop="payDay">
12
-        <el-date-picker clearable v-model="queryParams.payDay" type="date" value-format="yyyy-MM-dd"
13
-          placeholder="请选择发放日期">
14
-        </el-date-picker>
15
-      </el-form-item>
16 11
       <el-form-item label="发放月份" prop="payMonth">
17
-        <el-date-picker clearable v-model="queryParams.payMonth" type="date" value-format="yyyy-MM-dd"
12
+        <el-date-picker clearable v-model="queryParams.payMonth" type="month" value-format="yyyy-MM-dd"
18 13
           placeholder="请选择发放月份">
19 14
         </el-date-picker>
20 15
       </el-form-item>
@@ -43,9 +38,9 @@
43 38
       </el-col> -->
44 39
       <el-col :span="1.5">
45 40
         <el-button type="warning" plain icon="el-icon-upload2" size="mini" @click="handleImport"
46
-          v-hasPermi="['oa:wage:export']">导入</el-button>
41
+          v-hasPermi="['oa:wage:export']">上传社保公积金</el-button>
47 42
       </el-col>
48
-    
43
+
49 44
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
50 45
     </el-row>
51 46
 
@@ -64,7 +59,7 @@
64 59
       <el-table-column label="高温补贴" align="center" prop="highTemperatureSubsidy" />
65 60
       <el-table-column label="考勤扣款" align="center" prop="attendanceDeduct" />
66 61
       <el-table-column label="应发小计" align="center" prop="payableWage" /> -->
67
-      <el-table-column label="公积金" align="center" prop="houseFund" />
62
+      <el-table-column label="公积金单位部分" align="center" prop="houseFund" />
68 63
       <!-- <el-table-column label="养老保险" align="center" prop="endowmentInsurance" />
69 64
       <el-table-column label="失业保险" align="center" prop="unemploymentInsurance" />
70 65
       <el-table-column label="医疗保险" align="center" prop="medicalInsurance" />
@@ -73,14 +68,14 @@
73 68
       <el-table-column label="社保单位部分" align="center" prop="socialSecurityUnit" />
74 69
       <!-- <el-table-column label="个税" align="center" prop="individualIncomeTax" />
75 70
       <el-table-column label="实发工资" align="center" prop="paidWage" /> -->
76
-      <el-table-column label="发放日期" align="center" prop="payDay" width="180">
71
+      <!-- <el-table-column label="发放日期" align="center" prop="payDay" width="180">
77 72
         <template slot-scope="scope">
78 73
           <span>{{ parseTime(scope.row.payDay, '{y}-{m}-{d}') }}</span>
79 74
         </template>
80
-      </el-table-column>
75
+      </el-table-column> -->
81 76
       <el-table-column label="发放月份" align="center" prop="payMonth" width="180">
82 77
         <template slot-scope="scope">
83
-          <span>{{ parseTime(scope.row.payMonth, '{y}-{m}-{d}') }}</span>
78
+          <span>{{ parseTime(scope.row.payMonth, '{y}-{m}') }}</span>
84 79
         </template>
85 80
       </el-table-column>
86 81
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
@@ -97,7 +92,7 @@
97 92
       @pagination="getList" />
98 93
 
99 94
     <!-- 添加或修改员工工资对话框 -->
100
-    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
95
+    <el-dialog :title="title" :visible.sync="open" width="400px" append-to-body>
101 96
       <el-form ref="form" :model="form" :rules="rules" label-width="80px">
102 97
         <el-form-item label="员工id" prop="userId">
103 98
           <el-input v-model="form.userId" placeholder="请输入员工id" />
@@ -173,11 +168,35 @@
173 168
         <el-button @click="cancel">取 消</el-button>
174 169
       </div>
175 170
     </el-dialog>
171
+    <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
172
+      <el-upload ref="uploadRef" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url"
173
+        :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-change="handleFileUploadChange"
174
+        :on-success="handleFileSuccess" :auto-upload="false" drag v-loading="uploadLoading"
175
+        element-loading-text="正在上传,请稍等">
176
+        <i class="el-icon-upload"></i>
177
+        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
178
+        <template #tip>
179
+          <div class="el-upload__tip text-center">
180
+            <span>仅允许导入xls、xlsx格式文件。</span>
181
+            <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;"
182
+              @click="importTemplate">下载模板</el-link>
183
+          </div>
184
+        </template>
185
+      </el-upload>
186
+      <template #footer>
187
+        <div class="dialog-footer">
188
+          <el-button type="primary" @click="submitUpload">确 定</el-button>
189
+          <el-button @click="upload.open = false">取 消</el-button>
190
+        </div>
191
+      </template>
192
+    </el-dialog>
176 193
   </div>
177 194
 </template>
178 195
 
179 196
 <script>
180 197
 import { listWage, getWage, delWage, addWage, updateWage } from "@/api/oa/wage/wage";
198
+import { downloadTemplate } from "@/api/file/project";
199
+import { getToken } from "@/utils/auth";
181 200
 
182 201
 export default {
183 202
   name: "Wage",
@@ -232,7 +251,24 @@ export default {
232 251
       form: {},
233 252
       // 表单校验
234 253
       rules: {
235
-      }
254
+      },
255
+      upload: {
256
+        // 是否显示弹出层(用户导入)
257
+        open: false,
258
+        // 弹出层标题(用户导入)
259
+        title: "上传社保公积金",
260
+        // 是否禁用上传
261
+        isUploading: false,
262
+        // 是否更新已经存在的用户数据
263
+        updateSupport: 0,
264
+        // 设置上传的请求头部'Content-Type': 'multipart/form-data', 
265
+        headers: { 'Authorization': "Bearer " + getToken() },
266
+        data: undefined,
267
+        // 上传的地址
268
+        url: process.env.VUE_APP_BASE_API + "/oa/wage/uploadSheet"
269
+      },
270
+      uploadLoading: false,
271
+      uploadFormData: undefined,
236 272
     };
237 273
   },
238 274
   created() {
@@ -351,8 +387,47 @@ export default {
351 387
       }, `wage_${new Date().getTime()}.xlsx`)
352 388
     },
353 389
     handleImport() {
354
-
355
-    }
390
+      this.upload.open = true;
391
+    },
392
+    /**Excel文件上传中处理 */
393
+    handleFileUploadProgress(event, file, fileList) {
394
+      this.upload.isUploading = true;
395
+      this.uploadLoading = true;
396
+    },
397
+    /* Excel文件改变时 */
398
+    handleFileUploadChange(file, fileList) {
399
+      if (fileList.length > 1) {
400
+        fileList.splice(0, 1);
401
+      }
402
+      this.uploadFormData = new FormData();
403
+      this.uploadFormData.append("file", file);
404
+      this.upload.data = this.uploadFormData;
405
+    },
406
+    /** Excel文件上传成功处理 */
407
+    handleFileSuccess(response, file, fileList) {
408
+      this.upload.open = false;
409
+      this.upload.isUploading = false;
410
+      this.uploadLoading = false;
411
+      this.fileList = [];
412
+      this.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导入结果", { dangerouslyUseHTMLString: true });
413
+      this.$refs["uploadRef"].clearFiles();
414
+      this.getList();
415
+    },
416
+    /* Excel上传提交按钮 */
417
+    submitUpload() {
418
+      this.$refs['uploadRef'].submit();
419
+    },
420
+    /* 下载模板 */
421
+    importTemplate() {
422
+      const path = "http://127.0.0.1:8080/profile/template/userWage.xlsx"
423
+      // const path = "http://oa.sccehui.com:6104/prod-api/profile/template/cg-template.xlsx"
424
+      downloadTemplate(path).then(res => {
425
+        const blob = new Blob([res])
426
+        saveAs(blob, '社保公积金模版.xlsx');
427
+      });
428
+      // this.download("file/achievement/importTemplate", {
429
+      // }, `成果表模板.xlsx`);
430
+    },
356 431
   }
357 432
 };
358 433
 </script>

読み込み中…
キャンセル
保存