From c4b339705e5d2d1a33f4f3d6b5d7e19ac7d68faa Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期三, 20 八月 2025 10:14:27 +0800
Subject: [PATCH] 劳保台账修改

---
 src/views/example/DynamicTableExample.vue |  354 ++++++++++++++
 src/components/DynamicTable/index.vue     |  402 ++++++++++++++++
 src/api/lavorissce/ledger.js              |    2 
 src/views/example/SimpleExample.vue       |  135 +++++
 src/views/lavorissue/statistics/index.vue |   13 
 src/views/lavorissue/ledger/index.vue     |  556 +++++++++++----------
 6 files changed, 1,181 insertions(+), 281 deletions(-)

diff --git a/src/api/lavorissce/ledger.js b/src/api/lavorissce/ledger.js
index 049dc7c..2d81bd9 100644
--- a/src/api/lavorissce/ledger.js
+++ b/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',
diff --git a/src/components/DynamicTable/index.vue b/src/components/DynamicTable/index.vue
new file mode 100644
index 0000000..9da9a3c
--- /dev/null
+++ b/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>
diff --git a/src/views/example/DynamicTableExample.vue b/src/views/example/DynamicTableExample.vue
new file mode 100644
index 0000000..038cd43
--- /dev/null
+++ b/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>
diff --git a/src/views/example/SimpleExample.vue b/src/views/example/SimpleExample.vue
new file mode 100644
index 0000000..fb528eb
--- /dev/null
+++ b/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>
diff --git a/src/views/lavorissue/ledger/index.vue b/src/views/lavorissue/ledger/index.vue
index 13b9cf5..b23bffe 100644
--- a/src/views/lavorissue/ledger/index.vue
+++ b/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="鍙戞斁瀛e害:" 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">鍙戞斁瀛e害锛�</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: '绗竴瀛e害'
-  },
-  {
-    value: '2',
-    label: '绗簩瀛e害'
-  },
-  {
-    value: '3',
-    label: '绗笁瀛e害'
-  },
-  {
-    value: '4',
-    label: '绗洓瀛e害'
-  }
+	{
+		value: '1',
+		label: '绗竴瀛e害'
+	},
+	{
+		value: '2',
+		label: '绗簩瀛e害'
+	},
+	{
+		value: '3',
+		label: '绗笁瀛e害'
+	},
+	{
+		value: '4',
+		label: '绗洓瀛e害'
+	}
 ])
-
-// 澶氶�夊悗鍋氫粈涔�
-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>
-
diff --git a/src/views/lavorissue/statistics/index.vue b/src/views/lavorissue/statistics/index.vue
index a2fd6a8..5c6f286 100644
--- a/src/views/lavorissue/statistics/index.vue
+++ b/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 }) => {

--
Gitblit v1.9.3