Bläddra i källkod

新增绩效审批

余思翰 6 månader sedan
förälder
incheckning
5227f5e3a2

+ 1
- 1
oa-back/ruoyi-system/src/main/resources/mapper/oa/CmcPerformanceMapper.xml Visa fil

@@ -60,7 +60,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
60 60
         <where>  
61 61
             <if test="reporter != null "> and p.reporter = #{reporter}</if>
62 62
             <if test="document != null  and document != ''"> and p.document = #{document}</if>
63
-            <if test="reportTime != null "> and p.report_time = #{reportTime}</if>
63
+            <if test="reportTime != null "> and date_format(p.report_time, '%y%m') = date_format(#{reportTime}, '%y%m')</if>
64 64
             <if test="reportDept != null "> and p.report_dept = #{reportDept}</if>
65 65
             <if test="managerUserId != null "> and p.manager_user_id = #{managerUserId}</if>
66 66
             <if test="managerComment != null  and managerComment != ''"> and p.manager_comment = #{managerComment}</if>

+ 232
- 0
oa-ui/src/views/flowable/form/components/print/performancePrint.vue Visa fil

@@ -0,0 +1,232 @@
1
+<!--
2
+ * @Author: ysh
3
+ * @Date: 2024-09-29 17:20:07
4
+ * @LastEditors: Please set LastEditors
5
+ * @LastEditTime: 2024-09-30 14:51:58
6
+-->
7
+<template>
8
+  <div>
9
+    <div id="printPerformance">
10
+      <table border="1" class="text-center">
11
+        <tr>
12
+          <td colspan="7" class="header text-center">
13
+            {{ getDeptName(deptId) }}{{ year }}年{{ month }}月预发绩效表
14
+          </td>
15
+        </tr>
16
+        <tr class="double-border">
17
+          <td>上报人</td>
18
+          <td>{{ getUserName(form.reporter) }}</td>
19
+          <td>
20
+            上报部门
21
+          </td>
22
+          <td>
23
+            {{ getDeptName(deptId) }}
24
+          </td>
25
+          <td>
26
+            上报时间
27
+          </td>
28
+          <td>
29
+            {{ form.reportTime }}
30
+          </td>
31
+        </tr>
32
+        <tr>
33
+          <td>序号</td>
34
+          <td>部门</td>
35
+          <td>统计月份</td>
36
+          <td>姓名</td>
37
+          <td>预发绩效(元)</td>
38
+          <td>备注</td>
39
+        </tr>
40
+        <tr v-for="wage, index in wagesList" :key="index">
41
+          <td>
42
+            {{ index + 1 }}
43
+          </td>
44
+          <td>
45
+            {{ getDeptName(wage.deptId) }}
46
+          </td>
47
+          <td>
48
+            {{ (wage.payMonth).slice(0, 7) }}
49
+          </td>
50
+          <td>
51
+            {{ getUserName(wage.userId) }}
52
+          </td>
53
+          <td>
54
+            {{ wage.performanceSalary }}
55
+          </td>
56
+          <td>
57
+            {{ wage.remark }}
58
+          </td>
59
+        </tr>
60
+        <tr>
61
+          <td colspan="4"><b>合计</b></td>
62
+          <td><b>{{ total }}</b></td>
63
+          <td></td>
64
+        </tr>
65
+        <tr>
66
+          <td :colspan="1" class="fontbold">分管审核意见</td>
67
+          <td :colspan="3">{{ form.managerComment }}</td>
68
+          <td :colspan="1" style="text-align:left;min-width:120px;">
69
+            签名:<span class="auditor">{{ getUserName(form.managerUserId) }}</span>
70
+          </td>
71
+          <td :colspan="2" style="text-align:left;width:240px;">日期:{{ form.managerTime }}</td>
72
+        </tr>
73
+        <tr>
74
+          <td :colspan="1" class="fontbold">总经理审批意见</td>
75
+          <td :colspan="3">{{ form.zjlComment }}</td>
76
+          <td :colspan="1" style="text-align:left;min-width:120px;">
77
+            签名:<span class="auditor">{{ getUserName(form.zjlUserId) }}</span>
78
+          </td>
79
+          <td :colspan="2" style="text-align:left;width:240px;">日期:{{ form.zjlTime }}</td>
80
+        </tr>
81
+      </table>
82
+    </div>
83
+    <div class="text-center mt20">
84
+      <el-button type="primary" v-print="print">确认打印</el-button>
85
+      <el-button @click="$emit('cancel')">取消</el-button>
86
+    </div>
87
+  </div>
88
+</template>
89
+
90
+<script>
91
+import { listPerformance, getPerformance, addPerformance, updatePerformance, delPerformance } from "@/api/oa/performance/performance"
92
+import { listWage, getWage, addWage, updateWage, delWage } from "@/api/oa/wage/wage"
93
+import { listUser, getUser } from '@/api/system/user'
94
+export default {
95
+  props: {
96
+    formId: {
97
+      type: String,
98
+    }
99
+  },
100
+  data() {
101
+    return {
102
+      form: {},
103
+      deptId: undefined,
104
+      month: new Date().getMonth() + 1,
105
+      year: new Date().getFullYear(),
106
+      wagesList: [],
107
+      total: 0,
108
+      print: {
109
+        id: 'printPerformance',
110
+        popTitle: '绩效审批表', // 打印配置页上方标题
111
+        extraHead: '', //最上方的头部文字,附加在head标签上的额外标签,使用逗号分隔
112
+        preview: false, // 是否启动预览模式,默认是false(开启预览模式,可以先预览后打印)
113
+        previewTitle: '', // 打印预览的标题(开启预览模式后出现),
114
+        previewPrintBtnLabel: '', // 打印预览的标题的下方按钮文本,点击可进入打印(开启预览模式后出现)
115
+        zIndex: '', // 预览的窗口的z-index,默认是 20002(此值要高一些,这涉及到预览模式是否显示在最上面)
116
+        previewBeforeOpenCallback() { }, //预览窗口打开之前的callback(开启预览模式调用)
117
+        previewOpenCallback() { }, // 预览窗口打开之后的callback(开启预览模式调用)
118
+        beforeOpenCallback() { }, // 开启打印前的回调事件
119
+        openCallback() { }, // 调用打印之后的回调事件
120
+        closeCallback() { }, //关闭打印的回调事件(无法确定点击的是确认还是取消)
121
+        url: '',
122
+        standard: '',
123
+        extraCss: ''
124
+      }
125
+    }
126
+  },
127
+  created() {
128
+    this.initForm();
129
+    this.initWages();
130
+  },
131
+  methods: {
132
+    initForm() {
133
+      getPerformance(this.formId).then(res => {
134
+        if (res.data) {
135
+          this.form = res.data;
136
+          this.deptId = res.data.reportDept
137
+        }
138
+      })
139
+    },
140
+    initWages() {
141
+      const params = { pageSize: 999, performanceId: this.formId };
142
+      listWage(params).then(async res => {
143
+        for (let w of res.rows) {
144
+          let userData = await getUser(w.userId);
145
+          w.deptId = userData.data.deptId;
146
+        }
147
+        this.wagesList = res.rows;
148
+        this.getTotal();
149
+      })
150
+    },
151
+    getTotal() {
152
+      this.total = this.wagesList.reduce((accumulator, currentValue) => {
153
+        return accumulator + currentValue.performanceSalary;
154
+      }, 0);
155
+    },
156
+  },
157
+}
158
+</script>
159
+
160
+<style lang="scss" scoped>
161
+table {
162
+  /*边框*/
163
+  /* border: 1px solid black; */
164
+  width: 90%;
165
+  // text-align: center;
166
+  border-collapse: collapse;
167
+  margin: 0 auto;
168
+
169
+  /*设置背景颜色*/
170
+  /* background-color: #bfa; */
171
+  td {
172
+    padding: 5px;
173
+    // line-height: 30px;
174
+  }
175
+}
176
+
177
+.header {
178
+  font-family: '黑体';
179
+  font-size: 16px;
180
+  font-weight: bold;
181
+  line-height: 30px;
182
+}
183
+
184
+.bg {
185
+  background-color: #eee;
186
+  -webkit-print-color-adjust: exact;
187
+}
188
+
189
+.title {
190
+  font-family: '黑体';
191
+  font-size: 20px;
192
+  font-weight: bold;
193
+  line-height: 30px;
194
+}
195
+
196
+.fontbold {
197
+  font-weight: bold;
198
+  min-width: 150px;
199
+  text-align: center;
200
+}
201
+
202
+.conment-width {
203
+  // max-width: 200px;
204
+}
205
+
206
+
207
+@page {
208
+  size: auto;
209
+  /* 去除页脚 */
210
+  margin-bottom: 0;
211
+  // 横向A4
212
+  // size:A4 landscape;
213
+}
214
+
215
+@media print {
216
+  #print table {
217
+    width: 100%;
218
+  }
219
+}
220
+
221
+.double-border {
222
+  // border-top: 3px double black;
223
+  /* 双横线 */
224
+  border-bottom: 3px double black;
225
+  /* 双横线 */
226
+}
227
+
228
+.empty-row {
229
+  height: 9px;
230
+  /* 设置行高 */
231
+}
232
+</style>

+ 5
- 3
oa-ui/src/views/flowable/form/outsource/outsourceForm.vue Visa fil

@@ -1,8 +1,8 @@
1 1
 <!--
2 2
  * @Author: ysh
3 3
  * @Date: 2024-09-20 16:09:07
4
- * @LastEditors: wrh
5
- * @LastEditTime: 2024-09-24 14:56:45
4
+ * @LastEditors: Please set LastEditors
5
+ * @LastEditTime: 2024-09-30 15:57:01
6 6
 -->
7 7
 <template>
8 8
   <div class="app-container">
@@ -248,7 +248,9 @@ export default {
248 248
               this.$set(this.taskForm.variables, "approval", result.data[0].userId);
249 249
               this.successComplete();
250 250
             } else if (this.taskName == '总经理审批') {
251
-              this.successComplete();
251
+              this.$modal.confirm('最后一个节点,提交将结束流程,是否提交?').then(res => {
252
+                this.successComplete();
253
+              })
252 254
             }
253 255
           })
254 256
         } else {

+ 254
- 4
oa-ui/src/views/flowable/form/performance/performanceForm.vue Visa fil

@@ -1,15 +1,265 @@
1 1
 <template>
2
-  <div>
3
-    <el-empty description="正在开发中,敬请期待......"></el-empty>
2
+  <div class="app-container">
3
+    <el-row :gutter="20">
4
+      <el-col :span="isFlow ? 18 : 24" :xs="24">
5
+        <div class="mb20" v-if="showAlter">
6
+          <el-alert title="任务被退回,请修改后重新提交" type="error" :closable="false">
7
+            <return-comment :taskForm="taskForm" @isReturn="isReturn"></return-comment>
8
+          </el-alert>
9
+        </div>
10
+        <el-button type="success" icon="el-icon-printer" @click="printOpen = true">打印</el-button>
11
+        <h2 style="text-align: center;">绩效审批表</h2>
12
+        <el-form ref="form" :model="form" :rules="rules" :disabled="taskName == ''">
13
+          <el-row :gutter="20">
14
+            <el-col :span="7" :xs="24">
15
+              <el-form-item label="上报人:" prop="reporter" label-width="100px">
16
+                {{ getUserName(form.reporter) }}
17
+              </el-form-item>
18
+            </el-col>
19
+            <el-col :span="7" :xs="24">
20
+              <el-form-item label="上报部门:" prop="reportDept" label-width="100px">
21
+                {{ getDeptName(form.reportDept) }}
22
+              </el-form-item>
23
+            </el-col>
24
+            <el-col :span="7" :xs="24">
25
+              <el-form-item label="上报时间:" prop="reportTime" label-width="100px">
26
+                {{ form.reportTime }}
27
+              </el-form-item>
28
+            </el-col>
29
+          </el-row>
30
+          <el-form-item label="附件上传:" prop="document" label-width="100px">
31
+            <FileUpload v-if="!form.document" ref="orz" :limit="1" :isShowTip="false"
32
+              :filePathName="'绩效审批/' + parseTime(new Date(), '{y}-{m}-{d}-{h}-{i}-{s}')"
33
+              :fileType="['doc', 'docx', 'xls', 'xlsx', 'pdf', 'rar', 'zip']" @input="setDocument">
34
+            </FileUpload>
35
+            <div v-if="form.document" class="upload-list">
36
+              <el-link type="primary" @click="reviewWord(`${baseUrl}${'/profile/upload' + form.document}`)">
37
+                {{ getFileName(form.document) }}
38
+              </el-link>
39
+              <el-link class="ml20" type="warning" :href="`${baseUrl}${'/profile/upload' + form.document}`"
40
+                :underline="false" target="_blank">
41
+                <span class="el-icon-download">下载文件</span>
42
+              </el-link>
43
+              <span class="el-icon-delete del-file" @click="deleteDoc" v-if="taskName == '绩效上报'">删除文件</span>
44
+            </div>
45
+          </el-form-item>
46
+          <el-form-item label="绩效统计:">
47
+            <performance-wages ref="wagesRef" :deptId="form.reportDept" :performanceId="taskForm.formId"
48
+              :taskName="taskName" @getTotal="setAmount" @saves="saves()"></performance-wages>
49
+          </el-form-item>
50
+          <el-form-item label="分管审核意见:" prop="managerComment" label-width="130px">
51
+            <el-input type="textarea" v-model="form.managerComment" :autosize="{ minRows: 4 }"
52
+              :disabled="taskName != '分管审核'"></el-input>
53
+            <auditor-row ref="fgRef" :isCurrent="taskName == '分管审核'"
54
+              :signature="form.managerUserId ? form.managerUserId : null" :signTime="form.managerTime"></auditor-row>
55
+          </el-form-item>
56
+          <el-form-item label="总经理审批意见:" prop="zjlComment" label-width="130px">
57
+            <el-input type="textarea" v-model="form.zjlComment" :autosize="{ minRows: 4 }"
58
+              :disabled="taskName != '总经理审批'"></el-input>
59
+            <auditor-row ref="zjlRef" :isCurrent="taskName == '总经理审批'"
60
+              :signature="form.zjlUserId ? form.zjlUserId : null" :signTime="form.zjlTime"></auditor-row>
61
+          </el-form-item>
62
+          <el-form-item label="人事制单:" label-width="130px" v-if="taskName == '人事制单'">
63
+            <el-button type="success" icon="el-icon-printer" @click="printOpen = true">打印</el-button>
64
+          </el-form-item>
65
+        </el-form>
66
+        <el-row style="text-align: center;" v-if="taskName != ''">
67
+          <el-button type="danger" @click="returnOpen = true" v-show="taskName != '绩效上报'">退 回</el-button>
68
+          <el-button type="warning" @click="saves()">保存</el-button>
69
+          <el-button type="primary" @click="completeApply()">提交</el-button>
70
+        </el-row>
71
+      </el-col>
72
+      <el-col :span="6" :xs="24" v-if="isFlow">
73
+        <el-card>
74
+          <h2 style="text-align: center;">流程进度</h2>
75
+          <div>
76
+            <flow :flowData="flowData" />
77
+          </div>
78
+        </el-card>
79
+      </el-col>
80
+    </el-row>
81
+    <el-dialog title="退回" :visible.sync="returnOpen" width="40%" append-to-body>
82
+      <return-btn :taskForm="taskForm" @goBack="$emit('goBack')" @saves="" @cancel="returnOpen = false"></return-btn>
83
+    </el-dialog>
84
+    <el-dialog title="打印预览" :visible.sync="printOpen" width="60%" append-to-body>
85
+      <performance-print :formId="taskForm.formId" @cancel="printOpen = false"></performance-print>
86
+    </el-dialog>
4 87
   </div>
5 88
 </template>
6 89
 
7 90
 <script>
8
-  export default {
9
-    
91
+import flow from '@/views/flowable/task/todo/detail/flow';
92
+import { flowXmlAndNode } from "@/api/flowable/definition";
93
+import { parseTime } from "@/utils/ruoyi";
94
+import { complete, rejectTask, returnList, returnTask, getNextFlowNode, delegate, flowTaskForm, } from "@/api/flowable/todo";
95
+import { listPerformance, getPerformance, addPerformance, updatePerformance, delPerformance } from "@/api/oa/performance/performance"
96
+import { listWage, getWage, addWage, updateWage, delWage } from "@/api/oa/wage/wage"
97
+import { getUsersDeptLeaderByDept, getUsersManageLeaderByDept, getUserByPost } from '@/api/system/post'
98
+import { getUserByRole } from "@/api/system/role";
99
+import PerformanceWages from './performanceWages.vue';
100
+import { scrollTo } from '@/utils/scroll-to'
101
+import AuditorRow from '@/views/flowable/form/components/auditorRow.vue';
102
+import returnBtn from '@/views/flowable/form/components/flowBtn/returnBtn.vue';
103
+import ReturnComment from '@/views/flowable/form/components/flowBtn/returnComment.vue';
104
+import PerformancePrint from '@/views/flowable/form/components/print/performancePrint.vue';
105
+export default {
106
+  components: { flow, PerformanceWages, AuditorRow, returnBtn, ReturnComment, PerformancePrint },
107
+  props: {
108
+    taskName: {
109
+      type: String,
110
+      required: true
111
+    },
112
+    taskForm: {
113
+      type: Object,
114
+      required: true
115
+    },
116
+    isFlow: {
117
+      type: Boolean,
118
+      default: true
119
+    },
120
+  },
121
+  data() {
122
+    return {
123
+      baseUrl: process.env.VUE_APP_BASE_API,
124
+      flowData: {},
125
+      rules: {
126
+        document: [
127
+          { required: true, message: '请上传统计明细附件', trigger: 'blur' }
128
+        ]
129
+      },
130
+      form: {
131
+        deptId: undefined,
132
+        applyTime: undefined,
133
+        applier: undefined,
134
+      },
135
+      performanceId: '',
136
+      formTotal: 0,
137
+      returnOpen: false,
138
+      printOpen: false,
139
+      showAlter: true,
140
+    }
141
+  },
142
+  created() {
143
+    this.initFlow();
144
+    this.initForm();
145
+    if (this.taskName == '绩效上报')
146
+      this.saves();
147
+  },
148
+  methods: {
149
+    initFlow() {
150
+      if (this.isFlow) {
151
+        flowXmlAndNode({ procInsId: this.taskForm.procInsId, deployId: this.taskForm.deployId }).then(res => {
152
+          this.flowData = res.data;
153
+        })
154
+      }
155
+    },
156
+    initForm() {
157
+      const formId = this.taskForm.formId;
158
+      this.performanceId = formId;
159
+      if (this.taskName == '绩效上报') {
160
+        this.form.reporter = this.$store.getters.userId;
161
+        this.form.reportDept = this.$store.getters.deptId;
162
+        this.form.reportTime = parseTime(new Date(), "{y}-{m}-{d}")
163
+      }
164
+      getPerformance(formId).then(res => {
165
+        if (res.data) {
166
+          this.formTotal = 1
167
+          this.form = res.data;
168
+        }
169
+      })
170
+    },
171
+    setAmount(val) {
172
+      this.amount = val[0]
173
+      this.peopleNum = val[1]
174
+    },
175
+    async saves() {
176
+      if (this.formTotal != 0) {
177
+        if (this.taskName == '分管审核') {
178
+          this.form.managerUserId = this.$refs.fgRef.localSignatureUserId;
179
+          this.form.managerTime = this.$refs.fgRef.loaclSignTime;
180
+        } else if (this.taskName == '总经理审批') {
181
+          this.form.zjlUserId = this.$refs.zjlRef.localSignatureUserId;
182
+          this.form.zjlTime = this.$refs.zjlRef.loaclSignTime;
183
+        }
184
+        await updatePerformance(this.form)
185
+      } else {
186
+        this.form.performanceId = this.taskForm.formId;
187
+        await addPerformance(this.form)
188
+        this.formTotal = 1
189
+      }
190
+      this.savesWages()
191
+      this.$message.success('保存成功')
192
+    },
193
+    async savesWages() {
194
+      const wagesList = this.$refs.wagesRef.wagesList;
195
+      for (let wages of wagesList) {
196
+        await updateWage(wages)
197
+      }
198
+    },
199
+    completeApply() {
200
+      const params = { taskId: this.taskForm.taskId };
201
+      this.$refs['form'].validate(valid => {
202
+        if (valid) {
203
+          this.saves();
204
+          getNextFlowNode(params).then(async () => {
205
+            if (this.taskName == '绩效上报') {
206
+              let result = await getUsersManageLeaderByDept({ deptId: this.form.reportDept });
207
+              const managerList = result.data.map(element => element.userId);
208
+              this.$set(this.taskForm.variables, "approvalList", managerList);
209
+              this.successComplete();
210
+            } else if (this.taskName == '分管审核') {
211
+              let result = await getUserByPost({ postName: '总经理' })
212
+              this.$set(this.taskForm.variables, "approval", result.data[0].userId);
213
+              this.successComplete();
214
+            } else if (this.taskName == '总经理审批') {
215
+              let result = await getUserByRole({ roleId: 3 })
216
+              this.$set(this.taskForm.variables, "approvalList", result.data);
217
+              this.successComplete();
218
+            } else if (this.taskName == '人事制单') {
219
+              this.$modal.confirm('最后一个节点,提交将结束流程,是否提交?').then(res => {
220
+                this.successComplete();
221
+              })
222
+            }
223
+          })
224
+        } else {
225
+          scrollTo(0, 600)
226
+        }
227
+      })
228
+    },
229
+    successComplete() {
230
+      complete(this.taskForm).then(response => {
231
+        this.$modal.msgSuccess(response.msg);
232
+        this.$emit('goBack')
233
+      })
234
+    },
235
+    setDocument(val) {
236
+      let arr = val.split('/upload')
237
+      this.$set(this.form, 'document', arr[1])
238
+      if (val == "") {
239
+        this.$set(this.form, 'document', "")
240
+      }
241
+    },
242
+    deleteDoc() {
243
+      this.$set(this.form, 'document', undefined)
244
+    },
245
+    isReturn(val) {
246
+      this.showAlter = val
247
+    }
10 248
   }
249
+}
11 250
 </script>
12 251
 
13 252
 <style lang="scss" scoped>
253
+@import "@/assets/styles/element-reset.scss";
14 254
 
255
+::v-deep .el-descriptions-item__label.is-bordered-label {
256
+  color: #5a5757;
257
+  background: rgba($color: #a9adb3, $alpha: 0.1);
258
+  width: 150px;
259
+  min-width: 150px;
260
+}
261
+
262
+::v-deep .el-descriptions .is-bordered .el-descriptions-item__cell {
263
+  border: 1px solid #cdd0d3;
264
+}
15 265
 </style>

+ 249
- 0
oa-ui/src/views/flowable/form/performance/performanceWages.vue Visa fil

@@ -0,0 +1,249 @@
1
+<!--
2
+ * @Author: ysh
3
+ * @Date: 2024-09-24 11:03:09
4
+ * @LastEditors: Please set LastEditors
5
+ * @LastEditTime: 2024-09-30 10:14:34
6
+-->
7
+<template>
8
+  <div style="width:100%">
9
+    <table class="table" border="1" style="width:100%">
10
+      <tr>
11
+        <td colspan="7" class="head">{{ getDeptName(deptId) }}{{ year }}年{{ month }}月预发绩效表</td>
12
+      </tr>
13
+      <tr>
14
+        <td>序号</td>
15
+        <td>部门</td>
16
+        <td>统计月份</td>
17
+        <td>姓名</td>
18
+        <td>预发绩效(元)</td>
19
+        <td>备注</td>
20
+        <td v-if="taskName == '绩效上报'">操作</td>
21
+      </tr>
22
+      <tr v-for="user, index in wagesList" :key="index">
23
+        <td>
24
+          {{ index + 1 }}
25
+        </td>
26
+        <td>
27
+          {{ getDeptName(user.deptId) }}
28
+        </td>
29
+        <td>
30
+          {{ parseTime(payMonth, '{yy}{mm}') }}
31
+        </td>
32
+        <td>
33
+          {{ user.nickName ? user.nickName : getUserName(user.userId) }}
34
+        </td>
35
+        <td>
36
+          <el-input-number :controls="false" v-model="user.performanceSalary" style="width:100%;"
37
+            @blur="getTotal()" :disabled="taskName != '绩效上报'"></el-input-number>
38
+        </td>
39
+        <td>
40
+          <el-input v-model="user.remark" :disabled="taskName != '绩效上报'"></el-input>
41
+        </td>
42
+        <td v-if="taskName == '绩效上报'">
43
+          <el-popover trigger="click" v-model="user.popVisible" title="确认删除" width="200" :close-on-click-modal="false">
44
+            <p>
45
+              <i class="el-icon-question" style="color:rgb(255, 153, 0);"></i>
46
+              您确定要删除{{ user.nickName ? user.nickName : getUserName(user.userId) }}吗?
47
+            </p>
48
+            <div style="text-align: right;">
49
+              <el-button size="mini" @click="cancelDelete(user)">取消</el-button>
50
+              <el-button size="mini" type="primary" @click="confirmDelete(user)">确认</el-button>
51
+            </div>
52
+          </el-popover>
53
+          <div class="delete-btn" @click="user.popVisible = true">
54
+            <i class="el-icon-circle-close"></i>
55
+          </div>
56
+        </td>
57
+      </tr>
58
+      <tr>
59
+        <td colspan="4"><b>合计</b></td>
60
+        <td><b>{{ total }}</b></td>
61
+        <td></td>
62
+      </tr>
63
+    </table>
64
+    <el-button type="primary" size="mini" icon="el-icon-plus" @click="addUser()" v-if="taskName == '绩效上报'">新增人员</el-button>
65
+    <!-- 选择人员对话框 -->
66
+    <el-dialog title="选择人员" :visible.sync="openPeople" width="700px" append-to-body>
67
+      <choosePeople @chooseUser="getChooseUser"></choosePeople>
68
+    </el-dialog>
69
+  </div>
70
+</template>
71
+
72
+<script>
73
+import { listUser, getUser } from '@/api/system/user'
74
+import { parseTime } from "@/utils/ruoyi";
75
+import { listWage, getWage, addWage, updateWage, delWage } from "@/api/oa/wage/wage"
76
+import choosePeople from '@/views/flowable/form/budget/components/choosePeople.vue';
77
+export default {
78
+  components: { choosePeople },
79
+  props: {
80
+    deptId: {
81
+      type: Number,
82
+      require: true,
83
+    },
84
+    performanceId: {
85
+      type: String,
86
+    },
87
+    taskName: {
88
+      type: String,
89
+      require:true
90
+    }
91
+  },
92
+  data() {
93
+    return {
94
+      month: new Date().getMonth() + 1,
95
+      year: new Date().getFullYear(),
96
+      payMonth: '',
97
+      formTotal: 0,
98
+      wagesList: [],
99
+      total: 0,
100
+      openPeople: false,
101
+      generate: false,
102
+    }
103
+  },
104
+  created() {
105
+    this.payMonth = this.getLastMonthYearFormatted();
106
+    this.initWages();
107
+  },
108
+  methods: {
109
+    async initWages() {
110
+      const params = { pageSize: 999, performanceId: this.performanceId, payMonth: this.payMonth }
111
+      let res = await listWage(params)
112
+      if (res.total > 0) {
113
+        this.formTotal = 1;
114
+        for (let w of res.rows) {
115
+          let userData = await getUser(w.userId);
116
+          w.deptId = userData.data.deptId;
117
+        }
118
+        this.wagesList = res.rows;
119
+        this.initWagesPopver(this.wagesList)
120
+      } else {
121
+        let userRes = await listUser({ pageSize: 100, deptId: this.deptId });
122
+        if (userRes.total > 0) {
123
+          let list = userRes.rows;
124
+          let uList = []
125
+          for (let l of list) {
126
+            let obj = {};
127
+            obj.userId = l.userId;
128
+            obj.deptId = this.deptId;
129
+            obj.nickName = l.nickName;
130
+            obj.payMonth = this.payMonth;
131
+            obj.performanceSalary = 0;
132
+            obj.performanceId = this.performanceId;
133
+            uList.push(obj);
134
+          }
135
+          this.wagesList = uList;
136
+          this.addWageList(uList);
137
+          this.initWagesPopver(this.wagesList)
138
+        }
139
+      }
140
+      this.getTotal()
141
+    },
142
+    initWagesPopver(list) {
143
+      list.forEach(item => {
144
+        this.$set(item, 'popVisible', false);
145
+      });
146
+    },
147
+    async addWageList(list) {
148
+      for (let i of list) {
149
+        await addWage(i)
150
+      }
151
+      this.initWages();
152
+    },
153
+    getTotal() {
154
+      this.total = this.wagesList.reduce((accumulator, currentValue) => {
155
+        return accumulator + currentValue.performanceSalary;
156
+      }, 0);
157
+      let num = this.wagesList.length
158
+      this.$emit('getTotal', [this.total, num])
159
+    },
160
+    async addUser() {
161
+      for (let wages of this.wagesList) {
162
+        await updateWage(wages)
163
+      }
164
+      this.openPeople = true;
165
+    },
166
+    getChooseUser(val) {
167
+      if (val.length == 0) return
168
+      let addList = []
169
+      val.forEach((v) => {
170
+        v.performanceSalary = 0
171
+        v.performanceId = this.performanceId
172
+        v.payMonth = this.payMonth;
173
+        addList.push(v)
174
+      })
175
+      this.addWageList(addList);
176
+      this.initWages();
177
+      this.openPeople = false;
178
+    },
179
+    getLastMonthYearFormatted() {
180
+      // 获取当前日期  
181
+      const now = new Date();
182
+      // 设置月份为上个月,注意月份是从0开始的,所以要减1  
183
+      // 同时,如果现在是1月,减1会变为-1,所以使用上个月份的逻辑  
184
+      let lastMonth = now.getMonth() - 1;
185
+      if (lastMonth < 0) {
186
+        lastMonth = 11; // 变为去年的12月  
187
+        now.setFullYear(now.getFullYear() - 1); // 并将年份也减1  
188
+      }
189
+      // 设置日期为上个月的第一天(为了不影响月份)  
190
+      now.setDate(1);
191
+      now.setMonth(lastMonth);
192
+      return now
193
+    },
194
+    deleItem(user) {
195
+      delWage(user.wageId).then(() => {
196
+        this.initWages()
197
+      })
198
+    },
199
+    confirmDelete(user) {
200
+      this.deleItem(user)
201
+      user.popVisible = false; // 关闭气泡
202
+    },
203
+    cancelDelete(user) {
204
+      user.popVisible = false; // 关闭气泡
205
+    },
206
+  }
207
+}
208
+</script>
209
+
210
+<style lang="scss" scoped>
211
+@import "@/assets/styles/element-reset.scss";
212
+
213
+table {
214
+  /*边框*/
215
+  /* border: 1px solid black; */
216
+  text-align: center;
217
+  border-collapse: collapse;
218
+  border: 1px solid #a5abb0;
219
+
220
+  /*设置背景颜色*/
221
+  /* background-color: #bfa; */
222
+  td {
223
+    // padding: 2px;
224
+    padding: 0;
225
+    font-size: 14px;
226
+  }
227
+
228
+  tr:hover {
229
+    background-color: #eaf2f8;
230
+    cursor: pointer;
231
+  }
232
+}
233
+
234
+.delete-btn {
235
+  color: #F56C6C;
236
+  cursor: pointer;
237
+
238
+  i {
239
+    font-size: 25px;
240
+  }
241
+}
242
+
243
+.head {
244
+  font-size: 18px;
245
+  font-weight: bold;
246
+  letter-spacing: 3px;
247
+  font-family: '微软雅黑';
248
+}
249
+</style>

+ 19
- 14
oa-ui/src/views/flowable/task/myProcess/index.vue Visa fil

@@ -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-09-23 15:50:44
5
+ * @LastEditTime: 2024-09-30 15:19:58
6 6
 -->
7 7
 <template>
8 8
   <div class="app-container">
@@ -91,25 +91,20 @@
91 91
 </template>
92 92
 
93 93
 <script>
94
-import {
95
-  getDeployment,
96
-  delDeployment,
97
-  addDeployment,
98
-  updateDeployment,
99
-  exportDeployment,
100
-  flowRecord
101
-} from "@/api/flowable/finished";
94
+import { getDeployment, delDeployment, addDeployment, updateDeployment, exportDeployment, flowRecord } from "@/api/flowable/finished";
102 95
 import { todoList } from "@/api/flowable/todo";
103 96
 import { myProcessList, stopProcess } from "@/api/flowable/process";
104 97
 import { listDefinition } from "@/api/flowable/definition";
105 98
 import { getNextFlowNodeByStart } from "@/api/flowable/todo";
106 99
 import { definitionStart, flowXmlAndNode } from "@/api/flowable/definition";
107
-import { Snowflake } from '@/utils/snowFlake.js'
108
-import RowDetail from './send/rowDetail.vue'
100
+import { Snowflake } from '@/utils/snowFlake.js';
101
+import RowDetail from './send/rowDetail.vue';
109 102
 import ProgressTree from './progressTree.vue';
103
+import { parseTime } from "@/utils/ruoyi";
110 104
 import { getProcessVariables } from "@/api/flowable/definition";
111
-import conditionDisplay from '@/views/flowable/form/components/conditionDisplay.vue'
112
-import { deleteResources } from "@/utils/deleteResource"
105
+import conditionDisplay from '@/views/flowable/form/components/conditionDisplay.vue';
106
+import { deleteResources } from "@/utils/deleteResource";
107
+import { listPerformance } from "@/api/oa/performance/performance";
113 108
 export default {
114 109
   name: "Deploy",
115 110
   components: {
@@ -295,8 +290,18 @@ export default {
295 290
       });
296 291
     },
297 292
     /**  发起流程申请 */
298
-    handleStartProcess(row) {
293
+    async handleStartProcess(row) {
299 294
       console.log(row);
295
+      if (row.name == "绩效审批") {
296
+        let deptId = this.$store.getters.deptId;
297
+        let reportTime = parseTime(new Date(), '{y}-{m}')
298
+        let res = await listPerformance({ reportDept: deptId, reportTime });
299
+        if (res.total >= 1) {
300
+          let reporter = this.getUserName(res.rows[0].reporter)
301
+          this.$message.error('本月部门已发起过绩效审批,发起人:' + reporter + ',请勿再次发起。')
302
+          return
303
+        }
304
+      }
300 305
       // if (row.category == "assess" || row.category == "car" || ) {
301 306
       let formId = new Snowflake(1n, 1n, 0n).nextId().toString();
302 307
       getNextFlowNodeByStart({ deploymentId: row.deploymentId, variables: { formId: formId } }).then(res => {

Loading…
Avbryt
Spara