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