Jelajahi Sumber

福利规则管理:历史记录改为抽屉展示,展开查看详情

Xiao_123 1 hari lalu
induk
melakukan
a2949081ee

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

@@ -13,12 +13,18 @@
       v-bind="$attrs"
       v-on="listens"
       @sort-change="onSortChange"
+      @expand-change="onExpandChange"
     >
       <template #append>
         <slot name="table-append"></slot>
       </template>
       <template v-for="(header, index) in headers">
         <el-table-column v-if="['selection','index'].includes(header.type)" v-bind="header" :key="index" />
+        <el-table-column v-else-if="header.type === 'expand'" type="expand" :key="index">
+          <template #default="scope">
+            <slot name="expand" v-bind="scope"></slot>
+          </template>
+        </el-table-column>
         <m-table-column
           v-else
           :key="(header.prop ?? header.label) || index"
@@ -101,6 +107,9 @@ export default {
       this.$emit('sort-change', [
         { column: e.prop.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`), asc: e.order === 'ascending' }
       ])
+    },
+    onExpandChange (row, expandedRows) {
+      this.$emit('expand-change', row, expandedRows)
     }
   }
 }

+ 240 - 0
src/views/welfare/components/HistoryListTemplate.vue

@@ -0,0 +1,240 @@
+<template>
+  <div v-loading="loading">
+    <m-table
+      :card-title="cardTitle"
+      :items="items"
+      :headers="headers"
+      :total="total"
+      :page-size="pageInfo.size"
+      :page-current="pageInfo.current"
+      v-bind="$attrs"
+      @page-change="onPageChange"
+      @sort-change="onSortChange"
+      @expand-change="onExpandChange"
+    >
+      <template #card-tools>
+        <slot name="tool"></slot>
+      </template>
+      <template #expand="{ row }">
+        <div class="pa-3">
+          <el-form label-position="right" class="m-form" label-width="100px">
+            <el-form-item label="福利名称">
+              <el-tag>{{ row.subsidyName }}</el-tag>
+            </el-form-item>
+            <el-form-item label="创建时间">
+              <el-tag>{{ row.createDate }}</el-tag>
+            </el-form-item>
+            <el-form-item label="规则配置">
+              <div v-loading="expandLoading[row.subsidyId]">
+                <m-card
+                  v-for="item in expandData[row.subsidyId]"
+                  :key="item.subsidyId"
+                  class="mb-3"
+                >
+                  <el-form label-position="right" class="m-form" label-width="100px">
+                    <el-form-item label="配置机构">
+                      <div>
+                        <div class="organization-tags">
+                          <el-tag
+                            v-for="(name, i) in visibleOrganizations(item.subsidyOrganizationNames, item.subsidyId)"
+                            :key="i"
+                            type="primary"
+                            class="mr-3 mb-2"
+                          >
+                            {{ name }}
+                          </el-tag>
+                        </div>
+                        <div v-if="item.subsidyOrganizationNames && item.subsidyOrganizationNames.length > maxVisibleTags" class="expand-toggle">
+                          <el-button
+                            type="text"
+                            size="small"
+                            @click="toggleOrganizationExpansion(item.subsidyId)"
+                            class="p-0"
+                          >
+                            {{ expandedOrganizations[item.subsidyId] ? '收起' : `展开更多 (${item.subsidyOrganizationNames.length - maxVisibleTags}个)` }}
+                            <i :class="expandedOrganizations[item.subsidyId] ? 'el-icon-arrow-up' : 'el-icon-arrow-down'" class="ml-1"></i>
+                          </el-button>
+                        </div>
+                      </div>
+                    </el-form-item>
+                    <el-form-item label="福利薪资">
+                      <el-tag type="primary">{{ item.subsidySalary }}</el-tag>
+                    </el-form-item>
+                    <el-form-item label="描述">
+                      <span>{{ item.subsidyCheck }}</span>
+                    </el-form-item>
+                  </el-form>
+                </m-card>
+                <div v-if="!expandData[row.subsidyId] || expandData[row.subsidyId].length === 0" class="text-center text-gray-500">
+                  暂无规则配置
+                </div>
+              </div>
+            </el-form-item>
+          </el-form>
+        </div>
+      </template>
+    </m-table>
+  </div>
+</template>
+
+<script>
+import {
+  getWelfarePage,
+  getWelfareDetail
+} from '@/api/welfare'
+export default {
+  name: 'history-list-template',
+  props: {
+    cardTitle: {
+      type: String,
+      default: '历史记录'
+    },
+    showSearch: {
+      type: Boolean,
+      default: true
+    },
+    history: {
+      type: Boolean,
+      default: false
+    },
+    uuid: String
+  },
+  data () {
+    return {
+      searchQuery: {
+        subsidyName: null
+      },
+      searchItems: [
+        {
+          label: '福利名称',
+          prop: 'subsidyName',
+          type: 'input',
+          options: {
+            placeholder: '请输入福利名称'
+          }
+        }
+      ],
+      items: [],
+      headers: [
+        { type: 'expand', prop: 'expand' },
+        { label: '福利名称', prop: 'subsidyName' },
+        { label: '福利描述', prop: 'subsidyTag' },
+        { label: '创建日期', prop: 'createDate' }
+      ],
+      loading: false,
+      total: 0,
+      pageInfo: {
+        current: 1,
+        size: 10
+      },
+      orders: [
+        {
+          asc: false,
+          column: 'subsidy_id'
+        }
+      ],
+      expandData: {},
+      expandLoading: {},
+      maxVisibleTags: 8, // 初始显示8个标签
+      expandedOrganizations: {} // 记录哪些机构列表已展开
+    }
+  },
+  created () {
+    this.onInit()
+  },
+  methods: {
+    async onInit () {
+      this.loading = true
+      try {
+        const { data } = await getWelfarePage({
+          page: {
+            ...this.pageInfo,
+            orders: this.orders
+          },
+          entity: {
+            ...this.searchQuery,
+            history: this.history ? 1 : 0,
+            uuid: this.uuid
+          }
+        })
+        this.items = data.records
+        this.total = data.total
+      } catch (error) {
+        this.$message.error(error)
+      } finally {
+        this.loading = false
+      }
+    },
+    onSearch () {
+      this.pageInfo.current = 1
+      this.onInit()
+    },
+    onPageChange (page) {
+      this.pageInfo.current = page
+      this.onInit()
+    },
+    onSortChange (sort) {
+      this.orders = sort
+      this.onInit()
+    },
+    async loadExpandData (subsidyId) {
+      if (this.expandData[subsidyId]) {
+        return // 数据已加载,直接返回
+      }
+      this.$set(this.expandLoading, subsidyId, true)
+      try {
+        const { data } = await getWelfareDetail({ subsidyId })
+        this.$set(this.expandData, subsidyId, data.subsidyItems || [])
+      } catch (error) {
+        this.$message.error(error)
+        this.$set(this.expandData, subsidyId, [])
+      } finally {
+        this.$set(this.expandLoading, subsidyId, false)
+      }
+    },
+    onExpandChange (row, expandedRows) {
+      // 当行展开时加载数据
+      if (expandedRows.includes(row)) {
+        this.loadExpandData(row.subsidyId)
+      }
+    },
+    showExpandData (row) {
+      // 手动触发展开行
+      this.loadExpandData(row.subsidyId)
+    },
+    visibleOrganizations (organizations, subsidyId) {
+      if (!organizations || organizations.length === 0) return []
+      if (this.expandedOrganizations[subsidyId]) {
+        return organizations
+      }
+      return organizations.slice(0, this.maxVisibleTags)
+    },
+    toggleOrganizationExpansion (subsidyId) {
+      this.$set(this.expandedOrganizations, subsidyId, !this.expandedOrganizations[subsidyId])
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.organization-tags {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 8px;
+  margin-bottom: 8px;
+}
+
+.expand-toggle {
+  margin-top: 8px;
+  text-align: left;
+
+  .el-button {
+    color: #409EFF;
+    font-size: 12px;
+
+    &:hover {
+      color: #66b1ff;
+    }
+  }
+}
+</style>

+ 20 - 54
src/views/welfare/welfareRules/index.vue

@@ -15,44 +15,17 @@
     <WelfareRules ref="welfareRulesRefs" @refresh="onInit"></WelfareRules> -->
 
     <WelfareForm ref="welfareFormRefs" @refresh="onInit"></WelfareForm>
-    <HistoryDialog ref="historyDialogRefs">
-      <template #actions="{ row }">
-        <m-button type="primary" text @click="onClick(row)" size="small">查看配置规则</m-button>
-      </template>
-    </HistoryDialog>
     <DrawerHistory ref="drawerHistoryRefs" size="50%" :get-page="getPage">
-      <template #panel="{ item }">
-        <el-form label-position="right" class="m-form" label-width="100px">
-          <el-form-item label="福利名称">
-            <el-tag>{{ itemData.subsidyName }}</el-tag>
-          </el-form-item>
-          <el-form-item label="创建时间">
-            <el-tag>{{ itemData.createDate }}</el-tag>
-          </el-form-item>
-          <el-form-item label="规则配置">
-            <m-card
-              v-for="_item in item"
-              :key="_item.subsidyId"
-              class="mb-3"
-            >
-              <el-form label-position="right" class="m-form" label-width="100px">
-                <el-form-item label="配置机构">
-                  <div>
-                    <el-tag v-for="(_name, i) in _item.subsidyOrganizationNames" :key="i" type="primary" class="mr-3">
-                      {{ _name }}
-                    </el-tag>
-                  </div>
-                </el-form-item>
-                <el-form-item label="福利薪资">
-                  <el-tag type="primary">{{ _item.subsidySalary }}</el-tag>
-                </el-form-item>
-                <el-form-item label="描述">
-                  <span>{{ _item.subsidyCheck }}</span>
-                </el-form-item>
-              </el-form>
-            </m-card>
-          </el-form-item>
-        </el-form>
+      <template #panel>
+        <HistoryListTemplate
+          ref="historyListTemplateRefs"
+          :card-title="`${itemData.subsidyName} 历史记录`"
+          :show-search="false"
+          :history="true"
+          :uuid="itemData.uuid"
+          clearHeader
+        >
+        </HistoryListTemplate>
       </template>
     </DrawerHistory>
   </div>
@@ -61,23 +34,22 @@
 <script>
 import DrawerHistory from '@/components/DrawerHistory'
 import ListTemplate from '../components/ListTemplate.vue'
+import HistoryListTemplate from '../components/HistoryListTemplate.vue'
 import {
-  deleteWelfare,
-  getWelfareDetail
+  deleteWelfare
 } from '@/api/welfare'
 import WelfareForm from './welfareForm.vue'
 // import WelfareEdit from './welfareEdit.vue'
 // import WelfareRules from './welfareRules'
-import HistoryDialog from './historyDialog'
 export default {
   name: 'human-resources-welfare-list',
   components: {
     ListTemplate,
+    HistoryListTemplate,
     // WelfareEdit,
     WelfareForm,
-    DrawerHistory,
+    DrawerHistory
     // WelfareRules,
-    HistoryDialog
   },
   data () {
     return {
@@ -98,10 +70,6 @@ export default {
     onEditRules (item) {
       this.$refs.welfareRulesRefs.open(item)
     },
-    onClick (row) {
-      this.itemData = row
-      this.$refs.drawerHistoryRefs.open(`${row.subsidyName} 历史记录`)
-    },
     onDelete (item) {
       this.$confirm(`确定删除${item.subsidyName}吗?`, '提示').then(async () => {
         try {
@@ -114,16 +82,14 @@ export default {
       }).catch(_ => {})
     },
     onHistory (row) {
-      this.$refs.historyDialogRefs.open(row.uuid, row.subsidyName)
+      this.itemData = row
+      this.$refs.drawerHistoryRefs.open(`${row.subsidyName} 历史记录`)
     },
     async getPage () {
-      return new Promise((resolve, reject) => {
-        getWelfareDetail({ subsidyId: this.itemData.subsidyId }).then(({ data }) => {
-          resolve({
-            data: data.subsidyItems,
-            total: data.subsidyItems.length
-          })
-        }).catch(reject)
+      // 返回空数据,因为数据由HistoryListTemplate组件自己管理
+      return Promise.resolve({
+        data: [],
+        total: 0
       })
     }
   }