From db42d47f5692ef64e5436c5a6d29dcb537b44596 Mon Sep 17 00:00:00 2001
From: zouyu <2723363702@qq.com>
Date: 星期一, 26 一月 2026 16:36:13 +0800
Subject: [PATCH] 浪潮对接单点登录:mis调整
---
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