From 0ce559e6195a189ccc777b0fa439906bffb12b55 Mon Sep 17 00:00:00 2001 From: zhang_12370 <z2864490065@outlook.com> Date: 星期三, 25 六月 2025 17:58:31 +0800 Subject: [PATCH] 多页面添加查看功能 --- src/components/dialog/Descriptions.vue | 256 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 256 insertions(+), 0 deletions(-) diff --git a/src/components/dialog/Descriptions.vue b/src/components/dialog/Descriptions.vue new file mode 100644 index 0000000..dd53b35 --- /dev/null +++ b/src/components/dialog/Descriptions.vue @@ -0,0 +1,256 @@ +<template> + <el-dialog v-model="descriptionsVisible" :title="title" width="60%" :close-on-click-modal="false"> + <el-card> + <el-descriptions + class="margin-top" + :title="descriptionsTitle" + :column="column" + :size="size" + :border="border" + > + <template v-if="showOperations" #extra> + <slot name="extra"> + <el-button type="primary" @click="handleEdit" v-if="!isViewOnly">缂栬緫</el-button> + </slot> + </template> <!-- 鍔ㄦ�佹覆鏌撴墍鏈夋暟鎹」 --> + <el-descriptions-item + v-for="(item, key) in filteredData" + :key="`desc-item-${key}`" + :label="getFieldLabel(key)" + :span="getFieldSpan(key)" + > + {{ formatValue(item, key) }} + </el-descriptions-item> + </el-descriptions> + </el-card> + + <template #footer> + <div class="dialog-footer"> + <el-button @click="handleClose">鍏抽棴</el-button> + <el-button v-if="!isViewOnly" type="primary" @click="handleEdit">缂栬緫</el-button> + </div> + </template> + </el-dialog> +</template> + +<script setup> +import { defineProps, computed } from "vue"; + +const props = defineProps({ + // 寮圭獥鏍囬 + title: { + type: String, + default: "璇︽儏淇℃伅" + }, + // 鏁版嵁瀵硅薄 + formData: { + type: Object, + default: () => ({}) + }, + // 鏄惁涓烘煡鐪嬫ā寮� + isViewOnly: { + type: Boolean, + default: true + }, + // 鎻忚堪缁勪欢鏍囬 + descriptionsTitle: { + type: String, + default: "" + }, + // 鍒楁暟 + column: { + type: Number, + default: 2 + }, + // 灏哄 + size: { + type: String, + default: "default", + validator: (value) => ["large", "default", "small"].includes(value) + }, + // 鏄惁鏄剧ず杈规 + border: { + type: Boolean, + default: true + }, + // 鏄惁鏄剧ず鎿嶄綔鎸夐挳 + showOperations: { + type: Boolean, + default: true + }, + // 瀛楁鏄犲皠閰嶇疆 { key: { label: '鏄剧ず鍚嶇О', span?: 璺ㄥ垪鏁�, formatter?: 鏍煎紡鍖栧嚱鏁� } } + fieldConfig: { + type: Object, + default: () => ({}) + }, + // 闇�瑕佹帓闄ゆ樉绀虹殑瀛楁 + excludeFields: { + type: Array, + default: () => ['id', 'createTime', 'updateTime', 'deleted'] + }, // 闇�瑕佸寘鍚樉绀虹殑瀛楁锛堝鏋滆缃簡锛屽垯鍙樉绀鸿繖浜涘瓧娈碉級 + includeFields: { + type: Array, + default: () => [] + }, + // 瀛楁鏍囩鏄犲皠琛� { key: '鏄剧ず鍚嶇О' } + fieldLabels: { + type: Object, + default: () => ({}) + }, + // 瀛楁鏄剧ず椤哄簭 + fieldOrder: { + type: Array, + default: () => [] + } +}); + +const descriptionsVisible = defineModel("descriptionsVisible", { + type: Boolean, + default: false, +}); + +const emit = defineEmits(["update:descriptionsVisible", "edit", "close"]); + +// 杩囨护鍚庣殑鏁版嵁 +const filteredData = computed(() => { + if (!props.formData || typeof props.formData !== 'object') { + return {}; + } + + const data = { ...props.formData }; + let filteredResult = {}; + + // 濡傛灉鎸囧畾浜嗗寘鍚瓧娈碉紝鍒欏彧鏄剧ず杩欎簺瀛楁 + if (props.includeFields.length > 0) { + props.includeFields.forEach(field => { + if (data.hasOwnProperty(field)) { + filteredResult[field] = data[field]; + } + }); + } else { + // 鍚﹀垯鎺掗櫎鎸囧畾瀛楁 + Object.keys(data).forEach(key => { + if (!props.excludeFields.includes(key)) { + filteredResult[key] = data[key]; + } + }); + } + + // 濡傛灉鎸囧畾浜嗗瓧娈甸『搴忥紝鍒欐寜椤哄簭閲嶆柊缁勭粐鏁版嵁 + if (props.fieldOrder.length > 0) { + const orderedResult = {}; + + // 鍏堟寜鎸囧畾椤哄簭娣诲姞瀛楁 + props.fieldOrder.forEach(field => { + if (filteredResult.hasOwnProperty(field)) { + orderedResult[field] = filteredResult[field]; + } + }); + + // 鍐嶆坊鍔犳湭鍦ㄩ『搴忎腑鎸囧畾鐨勫叾浠栧瓧娈� + Object.keys(filteredResult).forEach(key => { + if (!props.fieldOrder.includes(key)) { + orderedResult[key] = filteredResult[key]; + } + }); + + return orderedResult; + } + + return filteredResult; +}); + +// 鑾峰彇瀛楁鏄剧ず鏍囩 +const getFieldLabel = (key) => { + // 1. 浼樺厛浣跨敤 fieldConfig 涓殑鏍囩閰嶇疆 + if (props.fieldConfig[key]?.label) { + return props.fieldConfig[key].label; + } + + // 2. 鍏舵浣跨敤浼犲叆鐨勫瓧娈垫槧灏勮〃 + if (props.fieldLabels[key]) { + return props.fieldLabels[key]; + } + + // 3. 鏈�鍚庝娇鐢ㄩ粯璁ょ殑瀛楁鍚嶈浆鎹紙椹煎嘲杞┖鏍硷級 + return key.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase()); +}; + +// 鑾峰彇瀛楁璺ㄥ垪鏁� +const getFieldSpan = (key) => { + return props.fieldConfig[key]?.span || 1; +}; + +// 鏍煎紡鍖栧�� +const formatValue = (value, key) => { + // 浼樺厛浣跨敤閰嶇疆鐨勬牸寮忓寲鍑芥暟 + if (props.fieldConfig[key]?.formatter && typeof props.fieldConfig[key].formatter === 'function') { + return props.fieldConfig[key].formatter(value); + } + + // 榛樿鏍煎紡鍖� + if (value === null || value === undefined || value === '') { + return '--'; + } + + // 鏁扮粍鏍煎紡鍖� + if (Array.isArray(value)) { + return value.join(', '); + } + + // 瀵硅薄鏍煎紡鍖� + if (typeof value === 'object') { + return JSON.stringify(value); + } + + // 鏃ユ湡鏍煎紡鍖� + if (key.toLowerCase().includes('time') || key.toLowerCase().includes('date')) { + try { + const date = new Date(value); + if (!isNaN(date.getTime())) { + return date.toLocaleString('zh-CN'); + } + } catch (e) { + // 濡傛灉涓嶆槸鏈夋晥鏃ユ湡锛岃繑鍥炲師鍊� + } + } + + return String(value); +}; + +// 澶勭悊缂栬緫鎸夐挳鐐瑰嚮 +const handleEdit = () => { + emit('edit', props.formData); +}; + +// 澶勭悊鍏抽棴 +const handleClose = () => { + descriptionsVisible.value = false; + emit('close'); +}; +</script> + +<style scoped> +.margin-top { + margin-top: 20px; +} + +.dialog-footer { + display: flex; + justify-content: flex-end; + gap: 12px; +} + +.cell-item { + display: flex; + align-items: center; +} + +:deep(.el-descriptions__label) { + font-weight: 600; +} + +:deep(.el-descriptions__content) { + word-break: break-word; +} +</style> -- Gitblit v1.9.3