zhengnaiwen_citu 6 ماه پیش
والد
کامیت
c032816256

+ 2 - 2
src/api/salary.js

@@ -67,6 +67,6 @@ export function getPayrollPage (data) {
 }
 
 // 工资单 - 导出报表
-export function downloadPayroll () {
-  return http.download('/employee/payroll/employee/download/export')
+export function downloadPayroll (data) {
+  return http.download('/employee/payroll/download/export', data)
 }

+ 4 - 24
src/api/welfare.js

@@ -3,40 +3,20 @@ import http from '@/utils/request'
 
 // 福利待遇 - 分页查询
 export function getWelfarePage (param) {
-  return http.post('/subsidy/category/page', param)
+  return http.post('/subsidy/page', param)
 }
 
 // 福利待遇 - 明细查询
 export function getWelfareDetail (param) {
-  return http.post('/subsidy/category/detail', param)
+  return http.post('/subsidy/detail', param)
 }
 
 // 福利待遇 - 保存
 export function saveWelfare (param) {
-  return http.post('/subsidy/category/save', param)
+  return http.post('/subsidy/save', param)
 }
 
 // 福利待遇 - 删除
 export function deleteWelfare (param) {
-  return http.post('/subsidy/category/del', param)
-}
-
-// 福利待遇 - 福利类型 分页查询
-export function getWelfareCategoryPage (param) {
-  return http.post('/subsidy/personnel/category/page', param)
-}
-
-// 福利待遇 - 福利类型 明细
-export function getWelfareCategoryDetails (param) {
-  return http.post('/subsidy/personnel/category/detail', param)
-}
-
-// 福利待遇 - 福利类型 保存
-export function saveWelfareCategory (param) {
-  return http.post('/subsidy/personnel/category/save', param)
-}
-
-// 福利待遇 - 福利类型 删除
-export function deleteWelfareCategory (param) {
-  return http.post('/subsidy/personnel/category/del', param)
+  return http.post('/subsidy/del', param)
 }

+ 3 - 2
src/components/AutoComponents/MDialog/index.vue

@@ -2,7 +2,7 @@
   <el-dialog
     :visible.sync="show"
     :title="title"
-    width="800px"
+    :width="width ?? '800px'"
     lock-scroll
     :close-on-click-modal="false"
     :close-on-press-escape="false"
@@ -22,7 +22,8 @@
 export default {
   name: 'm-dialog',
   props: {
-    title: String
+    title: String,
+    width: String
   },
   data () {
     return {

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

@@ -11,7 +11,7 @@
     <template v-for="(item, _i) in items">
       <el-form-item
         v-if="!item.hidden"
-        :key="item.prop || _i"
+        :key="item.prop + _i || _i"
         v-bind="item"
       >
         <template v-if="!item.type">

+ 8 - 0
src/components/AutoComponents/MTable/MTableColumn.vue

@@ -1,5 +1,13 @@
 <template>
   <el-table-column v-bind="item">
+    <template slot="header">
+      <template v-if="$scopedSlots[`${item.prop}-header`]">
+        <slot :name="`${item.prop}-header`"></slot>
+      </template>
+      <template v-else>
+        {{ item.label }}
+      </template>
+    </template>
     <!-- 默认插槽 -->
     <template slot-scope="scope">
       <!-- 如果有对应 prop 的插槽,则渲染插槽内容 -->

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

@@ -17,8 +17,12 @@
         <template v-if="$scopedSlots[header.prop]" #[header.prop]="scope">
           <slot :name="header.prop" v-bind="scope"></slot>
         </template>
+        <template v-if="$scopedSlots[`${header.prop}-header`]" #[`${header.prop}-header`]>
+          <slot :name="`${header.prop}-header`"></slot>
+        </template>
       </m-table-column>
     </el-table>
+    <slot></slot>
     <div class="pt-3 text-right" v-if="total">
       <el-pagination
         @current-change="handleCurrentChange"

+ 1 - 1
src/store/modules/user.js

@@ -30,7 +30,7 @@ const actions = {
     const newBase = new Base()
     const newParams = {
       username: username.trim(),
-      password: newBase.encode(password + (Math.random()).toString().slice(2, 8)),
+      password: newBase.encode(password.trim() + (Math.random()).toString().slice(2, 8)),
       ...query
     }
     // 账号密码处理

+ 4 - 0
src/styles/index.scss

@@ -81,3 +81,7 @@ $max-classes: 10;
 .text-nowrap {
   white-space: nowrap;
 }
+
+.d-flex {
+  display: flex;
+}

+ 95 - 21
src/views/humanResources/welfare/index.vue

@@ -1,39 +1,113 @@
 <template>
   <div class="white pa-3">
-    <el-tabs v-model="activeName" @tab-click="onClick">
-      <el-tab-pane v-for="item in items" :key="item.name" :label="item.label" :name="item.name">
-        <component :is="item.component"></component>
-      </el-tab-pane>
-    </el-tabs>
+    <m-search class="mb-3" :items="searchItems" v-model="searchQuery" @search="onSearch" @reset="onSearch">
+      <template #button>
+        <m-button type="primary" icon="el-icon-plus" @click="onAdd">新增</m-button>
+      </template>
+    </m-search>
+    <m-table
+      :items="items"
+      :headers="headers"
+      :loading="loading"
+      :total="total"
+      :page-size="pageInfo.size"
+      :page-current="pageInfo.current"
+      @page-change="onPageChange"
+    >
+      <template #title="{ row }">
+        {{ row.subsidyPersonnelCategory?.title ?? '找不到该项福利' }}
+      </template>
+      <template #actions="{ row }">
+        <m-button text type="primary" size="small" @click="onEdit(row)">编辑</m-button>
+        <m-button text type="primary" size="small" @click="onEditRules(row)">规则配置</m-button>
+        <m-button text type="danger" size="small" @click="onDelete(row)">删除</m-button>
+      </template>
+    </m-table>
+    <WelfareEdit ref="welfareEditRefs" @refresh="onInit"></WelfareEdit>
+    <WelfareRules ref="WelfareRulesRefs" @refresh="onInit"></WelfareRules>
   </div>
 </template>
 
 <script>
+import {
+  getWelfarePage
+} from '@/api/welfare'
+import WelfareEdit from './welfareEdit.vue'
+import WelfareRules from './welfareRules'
 export default {
   name: 'human-resources-welfare',
+  components: {
+    WelfareEdit,
+    WelfareRules
+  },
   data () {
     return {
-      activeName: null,
-      items: []
+      searchQuery: {
+        subsidyName: null
+      },
+      searchItems: [
+        {
+          label: '福利名称',
+          prop: 'subsidyName',
+          type: 'input'
+        }
+      ],
+      items: [],
+      headers: [
+        { label: '福利名称', prop: 'subsidyName' },
+        { label: '福利描述', prop: 'subsidyTag' },
+        { label: '创建日期', prop: 'createDate' },
+        { label: '操作', prop: 'actions' }
+      ],
+      loading: false,
+      total: 0,
+      pageInfo: {
+        current: 1,
+        size: 10
+      },
+      title: ''
     }
   },
   created () {
-    this.items = this.$route.meta.roles.map(e => {
-      return {
-        name: e.name,
-        label: e.label,
-        component: () => import(`@/views/${e.component}.vue`)
-      }
-    })
-    if (!this.$route.query.active) {
-      this.activeName = this.items[0].name
-    } else {
-      this.activeName = this.$route.query.active
-    }
+    this.onInit()
   },
   methods: {
-    onClick (tab) {
-      this.$router.push({ query: { active: tab.name } })
+    async onInit () {
+      try {
+        const { data } = await getWelfarePage({
+          page: {
+            ...this.pageInfo,
+            orders: [
+              {
+                asc: false,
+                column: 'subsidy_id'
+              }
+            ]
+          },
+          ...this.searchQuery
+        })
+        this.items = data.records
+        this.total = data.total
+      } catch (error) {
+        this.$message.error(error)
+      }
+    },
+    onEdit (item) {
+      this.$refs.welfareEditRefs.open(item)
+    },
+    onSearch () {
+      this.pageInfo.current = 1
+      this.onInit()
+    },
+    onAdd () {
+      this.$refs.welfareEditRefs.open()
+    },
+    onEditRules (item) {
+      this.$refs.WelfareRulesRefs.open(item)
+    },
+    onPageChange (page) {
+      this.pageInfo.current = page
+      this.onInit()
     }
   }
 }

+ 95 - 0
src/views/humanResources/welfare/welfareEdit.vue

@@ -0,0 +1,95 @@
+<template>
+  <m-dialog ref="dialog" :title="itemData.subsidy ? '编辑' : '新增'" @sure="onSure">
+    <m-form ref="form" v-model="formQuery" :items="items" v-loading="loading"></m-form>
+  </m-dialog>
+</template>
+
+<script>
+import {
+  saveWelfare,
+  getWelfareDetail
+} from '@/api/welfare'
+export default {
+  name: 'welfare-edit',
+  data () {
+    return {
+      loading: false,
+      formQuery: {
+        subsidyName: null,
+        subsidyTag: null
+      },
+      items: [
+        {
+          label: '福利名称',
+          prop: 'subsidyName',
+          type: 'input',
+          rules: [
+            { required: true, message: '请输入福利名称', trigger: 'blur' }
+          ],
+          options: {
+            placeholder: '请输入福利名称'
+          }
+        },
+        {
+          label: '福利描述',
+          prop: 'subsidyTag',
+          type: 'input',
+          options: {
+            placeholder: '请输入福利名称'
+          }
+        }
+      ],
+      itemData: {}
+    }
+  },
+  methods: {
+    async open (item) {
+      this.$refs.dialog.open()
+      if (item) {
+        this.formQuery.subsidyName = item.subsidyName
+        this.formQuery.subsidyTag = item.subsidyTag
+        this.loading = true
+        try {
+          const { data } = await getWelfareDetail({
+            subsidyId: item.subsidyId
+          })
+          this.itemData = data
+        } catch (error) {
+          this.$message.error(error)
+        } finally {
+          this.loading = false
+        }
+      } else {
+        this.formQuery.subsidyName = null
+        this.formQuery.subsidyTag = null
+        this.itemData = {}
+      }
+    },
+    onSure () {
+      this.$refs.form.validate(async valid => {
+        if (valid) {
+          const query = {
+            subsidy: {
+              subsidyId: this.itemData.subsidy?.subsidyId,
+              ...this.formQuery
+            },
+            subsidyItems: this.itemData.subsidyItems ?? []
+          }
+          try {
+            await saveWelfare(query)
+            this.$refs.dialog.close()
+            this.$emit('refresh')
+            this.$message.success('保存成功')
+          } catch (error) {
+            this.$message.error(error)
+          }
+        }
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 0 - 220
src/views/humanResources/welfare/welfareList.vue

@@ -1,220 +0,0 @@
-<template>
-  <div>
-    <m-search ref="search" :items="searchItems" v-model="searchValues" @search="onSearch" class="mb-3">
-      <template #button>
-        <m-button type="primary" icon="el-icon-plus" @click="onAdd">新增</m-button>
-      </template>
-    </m-search>
-    <m-table
-      :items="items"
-      :headers="headers"
-      :loading="loading"
-      :total="total"
-      :page-size="pageInfo.size"
-      :page-current="pageInfo.current"
-      @page-change="onPageChange"
-    >
-      <template #title="{ row }">
-        {{ row.subsidyPersonnelCategory?.title ?? '找不到该项福利' }}
-      </template>
-      <template #actions="{ row }">
-        <m-button text type="primary" size="small" @click="onEdit(row)">编辑</m-button>
-        <m-button text type="danger" size="small" @click="onDelete(row)">删除</m-button>
-      </template>
-    </m-table>
-    <welfareListEdit ref="welfareListEditRefs" :title="title" @refresh="init"></welfareListEdit>
-  </div>
-</template>
-
-<script>
-import {
-  getWelfarePage,
-  getWelfareDetail,
-  getWelfareCategoryPage,
-  deleteWelfare
-} from '@/api/welfare'
-import welfareListEdit from './welfareListEdit.vue'
-export default {
-  name: 'welfare-list',
-  components: {
-    welfareListEdit
-  },
-  data () {
-    return {
-      title: '',
-      subsidyPersonnelCategoryIdItems: [],
-      searchValues: {},
-      headers: [
-        {
-          label: '福利名称',
-          prop: 'subsidyName'
-        },
-        {
-          label: '福利类别',
-          prop: 'title'
-        },
-        {
-          label: '金额(元 / 月)',
-          prop: 'subsidySalary'
-        },
-        {
-          label: '描述',
-          prop: 'subsidyTag'
-        },
-        {
-          label: '创建时间',
-          prop: 'createDate'
-        },
-        {
-          label: '操作',
-          prop: 'actions'
-        }
-      ],
-      items: [],
-      loading: false,
-      total: 0,
-      pageInfo: {
-        current: 1,
-        size: 10
-      },
-      orders: [],
-      loadingSelect: false
-    }
-  },
-  computed: {
-    searchItems () {
-      return [
-        {
-          label: '福利名称',
-          prop: 'subsidyName',
-          type: 'input',
-          option: {
-            placeholder: '请输入福利名称'
-          }
-        },
-        {
-          label: '福利类别',
-          prop: 'subsidyPersonnelCategoryId',
-          type: 'select',
-          handles: {
-            focus: (v) => {
-              if (!this.searchValues.subsidyPersonnelCategoryId) {
-                this.$refs.search.$refs.select.remoteMethod(null)
-              }
-            }
-          },
-          option: {
-            ref: 'select',
-            placeholder: '请输入福利类别',
-            labelText: 'title',
-            labelValue: 'subsidyPersonnelCategoryId',
-            valueKey: 'subsidyPersonnelCategoryId',
-            filterable: true,
-            remote: true,
-            remoteMethod: this.remoteMethod,
-            defaultFirstOption: true,
-            loading: this.loadingSelect,
-            items: this.subsidyPersonnelCategoryIdItems
-          }
-        }
-      ]
-    }
-  },
-  created () {
-    this.init()
-  },
-  methods: {
-    async init () {
-      this.loading = true
-      try {
-        const { data } = await getWelfarePage({
-          subsidyCategory: this.searchValues,
-          page: {
-            ...this.pageInfo,
-            orders: this.orders
-          }
-        })
-        this.items = data.records
-        this.total = data.total
-      } catch (error) {
-        this.$message.error(error)
-      } finally {
-        this.loading = false
-      }
-    },
-    onSearch () {
-      this.pageInfo.current = 1
-      this.init()
-    },
-    onPageChange (page) {
-      this.pageInfo.current = page
-      this.init()
-    },
-    async remoteMethod (str) {
-      try {
-        this.loadingSelect = true
-        const { data } = await getWelfareCategoryPage({
-          page: {
-            current: 1,
-            size: 10
-          },
-          entity: {
-            title: str || null
-          }
-        })
-        this.subsidyPersonnelCategoryIdItems = data.records
-      } catch (error) {
-        this.subsidyPersonnelCategoryIdItems = []
-        this.$message.error(error)
-      } finally {
-        this.loadingSelect = false
-      }
-    },
-    onAdd () {
-      this.title = '新增福利'
-      this.$refs.welfareListEditRefs.open({
-        subsidyPersonnelCategoryId: null,
-        subsidySalary: null,
-        subsidyTag: null,
-        subsidyCheck: 0,
-        subsidyName: null
-      })
-    },
-    async onEdit (item) {
-      this.title = '编辑福利'
-      try {
-        const { data } = await getWelfareDetail({ subsidyCategoryId: item.subsidyCategoryId })
-        this.$refs.welfareListEditRefs.open({
-          subsidyCategoryId: data.subsidyCategoryId,
-          subsidyPersonnelCategoryId: data.subsidyPersonnelCategoryId,
-          subsidySalary: data.subsidySalary,
-          subsidyTag: data.subsidyTag,
-          subsidyCheck: data.subsidyCheck,
-          subsidyName: data.subsidyName
-        })
-      } catch (error) {
-        this.$message.error(error)
-      }
-    },
-    onDelete (item) {
-      this.$confirm('确定删除?', '提示', {
-        confirmButtonText: '确定',
-        cancelButtonText: '取消',
-        type: 'warning'
-      }).then(async () => {
-        try {
-          await deleteWelfare({ id: item.subsidyCategoryId })
-          this.$message.success('删除成功')
-          this.init()
-        } catch (error) {
-          this.$message.error(error)
-        }
-      }).catch(() => {})
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-
-</style>

+ 0 - 158
src/views/humanResources/welfare/welfareListEdit.vue

@@ -1,158 +0,0 @@
-<template>
-  <m-dialog ref="dialog" v-bind="$attrs" v-on="$listeners" @sure="onSure">
-    <m-form ref="form" :items="items" label-width="180px" v-model="values" v-loading="loadingPage"></m-form>
-  </m-dialog>
-</template>
-
-<script>
-import {
-  getWelfareCategoryPage,
-  saveWelfare,
-  getWelfareCategoryDetails
-} from '@/api/welfare'
-export default {
-  name: 'welfare-list-edit',
-  data () {
-    return {
-      loading: false,
-      loadingPage: false,
-      subsidyPersonnelCategoryIdItems: [],
-      values: {}
-    }
-  },
-  computed: {
-    items () {
-      return [
-        {
-          label: '福利名称',
-          prop: 'subsidyName',
-          type: 'input',
-          options: {
-            placeholder: '请输入福利名称'
-          },
-          rules: [
-            { required: true, message: '请输入福利名称', trigger: 'blur' }
-          ]
-        },
-        {
-          label: '福利类型',
-          prop: 'subsidyPersonnelCategoryId',
-          type: 'select',
-          handles: {
-            focus: () => {
-              if (!this.values.subsidyPersonnelCategoryId) {
-                this.remoteMethod(null)
-              }
-            }
-          },
-          options: {
-            ref: 'select',
-            placeholder: '请选择福利类型',
-            filterable: true,
-            remote: true,
-            labelText: 'title',
-            labelValue: 'subsidyPersonnelCategoryId',
-            remoteMethod: this.remoteMethod,
-            valueKey: 'subsidyPersonnelCategoryId',
-            defaultFirstOption: true,
-            loading: this.loading,
-            items: this.subsidyPersonnelCategoryIdItems
-          },
-          rules: [
-            { required: true, message: '请选择福利类型', trigger: 'change' }
-          ]
-        },
-        {
-          label: '金额(元 / 月)',
-          prop: 'subsidySalary',
-          type: 'number',
-          options: {
-            placeholder: '请输入金额'
-          },
-          rules: [
-            { required: true, message: '请输入金额', trigger: 'blur' }
-          ]
-        },
-        {
-          label: '福利限制',
-          prop: 'subsidyCheck',
-          type: 'radioGroup',
-          options: {
-            items: [
-              { text: '全额', label: 0 },
-              { text: '不超过', label: 1 }
-            ]
-          },
-          rules: [
-            { required: true, message: '请输入金额', trigger: 'blur' }
-          ]
-        },
-        {
-          label: '描述',
-          prop: 'subsidyTag',
-          type: 'input',
-          options: {
-            placeholder: '请输入描述'
-          }
-        }
-      ]
-    }
-  },
-  methods: {
-    async open (item) {
-      this.values = item
-      this.$refs.dialog.open()
-      if (item.subsidyCategoryId) {
-        this.loadingPage = true
-        try {
-          const { data } = await getWelfareCategoryDetails({
-            subsidyPersonnelCategoryId: item.subsidyPersonnelCategoryId
-          })
-          this.subsidyPersonnelCategoryIdItems = [data]
-        } catch (error) {
-          this.$message.error(error)
-        } finally {
-          this.loadingPage = false
-        }
-      }
-    },
-    async remoteMethod (query) {
-      this.loading = true
-      try {
-        const { data } = await getWelfareCategoryPage({
-          page: {
-            size: 50,
-            current: 1
-          },
-          entity: {
-            title: query || null
-          }
-        })
-        this.subsidyPersonnelCategoryIdItems = data.records
-      } catch (error) {
-        this.subsidyPersonnelCategoryIdItems = []
-        this.$message.error(error)
-      } finally {
-        this.loading = false
-      }
-    },
-    onSure () {
-      this.$refs.form.validate(async valid => {
-        if (!valid) return
-        try {
-          await saveWelfare({ subsidyCategory: this.values })
-          this.$message.success('操作成功')
-          this.$refs.dialog.close()
-          this.$emit('refresh')
-        } catch (error) {
-          this.$message.error(error)
-        }
-      })
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-
-</style>

+ 183 - 0
src/views/humanResources/welfare/welfareRules.vue

@@ -0,0 +1,183 @@
+<template>
+  <m-dialog ref="dialog" title="规则配置" width="1000px" @sure="onSure">
+    <el-form ref="form" :model="formQuery">
+      <m-table
+        shadow="naver"
+        :items="formQuery.items"
+        :headers="headers"
+      >
+        <div class="text-center mt-3">
+          <m-button icon="el-icon-plus" type="primary" size="small" @click="onAdd">添加一行</m-button>
+        </div>
+        <template #subsidyOrganizationNos="scope">
+          <el-form-item
+            :prop="`items.${scope.$index}.subsidyOrganizationNos`"
+            :rules="{ required: true, message: '请输入机构名称', trigger: 'blur' }"
+          >
+          <el-cascader
+            v-model="formQuery.items[scope.$index].subsidyOrganizationNos"
+            placeholder="请输入机构名称"
+            :ref="'cascader' + scope.$index"
+            :options="options"
+            :show-all-levels="false"
+            collapse-tags
+            :props="{
+              checkStrictly: false,
+              label: 'organizationName',
+              value: 'organizationNo',
+              children: 'child',
+              emitPath: false,
+              multiple: true
+            }"
+            @change="onChange($event, scope)"
+          ></el-cascader>
+          </el-form-item>
+        </template>
+        <template #subsidySalary="scope">
+          <el-form-item
+            :prop="`items.${scope.$index}.subsidySalary`"
+            :rules="{ required: true, message: '请输入福利薪资', trigger: 'blur' }"
+          >
+            <el-input-number
+              v-model="formQuery.items[scope.$index].subsidySalary"
+              placeholder="福利薪资"
+            ></el-input-number>
+          </el-form-item>
+        </template>
+        <template #subsidyCheck="scope">
+          <el-form-item
+            :prop="`items.${scope.$index}.subsidyCheck`"
+            :rules="{ required: true, message: '请输入福利条件描述', trigger: 'blur' }"
+          >
+            <el-input
+              v-model="formQuery.items[scope.$index].subsidyCheck"
+              placeholder="福利条件描述"
+              type="textarea"
+              :autosize="{ minRows: 1.335, maxRows: 4}"
+            ></el-input>
+          </el-form-item>
+        </template>
+        <template #actions="scope">
+          <m-button class="mb-5" size="small" text type="danger" @click="onDelete(scope)">移除</m-button>
+        </template>
+      </m-table>
+    </el-form>
+  </m-dialog>
+</template>
+
+<script>
+import {
+  saveWelfare,
+  getWelfareDetail
+} from '@/api/welfare'
+
+import {
+  getOrganizationTree
+} from '@/api/system'
+export default {
+  name: 'welfare-rules',
+  data () {
+    return {
+      formQuery: {
+        items: [
+          {
+            subsidyOrganizationNames: [],
+            subsidyOrganizationNos: [],
+            subsidySalary: null,
+            subsidyCheck: null
+          }
+        ]
+      },
+      headers: [
+        { label: '机构名称', prop: 'subsidyOrganizationNos' },
+        { label: '福利薪资', prop: 'subsidySalary' },
+        { label: '福利条件描述', prop: 'subsidyCheck', width: 420 },
+        { label: '操作', prop: 'actions', width: 100 }
+      ],
+      itemData: {},
+      options: []
+    }
+  },
+  methods: {
+    async open (item) {
+      this.$refs.dialog.open()
+      try {
+        const { data } = await getWelfareDetail({
+          subsidyId: item.subsidyId
+        })
+        this.itemData = data
+        this.formQuery.items = data.subsidyItems.map(e => {
+          return {
+            subsidyOrganizationNames: e.subsidyOrganizationNames,
+            subsidyOrganizationNos: e.subsidyOrganizationNos,
+            subsidySalary: e.subsidySalary,
+            subsidyCheck: e.subsidyCheck
+          }
+        })
+        await this.getDeptTree()
+      } catch (error) {
+        this.$message.error(error)
+      } finally {
+        this.loading = false
+      }
+    },
+    async getDeptTree () {
+      try {
+        const { data } = await getOrganizationTree()
+        this.options = this.assignData([data])
+      } catch (error) {
+        this.$message.error(error)
+      }
+    },
+    assignData (data) {
+      return data.map(res => {
+        const { child, ...e } = res
+        return {
+          ...e,
+          child: child && child.length ? this.assignData(child) : undefined
+        }
+      })
+    },
+    onAdd () {
+      this.formQuery.items.push({
+        subsidyOrganizationNames: [],
+        subsidyOrganizationNos: [],
+        subsidySalary: 0,
+        subsidyCheck: null
+      })
+    },
+    onDelete (scope) {
+      this.formQuery.items.splice(scope.$index, 1)
+    },
+    onChange (v, item) {
+      const data = this.$refs['cascader' + item.$index].getCheckedNodes(true)
+      this.formQuery.items[item.$index].subsidyOrganizationNames = data.map(e => e.data.organizationName)
+    },
+    onSure () {
+      this.$refs.form.validate(async valid => {
+        if (valid) {
+          const query = {
+            subsidy: {
+              subsidyId: this.itemData.subsidy.subsidyId,
+              subsidyName: this.itemData.subsidy.subsidyName
+            },
+            subsidyItems: this.formQuery.items
+          }
+          try {
+            await saveWelfare(query)
+            this.$refs.dialog.close()
+            this.$emit('refresh')
+            this.$message.success('保存成功')
+          } catch (error) {
+            this.$message.error(error)
+          }
+        }
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 0 - 147
src/views/humanResources/welfare/welfareType.vue

@@ -1,147 +0,0 @@
-<template>
-  <div>
-    <m-search :items="searchItems" v-model="searchValues" class="mb-3" @search="onSearch">
-      <template #button>
-        <m-button type="primary" icon="el-icon-plus" @click="onAdd">新增</m-button>
-      </template>
-    </m-search>
-    <m-table
-      :headers="headers"
-      :items="items"
-      :page-size="pageInfo.size"
-      :total="total"
-      :page-current="pageInfo.current"
-      v-loading="loading"
-      @page-change="onPageChange"
-    >
-      <template #actions="{ row }">
-        <m-button type="primary" text size="small" @click="onEdit(row)">编辑</m-button>
-        <m-button type="danger" text size="small" @click="onDelete(row)">删除</m-button>
-      </template>
-    </m-table>
-    <welfareTypeEdit ref="editRefs" @refresh="onInit"></welfareTypeEdit>
-  </div>
-</template>
-
-<script>
-import welfareTypeEdit from './welfareTypeEdit.vue'
-import {
-  getWelfareCategoryPage,
-  getWelfareCategoryDetails,
-  deleteWelfareCategory
-} from '@/api/welfare'
-export default {
-  name: 'welfare-type',
-  components: {
-    welfareTypeEdit
-  },
-  data () {
-    return {
-      searchItems: [
-        {
-          label: '名称',
-          type: 'input',
-          prop: 'title',
-          option: {
-            placeholder: '请输入名称'
-          }
-        },
-        {
-          label: '描述',
-          type: 'input',
-          prop: 'tag',
-          option: {
-            placeholder: '请输入描述'
-          }
-        }
-      ],
-      searchValues: {
-        title: null,
-        tag: null
-      },
-      headers: [
-        {
-          label: '名称',
-          prop: 'title'
-        },
-        {
-          label: '描述',
-          prop: 'tag'
-        },
-        {
-          label: '创建时间',
-          prop: 'createDate'
-        },
-        {
-          label: '操作',
-          prop: 'actions'
-        }
-      ],
-      items: [],
-      pageInfo: {
-        current: 1,
-        size: 10
-      },
-      total: 0,
-      loading: false
-    }
-  },
-  created () {
-    this.onInit()
-  },
-  methods: {
-    async onInit () {
-      this.loading = true
-      try {
-        const { data } = await getWelfareCategoryPage({
-          page: this.pageInfo,
-          entity: this.searchValues
-        })
-        this.items = data.records
-      } catch (error) {
-        this.$message.error(error)
-      } finally {
-        this.loading = false
-      }
-    },
-    onAdd () {
-      this.$refs.editRefs.open()
-    },
-    async onEdit (item) {
-      try {
-        const { data } = await getWelfareCategoryDetails({ subsidyPersonnelCategoryId: item.subsidyPersonnelCategoryId })
-        this.$refs.editRefs.open(data)
-      } catch (error) {
-        this.$message.error(error)
-      }
-    },
-    onDelete (item) {
-      this.$confirm('确定删除该条数据?', '提示', {
-        confirmButtonText: '确定',
-        cancelButtonText: '取消',
-        type: 'warning'
-      }).then(async () => {
-        try {
-          await deleteWelfareCategory({ subsidyPersonnelCategoryId: item.subsidyPersonnelCategoryId })
-          this.$message.success('删除成功')
-          this.onInit()
-        } catch (error) {
-          this.$message.error(error)
-        }
-      }).catch(_ => {})
-    },
-    onSearch () {
-      this.pageInfo.current = 1
-      this.onInit()
-    },
-    onPageChange (index) {
-      this.pageInfo.current = index
-      this.onInit()
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-
-</style>

+ 0 - 208
src/views/humanResources/welfare/welfareTypeEdit.vue

@@ -1,208 +0,0 @@
-<template>
-  <m-dialog ref="dialog" :title="title" v-bind="$attrs" v-on="$listeners" @sure="onSure">
-    <m-form ref="form" :items="formItems" label-width="180px" v-model="values" v-loading="loading">
-      <template #organizationName>
-        <el-dropdown trigger="click">
-          <el-input v-model="values.organizationName" readonly placeholder="请选择职务所属机构"></el-input>
-          <el-dropdown-menu slot="dropdown">
-            <div class="treeBox">
-              <el-tree
-                :data="treeItems"
-                node-key="uuid"
-                show-checkbox
-                :highlight-current="true"
-                :expand-on-click-node="false"
-                :default-expanded-keys="expandRowKeys"
-                :default-checked-keys="defaultCheckedKeys"
-                :props="{ label: 'organizationName', children: 'child' }"
-                @check="onCheck"
-              ></el-tree>
-            </div>
-          </el-dropdown-menu>
-        </el-dropdown>
-      </template>
-    </m-form>
-  </m-dialog>
-</template>
-
-<script>
-import { organizationDrill, getOrganizationTree } from '@/api/system'
-import {
-  saveWelfareCategory
-} from '@/api/welfare'
-export default {
-  name: 'welfare-type-edit',
-  data () {
-    return {
-      loading: false,
-      headers: [
-        { label: '职务名称', prop: 'organizationName' },
-        { label: '应用部门', prop: 'tag' }
-      ],
-      title: '',
-      values: {},
-      choose: [],
-      defaultCheckedKeys: [],
-      items: [],
-      treeItems: [],
-      expandRowKeys: []
-    }
-  },
-  computed: {
-    formItems () {
-      return [
-        {
-          label: '福利类型名称',
-          prop: 'title',
-          type: 'input',
-          options: {
-            placeholder: '请输入福利类型名称'
-          },
-          rules: [
-            { required: true, message: '请输入福利类型名称', trigger: 'blur' }
-          ]
-        },
-        {
-          label: '职务名称',
-          prop: 'postName',
-          type: 'select',
-          options: {
-            items: this.items,
-            labelText: 'organizationName',
-            labelValue: 'organizationName'
-          },
-          rules: [
-            { required: true, message: '请选择职务', trigger: 'change' }
-          ]
-        },
-        {
-          label: '机构',
-          prop: 'organizationName',
-          rules: [
-            { required: true, message: '请选择机构', trigger: 'change' }
-          ]
-        },
-        {
-          label: '描述',
-          prop: 'tag',
-          type: 'input',
-          options: {
-            type: 'textarea',
-            placeholder: '请输入描述'
-          }
-        }
-      ]
-    }
-  },
-  methods: {
-    async open (item) {
-      this.loading = true
-      this.$refs.dialog.open()
-      await this.getData()
-      await this.getOrganizationTree()
-      this.loading = false
-      if (!item) {
-        this.title = '新增福利类型'
-        this.values = {
-          title: null,
-          tag: null,
-          postName: null,
-          organizationName: null
-        }
-        this.defaultCheckedKeys = []
-      } else {
-        this.title = '编辑福利类型'
-        this.values = {
-          subsidyPersonnelCategoryId: item.subsidyPersonnelCategoryId,
-          title: item.title,
-          tag: item.tag,
-          postName: item.subsidyPersonnelCategoryItems[0]?.postName ?? null,
-          organizationName: this.onShow(item.subsidyPersonnelCategoryItems.length)
-        }
-        this.choose = item.subsidyPersonnelCategoryItems
-        this.defaultCheckedKeys = this.onGetUUID(item.subsidyPersonnelCategoryItems, this.treeItems)
-      }
-    },
-    onSure () {
-      this.$refs.form.validate(async valid => {
-        if (!valid) {
-          return
-        }
-        try {
-          await saveWelfareCategory({
-            subsidyPersonnelCategory: {
-              subsidyPersonnelCategoryId: this.values.subsidyPersonnelCategoryId,
-              title: this.values.title,
-              tag: this.values.tag
-            },
-            subsidyPersonnelCategoryItems: this.choose.map(e => {
-              return {
-                postName: this.values.postName,
-                organizationName: e.organizationName,
-                level: e.level
-              }
-            })
-          })
-          this.$message.success('保存成功')
-          this.$refs.dialog.close()
-          this.$emit('refresh')
-        } catch (error) {
-          this.$message.error(error)
-        }
-      })
-    },
-    async getOrganizationTree () {
-      try {
-        const { data } = await getOrganizationTree()
-        this.expandRowKeys = [data.uuid]
-        this.treeItems = [data]
-      } catch (error) {
-        this.$message.error(error)
-      }
-    },
-    async getData () {
-      try {
-        const { data } = await organizationDrill({ resDataType: 1 })
-        this.items = data.map(e => {
-          return {
-            ...e,
-            value: null
-          }
-        })
-      } catch (error) {
-        this.$message.error(error)
-      }
-    },
-    onGetUUID (arr, items, content = []) {
-      items.forEach(e => {
-        if (e.child && e.child.length) {
-          content.push(...this.onGetUUID(arr, e.child, content))
-        }
-        const item = arr.find(_e => _e.level === e.level && _e.organizationName === e.organizationName)
-        if (item) {
-          content.push(e.uuid)
-        }
-      })
-      return content
-    },
-    onShow (val) {
-      if (!val) {
-        return null
-      }
-      return `已选 ${val} 个机构`
-    },
-    onCheck (data, event) {
-      this.choose = event.checkedNodes
-      this.values.organizationName = this.onShow(this.choose.length)
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-.treeBox {
-  width: 250px;
-  max-height: 400px;
-  overflow: auto;
-}
-</style>

+ 3 - 0
src/views/salary/allocation/index.vue

@@ -56,6 +56,9 @@ export default {
       pageInfo: {
         current: 1,
         size: 10
+      },
+      method: {
+        onExpandChange () {}
       }
 
     }

+ 88 - 4
src/views/salary/calculate/index.vue

@@ -1,15 +1,99 @@
 <template>
-  <div>
-
+  <div class="white pa-3">
+    <div class="content pa-3">
+      <m-form ref="form" :items="items" v-model="query" label-width="300px">
+        <template v-for="item in items" #[item.prop]>
+          <el-upload
+            :key="item.prop"
+            ref="upload"
+            action="#"
+            :limit="1"
+            :on-exceed="() => $message.warning('只能上传一个文件')"
+            :http-request="e => onImport(e, item.prop)"
+            :on-remove="() => onRemove(item.prop)"
+          >
+            <m-button slot="trigger" size="small">点击上传</m-button>
+            <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
+          </el-upload>
+        </template>
+      </m-form>
+      <div class="buttons">
+        <m-button icon="el-icon-upload">上传</m-button>
+        <m-button icon="el-icon-s-tools">加工</m-button>
+        <m-button icon="el-icon-time">加工历史记录</m-button>
+        </div>
+    </div>
   </div>
 </template>
 
 <script>
 export default {
-  name: 'salary-calculate'
+  name: 'salary-calculate',
+  data () {
+    return {
+      query: {
+        month: null,
+        example1: null,
+        example2: null,
+        example3: null
+      },
+      items: [
+        {
+          label: '月份',
+          prop: 'month',
+          type: 'datePicker',
+          options: {
+            type: 'month',
+            format: 'yyyy-MM',
+            valueFormat: 'yyyy-MM',
+            placeholder: '选择更新月份'
+          }
+        },
+        {
+          label: '计算样例1',
+          prop: 'example1',
+          rules: [
+            { required: true, message: '请上传文件', trigger: 'change' }
+          ]
+        },
+        {
+          label: '计算样例2',
+          prop: 'example2',
+          rules: [
+            { required: true, message: '请上传文件', trigger: 'change' }
+          ]
+        },
+        {
+          label: '计算样例3',
+          prop: 'example3',
+          rules: [
+            { required: true, message: '请上传文件', trigger: 'change' }
+          ]
+        }
+      ]
+    }
+  },
+  methods: {
+    onImport (e, key) {
+      this.query[key] = e.file
+    },
+    onRemove (key) {
+      this.query[key] = null
+      console.log(this.query)
+    }
+  }
 }
 </script>
 
 <style lang="scss" scoped>
-
+.content {
+  width: 50%;
+  min-width: 500px;
+  margin: 0 auto;
+}
+.buttons {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
 </style>

+ 1 - 1
src/views/salary/payroll/index.vue

@@ -108,7 +108,7 @@ export default {
     async onExport () {
       try {
         this.exportLoading = true
-        const { data, name } = await downloadPayroll()
+        const { data, name } = await downloadPayroll(this.searchValues)
         downloadFile(data, name)
       } catch (error) {
         this.$message.error(error)