yubo
2026-03-10 3d213c064d4e6906e720fd9c3a6ccc055be24104
feat(remind): 添加员工退休提醒页面导出功能

- 新增 ExportEmpBase.vue 组件实现员工信息导出功能
- 在 retirement.vue 页面集成导出对话框组件
- 添加性别格式化器用于数据显示
- 配置默认导出字段包括员工编号、部门、岗位、姓名等基本信息
- 实现导出确认逻辑和文件下载功能
- 更新表格列显示性别和年龄字段
1个文件已添加
1个文件已修改
237 ■■■■■ 已修改文件
src/components/ExportEmpBase.vue 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/remind/retirement.vue 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/ExportEmpBase.vue
New file
@@ -0,0 +1,178 @@
<template>
  <el-dialog
    title="导出员工"
    :visible.sync="isVisible"
    width="800px"
    @close="handleClose"
  >
    <div style="font-size: 16px;font-weight: 400;height: 35px;margin-top: -30px;color: #409EFF;">
      请勾选需要导出的字段
    </div>
    <!-- 全选行 -->
    <div style="margin-top: 20px; padding-left: 20px;">
      <el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange">
        全部字段
      </el-checkbox>
    </div>
    <!-- 网格布局替代表格 -->
    <el-checkbox-group
      v-model="checkedCities"
      class="field-grid"
      @change="handleCheckedCitiesChange"
    >
      <div v-for="field in allFields" :key="field.value" class="grid-item">
        <el-checkbox :label="field.value">{{ field.label }}</el-checkbox>
      </div>
    </el-checkbox-group>
    <div slot="footer" class="dialog-footer">
      <el-button @click="handleClose">取 消</el-button>
      <el-button type="primary" @click="handleConfirm">确 定</el-button>
    </div>
  </el-dialog>
</template>
<script>
// 预定义的所有可导出字段
const ALL_EXPORT_FIELDS = [
  { label: '档案号', value: 'archivesNumb' },
  { label: '编号', value: 'empNumb' },
  { label: '姓名', value: 'empName' },
  { label: '性别', value: 'sexName' },
  { label: '身份证号码', value: 'certificateNumb' },
  { label: '出生日期', value: 'birthdate' },
  { label: '年龄', value: 'age' },
  { label: '民族', value: 'nationName' },
  { label: '籍贯', value: 'nativePlaceName' },
  { label: '政治面貌', value: 'politicsName' },
  { label: '婚姻状况', value: 'marriageName' },
  { label: '身高 (cm)', value: 'stature' },
  { label: '学历', value: 'educationName' },
  { label: '部门 (护卫点)', value: 'allDeptName' },
  { label: '岗位', value: 'jobName' },
  { label: '员工类别', value: 'empTypeName' },
  { label: '联系电话', value: 'telePhone' },
  { label: '现住址', value: 'currentAddress' },
  { label: '户籍地址', value: 'censusAddress' },
  { label: '入职日期', value: 'entryDate' },
  { label: '社保档位', value: 'insuranceTypeName' },
  { label: '银行名称', value: 'bankName' },
  { label: '银行账号', value: 'bankNumb' },
  { label: '保安员证号', value: 'guardNumb' },
  { label: '档案状态', value: 'archivesStatusName' },
  { label: '合同状态', value: 'contractStatusName' },
  { label: '工作证', value: 'empCardStatusName' },
  { label: '员工手册', value: 'handbookStatusName' },
  { label: '相关证件', value: 'certificateListName' },
  { label: '家庭成员及关系 1', value: 'family' },
  { label: '家庭成员及关系 2', value: 'urgencyPhone' },
  { label: '入司工龄', value: 'seniority' },
  { label: '年假天数', value: 'annualLeave' },
  { label: '备注', value: 'remark' }
]
export default {
  name: 'ExportDialog',
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    // 默认选中的字段数组(传入则自动勾选这些字段)
    selectedFields: {
      type: Array,
      default: null
    }
  },
  data() {
    return {
      isVisible: false,
      checkAll: false,
      isIndeterminate: false,
      checkedCities: [],
      cityOptions: [],
      fieldRows: [],
      allFields: ALL_EXPORT_FIELDS
    }
  },
  watch: {
    visible(val) {
      this.isVisible = val
      if (val) {
        this.initFields()
      }
    },
    isVisible(val) {
      this.$emit('update:visible', val)
    }
  },
  methods: {
    initFields() {
      const fieldsToUse = [...this.allFields]
      const allValues = fieldsToUse.map(f => f.value)
      if (this.selectedFields && this.selectedFields.length > 0) {
        this.checkedCities = this.selectedFields.filter(f => allValues.includes(f))
      } else {
        this.checkedCities = []
      }
      const checkedCount = this.checkedCities.length
      this.checkAll = checkedCount === allValues.length
      this.isIndeterminate = checkedCount > 0 && checkedCount < allValues.length
    },
    handleCheckAllChange(val) {
      this.checkedCities = val ? this.allFields.map(f => f.value) : []
      this.isIndeterminate = false
    },
    handleCheckedCitiesChange(value) {
      const checkedCount = value.length
      this.checkAll = checkedCount === this.allFields.length
      this.isIndeterminate = checkedCount > 0 && checkedCount < this.allFields.length
    },
    handleClose() {
      this.isVisible = false
      this.$emit('update:visible', false)
      this.$emit('cancel')
    },
    handleConfirm() {
      this.isVisible = false
      this.$emit('update:visible', false)
      this.$emit('confirm', this.checkedCities)
    }
  }
}
</script>
<style lang="scss" scoped>
.field-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px 16px;
  margin-top: 16px;
  padding: 0 10px 10px 20px; /* 与左侧全选行对齐 */
  border-bottom: 1px dashed #ccc; /* 模仿原表格的下划线效果 */
}
.grid-item {
  display: flex;
  align-items: center;
  height: 40px; /* 与原表格行高一致 */
  border-bottom: 1px dashed #ccc; /* 每行之间保留虚线 */
}
/* 最后一个网格行取消下边框(可选) */
.grid-item:last-child,
.grid-item:nth-last-child(-n+3) { /* 若最后一行不足三个,可根据实际情况调整 */
  border-bottom: none;
}
/* 调整复选框标签样式 */
.el-checkbox {
  /deep/ .el-checkbox__label {
    color: #606266;
    font-size: 14px;
  }
}
</style>
src/views/remind/retirement.vue
@@ -36,12 +36,14 @@
              >解骋</span>
            </template>
          </el-table-column>
          <el-table-column show-overflow-tooltip prop="empNumb" label="员工编号" width="120" />
          <el-table-column show-overflow-tooltip prop="empNumb" label="员工编号" width="160" />
          <el-table-column show-overflow-tooltip prop="allDeptName" label="部门(护卫点)" />
          <el-table-column show-overflow-tooltip prop="jobName" label="岗位" width="100" />
          <el-table-column show-overflow-tooltip prop="empName" label="姓名" width="100" />
          <el-table-column show-overflow-tooltip prop="sex" label="性别" width="100" :formatter="sexFormatter" />
          <el-table-column show-overflow-tooltip prop="certificateNumb" label="身份证号码" width="160" />
          <el-table-column show-overflow-tooltip prop="birthdate" label="出生日期" width="120" />
          <el-table-column show-overflow-tooltip prop="age" label="年龄" width="120" />
        </el-table>
        <pagination
          v-show="total>0"
@@ -142,16 +144,24 @@
        <el-button @click="dialogIsShow()">取 消</el-button>
      </div>
    </el-dialog>
    <!-- 通用导出对话框 -->
    <export-dialog
      :visible.sync="exportDialogVisible"
      :selected-fields="exportConfig.selectedFields"
      @confirm="handleExportConfirm"
    />
  </div>
</template>
<script>
import Pagination from '@/components/Pagination'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { dateDifference } from '@/utils/myUtil'
import ExportDialog from '@/components/ExportEmpBase.vue'
export default {
  components: {
    Pagination
    Pagination,
    ExportDialog
  },
  data() {
    return {
@@ -226,6 +236,25 @@
        beginDate: [{ required: true, message: '请选择合同开始日期', trigger: 'change' }],
        endDate: [{ required: true, validator: this.endDate }],
        remark: [{ max: 512, message: '长度不超过512个字符', trigger: 'blur' }]
      },
      exportDialogVisible: false,
      // 导出配置(每个模块自定义)
      exportConfig: {
        // 默认选中的字段(根据模块需要配置)
        selectedFields: [
          'empNumb', // 员工编号
          'allDeptName', // 部门(护卫点)
          'jobName', // 岗位
          'empName', // 姓名
          'sexName', // 性别
          'certificateNumb', // 身份证号码
          'birthdate', // 出生日期
          'age' // 年龄
        ],
        // 导出接口地址
        exportUrl: 'hr/empBaseInfo/export/retirement',
        // 导出文件名
        fileName: '员工退休提醒.xls'
      }
    }
  },
@@ -252,7 +281,6 @@
      params.pageNum = this.pagination.num
      params.delFlag = 0
      params.empStatus = 0
      this.$get('hr/empBaseInfo/retire/alert', {
        ...params
      }).then((r) => {
@@ -265,6 +293,10 @@
      this.sort.field = val.prop
      this.sort.order = val.order
      this.fetch()
    },
    sexFormatter(row, column, cellValue) {
      const option = this.sexOptions.find(item => item.dicItemCode === cellValue)
      return option ? option.dicItemName : cellValue
    },
    // 续签合同
    goOn(row) {
@@ -385,6 +417,27 @@
          })
        }
      })
    },
    // 显示导出对话框
    showDcyg() {
      this.exportDialogVisible = true
    },
    // 确认导出
    handleExportConfirm(selectedFields) {
      const params = { ...this.queryParams }
      params.empStatus = '0'
      params.exportField = selectedFields.join(',')
      this.$download(
        this.exportConfig.exportUrl,
        { ...params },
        this.exportConfig.fileName
      ).then(() => {
        this.$message({
          message: '下载成功!',
          type: 'success'
        })
      })
    }
  }
}