zhengnaiwen_citu 4 місяців тому
батько
коміт
189f5b991b

+ 15 - 0
src/api/salary.js

@@ -195,3 +195,18 @@ export function getAccessOrganization () {
 export function getPerformanceGroupPage (data) {
   return http.post('/customer/performance/group/page', data)
 }
+
+// 获取最大可分润比例
+export function getClaimRatioMax () {
+  return http.get('/performance/configuration/claim/max/radio')
+}
+
+// 分润批量认领
+export function claimPerformanceMore (data) {
+  return http.post('/customer/performance/batch/add/claim', data)
+}
+
+// 专业机构批量分润
+export function claimPerformanceMoreByBatch (data) {
+  return http.post('/customer/performance/major/dept/batch/add/claim', data)
+}

+ 1 - 1
src/components/AutoComponents/MButton/index.vue

@@ -1,7 +1,7 @@
 <template>
   <el-button v-bind="$attrs" :type="text ? 'text' : type" v-on="$listeners">
     <template v-if="text">
-      <el-link :underline="false" :type="type" text>
+      <el-link :underline="false" :type="type" text :disabled="$attrs.disabled">
         <slot></slot>
       </el-link>
     </template>

+ 1 - 0
src/views/bonus/allocation/index.vue

@@ -114,6 +114,7 @@ export default {
           type: 'select',
           options: {
             clearable: false,
+            filterable: true,
             placeholder: '请选择机构类型',
             items: this.organizationCategoryItems,
             labelValue: 'organizationNo',

+ 2 - 1
src/views/salary/claim/sharingClaim/index.vue

@@ -83,6 +83,7 @@ export default {
           type: 'select',
           options: {
             clearable: false,
+            filterable: true,
             placeholder: '请选择机构名称',
             items: this.organizationItems,
             labelValue: 'organizationNo'
@@ -175,7 +176,7 @@ export default {
     onDetails (item) {
       this.$refs.sharingClaimDetailsRefs.open({
         month: this.queryValues.month,
-        majorOrganization: this.organizationItems.find(e => e.organizationNo === this.queryValues.manageOrganizationNo)?.majorOrganization ?? null,
+        majorOrganization: this.organizationItems.find(e => e.organizationNo === this.queryValues.manageOrganizationNo)?.majorOrganization ?? false,
         manageOrganizationNo: item.organizationNo,
         ...item
       })

+ 55 - 15
src/views/salary/claim/sharingClaim/sharingClaimDetails.vue

@@ -1,5 +1,5 @@
 <template>
-  <m-dialog title="分润明细" ref="dialog" width="1280px">
+  <m-dialog title="分润明细" ref="dialog" width="1360px">
     <m-table
       clearHeader
       shadow="never"
@@ -12,36 +12,55 @@
       @page-change="onPageChange"
       @sort-change="onSortChange"
     >
+      <template #alreadyDistributedRatio="{ row }">
+        {{ row.alreadyDistributedRatio * 100 }} %
+      </template>
+      <template #employeeProfitSharingRatio="{ row }">
+        {{ row.employeeProfitSharingRatio * 100 }} %
+      </template>
       <template #actions="{ row }">
-        <!-- <m-button type="primary" text @click="onDetails(row)">查看明细</m-button> -->
-        <m-button type="primary" text @click="onClaim(row)" >分润认领</m-button>
-        <m-button type="primary" text @click="onClaim(row)" >专业部门分配</m-button>
+        <m-button
+          v-if="!majorOrganization"
+          type="primary"
+          text
+          @click="onClaim(row)"
+          :disabled="row.alreadyDistributedRatio * 100 >= maxRatio"
+        >
+          {{ row.alreadyDistributedRatio * 100 >= maxRatio ? '已分完' : '分润'}}
+        </m-button>
+        <m-button v-else type="primary" text @click="onClaimByDept(row)" >专业部门分配</m-button>
       </template>
     </m-table>
-    <SharingClaimDetailsClaim ref="sharingClaimDetailsClaimRefs"></SharingClaimDetailsClaim>
+    <SharingClaimDetailsClaim ref="sharingClaimDetailsClaimRefs" @success="getPage"></SharingClaimDetailsClaim>
+    <SharingClaimDetailsClaimByDept ref="sharingClaimDetailsClaimByDeptRefs" @success="getPage"></SharingClaimDetailsClaimByDept>
   </m-dialog>
 </template>
 
 <script>
 import {
-  getProfitSharingClaim
+  getProfitSharingClaim,
+  getClaimRatioMax
 } from '@/api/salary'
 import SharingClaimDetailsClaim from './sharingClaimDetailsClaim'
+import SharingClaimDetailsClaimByDept from './sharingClaimDetailsClaimByDept.vue'
 export default {
   name: 'sharingClaimDetails',
   components: {
-    SharingClaimDetailsClaim
+    SharingClaimDetailsClaim,
+    SharingClaimDetailsClaimByDept
   },
   data () {
     return {
       headers: [
         { label: '机构名称', prop: 'organizationName', sortable: false },
-        { label: '数据日期', prop: 'dataDate', width: 120 },
-        { label: '客户编号', prop: 'customerId', align: 'center', width: 120 },
+        { label: '数据日期', prop: 'dataDate', width: 105 },
+        { label: '客户编号', prop: 'customerId', align: 'center', width: 105 },
         { label: '一级科目编码/名称', prop: 'oneLevelSubject', width: 180 },
         { label: '二级科目编码/名称', prop: 'twoLevelSubject', width: 180 },
-        { label: '金额', prop: 'amount' },
-        { label: '员工分润比例', prop: 'employeeProfitSharingRatio', align: 'center', width: 140 },
+        { label: '认领金额', prop: 'amount', align: 'center', width: 105 },
+        { label: '认领比例', prop: 'employeeProfitSharingRatio', align: 'center', width: 105 },
+        { label: '分润金额', prop: 'residualAmount', align: 'center', width: 105 },
+        { label: '分润比例', prop: 'alreadyDistributedRatio', align: 'center', width: 105 },
         { label: '管户层级标识', prop: 'customerLevelIdentifier', width: 140 },
         { label: '客户类别标识', prop: 'customerCategoryIdentifier', width: 140 },
         { label: '统一认证号1', prop: 'unifiedCertificationNumber1', width: 150 },
@@ -66,17 +85,30 @@ export default {
         twoLevelSubject: null,
         customerLevelIdentifier: null,
         customerCategoryIdentifier: null
-      }
+      },
+      majorOrganization: false, // 是否是专业机构分润
+      maxRatio: 0 // 最大可分润比例
     }
   },
   methods: {
-    open (item) {
+    async open (item) {
+      this.majorOrganization = item.majorOrganization
       Object.keys(this.searchValues).forEach(key => {
         this.searchValues[key] = item[key]
       })
       this.$refs.dialog.open()
+      this.loading = true
+      await this.getRatioMax()
       this.getPage()
     },
+    async getRatioMax () {
+      try {
+        const { data } = await getClaimRatioMax()
+        this.maxRatio = data
+      } catch (error) {
+        this.$message.error(error)
+      }
+    },
     async getPage () {
       this.loading = true
       try {
@@ -87,7 +119,6 @@ export default {
           },
           ...this.searchValues
         })
-        // this.majorOrganization = this.organizationItems.find(e => e.organizationNo === this.searchValues.manageOrganizationNo).majorOrganization
         this.items = data.records
         this.total = data.total
       } catch (error) {
@@ -97,7 +128,16 @@ export default {
       }
     },
     onClaim (item) {
-      this.$refs.sharingClaimDetailsClaimRefs.open(item)
+      this.$refs.sharingClaimDetailsClaimRefs.open({
+        ...item,
+        maxRatio: this.maxRatio
+      })
+    },
+    onClaimByDept (item) {
+      this.$refs.sharingClaimDetailsClaimByDeptRefs.open({
+        ...item,
+        maxRatio: this.maxRatio
+      })
     },
     onPageChange (index) {
       this.pageInfo.current = index

+ 83 - 39
src/views/salary/claim/sharingClaim/sharingClaimDetailsClaim.vue

@@ -1,12 +1,18 @@
 <template>
   <m-dialog title="分润认领" ref="dialog" append-to-body @sure="onSure">
-    <m-form ref="form" :items="formItems" v-model="formValues" v-loading="loading">
+    <m-form :items="formItems" v-model="formValues" v-loading="loading" label-width="140px">
       <template #customerId>
         <el-tag>{{ formValues.customerId }}</el-tag>
       </template>
       <template #organizationName>
         <el-tag>{{ formValues.organizationName }}</el-tag>
       </template>
+      <template #maxRatio>
+        <el-tag>{{ formValues.maxRatio }} %</el-tag>
+      </template>
+      <template #nowRatio>
+        <el-tag>{{ nowRatio }} %</el-tag>
+      </template>
       <template #sharing>
         <el-form ref="form" :model="formQuery">
           <m-table
@@ -20,7 +26,7 @@
                 :prop="`items.${scope.$index}.unifiedCertificationNumber`"
                 :rules="{ required: true, message: '请选择员工', trigger: 'change' }"
               >
-                <el-select v-model="scope.unifiedCertificationNumber" filterable placeholder="请选择员工">
+                <el-select v-model="scope.row.unifiedCertificationNumber" filterable placeholder="请选择员工">
                   <el-option
                     v-for="item in employeeItems"
                     :key="item.personnelCode"
@@ -30,12 +36,16 @@
                 </el-select>
               </el-form-item>
             </template>
-            <template #employeeProfitSharingRatio="{ row }">
+            <template #employeeProfitSharingRatio="scope">
               <el-form-item
                 :prop="`items.${scope.$index}.employeeProfitSharingRatio`"
-                :rules="{ required: true, message: '请填写分润比例', trigger: 'blur' }"
+                :rules="employeeProfitSharingRatioRules"
               >
-                <el-input v-model="row.employeeProfitSharingRatio"></el-input>
+                <el-input v-model="scope.row.employeeProfitSharingRatio" placeholder="请输入分配比例">
+                  <template #append>
+                    %
+                  </template>
+                </el-input>
               </el-form-item>
             </template>
             <div class="d-flex justify-center pa-3">
@@ -50,12 +60,15 @@
 
 <script>
 import { getRosterList } from '@/api/system'
+import {
+  claimPerformanceMore
+} from '@/api/salary'
 const defaultItem = {
   unifiedCertificationNumber: null,
   employeeProfitSharingRatio: null
 }
 export default {
-  name: 'sharingClaimEdit',
+  name: 'sharingClaimDetailsClaim',
   data () {
     return {
       formValues: {},
@@ -66,57 +79,65 @@ export default {
       },
       headers: [
         { label: '员工姓名', prop: 'unifiedCertificationNumber' },
-        { label: '分润比例', prop: 'employeeProfitSharingRatio' }
+        { label: '分润比例 ( % )', prop: 'employeeProfitSharingRatio' }
       ],
       formItems: [
         {
           label: '客户编号',
           prop: 'customerId'
-        }, {
+        },
+        {
           label: '机构名称',
           prop: 'organizationName'
         },
+        {
+          label: '可分配比例',
+          prop: 'maxRatio'
+        },
+        {
+          label: '当前已分配',
+          prop: 'nowRatio'
+        },
         {
           label: '分润',
           prop: 'sharing'
         }
-        // {
-        //   label: '分润比例(%)',
-        //   prop: 'employeeProfitSharingRatio',
-        //   type: 'input',
-        //   slots: ['append'],
-        //   required: true,
-        //   options: {
-        //     placeholder: '请输入分润比例'
-        //   },
-        //   rules: [
-        //     {
-        //       validator: (rule, value, callback) => {
-        //         if (!value) {
-        //           return callback(new Error('请输入分润比例'))
-        //         }
-        //         if (isNaN(value) || isNaN(parseFloat(value))) {
-        //           callback(new Error('请输入数字值'))
-        //         } else {
-        //           if (value > 100 || value < 0) {
-        //             callback(new Error('请输入0-100的数字值'))
-        //           } else {
-        //             callback()
-        //           }
-        //         }
-        //       },
-        //       trigger: ['blur', 'change']
-        //     }
-        //   ]
-        // }
+      ],
+      employeeProfitSharingRatioRules: [
+        {
+          validator: (rule, value, callback) => {
+            if (!value) {
+              return callback(new Error('请输入分润比例'))
+            }
+            if (isNaN(value) || isNaN(parseFloat(value))) {
+              callback(new Error('请输入数字值'))
+            } else {
+              if (value > 100 || value < 0) {
+                callback(new Error('请输入0-100的数字值'))
+              } else {
+                callback()
+              }
+            }
+          },
+          trigger: ['blur', 'change']
+        }
       ]
     }
   },
+  computed: {
+    nowRatio () {
+      return this.formQuery.items.reduce((sum, e) => {
+        return sum + +(e.employeeProfitSharingRatio || 0)
+      }, 0)
+    }
+  },
   methods: {
     open (item) {
       this.formValues = {
         organizationName: item.organizationName,
-        customerId: item.customerId
+        customerId: item.customerId,
+        serialNumber: item.serialNumber,
+        maxRatio: item.maxRatio - item.alreadyDistributedRatio * 100
       }
       this.formQuery.items = [{ ...defaultItem }]
       this.$refs.dialog.open()
@@ -145,7 +166,30 @@ export default {
     addItem () {
       this.formQuery.items.push({ ...defaultItem })
     },
-    onSure () {}
+    onSure () {
+      this.$refs.form.validate(async (valid) => {
+        if (!valid) {
+          this.$message.error('请填写完整')
+        }
+        try {
+          await claimPerformanceMore({
+            serialNumber: this.formValues.serialNumber,
+            items: this.formQuery.items.map(e => {
+              return {
+                serialNumber: this.formValues.serialNumber,
+                employeeProfitSharingRatio: e.employeeProfitSharingRatio / 100,
+                unifiedCertificationNumber: e.unifiedCertificationNumber
+              }
+            })
+          })
+          this.$message.success('分润成功')
+          this.$refs.dialog.close()
+          this.$emit('success')
+        } catch (error) {
+          this.$message.error(error)
+        }
+      })
+    }
   }
 }
 </script>

+ 186 - 0
src/views/salary/claim/sharingClaim/sharingClaimDetailsClaimByDept.vue

@@ -0,0 +1,186 @@
+<template>
+  <m-dialog title="专业部门分配" ref="dialog" append-to-body @sure="onSure">
+    <m-form :items="formItems" v-model="formValues" v-loading="loading" label-width="140px">
+      <template #customerId>
+        <el-tag>{{ formValues.customerId }}</el-tag>
+      </template>
+      <template #maxRatio>
+        <el-tag>{{ formValues.maxRatio }} %</el-tag>
+      </template>
+      <template #nowRatio>
+        <el-tag>{{ nowRatio }} %</el-tag>
+      </template>
+      <template #sharing>
+        <el-form ref="form" :model="formQuery">
+          <m-table
+            clearHeader
+            shadow="never"
+            :headers="headers"
+            :items="formQuery.items"
+          >
+            <template #unifiedCertificationNumber="scope">
+              <el-form-item
+                :prop="`items.${scope.$index}.unifiedCertificationNumber`"
+                :rules="{ required: true, message: '请选择员工', trigger: 'change' }"
+              >
+                <el-cascader
+                  v-model="scope.row.unifiedCertificationNumber"
+                  :options="employeeItems"
+                  :show-all-levels="false"
+                  filterable
+                  :props="{
+                    emitPath: false,
+                    value: 'id',
+                    label: 'title',
+                    children: 'child'
+                  }"></el-cascader>
+              </el-form-item>
+            </template>
+            <template #employeeProfitSharingRatio="scope">
+              <el-form-item
+                :prop="`items.${scope.$index}.employeeProfitSharingRatio`"
+                :rules="employeeProfitSharingRatioRules"
+              >
+                <el-input v-model="scope.row.employeeProfitSharingRatio" placeholder="请输入分配比例">
+                  <template #append>
+                    %
+                  </template>
+                </el-input>
+              </el-form-item>
+            </template>
+            <div class="d-flex justify-center pa-3">
+              <m-button size="small" type="orange" icon="el-icon-plus" @click="addItem">新增一个分润</m-button>
+            </div>
+          </m-table>
+        </el-form>
+      </template>
+    </m-form>
+  </m-dialog>
+</template>
+
+<script>
+import { getOrganizationAtlasAll } from '@/api/system'
+import {
+  claimPerformanceMoreByBatch
+} from '@/api/salary'
+const defaultItem = {
+  unifiedCertificationNumber: null,
+  employeeProfitSharingRatio: null
+}
+export default {
+  name: 'sharingClaimDetailsClaimByDept',
+  data () {
+    return {
+      formValues: {},
+      loading: false,
+      employeeItems: [],
+      formQuery: {
+        items: []
+      },
+      headers: [
+        { label: '员工姓名', prop: 'unifiedCertificationNumber' },
+        { label: '分润比例 ( % )', prop: 'employeeProfitSharingRatio' }
+      ],
+      formItems: [
+        {
+          label: '客户编号',
+          prop: 'customerId'
+        },
+        {
+          label: '可分配比例',
+          prop: 'maxRatio'
+        },
+        {
+          label: '当前已分配',
+          prop: 'nowRatio'
+        },
+        {
+          label: '分配',
+          prop: 'sharing'
+        }
+      ],
+      employeeProfitSharingRatioRules: [
+        {
+          validator: (rule, value, callback) => {
+            if (!value) {
+              return callback(new Error('请输入分润比例'))
+            }
+            if (isNaN(value) || isNaN(parseFloat(value))) {
+              callback(new Error('请输入数字值'))
+            } else {
+              if (value > 100 || value < 0) {
+                callback(new Error('请输入0-100的数字值'))
+              } else {
+                callback()
+              }
+            }
+          },
+          trigger: ['blur', 'change']
+        }
+      ]
+    }
+  },
+  computed: {
+    nowRatio () {
+      return this.formQuery.items.reduce((sum, e) => {
+        return sum + +(e.employeeProfitSharingRatio || 0)
+      }, 0)
+    }
+  },
+  methods: {
+    open (item) {
+      this.formValues = {
+        customerId: item.customerId,
+        serialNumber: item.serialNumber,
+        maxRatio: item.maxRatio - item.alreadyDistributedRatio * 100
+      }
+      this.formQuery.items = [{ ...defaultItem }]
+      this.$refs.dialog.open()
+      this.getEmployeeItems()
+    },
+    async getEmployeeItems () {
+      this.loading = true
+      try {
+        const { data } = await getOrganizationAtlasAll({ type: 0 })
+        this.employeeItems = [data]
+      } catch (error) {
+        this.employeeItems = []
+        this.$message.error(error)
+      } finally {
+        this.loading = false
+      }
+    },
+    addItem () {
+      this.formQuery.items.push({ ...defaultItem })
+    },
+    onSure () {
+      this.$refs.form.validate(async (valid) => {
+        if (!valid) {
+          this.$message.error('请填写完整')
+        }
+        try {
+          await claimPerformanceMoreByBatch({
+            serialNumber: this.formValues.serialNumber,
+            items: this.formQuery.items.map(e => {
+              return {
+                serialNumber: this.formValues.serialNumber,
+                employeeProfitSharingRatio: e.employeeProfitSharingRatio / 100,
+                unifiedCertificationNumber: e.unifiedCertificationNumber
+              }
+            })
+          })
+          this.$message.success('分润成功')
+          this.$refs.dialog.close()
+          this.$emit('success')
+        } catch (error) {
+          this.$message.error(error)
+        }
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 1 - 1
src/views/salaryFixed/salaryFixedRules/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="pa-3 white">
-    <TabTemplate :import-context="(path) => import(`./${path}`)" @history="onHistory"></TabTemplate>
+    <TabTemplate :import-context="(path) => import(`./${path}`)"></TabTemplate>
   </div>
 </template>