gaoluyang
4 天以前 c4b339705e5d2d1a33f4f3d6b5d7e19ac7d68faa
劳保台账修改
已修改3个文件
已添加3个文件
1462 ■■■■ 文件已修改
src/api/lavorissce/ledger.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/DynamicTable/index.vue 402 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/example/DynamicTableExample.vue 354 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/example/SimpleExample.vue 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/lavorissue/ledger/index.vue 556 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/lavorissue/statistics/index.vue 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/lavorissce/ledger.js
@@ -1,7 +1,7 @@
import request from '@/utils/request'
// åˆ†é¡µæŸ¥è¯¢
export function listPage(params) {
export function lavorIssueListPage(params) {
    return request({
        url: '/lavorIssue/listPage',
        method: 'get',
src/components/DynamicTable/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,402 @@
<template>
  <div class="dynamic-table-container">
    <el-table
      ref="tableRef"
      v-loading="loading"
      :data="tableData"
      :border="border"
      :height="height"
      :header-cell-style="{ background: '#F0F1F5', color: '#333333' }"
      style="width: 100%"
      @selection-change="handleSelectionChange"
      @row-click="handleRowClick"
    >
      <!-- é€‰æ‹©åˆ— -->
      <el-table-column
        v-if="showSelection"
        align="center"
        type="selection"
        width="55"
      />
      <!-- åºå·åˆ— -->
      <el-table-column
        v-if="showIndex"
        align="center"
        label="序号"
        type="index"
        width="60"
      />
      <!-- å›ºå®šåˆ—:部门 -->
      <el-table-column
        label="部门"
        prop="department"
        width="120"
        show-overflow-tooltip
        align="center"
      />
      <!-- å›ºå®šåˆ—:姓名 -->
      <el-table-column
        label="姓名"
        prop="name"
        width="100"
        show-overflow-tooltip
        align="center"
      />
      <!-- å›ºå®šåˆ—:工号 -->
      <el-table-column
        label="工号"
        prop="employeeId"
        width="100"
        show-overflow-tooltip
        align="center"
      />
      <!-- åŠ¨æ€åˆ—ï¼šæ ¹æ®å­—å…¸æ¸²æŸ“ -->
      <el-table-column
        v-for="(dictItem, index) in dynamicColumns"
        :key="dictItem.value"
        :label="dictItem.label"
        :prop="dictItem.value"
        :width="dictItem.width || 120"
        show-overflow-tooltip
        align="center"
      >
        <template #default="scope">
          <!-- æ ¹æ®å­—典类型渲染不同的显示方式 -->
          <template v-if="dictItem.renderType === 'tag'">
            <el-tag
              :type="getTagType(scope.row[dictItem.value])"
              size="small"
            >
              {{ getDictValueLabel(dictItem.dictType, scope.row[dictItem.value]) }}
            </el-tag>
          </template>
          <template v-else-if="dictItem.renderType === 'select'">
            <el-select
              v-model="scope.row[dictItem.value]"
              placeholder="请选择"
              size="small"
              @change="handleSelectChange(scope.row, dictItem.value, $event)"
            >
              <el-option
                v-for="option in dictItem.options"
                :key="option.value"
                :label="option.label"
                :value="option.value"
              />
            </el-select>
          </template>
          <template v-else-if="dictItem.renderType === 'input'">
            <el-input
              v-model="scope.row[dictItem.value]"
              size="small"
              placeholder="请输入"
              @blur="handleInputChange(scope.row, dictItem.value, $event)"
            />
          </template>
          <template v-else>
            <span>{{ getDictValueLabel(dictItem.dictType, scope.row[dictItem.value]) }}</span>
          </template>
        </template>
      </el-table-column>
      <!-- æ“ä½œåˆ— -->
      <el-table-column
        v-if="showActions"
        label="操作"
        width="150"
        align="center"
        fixed="right"
      >
        <template #default="scope">
          <el-button
            type="primary"
            link
            size="small"
            @click="handleEdit(scope.row, scope.$index)"
          >
            ç¼–辑
          </el-button>
          <el-button
            type="danger"
            link
            size="small"
            @click="handleDelete(scope.row, scope.$index)"
          >
            åˆ é™¤
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- åˆ†é¡µç»„ä»¶ -->
    <div v-if="showPagination" class="pagination-container">
      <el-pagination
        v-model:current-page="pagination.current"
        v-model:page-size="pagination.size"
        :page-sizes="[10, 20, 50, 100]"
        :total="pagination.total"
        layout="total, sizes, prev, pager, next, jumper"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
  </div>
</template>
<script setup>
import { ref, computed, onMounted, watch } from 'vue'
import { useDict } from '@/utils/dict'
// å®šä¹‰ç»„件属性
const props = defineProps({
  // è¡¨æ ¼æ•°æ®
  data: {
    type: Array,
    default: () => []
  },
  // å­—典类型数组,用于动态生成列
  dictTypes: {
    type: Array,
    default: () => []
  },
  // æ˜¯å¦æ˜¾ç¤ºé€‰æ‹©åˆ—
  showSelection: {
    type: Boolean,
    default: false
  },
  // æ˜¯å¦æ˜¾ç¤ºåºå·åˆ—
  showIndex: {
    type: Boolean,
    default: true
  },
  // æ˜¯å¦æ˜¾ç¤ºæ“ä½œåˆ—
  showActions: {
    type: Boolean,
    default: false
  },
  // æ˜¯å¦æ˜¾ç¤ºåˆ†é¡µ
  showPagination: {
    type: Boolean,
    default: false
  },
  // è¡¨æ ¼é«˜åº¦
  height: {
    type: [String, Number],
    default: 'auto'
  },
  // æ˜¯å¦æ˜¾ç¤ºè¾¹æ¡†
  border: {
    type: Boolean,
    default: true
  },
  // åŠ è½½çŠ¶æ€
  loading: {
    type: Boolean,
    default: false
  },
  // åˆ†é¡µé…ç½®
  pagination: {
    type: Object,
    default: () => ({
      current: 1,
      size: 10,
      total: 0
    })
  }
})
// å®šä¹‰äº‹ä»¶
const emit = defineEmits([
  'selection-change',
  'row-click',
  'edit',
  'delete',
  'select-change',
  'input-change',
  'size-change',
  'current-change'
])
// å“åº”式数据
const tableRef = ref(null)
const tableData = ref([])
// èŽ·å–å­—å…¸æ•°æ®
const dictData = ref({})
// åŠ¨æ€åˆ—é…ç½®
const dynamicColumns = computed(() => {
  const columns = []
  props.dictTypes.forEach(dictType => {
    const dictItems = dictData.value[dictType] || []
    // ä¸ºæ¯ä¸ªå­—典类型创建一个列,而不是为每个字典项创建列
    if (dictItems.length > 0) {
      columns.push({
        label: getDictLabel(dictType), // èŽ·å–å­—å…¸ç±»åž‹çš„æ˜¾ç¤ºåç§°
        value: dictType, // ä½¿ç”¨å­—典类型作为字段名
        width: 120,
        renderType: 'tag', // é»˜è®¤ä½¿ç”¨æ ‡ç­¾æ˜¾ç¤º
        options: dictItems, // æä¾›é€‰é¡¹
        dictType: dictType
      })
    }
  })
  return columns
})
// èŽ·å–å­—å…¸ç±»åž‹çš„æ˜¾ç¤ºåç§°
const getDictLabel = (dictType) => {
  const labelMap = {
    'sys_normal_disable': '状态',
    'sys_user_level': '级别',
    'sys_user_position': '职位',
    'sys_yes_no': '是否',
    'sys_user_sex': '性别',
    'sys_lavor_issue': '劳务问题'  // æ·»åŠ åŠ³åŠ¡é—®é¢˜å­—å…¸
  }
  return labelMap[dictType] || dictType
}
// èŽ·å–å­—å…¸æ•°æ®
const loadDictData = async () => {
  try {
    const dictPromises = props.dictTypes.map(async (dictType) => {
      const { getDicts } = await import('@/api/system/dict/data')
      const response = await getDicts(dictType)
      return {
        type: dictType,
        data: response.data.map(item => ({
          label: item.dictLabel,
          value: item.dictValue,
          elTagType: item.listClass,
          elTagClass: item.cssClass
        }))
      }
    })
    const results = await Promise.all(dictPromises)
    results.forEach(result => {
      dictData.value[result.type] = result.data
    })
  } catch (error) {
    console.error('加载字典数据失败:', error)
    // å¦‚果字典加载失败,使用默认数据
    props.dictTypes.forEach(dictType => {
      if (!dictData.value[dictType]) {
        dictData.value[dictType] = []
      }
    })
  }
}
// èŽ·å–æ ‡ç­¾ç±»åž‹
const getTagType = (value) => {
  // æ ¹æ®å€¼è¿”回不同的标签类型
  if (value === '1' || value === 'true' || value === '是') return 'success'
  if (value === '0' || value === 'false' || value === '否') return 'danger'
  if (value === '2' || value === 'warning') return 'warning'
  return 'info'
}
// èŽ·å–å­—å…¸å€¼çš„æ ‡ç­¾
const getDictValueLabel = (dictType, value) => {
  if (!value) return '-'
  const dictItems = dictData.value[dictType] || []
  const item = dictItems.find(item => item.value === value)
  return item ? item.label : value
}
// äº‹ä»¶å¤„理函数
const handleSelectionChange = (selection) => {
  emit('selection-change', selection)
}
const handleRowClick = (row, column, event) => {
  emit('row-click', row, column, event)
}
const handleEdit = (row, index) => {
  emit('edit', row, index)
}
const handleDelete = (row, index) => {
  emit('delete', row, index)
}
const handleSelectChange = (row, prop, value) => {
  emit('select-change', row, prop, value)
}
const handleInputChange = (row, prop, event) => {
  emit('input-change', row, prop, event.target.value)
}
const handleSizeChange = (size) => {
  emit('size-change', size)
}
const handleCurrentChange = (current) => {
  emit('current-change', current)
}
// ç›‘听数据变化
watch(() => props.data, (newData) => {
  tableData.value = newData
}, { immediate: true })
// ç›‘听字典类型变化
watch(() => props.dictTypes, () => {
  loadDictData()
}, { immediate: true })
// ç»„件挂载时加载字典数据
onMounted(() => {
  loadDictData()
})
// æš´éœ²æ–¹æ³•给父组件
defineExpose({
  tableRef,
  getSelection: () => tableRef.value?.getSelectionRows() || [],
  clearSelection: () => tableRef.value?.clearSelection(),
  toggleRowSelection: (row, selected) => tableRef.value?.toggleRowSelection(row, selected),
  setCurrentRow: (row) => tableRef.value?.setCurrentRow(row)
})
</script>
<style scoped>
.dynamic-table-container {
  width: 100%;
}
.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}
:deep(.el-table .el-table__header-wrapper th) {
  background-color: #F0F1F5 !important;
  color: #333333;
  font-weight: 600;
}
:deep(.el-table .el-table__body-wrapper td) {
  padding: 8px 0;
}
:deep(.el-select) {
  width: 100%;
}
:deep(.el-input) {
  width: 100%;
}
</style>
src/views/example/DynamicTableExample.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,354 @@
<template>
  <div class="app-container">
    <div class="search-form">
      <el-form :inline="true" :model="searchForm">
        <el-form-item label="部门">
          <el-input
            v-model="searchForm.department"
            placeholder="请输入部门名称"
            clearable
            style="width: 200px"
          />
        </el-form-item>
        <el-form-item label="姓名">
          <el-input
            v-model="searchForm.name"
            placeholder="请输入姓名"
            clearable
            style="width: 200px"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">搜索</el-button>
          <el-button @click="handleReset">重置</el-button>
          <el-button type="success" @click="handleAdd">新增</el-button>
        </el-form-item>
      </el-form>
    </div>
    <div class="table-container">
      <DynamicTable
        ref="dynamicTableRef"
        :data="tableData"
        :dict-types="dictTypes"
        :loading="loading"
        :show-selection="true"
        :show-actions="true"
        :show-pagination="true"
        :pagination="pagination"
        height="calc(100vh - 280px)"
        @selection-change="handleSelectionChange"
        @edit="handleEdit"
        @delete="handleDelete"
        @select-change="handleSelectChange"
        @input-change="handleInputChange"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
    <!-- æ–°å¢ž/编辑对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogTitle"
      width="600px"
      append-to-body
    >
      <el-form
        ref="formRef"
        :model="form"
        :rules="rules"
        label-width="100px"
      >
        <el-form-item label="部门" prop="department">
          <el-input v-model="form.department" placeholder="请输入部门" />
        </el-form-item>
        <el-form-item label="姓名" prop="name">
          <el-input v-model="form.name" placeholder="请输入姓名" />
        </el-form-item>
        <el-form-item label="工号" prop="employeeId">
          <el-input v-model="form.employeeId" placeholder="请输入工号" />
        </el-form-item>
        <!-- åŠ¨æ€è¡¨å•é¡¹ï¼šæ ¹æ®å­—å…¸ç”Ÿæˆ -->
        <el-form-item
          v-for="dictItem in dynamicFormItems"
          :key="dictItem.value"
          :label="dictItem.label"
          :prop="dictItem.value"
        >
          <el-select
            v-model="form[dictItem.value]"
            placeholder="请选择"
            style="width: 100%"
          >
            <el-option
              v-for="option in dictItem.options"
              :key="option.value"
              :label="option.label"
              :value="option.value"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleSubmit">确定</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import DynamicTable from '@/components/DynamicTable/index.vue'
// å“åº”式数据
const loading = ref(false)
const dialogVisible = ref(false)
const dialogTitle = ref('')
const editIndex = ref(-1)
const selectedRows = ref([])
// æœç´¢è¡¨å•
const searchForm = reactive({
  department: '',
  name: ''
})
// è¡¨æ ¼æ•°æ®
const tableData = ref([
  {
    id: 1,
    department: '技术部',
    name: '张三',
    employeeId: 'EMP001',
    status: '1',
    level: '2',
    position: '1'
  },
  {
    id: 2,
    department: '人事部',
    name: '李四',
    employeeId: 'EMP002',
    status: '0',
    level: '1',
    position: '2'
  },
  {
    id: 3,
    department: '财务部',
    name: '王五',
    employeeId: 'EMP003',
    status: '1',
    level: '3',
    position: '1'
  }
])
// å­—典类型配置
const dictTypes = ref([
  'sys_normal_disable', // çŠ¶æ€å­—å…¸
  'sys_user_level',     // çº§åˆ«å­—å…¸
  'sys_user_position'   // èŒä½å­—å…¸
])
// åˆ†é¡µé…ç½®
const pagination = reactive({
  current: 1,
  size: 10,
  total: 0
})
// è¡¨å•数据
const form = reactive({
  department: '',
  name: '',
  employeeId: '',
  status: '',
  level: '',
  position: ''
})
// è¡¨å•验证规则
const rules = {
  department: [
    { required: true, message: '请输入部门', trigger: 'blur' }
  ],
  name: [
    { required: true, message: '请输入姓名', trigger: 'blur' }
  ],
  employeeId: [
    { required: true, message: '请输入工号', trigger: 'blur' }
  ]
}
// åŠ¨æ€è¡¨å•é¡¹
const dynamicFormItems = computed(() => {
  // è¿™é‡Œå¯ä»¥æ ¹æ®å­—典数据动态生成表单项
  return [
    {
      label: '状态',
      value: 'status',
      options: [
        { label: '启用', value: '1' },
        { label: '禁用', value: '0' }
      ]
    },
    {
      label: '级别',
      value: 'level',
      options: [
        { label: '初级', value: '1' },
        { label: '中级', value: '2' },
        { label: '高级', value: '3' }
      ]
    },
    {
      label: '职位',
      value: 'position',
      options: [
        { label: '员工', value: '1' },
        { label: '主管', value: '2' },
        { label: '经理', value: '3' }
      ]
    }
  ]
})
// ç»„件引用
const dynamicTableRef = ref(null)
const formRef = ref(null)
// äº‹ä»¶å¤„理函数
const handleSearch = () => {
  // å®žçŽ°æœç´¢é€»è¾‘
  console.log('搜索条件:', searchForm)
  ElMessage.success('搜索功能待实现')
}
const handleReset = () => {
  searchForm.department = ''
  searchForm.name = ''
}
const handleAdd = () => {
  dialogTitle.value = '新增员工'
  editIndex.value = -1
  resetForm()
  dialogVisible.value = true
}
const handleEdit = (row, index) => {
  dialogTitle.value = '编辑员工'
  editIndex.value = index
  Object.assign(form, row)
  dialogVisible.value = true
}
const handleDelete = async (row, index) => {
  try {
    await ElMessageBox.confirm('确定要删除这条记录吗?', '提示', {
      type: 'warning'
    })
    tableData.value.splice(index, 1)
    ElMessage.success('删除成功')
  } catch (error) {
    // ç”¨æˆ·å–消删除
  }
}
const handleSelectionChange = (selection) => {
  selectedRows.value = selection
}
const handleSelectChange = (row, prop, value) => {
  console.log('选择变化:', row, prop, value)
  // å¯ä»¥åœ¨è¿™é‡Œå¤„理数据更新逻辑
}
const handleInputChange = (row, prop, value) => {
  console.log('输入变化:', row, prop, value)
  // å¯ä»¥åœ¨è¿™é‡Œå¤„理数据更新逻辑
}
const handleSizeChange = (size) => {
  pagination.size = size
  // é‡æ–°åŠ è½½æ•°æ®
}
const handleCurrentChange = (current) => {
  pagination.current = current
  // é‡æ–°åŠ è½½æ•°æ®
}
const handleSubmit = async () => {
  try {
    await formRef.value.validate()
    if (editIndex.value === -1) {
      // æ–°å¢ž
      const newRow = {
        id: Date.now(),
        ...form
      }
      tableData.value.push(newRow)
      ElMessage.success('新增成功')
    } else {
      // ç¼–辑
      Object.assign(tableData.value[editIndex.value], form)
      ElMessage.success('编辑成功')
    }
    dialogVisible.value = false
  } catch (error) {
    console.error('表单验证失败:', error)
  }
}
const resetForm = () => {
  Object.assign(form, {
    department: '',
    name: '',
    employeeId: '',
    status: '',
    level: '',
    position: ''
  })
  formRef.value?.resetFields()
}
// ç»„件挂载时初始化数据
onMounted(() => {
  pagination.total = tableData.value.length
})
</script>
<style scoped>
.app-container {
  padding: 20px;
}
.search-form {
  margin-bottom: 20px;
  padding: 20px;
  background-color: #f5f5f5;
  border-radius: 4px;
}
.table-container {
  background-color: #fff;
  border-radius: 4px;
  padding: 20px;
}
.dialog-footer {
  text-align: right;
}
</style>
src/views/example/SimpleExample.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,135 @@
<template>
  <div class="app-container">
    <!-- ç®€å•的搜索区域 -->
    <el-card class="search-card">
      <el-form :inline="true">
        <el-form-item label="部门">
          <el-input v-model="searchForm.department" placeholder="请输入部门" clearable />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">搜索</el-button>
          <el-button @click="handleReset">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <!-- åŠ¨æ€è¡¨æ ¼ -->
    <el-card class="table-card">
      <template #header>
        <div class="card-header">
          <span>员工信息表</span>
          <el-button type="primary" size="small" @click="handleAdd">新增员工</el-button>
        </div>
      </template>
      <DynamicTable
        :data="tableData"
        :dict-types="dictTypes"
        :loading="loading"
        :show-selection="true"
        :show-actions="true"
        height="400px"
        @selection-change="handleSelectionChange"
        @edit="handleEdit"
        @delete="handleDelete"
      />
    </el-card>
  </div>
</template>
<script setup>
import { ref, reactive } from 'vue'
import { ElMessage } from 'element-plus'
import DynamicTable from '@/components/DynamicTable/index.vue'
// æœç´¢è¡¨å•
const searchForm = reactive({
  department: ''
})
// è¡¨æ ¼æ•°æ®
const tableData = ref([
  {
    id: 1,
    department: '技术部',
    name: '张三',
    employeeId: 'EMP001',
    sys_normal_disable: '1',  // çŠ¶æ€
    sys_user_level: '2',      // çº§åˆ«
    sys_user_position: '1'    // èŒä½
  },
  {
    id: 2,
    department: '人事部',
    name: '李四',
    employeeId: 'EMP002',
    sys_normal_disable: '0',  // çŠ¶æ€
    sys_user_level: '1',      // çº§åˆ«
    sys_user_position: '2'    // èŒä½
  }
])
// å­—典类型
const dictTypes = ref([
  'sys_normal_disable', // çŠ¶æ€ï¼šå¯ç”¨/禁用
  'sys_user_level',     // çº§åˆ«ï¼šåˆçº§/中级/高级
  'sys_user_position'   // èŒä½ï¼šå‘˜å·¥/主管/经理
])
// åŠ è½½çŠ¶æ€
const loading = ref(false)
// äº‹ä»¶å¤„理
const handleSearch = () => {
  loading.value = true
  // æ¨¡æ‹Ÿæœç´¢
  setTimeout(() => {
    loading.value = false
    ElMessage.success('搜索完成')
  }, 1000)
}
const handleReset = () => {
  searchForm.department = ''
}
const handleAdd = () => {
  ElMessage.info('新增功能待实现')
}
const handleSelectionChange = (selection) => {
  console.log('选中的行:', selection)
}
const handleEdit = (row, index) => {
  ElMessage.info(`编辑第${index + 1}行数据`)
}
const handleDelete = (row, index) => {
  ElMessage.warning(`删除第${index + 1}行数据`)
}
</script>
<style scoped>
.app-container {
  padding: 20px;
}
.search-card {
  margin-bottom: 20px;
}
.table-card {
  margin-bottom: 20px;
}
.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
:deep(.el-form-item) {
  margin-bottom: 0;
}
</style>
src/views/lavorissue/ledger/index.vue
@@ -1,300 +1,314 @@
<template>
  <div class="app-container">
    <el-form :model="filters" :inline="true">
      <el-form-item label="发放季度:" prop="season">
        <el-select
            style="width: 200px;"
            @change="handleQuery"
            v-model="filters.season"
            placeholder="请选择"
            :clearable="false"
        >
          <el-option :label="item.label" :value="item.value" v-for="(item,index) in jidu" :key="value" />
        </el-select>
      </el-form-item>
      <el-form-item label="员工名称:">
        <el-input
            v-model="filters.staffName"
            style="width: 240px"
            placeholder="请输入"
            @change="handleQuery"
            clearable
            prefix-icon="Search"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="getTableData">搜索</el-button>
        <el-button @click="resetFilters">重置</el-button>
      </el-form-item>
    </el-form>
    <div class="table_list">
      <div class="actions">
        <div></div>
        <div>
          <el-button type="primary" @click="add" icon="Plus"> æ–°å¢ž </el-button>
          <el-button @click="handleOut" icon="download">导出</el-button>
          <el-button
              type="danger"
              icon="Delete"
              :disabled="multipleList.length <= 0"
              @click="deleteRow(multipleList.map((item) => item.id))"
          >
            æ‰¹é‡åˆ é™¤
          </el-button>
        </div>
      </div>
      <PIMTable
          rowKey="id"
          isSelection
          :column="columns"
          :tableData="dataList"
          :page="{
          current: pagination.currentPage,
          size: pagination.pageSize,
          total: pagination.total,
        }"
          @selection-change="handleSelectionChange"
          @pagination="changePage"
      >
        <template #operation="{ row }">
          <el-button type="primary" text @click="edit(row)" icon="editPen">
            ç¼–辑
          </el-button>
          <el-button type="primary" :disabled="row.adoptedDate ? true : false" text @click="adopted(row)">
            é¢†ç”¨
          </el-button>
        </template>
      </PIMTable>
    </div>
    <Modal ref="modalRef" @success="getTableData"></Modal>
    <files-dia ref="filesDia"></files-dia>
  </div>
    <div class="app-container">
        <div class="search_form">
            <div>
                <span class="search_title">发放季度:</span>
                <el-select
                    style="width: 200px;"
                    @change="handleQuery"
                    v-model="searchForm.season"
                    placeholder="请选择"
                    :clearable="false"
                >
                    <el-option :label="item.label" :value="item.value" v-for="(item,index) in jidu" :key="item.value" />
                </el-select>
                <span class="search_title ml10">员工名称:</span>
                <el-input
                    v-model="searchForm.staffName"
                    style="width: 240px"
                    placeholder="请输入"
                    @change="handleQuery"
                    clearable
                    prefix-icon="Search"
                />
                <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
                >搜索</el-button
                >
            </div>
            <div>
                <el-button type="primary" @click="add" icon="Plus"> æ–°å¢ž </el-button>
                <el-button @click="handleOut" icon="download">导出</el-button>
                <el-button
                    type="danger"
                    icon="Delete"
                    :disabled="multipleList.length <= 0"
                    @click="deleteRow(multipleList.map((item) => item.id))"
                >
                    æ‰¹é‡åˆ é™¤
                </el-button>
            </div>
        </div>
        <div class="table_list">
            <el-table
                ref="tableRef"
                v-loading="tableLoading"
                :data="tableData"
                border
                height="calc(100vh - 21em)"
                :header-cell-style="{ background: '#F0F1F5', color: '#333333' }"
                style="width: 100%"
                @selection-change="handleSelectionChange"
            >
                <!-- é€‰æ‹©åˆ— -->
                <el-table-column
                    align="center"
                    type="selection"
                    width="55"
                    fixed="left"
                />
                <!-- åºå·åˆ— -->
                <el-table-column
                    align="center"
                    label="序号"
                    type="index"
                    width="60"
                    fixed="left"
                />
                <!-- å›ºå®šåˆ—:部门 -->
<!--                <el-table-column-->
<!--                    label="部门"-->
<!--                    prop="deptName"-->
<!--                    width="120"-->
<!--                    show-overflow-tooltip-->
<!--                    align="center"-->
<!--                    fixed="left"-->
<!--                />-->
                <!-- å›ºå®šåˆ—:姓名 -->
                <el-table-column
                    label="姓名"
                    prop="staffName"
                    width="100"
                    show-overflow-tooltip
                    align="center"
                    fixed="left"
                />
                <!-- å›ºå®šåˆ—:工号 -->
                <el-table-column
                    label="工号"
                    prop="staffNo"
                    width="100"
                    show-overflow-tooltip
                    align="center"
                    fixed="left"
                />
                <!-- åŠ¨æ€åˆ—ï¼šæ ¹æ®å­—å…¸æ¸²æŸ“ -->
                <el-table-column
                    v-for="(dictItem, index) in sys_lavor_issue"
                    :key="dictItem.value"
                    :label="dictItem.label"
                    :prop="dictItem.value"
                    show-overflow-tooltip
                >
                </el-table-column>
                <!-- æ“ä½œåˆ— -->
                <el-table-column
                    label="操作"
                    width="150"
                    align="center"
                    fixed="right"
                >
                    <template #default="scope">
                        <el-button
                            type="primary"
                            link
                            size="small"
                            @click="edit(scope.row)"
                        >
                            ç¼–辑
                        </el-button>
                        <el-button
                            type="danger"
                            link
                            size="small"
                            :disabled="!!scope.row.adoptedDate"
                            @click="adopted(scope.row)"
                        >
                            é¢†ç”¨
                        </el-button>
                    </template>
                </el-table-column>
            </el-table>
            <pagination :total="total" layout="total, sizes, prev, pager, next, jumper"
                                    :page="page.current" :limit="page.size" @pagination="paginationChange" />
        </div>
        <Modal ref="modalRef" @success="handleQuery"></Modal>
        <files-dia ref="filesDia"></files-dia>
    </div>
</template>
<script setup>
import { usePaginationApi } from "@/hooks/usePaginationApi";
import { listPage,deleteLedger,update } from "@/api/lavorissce/ledger";
import { onMounted, getCurrentInstance } from "vue";
import Modal from "./Modal.vue";
import { ElMessageBox, ElMessage } from "element-plus";
import { ref, onMounted } from 'vue'
import dayjs from "dayjs";
import Modal from "./Modal.vue";
import FilesDia from "./filesDia.vue";
import { getCurrentMonth } from "@/utils/util"
// è¡¨æ ¼å¤šé€‰æ¡†é€‰ä¸­é¡¹
const multipleList = ref([]);
import {lavorIssueListPage} from "@/api/lavorissce/ledger.js";
import {ElMessageBox} from "element-plus";
const { proxy } = getCurrentInstance();
const page = ref({
    current: 1,
    size: 100,
})
const total = ref(0)
// å“åº”式数据
const tableRef = ref(null)
const tableData = ref([])
const tableLoading = ref(false)
const { sys_lavor_issue } = proxy.useDict("sys_lavor_issue")
const data = reactive({
    searchForm: {
        feedbackDate: "",
        disDate: "",
    },
});
const modalRef = ref();
const { payment_methods } = proxy.useDict("payment_methods");
const { income_types } = proxy.useDict("income_types");
const filesDia = ref()
const {
  filters,
  columns,
  dataList,
  pagination,
  getTableData,
  resetFilters,
  onCurrentChange,
} = usePaginationApi(
    listPage,
    {
      staffName: '',
      season: getCurrentMonth(),
    },
    [
      {
        label: "劳保单号",
        align: "center",
        prop: "orderNo",
      },
      {
        label: "员工名称",
        align: "center",
        prop: "staffName",
      },
      {
        label: "员工编号",
        align: "center",
        prop: "staffNo"
      },
      {
        label: "劳保类型",
        align: "center",
        prop: "dictTypeName",
      },
      {
        label: "劳保防具",
        align: "center",
        prop: "dictName",
      },
      {
        label: "发放数量",
        align: "center",
        prop: "num",
      },
      {
        label: "进厂日期",
        align: "center",
        prop: "factoryDate",
      },
      {
        label: "发放日期",
        align: "center",
        prop: "issueDate",
      },
      {
        label: "领用日期",
        align: "center",
        prop: "adoptedDate",
      },
      {
        fixed: "right",
        label: "操作",
        dataType: "slot",
        slot: "operation",
        align: "center",
        width: "200px",
      },
    ]
);
const filesDia = ref();
const { searchForm } = toRefs(data);
const multipleList = ref([]);
const jidu = ref([
  {
    value: '1',
    label: '第一季度'
  },
  {
    value: '2',
    label: '第二季度'
  },
  {
    value: '3',
    label: '第三季度'
  },
  {
    value: '4',
    label: '第四季度'
  }
    {
        value: '1',
        label: '第一季度'
    },
    {
        value: '2',
        label: '第二季度'
    },
    {
        value: '3',
        label: '第三季度'
    },
    {
        value: '4',
        label: '第四季度'
    }
])
// å¤šé€‰åŽåšä»€ä¹ˆ
const handleSelectionChange = (selectionList) => {
  multipleList.value = selectionList;
};
const adopted = (row) => {
  ElMessageBox.confirm("是否确认领用?", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(async () => {
    const params = {
      id: row.id,
      adoptedDate: dayjs().format("YYYY-MM-DD")
    }
    const { code } = await update(params);
    if (code == 200) {
      ElMessage({
        type: "success",
        message: "领用成功",
      });
      getTableData();
    }
  })
}
const add = () => {
  modalRef.value.openModal();
};
const edit = (row) => {
  modalRef.value.loadForm(row);
};
/** æœç´¢æŒ‰é’®æ“ä½œ */
const handleQuery = () => {
  getTableData();
    page.current = 1;
    getList();
};
const changePage = ({ page, limit }) => {
  pagination.currentPage = page;
  pagination.pageSize = limit;
  onCurrentChange(page);
// èŽ·å–å­—å…¸æ•°æ®
const getList = async () => {
    tableLoading.value = true;
    lavorIssueListPage().then(res => {
        tableLoading.value = false;
        tableData.value = res.data.records;
        page.total = res.data.total;
    }).catch(err => {
        tableLoading.value = false;
    })
}
const add = () => {
    modalRef.value.openModal();
};
const edit = (row) => {
    modalRef.value.loadForm(row);
};
const deleteRow = (id) => {
  ElMessageBox.confirm("此操作将永久删除该数据, æ˜¯å¦ç»§ç»­?", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(async () => {
    const { code } = await deleteLedger(id);
    if (code == 200) {
      ElMessage({
        type: "success",
        message: "删除成功",
      });
      getTableData();
    }
  });
    ElMessageBox.confirm("此操作将永久删除该数据, æ˜¯å¦ç»§ç»­?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
    }).then(async () => {
        const { code } = await deleteLedger(id);
        if (code == 200) {
            ElMessage({
                type: "success",
                message: "删除成功",
            });
            getTableData();
        }
    });
};
const changeDaterange = (value) => {
  if (value) {
    filters.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
    filters.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
  } else {
    filters.entryDateStart = undefined;
    filters.entryDateEnd = undefined;
  }
  getTableData();
};
const handleOut = () => {
  ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
      .then(() => {
        proxy.download(`/lavorIssue/exportCopy`, {season: filters.season}, "劳保台账.xlsx");
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
    ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", {
        confirmButtonText: "确认",
        cancelButtonText: "取消",
        type: "warning",
    })
        .then(() => {
            proxy.download(`/lavorIssue/exportCopy`, {season: filters.season}, "劳保台账.xlsx");
        })
        .catch(() => {
            proxy.$modal.msg("已取消");
        });
};
const adopted = (row) => {
    ElMessageBox.confirm("是否确认领用?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
    }).then(async () => {
        const params = {
            id: row.id,
            adoptedDate: dayjs().format("YYYY-MM-DD")
        }
        const { code } = await update(params);
        if (code == 200) {
            ElMessage({
                type: "success",
                message: "领用成功",
            });
            getTableData();
        }
    })
}
// æ‰“开附件弹框
const openFilesFormDia = (row) => {
  nextTick(() => {
    filesDia.value?.openDialog( row,'收入')
  })
    nextTick(() => {
        filesDia.value?.openDialog( row,'收入')
    })
};
// äº‹ä»¶å¤„理函数
const handleSelectionChange = (selection) => {
    multipleList.value = selection;
}
const paginationChange = (size) => {
    console.log(size)
}
// ç»„件挂载时加载字典数据
onMounted(() => {
  filters.entryDate = [
    dayjs().format("YYYY-MM-DD"),
    dayjs().add(1, "day").format("YYYY-MM-DD"),
  ]
  filters.entryDateStart = dayjs().format("YYYY-MM-DD")
  filters.entryDateEnd = dayjs().add(1, "day").format("YYYY-MM-DD")
  getTableData();
});
    handleQuery()
})
</script>
<style lang="scss" scoped>
.table_list {
  margin-top: unset;
<style scoped>
.dynamic-table-container {
    width: 100%;
}
.actions {
  display: flex;
  justify-content: space-between;
  margin-bottom: 10px;
.pagination-container {
    margin-top: 20px;
    display: flex;
    justify-content: flex-end;
}
:deep(.el-table .el-table__header-wrapper th) {
    background-color: #F0F1F5 !important;
    color: #333333;
    font-weight: 600;
}
:deep(.el-table .el-table__body-wrapper td) {
    padding: 8px 0;
}
:deep(.el-select) {
    width: 100%;
}
:deep(.el-input) {
    width: 100%;
}
</style>
src/views/lavorissue/statistics/index.vue
@@ -58,16 +58,11 @@
<script setup>
import { usePaginationApi } from "@/hooks/usePaginationApi";
import { listPage,statistics } from "@/api/lavorissce/ledger";
import { onMounted, getCurrentInstance } from "vue";
import { ElMessageBox, ElMessage } from "element-plus";
import dayjs from "dayjs";
import {lavorIssueListPage, statistics} from "@/api/lavorissce/ledger";
import { onMounted } from "vue";
// è¡¨æ ¼å¤šé€‰æ¡†é€‰ä¸­é¡¹
const multipleList = ref([]);
const { proxy } = getCurrentInstance();
const modalRef = ref();
const filesDia = ref()
const jidu = ref([
  {
    value: '1',
@@ -96,7 +91,7 @@
  resetFilters,
  onCurrentChange,
} = usePaginationApi(
    listPage,
    lavorIssueListPage,
    {
      season: '',
      issueDate: '',
@@ -197,7 +192,7 @@
/** æœç´¢æŒ‰é’®æ“ä½œ */
const handleQuery = () => {
  page.current = 1;
    pagination.current = 1;
  getTableData();
};
const changePage = ({ page, limit }) => {