From 75a462f8ee30491f05d29ccac1b65d31e835957b Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期三, 20 八月 2025 15:57:14 +0800
Subject: [PATCH] 档案管理调整

---
 src/components/DynamicTable/index.vue |  402 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 402 insertions(+), 0 deletions(-)

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>

--
Gitblit v1.9.3