zhengnaiwen_citu 6 miesięcy temu
rodzic
commit
cb04c77967

+ 17 - 2
src/api/salary.js

@@ -81,9 +81,24 @@ export function saveAllocationGrant (data) {
   return http.post('/employee/performance/grant', data)
 }
 
-// 业绩分配 绩效分配
+// 业绩分配 员工类型字典
 export function getAllocationEmployeeCategory (data) {
-  return http.post('/employee/performance/employee/category/dict', data)
+  return http.post('/employee/performance/category/dict', data)
+}
+
+// 业绩分配 检查审批状态
+export function checkAllocationSubmitStatus (data) {
+  return http.post('/employee/performance/confirmation/check/submit', data)
+}
+
+// 业绩分配 绩效分配统计
+export function getAllocationStatistics (data) {
+  return http.post('/employee/performance/grant/statistics', data)
+}
+
+// 业绩分配 绩效分配统计
+export function saveAllocation (data) {
+  return http.post('/employee/performance/submit/grant', data)
 }
 
 // 绩效方案 分页查询

+ 2 - 2
src/components/AutoComponents/MForm/index.vue

@@ -61,8 +61,8 @@
               <el-option
                 v-for="_item in item.options.items"
                 :key="_item.label"
-                :label="_item[item.options.labelText ?? _item.label]"
-                :value="_item[item.options.labelValue ?? _item.value]"
+                :label="_item[item.options.labelText ?? 'label']"
+                :value="_item[item.options.labelValue ?? 'value']"
                 :disable="_item.disable"
               ></el-option>
             </template>

+ 2 - 2
src/components/AutoComponents/MSearch/index.vue

@@ -38,8 +38,8 @@
             <el-option
               v-for="option in item.option.items"
               :key="option.value"
-              :label="option[item.option.labelText ?? option.label]"
-              :value="option[item.option.labelValue ?? option.value]"
+              :label="option[item.option?.labelText ?? 'label']"
+              :value="option[item.option?.labelValue ?? 'value']"
             ></el-option>
           </el-select>
 

+ 171 - 70
src/views/salary/allocation/index.vue

@@ -2,22 +2,7 @@
   <div class="pa-3 white">
     <m-search :items="searchItems" v-model="searchValues" class="mb-3" @search="onSearch">
       <template #button>
-        <m-button
-          :type="isEdit ? 'success' : 'primary'"
-          size="small"
-          :icon="isEdit ? 'el-icon-check' : 'el-icon-edit'"
-          @click="onDistribute"
-        >
-          {{ isEdit ? '保存分配' : '编辑分配'}}
-        </m-button>
-        <m-button
-          type="primary"
-          size="small"
-          icon="el-icon-finished"
-          @click="onDistribute"
-        >
-          确认分配
-        </m-button>
+        <div class="ml-3">可发放绩效:{{ statisticObj.residue + ' / ' + statisticObj.total }}</div>
       </template>
     </m-search>
     <m-table
@@ -33,13 +18,21 @@
       <template #status="{ row }">
         <el-tag :type="statusList[row.status].color">{{ statusList[row.status].text }}</el-tag>
       </template>
-      <template #allocationPerformanceSalary="{ row }">
-        <template v-if="isEdit">
-          <el-input-number v-model="values[row.employeePerformanceId]" placeholder="分配绩效" size="small"></el-input-number>
-        </template>
-        <template v-else>
-          {{ row.allocationPerformanceSalary }}
-        </template>
+      <template #dataType="{row}">
+        {{ row.dataType === 1 ? '手工数据' : '系统数据' }}
+      </template>
+      <template #actions-header>
+        <el-button
+          type="primary"
+          size="small"
+          :loading="auditStatusLoading"
+          :disabled="auditStatus === 0 || auditStatus === 1"
+          @click="onSave">
+          {{ auditStatusList[auditStatus] ?? '确认分配' }}
+        </el-button>
+      </template>
+      <template #actions="{ row }">
+        <el-input :disabled="auditStatusLoading" v-model="values[row.employeePerformanceId]" placeholder="请输入绩效" size="small"></el-input>
       </template>
     </m-table>
   </div>
@@ -49,15 +42,20 @@
 import { dateFormat } from '@/utils/date'
 import {
   getAllocationPage,
-  saveAllocationGrant
-  // getAllocationEmployeeCategory
+  saveAllocationGrant,
+  getAllocationEmployeeCategory,
+  checkAllocationSubmitStatus,
+  getAllocationStatistics,
+  saveAllocation
 } from '@/api/salary'
 export default {
   name: 'salary-allocation',
   data () {
     return {
+      auditStatusList: ['审核中', '审核已通过', '审核未通过'],
+      auditStatus: null,
+      auditStatusLoading: true,
       values: {},
-      isEdit: false,
       statusList: {
         0: {
           text: '未分配',
@@ -72,39 +70,27 @@ export default {
           color: 'info'
         }
       },
-      searchItems: [
-        {
-          label: '月份',
-          prop: 'month',
-          type: 'datePicker',
-          option: {
-            placeholder: '请选择月份',
-            type: 'month',
-            valueFormat: 'yyyy-MM',
-            format: 'yyyy 年 MM 月'
-          }
-        }
-      ],
       searchValues: {
-        month: dateFormat('YYYY-mm', new Date())
+        month: dateFormat('YYYY-mm', new Date()),
+        employeeCategory: null
       },
       query: {
         month: dateFormat('YYYY-mm', new Date())
       },
       headers: [
         { label: '月份', prop: 'month' },
-        { label: '机构名称', prop: 'organizationName' },
+        { label: '机构名称', prop: 'organizationName', width: 150 },
         { label: '员工姓名', prop: 'employeeName' },
-        { label: '分配状态', prop: 'status' },
-        { label: '员工类型', prop: 'employeeCategory' },
-        { label: '可分配绩效薪资', prop: 'assignablePerformanceSalary', width: 150 },
-        { label: '领导分配绩效薪资', prop: 'allocationPerformanceSalary', width: 150 },
-        { label: '基础绩效薪资', prop: 'basicPerformanceSalary', width: 120 },
-        { label: '总绩效薪资', prop: 'performanceSalary' },
-        { label: '数据来源', prop: 'dataType' },
+        { label: '分配状态', prop: 'status', align: 'center' },
+        { label: '员工类型', prop: 'employeeCategory', align: 'center' },
+        { label: '可分配绩效薪资', prop: 'assignablePerformanceSalary', align: 'center', width: 150 },
+        { label: '领导分配绩效薪资', prop: 'allocationPerformanceSalary', align: 'center', width: 150 },
+        { label: '基础绩效薪资', prop: 'basicPerformanceSalary', align: 'center', width: 120 },
+        { label: '总绩效薪资', prop: 'performanceSalary', align: 'center', width: 120 },
+        { label: '数据来源', prop: 'dataType', align: 'center' },
         { label: '数据版本', prop: 'version', width: 160 },
         { label: '创建时间', prop: 'createDate', width: 160 },
-        { label: '操作', prop: 'actions', align: 'center', width: 100, fixed: 'right' }
+        { label: '操作', prop: 'actions', width: 160, fixed: 'right' }
       ],
       items: [
       ],
@@ -112,17 +98,55 @@ export default {
       total: 0,
       pageInfo: {
         current: 1,
-        size: 10
+        size: 50
       },
-      orders: []
-
+      orders: [],
+      employeeCategoryItems: [],
+      statisticObj: {
+        residue: null,
+        total: null
+      }
     }
   },
-  created () {
+  computed: {
+    searchItems () {
+      return [
+        {
+          label: '月份',
+          prop: 'month',
+          type: 'datePicker',
+          option: {
+            placeholder: '请选择月份',
+            clearable: false,
+            type: 'month',
+            valueFormat: 'yyyy-MM',
+            format: 'yyyy 年 MM 月'
+          },
+          handles: {
+            change: this.getEmployeeCategoryItems
+          }
+        },
+        {
+          label: '员工类型',
+          prop: 'employeeCategory',
+          type: 'select',
+          option: {
+            clearable: false,
+            placeholder: '请选择员工类型',
+            items: this.employeeCategoryItems
+          }
+        }
+      ]
+    }
+  },
+  async created () {
+    this.loading = true
+    await this.getEmployeeCategoryItems()
     this.onInit()
   },
   methods: {
     async onInit () {
+      this.loading = true
       try {
         const { data } = await getAllocationPage({
           page: {
@@ -133,13 +157,44 @@ export default {
             ...this.searchValues
           }
         })
+        await this.onCheckStatus()
+        await this.onStatistics()
+        data.records.forEach(e => {
+          if (Object.prototype.hasOwnProperty.call(this.values, e.employeePerformanceId)) {
+            return
+          }
+          this.$set(this.values, e.employeePerformanceId, e.allocationPerformanceSalary || null)
+        })
         this.items = data.records.map(e => {
           e.createDate = dateFormat('YYYY-mm-dd HH:MM:SS', new Date(e.createDate))
           return e
         })
         this.total = data.total
       } catch (error) {
-        this.$snackbar.error(error)
+        this.$message.error(error)
+      } finally {
+        this.loading = false
+      }
+    },
+    async getEmployeeCategoryItems () {
+      try {
+        const { data } = await getAllocationEmployeeCategory({
+          month: this.searchValues.month
+        })
+        this.employeeCategoryItems = data.map(e => {
+          return {
+            label: e,
+            value: e
+          }
+        })
+        if (!data.length) {
+          this.searchValues.employeeCategory = null
+          return
+        }
+        this.searchValues.employeeCategory = this.employeeCategoryItems[0].value
+      } catch (error) {
+        this.employeeCategoryItems = []
+        this.$message.error(error)
       }
     },
     onSearch () {
@@ -148,28 +203,74 @@ export default {
       this.onInit()
     },
     // 领导分配绩效薪资
-    onDistribute () {
-      if (this.isEdit) {
-        this.$confirm('确定保存当前数据?', '提示', {
-          confirmButtonText: '确定',
-          cancelButtonText: '取消',
-          type: 'warning'
-        }).then(() => {
-          this.onSave()
-        }).catch((error) => {
+    onSave () {
+      this.$confirm('确定提交所有数据?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(async () => {
+        try {
+          await saveAllocationGrant({
+            ...this.query,
+            employeePerformanceGrantItems: Object.keys(this.values).reduce((res, key) => {
+              res.push({
+                employeePerformanceId: key,
+                allocationPerformanceSalary: this.values[key]
+              })
+              return res
+            }, [])
+          })
+          if (this.statisticObj.residue !== this.statisticObj.total) {
+            this.$confirm('当前非完全配额,是否强制提交', '提示', {
+              confirmButtonText: '确定',
+              cancelButtonText: '取消',
+              type: 'warning'
+            }).then(() => {
+              this.onSaveAll(true)
+            }).catch(_ => {
+              this.onSaveAll(false)
+            })
+          } else {
+            this.onSaveAll(false)
+          }
+        } catch (error) {
           this.$message.error(error)
+        }
+      }).catch(_ => {})
+    },
+    async onSaveAll (force) {
+      try {
+        await saveAllocation({
+          ...this.query,
+          force: force ? 1 : 0
         })
+        this.$message.success('提交成功')
+        this.onInit()
+      } catch (error) {
+        this.$message.error(error)
       }
-      this.isEdit = !this.isEdit
     },
-    async onSave () {
+    // 查询提交状态
+    async onCheckStatus () {
+      this.auditStatusLoading = true
       try {
-        const { data } = await saveAllocationGrant({
-
-        })
-        console.log(data)
+        const { data } = await checkAllocationSubmitStatus(this.query)
+        this.auditStatus = data?.status ?? null
+      } catch (error) {
+        this.$message.error(error)
+      } finally {
+        this.auditStatusLoading = false
+      }
+    },
+    // 统计分配
+    async onStatistics () {
+      try {
+        const { data } = await getAllocationStatistics(this.query)
+        const { totalAllocationPerformanceSalary, totalGrantPerformanceSalary } = data
+        this.statisticObj.residue = totalGrantPerformanceSalary - totalAllocationPerformanceSalary
+        this.statisticObj.total = totalGrantPerformanceSalary || 0
       } catch (error) {
-        this.$snackbar.error(error)
+        this.$message.error(error)
       }
     },
     onDetails () {},