Browse Source

新增工作填报表单

余思翰 9 months ago
parent
commit
cf6a7a98e5

+ 24
- 18
oa-ui/src/utils/deleteResource.js View File

@@ -2,7 +2,7 @@
2 2
  * @Author: ysh
3 3
  * @Date: 2024-06-13 17:07:59
4 4
  * @LastEditors: Please set LastEditors
5
- * @LastEditTime: 2024-08-09 15:00:11
5
+ * @LastEditTime: 2024-08-16 15:04:21
6 6
  */
7 7
 import request from '@/utils/request'
8 8
 
@@ -90,29 +90,35 @@ const apiEndpoints = [
90 90
       '/oa/brandPayment/:id'
91 91
     ]
92 92
   },
93
+  {
94
+    procDefName: '工作填报',
95
+    apiUrl: [
96
+      '/oa/declare/:id'
97
+    ]
98
+  },
93 99
 ]
94 100
 
95 101
 // 编写一个方法来处理删除请求,并同时发送所有API请求  
96
-export async function deleteResources(procDefName, id) {  
102
+export async function deleteResources(procDefName, id) {
97 103
   // 查找对应的API端点  
98
-  const endpoint = apiEndpoints.find(endpoint => endpoint.procDefName === procDefName);  
99
-  if (!endpoint) {  
100
-    throw new Error(`No API endpoints found for process definition: ${procDefName}`);  
101
-  }  
102
-    
104
+  const endpoint = apiEndpoints.find(endpoint => endpoint.procDefName === procDefName);
105
+  if (!endpoint) {
106
+    throw new Error(`No API endpoints found for process definition: ${procDefName}`);
107
+  }
108
+
103 109
   // 构建所有请求的Promise数组  
104
-  const deletePromises = endpoint.apiUrl.map(apiUrl => {  
110
+  const deletePromises = endpoint.apiUrl.map(apiUrl => {
105 111
     // 替换URL中的:id占位符  
106
-    const url = apiUrl.replace(':id', id);  
112
+    const url = apiUrl.replace(':id', id);
107 113
     // 发送DELETE请求并返回Promise  
108
-    return request.delete(url)  
109
-  });  
110
-    
114
+    return request.delete(url)
115
+  });
116
+
111 117
   // 等待所有请求完成  
112
-  try {  
113
-    return await Promise.all(deletePromises);  
114
-    console.log('删除完成!');  
115
-  } catch (error) {  
116
-    console.error('One or more deletion requests failed:', error);  
117
-  }  
118
+  try {
119
+    return await Promise.all(deletePromises);
120
+    console.log('删除完成!');
121
+  } catch (error) {
122
+    console.error('One or more deletion requests failed:', error);
123
+  }
118 124
 } 

+ 7
- 3
oa-ui/src/views/flowable/form/components/conditionDisplay.vue View File

@@ -1,8 +1,8 @@
1 1
 <!--
2 2
  * @Author: ysh
3 3
  * @Date: 2024-04-23 17:08:16
4
- * @LastEditors: wrh
5
- * @LastEditTime: 2024-08-06 17:28:23
4
+ * @LastEditors: Please set LastEditors
5
+ * @LastEditTime: 2024-08-16 15:26:43
6 6
 -->
7 7
 <template>
8 8
   <div>
@@ -33,6 +33,7 @@
33 33
     <deposit-form :key="'deposit'+taskForm.taskId" :taskForm="taskForm" :taskName="''" v-else-if="taskForm.procDefName == '保证金审批'"></deposit-form>
34 34
     <device-form :key="'device'+taskForm.taskId" :taskForm="taskForm" :taskName="''" :formDisabled="true" v-else-if="taskForm.procDefName == '设备审批'"></device-form>
35 35
     <change-form :key="'change'+taskForm.taskId" :taskForm="taskForm" :taskName="''" v-else-if="taskForm.procDefName == '项目变更'"></change-form>
36
+    <declare :key="'work'+taskForm.taskId" :taskForm="taskForm" :taskName="''" :formDisabled="true" v-else-if="taskForm.procDefName == '工作填报'"></declare>
36 37
   </div>
37 38
 </template>
38 39
 
@@ -60,6 +61,8 @@ import BrandForm from '../business/brandForm.vue';
60 61
 import DepositForm from '../finance/depositForm.vue';
61 62
 import DeviceForm from '../oa/deviceForm.vue';
62 63
 import changeForm from "../changeForm.vue";
64
+import workFilling from "../work/declareForm.vue";
65
+import declare from "../work/declareForm.vue";
63 66
 export default {
64 67
   props: {
65 68
     passingParam: {
@@ -94,7 +97,8 @@ export default {
94 97
     BrandForm,
95 98
     DepositForm,
96 99
     DeviceForm,
97
-    changeForm
100
+    changeForm,
101
+    declare
98 102
   },
99 103
   data() {
100 104
     return {

+ 5
- 1
oa-ui/src/views/flowable/form/components/detailDisplay.vue View File

@@ -44,6 +44,8 @@
44 44
       @goBack="goBack"></settle-other>
45 45
     <change-form :taskName="taskName" :taskForm="taskForm" v-else-if="taskForm.procDefName == '项目变更'"
46 46
       @goBack="goBack"></change-form>
47
+    <declare-form :taskName="taskName" :taskForm="taskForm" v-else-if="taskForm.procDefName == '工作填报'"
48
+      @goBack="goBack"></declare-form>
47 49
   </div>
48 50
 </template>
49 51
 
@@ -72,6 +74,7 @@ import archiveForm from '@/views/flowable/form/archiveForm.vue';
72 74
 import settleForm from '@/views/flowable/form/settleForm.vue';
73 75
 import settleOther from '@/views/flowable/form/settleOther.vue';
74 76
 import changeForm from '@/views/flowable/form/changeForm.vue';
77
+import declareForm from '../work/declareForm.vue';
75 78
 export default {
76 79
   components: {
77 80
     ScTable,
@@ -97,7 +100,8 @@ export default {
97 100
     archiveForm,
98 101
     settleForm,
99 102
     settleOther,
100
-    changeForm
103
+    changeForm,
104
+    declareForm
101 105
   },
102 106
   props: {
103 107
     taskForm: {

+ 340
- 0
oa-ui/src/views/flowable/form/work/declareForm.vue View File

@@ -0,0 +1,340 @@
1
+<!--
2
+ * @Author: ysh
3
+ * @Date: 2024-08-16 09:16:36
4
+ * @LastEditors: Please set LastEditors
5
+ * @LastEditTime: 2024-08-16 16:24:17
6
+-->
7
+<template>
8
+  <div class="app-container">
9
+    <el-row :gutter="20">
10
+      <el-col :span="isFlow ? 18 : 24" :xs="24">
11
+        <h2 class="text-center">项目工作填报表</h2>
12
+        <el-divider></el-divider>
13
+        <el-form ref="form" :model="form" :rules="rules" label-width="100px" :disabled="formDisabled">
14
+          <el-form-item label="项目名称:" prop="projectId">
15
+            <el-button icon="el-icon-plus" type="primary" @click="prOpen = true" size="mini"
16
+              v-if="taskName == '工作填报'">选择项目</el-button>
17
+            <el-descriptions border v-if="form.projectId" style="margin-top: 10px" :column="2">
18
+              <el-descriptions-item label="项目编号">
19
+                {{ chooseProject.projectNumber }}
20
+              </el-descriptions-item>
21
+              <el-descriptions-item label="项目名称">
22
+                {{ chooseProject.projectName }}
23
+              </el-descriptions-item>
24
+              <el-descriptions-item label="项目负责人">
25
+                {{ getUserName(chooseProject.projectLeader) }}
26
+              </el-descriptions-item>
27
+              <el-descriptions-item label="甲方单位">
28
+                {{ chooseProject.partyA ? chooseProject.partyA.partyAName : '' }}
29
+              </el-descriptions-item>
30
+              <el-descriptions-item label="联系人">
31
+                {{ chooseProject.contactPerson }}
32
+              </el-descriptions-item>
33
+              <el-descriptions-item label="联系电话">
34
+                {{ chooseProject.telephone }}
35
+              </el-descriptions-item>
36
+              <el-descriptions-item label="项目类型">
37
+                {{ chooseProject.projectType }}
38
+              </el-descriptions-item>
39
+              <el-descriptions-item label="项目级别">
40
+                {{ chooseProject.projectLevel == "0" ? " 一般项目" : "重大项目" }}
41
+              </el-descriptions-item>
42
+              <el-descriptions-item label="承担部门">
43
+                {{ chooseProject.undertakingDeptName }}
44
+              </el-descriptions-item>
45
+              <el-descriptions-item label="项目登记人">
46
+                {{ chooseProject.projectRegistrantUser ? chooseProject.projectRegistrantUser.nickName : "" }}
47
+              </el-descriptions-item>
48
+            </el-descriptions>
49
+          </el-form-item>
50
+          <el-form-item label="工作类别:" prop="workType">
51
+            <el-select v-model="form.workType" @change="getWorkItemList(form.workType)" :style="{ width: '100%' }"
52
+              :disabled="taskName != '工作填报'">
53
+              <el-option v-for="item in workTypeList" :key="item.value" :label="item.label" :value="item.value">
54
+              </el-option>
55
+            </el-select>
56
+          </el-form-item>
57
+          <el-form-item label="工作细项:" prop="workItem">
58
+            <el-select v-model="form.workItem" :style="{ width: '100%' }" :disabled="taskName != '工作填报'">
59
+              <el-option v-for="item in workItemList" :key="item.value" :label="item.label" :value="item.value">
60
+              </el-option>
61
+            </el-select>
62
+          </el-form-item>
63
+          <el-form-item label="具体内容:" prop="workContent">
64
+            <el-input type="textarea" v-model="form.workContent" :autosize="{ minRows: 4, maxRows: 10 }"
65
+              :disabled="taskName != '工作填报'"></el-input>
66
+          </el-form-item>
67
+          <el-form-item label="工天:" prop="workLoad">
68
+            <el-input-number v-model="form.workLoad" @change="countMoney()"
69
+              :disabled="taskName != '工作填报'"></el-input-number>
70
+          </el-form-item>
71
+          <el-row class="text-center">
72
+            <el-col :span="8" :offset="8">
73
+              <p>填报人:<span class="auditor">{{ getUserName(form.userId) }}</span></p>
74
+            </el-col>
75
+            <el-col :span="8">
76
+              <p>填报日期:{{ parseTime(form.submitTime, "{y}-{m}-{d}") }}</p>
77
+            </el-col>
78
+          </el-row>
79
+          <el-form-item label="工天单价:" prop="price" v-if="taskName != '工作填报'">
80
+            <el-tag>{{ form.price }}元 /人天</el-tag>
81
+          </el-form-item>
82
+          <el-form-item label="系数:" prop="coefficient" v-if="taskName != '工作填报'">
83
+            <el-input-number :controls="false" v-model="form.coefficient" @blur="countMoney()"
84
+              :disabled="taskName == '填报人确认'"></el-input-number>
85
+          </el-form-item>
86
+          <el-form-item label="预估绩效:" v-if="taskName != '工作填报'">
87
+            <span class="auditor">{{ money }}(元)</span>
88
+          </el-form-item>
89
+        </el-form>
90
+        <el-row class="text-center mt20" v-if="!formDisabled">
91
+          <el-button type="warning" @click="save" v-if="taskName != '填报人确认'">保 存</el-button>
92
+          <el-button type="primary" @click="submitForm" v-if="taskName == '工作填报'">提 交</el-button>
93
+          <el-button type="success" @click="approveForm"
94
+            v-if="taskName != '工作填报' && taskName != '填报人确认'">审核通过</el-button>
95
+          <el-button type="primary" @click="confirmForm" v-if="taskName == '填报人确认'">确 认</el-button>
96
+        </el-row>
97
+      </el-col>
98
+      <el-col :span="6" :xs="24" v-if="isFlow">
99
+        <el-card>
100
+          <h2 style="text-align: center;">流程进度</h2>
101
+          <div>
102
+            <flow :flowData="flowData" />
103
+          </div>
104
+        </el-card>
105
+      </el-col>
106
+    </el-row>
107
+    <el-dialog title="选择项目" :visible.sync="prOpen" width="70%" append-to-body>
108
+      <choose-project @chooseProject="confirmProject"></choose-project>
109
+    </el-dialog>
110
+  </div>
111
+</template>
112
+
113
+<script>
114
+import flow from '@/views/flowable/task/todo/detail/flow';
115
+import { flowXmlAndNode } from "@/api/flowable/definition";
116
+import { getWorkTypeList, getWorkItemList } from '@/api/oa/price/price'
117
+import { listDeclare, getDeclare, addDeclare, updateDeclare } from '@/api/oa/declare/declare';
118
+import { listProject, getProject } from "@/api/oa/project/project";
119
+import { mapState } from 'vuex';
120
+import { complete, getNextFlowNode } from "@/api/flowable/todo";
121
+import chooseProject from '../components/chooseProject.vue';
122
+import { parseTime } from "@/utils/ruoyi";
123
+import { getUsersDeptLeader, getUsersDeptLeaderByDept, getUsersManageLeaderByDept } from "@/api/system/post.js";
124
+export default {
125
+  components: {
126
+    flow,
127
+    chooseProject
128
+  },
129
+  computed: {
130
+    ...mapState({
131
+      device: state => state.app.device,
132
+    })
133
+  },
134
+  props: {
135
+    taskName: {
136
+      type: String,
137
+      required: true
138
+    },
139
+    taskForm: {
140
+      type: Object,
141
+      required: true
142
+    },
143
+    isFlow: {
144
+      type: Boolean,
145
+      default: true
146
+    },
147
+    formDisabled: {
148
+      type: Boolean,
149
+      default: false
150
+    }
151
+  },
152
+  created() {
153
+    this.getWorkTypeList();
154
+    this.initForm();
155
+    if (this.device == 'mobile') {
156
+      this.isFlow = false
157
+    }
158
+    if (this.isFlow) {
159
+      flowXmlAndNode({ procInsId: this.taskForm.procInsId, deployId: this.taskForm.deployId }).then(res => {
160
+        this.flowData = res.data;
161
+      })
162
+    }
163
+  },
164
+  data() {
165
+    return {
166
+      flowData: {},
167
+      form: {
168
+        workLoad: 1,
169
+        coefficient: 1,
170
+        price: 216,
171
+        userId: undefined,
172
+        submitTime: undefined,
173
+      },
174
+      rules: {
175
+        projectId: [
176
+          { required: true, trigger: "blur", message: "请选择项目" },
177
+        ],
178
+        workType: [
179
+          { required: true, trigger: "change", message: "请选择工作类别" },
180
+        ],
181
+        workItem: [
182
+          { required: true, trigger: "change", message: "请选择工作细项" },
183
+        ],
184
+        workContent: [
185
+          { required: true, trigger: "blur", message: "请填写具体内容" },
186
+        ]
187
+      },
188
+      prOpen: false,
189
+      chooseProject: {},
190
+      workTypeList: [],
191
+      workItemList: [],
192
+      hasForm: false,
193
+      money: 0
194
+    }
195
+  },
196
+  methods: {
197
+    initForm() {
198
+      if (this.taskName == '工作填报') {
199
+        this.$set(this.form, 'userId', this.$store.state.user.id)
200
+        this.form.submitTime = parseTime(new Date(), "{y}-{m}-{d}")
201
+      }
202
+      getDeclare(this.taskForm.formId).then(res => {
203
+        if (res.data) {
204
+          this.form = res.data;
205
+          this.form.price = 216;
206
+          this.hasForm = true;
207
+          this.countMoney();
208
+          getProject(res.data.projectId).then(res => {
209
+            if (res.data) {
210
+              this.chooseProject = res.data
211
+            }
212
+          })
213
+          this.getWorkItemList(this.form.workType);
214
+        }
215
+      })
216
+    },
217
+    async save() {
218
+      if (this.hasForm) {
219
+        let updateRes = await updateDeclare(this.form);
220
+      } else {
221
+        this.form.formId = this.taskForm.formId;
222
+        let addRes = await addDeclare(this.form);
223
+        this.$router.go(0)
224
+      }
225
+      this.$message.success('保存成功');
226
+    },
227
+    submitForm() {
228
+      this.$refs['form'].validate(valid => {
229
+        if (valid) {
230
+          if (!this.chooseProject.projectLeader) {
231
+            this.$message.error('该项目未指定项目负责人,无法提交。')
232
+            return
233
+          }
234
+          this.$confirm('是否确认提交表单?', '提示', {
235
+            confirmButtonText: '确定',
236
+            cancelButtonText: '取消',
237
+            type: 'warning'
238
+          }).then(() => {
239
+            if (this.hasForm) {
240
+              updateDeclare(this.form);
241
+            } else {
242
+              this.form.formId = this.taskForm.formId;
243
+              addDeclare(this.form);
244
+            }
245
+            const params = { taskId: this.taskForm.taskId };
246
+            let approval = this.chooseProject.projectLeader;
247
+            getNextFlowNode(params).then(() => {
248
+              this.$set(this.taskForm.variables, "approval", approval);
249
+              this.handleComplete(this.taskForm);
250
+            })
251
+          })
252
+        } else {
253
+          this.$message.error('请完善必填项');
254
+        }
255
+      })
256
+    },
257
+    async approveForm() {
258
+      updateDeclare(this.form);
259
+      const params = { taskId: this.taskForm.taskId };
260
+      if (this.taskName == '项目负责人审核') {
261
+        let resData = await getUsersDeptLeader({ userId: this.form.userId });
262
+        if (resData.data) {
263
+          this.$set(this.taskForm.variables, "approval", resData.data.userId);
264
+          getNextFlowNode(params).then(() => {
265
+            this.handleComplete(this.taskForm);
266
+          })
267
+        }
268
+      } else if (this.taskName == '部门负责人审核') {
269
+        this.$set(this.taskForm.variables, "approval", this.form.userId);
270
+        getNextFlowNode(params).then(() => {
271
+          this.handleComplete(this.taskForm);
272
+        })
273
+      }
274
+    },
275
+    confirmForm() {
276
+      const params = { taskId: this.taskForm.taskId };
277
+      getNextFlowNode(params).then(() => {
278
+        this.handleComplete(this.taskForm);
279
+      })
280
+    },
281
+    handleComplete(taskForm) {
282
+      complete(taskForm).then(response => {
283
+        this.$modal.msgSuccess(response.msg);
284
+        this.$emit('goBack');
285
+      })
286
+    },
287
+    countMoney() {
288
+      let result = parseFloat(this.form.price * this.form.workLoad * this.form.coefficient)
289
+      this.money = result.toFixed(2)
290
+    },
291
+    confirmProject(val) {
292
+      if (val.length != 1) {
293
+        this.$message.error("项目只能选择一个!");
294
+        return;
295
+      }
296
+      this.chooseProject = val[0]
297
+      this.$set(this.form, 'projectId', val[0].projectId)
298
+      this.prOpen = false;
299
+      this.$refs.form.validateField('projectId');
300
+    },
301
+    /* 获取工作类别 */
302
+    getWorkTypeList() {
303
+      getWorkTypeList().then(res => {
304
+        if (res) {
305
+          this.workTypeList = this.setArray(res);
306
+        }
307
+      });
308
+    },
309
+    /* 获取工作项目 */
310
+    getWorkItemList(workType) {
311
+      getWorkItemList({ workType: workType }).then(res => {
312
+        if (res) {
313
+          let workItemList = this.setArray(res);
314
+          this.workItemList = workItemList;
315
+        }
316
+      })
317
+    },
318
+    // 数组去重,并格式化为label、value形式
319
+    setArray(arr) {
320
+      if (arr != [] && arr != undefined) {
321
+        let datalist = [...new Set(arr)];
322
+        let list = [];
323
+        for (let i of datalist) {
324
+          let obj = new Object();
325
+          obj.label = i;
326
+          obj.value = i;
327
+          list.push(obj);
328
+        }
329
+        return list;
330
+      } else {
331
+        return [];
332
+      }
333
+    },
334
+  },
335
+}
336
+</script>
337
+
338
+<style lang="scss" scoped>
339
+@import "@/assets/styles/element-reset.scss";
340
+</style>

+ 2
- 2
oa-ui/src/views/flowable/task/todo/detail/index.vue View File

@@ -2,7 +2,7 @@
2 2
  * @Author: ysh
3 3
  * @Date: 2024-01-03 09:23:11
4 4
  * @LastEditors: Please set LastEditors
5
- * @LastEditTime: 2024-08-07 14:12:06
5
+ * @LastEditTime: 2024-08-16 09:18:46
6 6
 -->
7 7
 <template>
8 8
   <div class="app-container">
@@ -481,7 +481,7 @@ export default {
481 481
         || (this.taskForm.procDefName == '项目预算' && this.taskName != '预算审核') || this.taskForm.procDefName == '借款审批' || this.taskForm.procDefName == '安全交底' ||
482 482
         this.taskForm.procDefName == '技术交底' || this.taskForm.procDefName == '技术方案' || this.taskForm.procDefName == '承接合同评审' || this.taskForm.procDefName == '分包合同评审'
483 483
         || this.taskForm.procDefName == '品牌项目支付' || this.taskForm.procDefName == '保证金审批' || this.taskForm.procDefName == '成果归档' || this.taskForm.procDefName == '项目结算'
484
-        || this.taskForm.procDefName == '项目变更' || this.taskForm.procDefName == '其他结算') {
484
+        || this.taskForm.procDefName == '项目变更' || this.taskForm.procDefName == '其他结算' ||this.taskForm.procDefName == '工作填报') {
485 485
         return false
486 486
       } else {
487 487
         return true

Loading…
Cancel
Save