瀏覽代碼

薪酬对比

zhengnaiwen_citu 7 月之前
父節點
當前提交
9a5d2540e3

+ 29 - 0
src/api/salary.js

@@ -31,3 +31,32 @@ export function addConfig (param) {
 export function updateConfig (param) {
   return http.put('/configurations', param)
 }
+
+// 薪酬对比 - 钻取查询
+export function getComparisonByEmployee (param) {
+  return http.post('/employee/performance/record/page', param)
+}
+
+// 薪酬对比 - 对比员工清单
+export function getComparisonPage (param) {
+  return http.post('/employee/performance/record/employee/page', param)
+}
+// 薪酬对比 - 上传手工模版
+export function uploadComparisonTemplate (param) {
+  return http.upload('/employee/performance/record/manual/upload', param)
+}
+
+// 薪酬对比 - 下载手工模版
+export function downloadComparisonTemplate () {
+  return http.download('/employee/performance/record/download/template')
+}
+
+// 薪酬对比 - 查看已确认绩效
+export function getComparisonConfirm (data) {
+  return http.post('/employee/performance/confirmation/page', data)
+}
+
+// 薪酬对比 - 确认绩效
+export function confirmComparisonVersion (data) {
+  return http.post('/employee/performance/confirmation/save', data)
+}

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

@@ -2,7 +2,7 @@
   <m-card>
     <el-form
       :inline="true"
-      :model="form"
+      :model="query"
       ref="form"
       label-width="80px"
       size="small"
@@ -17,7 +17,7 @@
         <!-- 输入框 -->
         <el-input
           v-if="item.type === 'input'"
-          v-model="form[item.prop]"
+          v-model="query[item.prop]"
           @keydown.enter.native="onSubmit"
           :clearable="item.option?.clearable ?? true"
           v-bind="item.option"
@@ -27,7 +27,7 @@
         <!-- 下拉框 -->
         <el-select
           v-if="item.type === 'select'"
-          v-model="form[item.prop]"
+          v-model="query[item.prop]"
           :clearable="item.option?.clearable ?? true"
           v-bind="item.option"
           v-on="item.handles"
@@ -42,7 +42,7 @@
 
         <el-autocomplete
           v-if="item.type === 'autocomplete'"
-          v-model="form[item.prop]"
+          v-model="query[item.prop]"
           v-bind="item.option"
           v-on="item.handles"
         >
@@ -54,7 +54,7 @@
         <!-- 时间选择器 -->
         <el-date-picker
           v-if="item.type === 'date'"
-          v-model="form[item.prop]"
+          v-model="query[item.prop]"
           v-bind="item.option"
           v-on="item.handles"
         ></el-date-picker>
@@ -87,17 +87,17 @@ export default {
   },
   data () {
     return {
-      form: { ...this.value }
+      query: { ...this.value }
     }
   },
   watch: {
     value: {
       handler (newVal) {
-        this.form = newVal
+        this.query = newVal
       },
       deep: true
     },
-    form: {
+    query: {
       handler (newVal) {
         this.$emit('input', newVal)
       },
@@ -106,11 +106,11 @@ export default {
   },
   methods: {
     onSubmit () {
-      this.$emit('search', this.form)
+      this.$emit('search', this.query)
     },
     onReset () {
       this.$refs.form.resetFields()
-      this.$emit('search', this.form)
+      this.$emit('search', this.query)
     }
   }
 }

+ 4 - 3
src/components/AutoComponents/MTable/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <m-card>
+  <m-card :shadow="shadow">
     <el-table
       ref="table"
       :data="items"
@@ -10,8 +10,8 @@
         <slot name="table-append"></slot>
       </template>
       <m-table-column
-        v-for="header in headers"
-        :key="header.prop ?? header.label"
+        v-for="(header, index) in headers"
+        :key="(header.prop ?? header.label) || index"
         :item="header"
       >
         <template v-if="$scopedSlots[header.prop]" #[header.prop]="scope">
@@ -39,6 +39,7 @@ export default {
   name: 'm-table',
   components: { MTableColumn },
   props: {
+    shadow: String,
     items: {
       type: Array,
       default: () => []

+ 193 - 16
src/views/salary/comparison/index.vue

@@ -1,9 +1,12 @@
 <template>
   <div class="white pa-3">
-    <m-search :items="searchItems" v-model="searchValues" class="mb-3">
+    <m-search :items="searchItems" v-model="searchValues" class="mb-3" @search="onSearch">
       <template #button>
-        <m-button type="primary" icon="el-icon-plus">导入手工数据</m-button>
-        <m-button type="primary" icon="el-icon-check">提交薪酬对比</m-button>
+        <el-upload class="el-button pa-0" action="#" :show-file-list="false" :http-request="onImport">
+          <m-button type="primary" icon="el-icon-upload2" :loading="importLoading">导入手工数据</m-button>
+        </el-upload>
+        <m-button type="primary" icon="el-icon-download" :loading="downloadLoading" @click="onExport">导出手工数据模板</m-button>
+        <!-- <m-button type="primary" icon="el-icon-check" :loading="submitLoading" :disable="checked" @click="onSubmit">薪酬对比确认</m-button> -->
       </template>
     </m-search>
     <m-table
@@ -14,27 +17,95 @@
       :page-size="pageInfo.size"
       :page-current="pageInfo.current"
       @page-change="onPageChange"
-    ></m-table>
+      @expand-change="onExpandChange"
+    >
+      <template #expand="{ row }">
+        <el-form label-position="left" inline class="demo-table-expand">
+          <m-card shadow="nerve">
+            <el-timeline :reverse="reverse">
+              <el-timeline-item
+                :hide-timestamp="true">
+                <el-row>
+                  <el-col :span="4">月份</el-col>
+                  <el-col :span="4">绩效薪资</el-col>
+                  <el-col :span="4">数据来源</el-col>
+                  <el-col :span="4">写入时间</el-col>
+                  <el-col :span="4">操作</el-col>
+                </el-row>
+              </el-timeline-item>
+              <el-timeline-item
+                v-for="(list, index) in row.childrenList"
+                :key="index"
+                :hide-timestamp="true">
+                <el-row>
+                  <el-col class="col" :span="4">{{ list.month }}</el-col>
+                  <el-col class="col" :span="4">{{ list.performanceSalary || '暂无' }}</el-col>
+                  <el-col class="col" :span="4">{{ list.dataType === 1 ? '手工录入' : '系统数据'}}</el-col>
+                  <el-col class="col" :span="4">{{ list.createDate }}</el-col>
+                  <el-col class="col" :span="4">
+                    <m-button v-if="checked"  type="text" size="small" icon="el-icon-checked" disabled>已使用当前版本</m-button>
+                    <m-button
+                      v-else
+                      type="primary"
+                      size="small"
+                      @click="onConfirm(list)"
+                    >确认使用该版本</m-button>
+                  </el-col>
+                </el-row>
+              </el-timeline-item>
+            </el-timeline>
+          </m-card>
+        </el-form>
+      </template>
+    </m-table>
   </div>
 </template>
 
 <script>
+import {
+  getComparisonPage,
+  uploadComparisonTemplate,
+  downloadComparisonTemplate,
+  getComparisonByEmployee,
+  getComparisonConfirm,
+  confirmComparisonVersion
+} from '@/api/salary'
+import { dateFormat } from '@/utils/date'
+import { downloadFile } from '@/utils'
 export default {
   name: 'salary-comparison',
   data () {
     return {
+      importLoading: false,
+      downloadLoading: false,
+      submitLoading: false,
       searchItems: [
-        { label: '月份', prop: 'month', type: 'date', option: { placeholder: '请选择月份', type: 'month' } },
-        { label: '姓名', prop: 'name', type: 'input', option: { placeholder: '请输入姓名' } },
-        { label: '部门', prop: 'department', type: 'input', option: { placeholder: '请输入部门' } }
+        {
+          label: '月份',
+          prop: 'month',
+          type: 'date',
+          option: {
+            placeholder: '请选择月份',
+            type: 'month',
+            valueFormat: 'yyyy-MM',
+            format: 'yyyy 年 MM 月'
+          }
+        },
+        { label: '部门', prop: 'organizationName', type: 'input', option: { placeholder: '请输入部门' } },
+        { label: '姓名', prop: 'employeeName', type: 'input', option: { placeholder: '请输入姓名' } }
       ],
-      searchValues: {},
+      searchValues: {
+        month: dateFormat('YYYY-mm', new Date()),
+        organizationName: null,
+        employeeName: null
+      },
       headers: [
-        { label: '姓名', prop: 'name' },
-        { label: '部门', prop: 'department' },
-        { label: '岗位', prop: 'post' },
-        { label: '月份', prop: 'month' },
-        { label: '操作', prop: 'action', align: 'center', width: 100 }
+        { type: 'expand', prop: 'expand' },
+        { label: '机构', prop: 'organizationName' },
+        { label: '姓名', prop: 'employeeName' },
+        { label: '统一认证号', prop: 'unifiedCertificationNumber' },
+        { label: '月份', prop: 'month' }
+        // { label: '操作', prop: 'action', align: 'center', width: 100 }
       ],
       items: [
       ],
@@ -43,12 +114,115 @@ export default {
       pageInfo: {
         current: 1,
         size: 10
-      }
+      },
+      checked: false
     }
   },
+  created () {
+    this.init()
+  },
   methods: {
     async init () {
-
+      try {
+        const { data } = await getComparisonPage({
+          page: this.pageInfo,
+          ...this.searchValues
+        })
+        // 确认是否已经确认方案
+        const { data: _data } = await getComparisonConfirm({
+          page: {
+            size: 10,
+            current: 1
+          },
+          month: this.searchValues.month
+        })
+        this.checked = _data.records[0]?.version ?? false
+        this.items = data.records.map(e => {
+          return {
+            ...e,
+            childrenList: []
+          }
+        })
+        this.total = data.total
+      } catch (error) {
+        this.$message.error(error)
+      }
+    },
+    onSearch () {
+      this.pageInfo.current = 1
+      this.init()
+    },
+    async onImport (response) {
+      this.importLoading = true
+      const formData = new FormData()
+      formData.append('file', response.file)
+      try {
+        await uploadComparisonTemplate(formData)
+        this.$message.success('导入成功')
+        this.init()
+      } catch (error) {
+        this.$message.error(error)
+      } finally {
+        this.importLoading = false
+      }
+    },
+    async onExport () {
+      this.downloadLoading = true
+      try {
+        const { data, name } = await downloadComparisonTemplate()
+        downloadFile(data, name)
+      } catch (error) {
+        this.$message.error(error)
+      } finally {
+        this.downloadLoading = false
+      }
+    },
+    async onExpandChange (row, expandedRows) {
+      if (row.childrenList.length) {
+        return
+      }
+      try {
+        const { data } = await getComparisonByEmployee({
+          page: {
+            size: 999,
+            current: 1
+          },
+          entity: {
+            unifiedCertificationNumber: row.unifiedCertificationNumber,
+            month: row.month
+          }
+        })
+        row.childrenList = data.records
+      } catch (error) {
+        this.$message.error(error)
+      }
+    },
+    onConfirm (item) {
+      const h = this.$createElement
+      this.$confirm(h('div', null, [
+        h('p', undefined, '确认后将无法修改,是否确认?'),
+        h('p', { style: 'color: #ff5555' }, '注:版本确认之后所有人将同步使用当前选择的版本')
+      ]), '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(async () => {
+        try {
+          await confirmComparisonVersion({
+            employeePerformanceConfirmation: {
+              month: item.month,
+              version: item.version
+            }
+          })
+          this.$message.success('确认成功')
+          this.checked = true
+        } catch (error) {
+          this.$message.error(error)
+        }
+      }).catch(_ => {})
+    },
+    onSubmit () {
+      this.submitLoading = true
     },
     onPageChange (page) {
       this.pageInfo.current = page
@@ -59,5 +233,8 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-
+.col {
+  height: 32px;
+  line-height: 30px;
+}
 </style>