From 1c4e88c1cb0639663f77a33dbab26c3cac71ad93 Mon Sep 17 00:00:00 2001 From: zhang_12370 <z2864490065@outlook.com> Date: 星期四, 26 六月 2025 13:28:05 +0800 Subject: [PATCH] 开发通用 删除 优化文档管理模块 --- src/hooks/useFormData.js | 326 ++++++++++++++++++++++++++++++++++++++++ src/views/basicInformation/index.vue | 67 +------ src/views/archiveManagement/mould/archiveDialog.vue | 7 src/hooks/useDelete.js | 53 ++++++ src/views/archiveManagement/index.vue | 5 5 files changed, 390 insertions(+), 68 deletions(-) diff --git a/src/hooks/useDelete.js b/src/hooks/useDelete.js index 7c6df82..60615b3 100644 --- a/src/hooks/useDelete.js +++ b/src/hooks/useDelete.js @@ -7,8 +7,8 @@ /** * 鍒涘缓鍒犻櫎鍔熻兘 * @param {Object} options 閰嶇疆閫夐」 - * @param {Function} options.deleteApi 鍒犻櫎API鍑芥暟 - * @param {Function} options.getList 閲嶆柊鑾峰彇鍒楄〃鏁版嵁鐨勫嚱鏁� + * @param {Function|Function} options.deleteApi 鍒犻櫎API鍑芥暟鎴栬繑鍥濧PI鍑芥暟鐨勫嚱鏁� + * @param {Function|Function} options.getList 閲嶆柊鑾峰彇鍒楄〃鏁版嵁鐨勫嚱鏁版垨杩斿洖鍑芥暟鐨勫嚱鏁� * @param {Ref} options.selectedRows 閫変腑琛岀殑鍝嶅簲寮忓紩鐢� * @param {Ref} options.tableData 琛ㄦ牸鏁版嵁鐨勫搷搴斿紡寮曠敤 * @param {Ref} options.total 鎬绘暟鐨勫搷搴斿紡寮曠敤 @@ -28,6 +28,41 @@ successText = "鍒犻櫎鎴愬姛", useLocalUpdate = false } = options; + + /** + * 鑾峰彇瀹為檯鐨勫垹闄PI鍑芥暟 + * 鏀寔鐩存帴浼犲叆鍑芥暟鎴栬繑鍥炲嚱鏁扮殑鍑芥暟 + */ + const getDeleteApi = () => { + if (typeof deleteApi === 'function') { + // 灏濊瘯璋冪敤鐪嬫槸鍚﹁繑鍥炲嚱鏁� + try { + const result = deleteApi(); + return typeof result === 'function' ? result : deleteApi; + } catch (error) { + // 濡傛灉璋冪敤鍑洪敊锛岃鏄庤繖鏈韩灏辨槸API鍑芥暟 + return deleteApi; + } + } + return deleteApi; + }; + + /** + * 鑾峰彇瀹為檯鐨勮幏鍙栧垪琛ㄥ嚱鏁� + * 鏀寔鐩存帴浼犲叆鍑芥暟鎴栬繑鍥炲嚱鏁扮殑鍑芥暟 + */ + const getListFunction = () => { + if (typeof getList === 'function') { + try { + const result = getList(); + return typeof result === 'function' ? result : getList; + } catch (error) { + // 濡傛灉璋冪敤鍑洪敊锛岃鏄庤繖鏈韩灏辨槸鍒楄〃鍑芥暟 + return getList; + } + } + return getList; + }; /** * 鎵归噺鍒犻櫎鏂规硶 @@ -55,9 +90,16 @@ // 鎻愬彇ID const ids = rowsToDelete.map(item => item.id); + + // 鑾峰彇褰撳墠鐨勫垹闄PI鍑芥暟 + const currentDeleteApi = getDeleteApi(); + if (!currentDeleteApi) { + ElMessage.error("鍒犻櫎API鏈厤缃�"); + return false; + } // 璋冪敤鍒犻櫎API - const res = await deleteApi(ids); + const res = await currentDeleteApi(ids); if (res.code === 200) { // 鏍规嵁閰嶇疆閫夋嫨鏇存柊鏂瑰紡 @@ -69,8 +111,9 @@ } } else { // 閲嶆柊鑾峰彇鏁版嵁 - if (getList) { - await getList(); + const currentGetList = getListFunction(); + if (currentGetList) { + await currentGetList(); } } diff --git a/src/hooks/useFormData.js b/src/hooks/useFormData.js index 7363aa8..325e981 100644 --- a/src/hooks/useFormData.js +++ b/src/hooks/useFormData.js @@ -1,8 +1,330 @@ -import { reactive } from "vue"; +/** + * 閫氱敤琛ㄥ崟鏁版嵁绠$悊缁勫悎寮忓嚱鏁� + * 鎻愪緵琛ㄥ崟鏁版嵁鐨勫鍒犳敼鏌ャ�侀獙璇併�侀噸缃瓑鍔熻兘 + */ +import { ref, reactive, computed, nextTick } from "vue"; +import { ElMessage, ElMessageBox } from "element-plus"; import { clone } from "lodash"; +/** + * 鍒涘缓琛ㄥ崟鏁版嵁绠$悊鍔熻兘 + * @param {Object} options 閰嶇疆閫夐」 + * @param {Object} options.defaultForm 榛樿琛ㄥ崟缁撴瀯 + * @param {Function} options.addApi 鏂板API鍑芥暟 + * @param {Function} options.updateApi 鏇存柊API鍑芥暟 + * @param {Function} options.getDetailApi 鑾峰彇璇︽儏API鍑芥暟 + * @param {Object} options.rules 琛ㄥ崟楠岃瘉瑙勫垯 + * @param {Function} options.beforeSubmit 鎻愪氦鍓嶇殑鏁版嵁澶勭悊鍑芥暟 + * @param {Function} options.afterSubmit 鎻愪氦鍚庣殑鍥炶皟鍑芥暟 + * @param {Boolean} options.autoReset 鎻愪氦鎴愬姛鍚庢槸鍚﹁嚜鍔ㄩ噸缃〃鍗� + * @returns {Object} 杩斿洖琛ㄥ崟绠$悊鐩稿叧鐨勬柟娉曞拰鐘舵�� + */ +export function useFormData(options = {}) { + const { + defaultForm = {}, + addApi, + updateApi, + getDetailApi, + rules = {}, + beforeSubmit, + afterSubmit, + autoReset = true + } = options; -export default function useFormData(initData) { + // 琛ㄥ崟鐘舵�� + const form = ref({ ...defaultForm }); + const originalForm = ref({ ...defaultForm }); + const loading = ref(false); + const dialogVisible = ref(false); + const mode = ref('add'); // 'add', 'edit', 'view' + const title = ref(''); + const formRef = ref(null); + + // 璁$畻灞炴�� + const isAdd = computed(() => mode.value === 'add'); + const isEdit = computed(() => mode.value === 'edit'); + const isView = computed(() => mode.value === 'view'); + const isReadonly = computed(() => mode.value === 'view'); + const submitButtonText = computed(() => { + return isAdd.value ? '鏂板' : '淇濆瓨'; + }); + + /** + * 鎵撳紑琛ㄥ崟瀵硅瘽妗� + * @param {String} formMode 琛ㄥ崟妯″紡锛�'add', 'edit', 'view' + * @param {Object} data 缂栬緫/鏌ョ湅鏃剁殑鏁版嵁 + * @param {String} customTitle 鑷畾涔夋爣棰� + */ + const openForm = async (formMode = 'add', data = null, customTitle = '') => { + mode.value = formMode; + + // 璁剧疆鏍囬 + if (customTitle) { + title.value = customTitle; + } else { + const titleMap = { + add: '鏂板', + edit: '缂栬緫', + view: '鏌ョ湅' + }; + title.value = titleMap[formMode] || '琛ㄥ崟'; + } + + // 鏍规嵁妯″紡澶勭悊鏁版嵁 + if (formMode === 'add') { + resetForm(); + } else if (data) { + // 缂栬緫/鏌ョ湅妯″紡锛屽鏋滄湁璇︽儏API鍒欒幏鍙栨渶鏂版暟鎹� + if (getDetailApi && data.id) { + loading.value = true; + try { + const res = await getDetailApi(data.id); + if (res.code === 200) { + setFormData(res.data); + } else { + ElMessage.error('鑾峰彇璇︽儏澶辫触'); + setFormData(data); + } + } catch (error) { + console.error('鑾峰彇璇︽儏澶辫触:', error); + setFormData(data); + } finally { + loading.value = false; + } + } else { + setFormData(data); + } + } + + dialogVisible.value = true; + }; + + /** + * 璁剧疆琛ㄥ崟鏁版嵁 + * @param {Object} data 琛ㄥ崟鏁版嵁 + */ + const setFormData = (data) => { + form.value = { ...defaultForm, ...data }; + originalForm.value = { ...form.value }; + }; + + /** + * 閲嶇疆琛ㄥ崟 + */ + const resetForm = () => { + form.value = { ...defaultForm }; + originalForm.value = { ...defaultForm }; + if (formRef.value) { + formRef.value.resetFields(); + } + }; + + /** + * 鎭㈠琛ㄥ崟鍒板師濮嬬姸鎬� + */ + const restoreForm = () => { + form.value = { ...originalForm.value }; + if (formRef.value) { + formRef.value.clearValidate(); + } + }; + + /** + * 琛ㄥ崟楠岃瘉 + * @returns {Promise<Boolean>} 楠岃瘉缁撴灉 + */ + const validateForm = async () => { + if (!formRef.value) return true; + + try { + await formRef.value.validate(); + return true; + } catch (error) { + console.log('琛ㄥ崟楠岃瘉澶辫触:', error); + return false; + } + }; + + /** + * 鎻愪氦琛ㄥ崟 + * @param {Object} customData 鑷畾涔夋彁浜ゆ暟鎹� + * @returns {Promise<Boolean>} 鎻愪氦缁撴灉 + */ + const submitForm = async (customData = null) => { + // 楠岃瘉琛ㄥ崟 + const isValid = await validateForm(); + if (!isValid) { + ElMessage.warning('璇锋鏌ヨ〃鍗曟暟鎹�'); + return false; + } + + // 鍑嗗鎻愪氦鏁版嵁 + let submitData = customData || { ...form.value }; + + // 鎵ц鎻愪氦鍓嶅鐞� + if (beforeSubmit && typeof beforeSubmit === 'function') { + try { + submitData = await beforeSubmit(submitData, mode.value); + } catch (error) { + console.error('鎻愪氦鍓嶅鐞嗗け璐�:', error); + ElMessage.error('鏁版嵁澶勭悊澶辫触'); + return false; + } + } + + loading.value = true; + + try { + let res; + + if (isAdd.value && addApi) { + res = await addApi(submitData); + } else if (isEdit.value && updateApi) { + res = await updateApi(submitData); + } else { + ElMessage.error('鏈厤缃浉搴旂殑API鎺ュ彛'); + return false; + } + + if (res.code === 200) { + const action = isAdd.value ? '鏂板' : '鏇存柊'; + ElMessage.success(`${action}鎴愬姛`); + + // 鎵ц鎻愪氦鍚庡洖璋� + if (afterSubmit && typeof afterSubmit === 'function') { + await afterSubmit(res.data, mode.value, submitData); + } + + // 鑷姩閲嶇疆琛ㄥ崟 + if (autoReset) { + closeForm(); + } + + return true; + } else { + ElMessage.error(res.msg || '鎿嶄綔澶辫触'); + return false; + } + } catch (error) { + console.error('鎻愪氦澶辫触:', error); + ElMessage.error('鎿嶄綔澶辫触锛岃绋嶅悗閲嶈瘯'); + return false; + } finally { + loading.value = false; + } + }; + + /** + * 鍏抽棴琛ㄥ崟瀵硅瘽妗� + */ + const closeForm = () => { + dialogVisible.value = false; + resetForm(); + }; + + /** + * 妫�鏌ヨ〃鍗曟槸鍚︽湁鍙樻洿 + * @returns {Boolean} 鏄惁鏈夊彉鏇� + */ + const hasChanges = computed(() => { + return JSON.stringify(form.value) !== JSON.stringify(originalForm.value); + }); + + /** + * 甯︾‘璁ょ殑鍏抽棴琛ㄥ崟 + */ + const closeFormWithConfirm = async () => { + if (hasChanges.value && !isView.value) { + try { + await ElMessageBox.confirm('琛ㄥ崟鏁版嵁宸蹭慨鏀癸紝纭畾瑕佺寮�鍚楋紵', '鎻愮ず', { + confirmButtonText: '纭畾', + cancelButtonText: '鍙栨秷', + type: 'warning', + }); + closeForm(); + } catch { + // 鐢ㄦ埛鍙栨秷 + } + } else { + closeForm(); + } + }; + + /** + * 璁剧疆琛ㄥ崟瀛楁鍊� + * @param {String} field 瀛楁鍚� + * @param {Any} value 瀛楁鍊� + */ + const setFieldValue = (field, value) => { + form.value[field] = value; + }; + + /** + * 鑾峰彇琛ㄥ崟瀛楁鍊� + * @param {String} field 瀛楁鍚� + * @returns {Any} 瀛楁鍊� + */ + const getFieldValue = (field) => { + return form.value[field]; + }; + + /** + * 鎵归噺璁剧疆琛ㄥ崟瀛楁鍊� + * @param {Object} values 瀛楁鍊煎璞� + */ + const setFieldValues = (values) => { + Object.keys(values).forEach(key => { + if (form.value.hasOwnProperty(key)) { + form.value[key] = values[key]; + } + }); + }; + + /** + * 娓呴櫎瀛楁楠岃瘉 + * @param {String|Array} fields 瀛楁鍚嶆垨瀛楁鍚嶆暟缁� + */ + const clearValidate = (fields = null) => { + if (formRef.value) { + formRef.value.clearValidate(fields); + } + }; + + return { + // 鐘舵�� + form, + loading, + dialogVisible, + mode, + title, + formRef, + + // 璁$畻灞炴�� + isAdd, + isEdit, + isView, + isReadonly, + submitButtonText, + hasChanges, + + // 鏂规硶 + openForm, + setFormData, + resetForm, + restoreForm, + validateForm, + submitForm, + closeForm, + closeFormWithConfirm, + setFieldValue, + getFieldValue, + setFieldValues, + clearValidate + }; +} + +// 鍚戝悗鍏煎鐨勯粯璁ゅ鍑� +export default function useFormDataSimple(initData) { const form = reactive(clone(initData, true)); function resetForm() { diff --git a/src/views/archiveManagement/index.vue b/src/views/archiveManagement/index.vue index f1fb1e2..7bcbed9 100644 --- a/src/views/archiveManagement/index.vue +++ b/src/views/archiveManagement/index.vue @@ -208,13 +208,14 @@ const tableSwitch = ref(false); // 澶勭悊鑺傜偣鐐瑰嚮 const handleNodeClick = (data) => { - console.log("鐐瑰嚮鑺傜偣", data); + rowClickData.value = data; // 瀛樺偍褰撳墠鐐瑰嚮鐨勮妭鐐规暟鎹� tableSwitch.value = true; // 鍒囨崲鑺傜偣鏃堕噸缃埌绗竴椤� queryParams.current = 1; queryParams.treeId = data.id; getArchiveListData(); }; +const rowClickData = ref({}); // 瀛樺偍褰撳墠鐐瑰嚮鐨勮妭鐐规暟鎹� const archiveDialogs = ref(null); // 琛ㄦ牸缁勪欢寮曠敤 // 鏂板褰掓。 const add = () => { @@ -226,7 +227,7 @@ // 纭繚缁勪欢寮曠敤瀛樺湪鍚庡啀璋冪敤鏂规硶 nextTick(() => { if (archiveDialogs.value && typeof archiveDialogs.value.initForm === 'function') { - archiveDialogs.value.initForm(); // 閲嶇疆琛ㄥ崟 + archiveDialogs.value.initForm(rowClickData.value); // 閲嶇疆琛ㄥ崟 } }); } catch (error) { diff --git a/src/views/archiveManagement/mould/archiveDialog.vue b/src/views/archiveManagement/mould/archiveDialog.vue index 07b1e00..d60cd84 100644 --- a/src/views/archiveManagement/mould/archiveDialog.vue +++ b/src/views/archiveManagement/mould/archiveDialog.vue @@ -101,9 +101,9 @@ const initTreeDataId = ref(null); const fileUploadRef = ref(null); const initForm = (val) => { - initTreeDataId.value = val.value.id || null; // 纭繚 initTreeDataId 鍒濆鍖栦负 null + initTreeDataId.value = val.id || null; // 纭繚 initTreeDataId 鍒濆鍖栦负 null ruleForm.value = {}; - ruleForm.value.treeId = val.value.id || null; // 纭繚 treeId 鍒濆鍖栦负 null + ruleForm.value.treeId = val.id || null; // 纭繚 treeId 鍒濆鍖栦负 null nextTick(() => { fileUploadRef.value.init(); }); @@ -146,9 +146,6 @@ }); return; } - // 鍙戦�� emit 浜嬩欢 - - // 鍏抽棴瀵硅瘽妗� centerDialogVisible.value = false; } catch (error) { ElMessage({ diff --git a/src/views/basicInformation/index.vue b/src/views/basicInformation/index.vue index 238cbf2..907d60d 100644 --- a/src/views/basicInformation/index.vue +++ b/src/views/basicInformation/index.vue @@ -58,7 +58,6 @@ @selection-change="handleSelectionChange" :operations="['edit', 'viewRow']" :operationsWidth="200" - :show-overflow-tooltip="false" > <!-- 瀛楁鍚嶇О鍒楃殑鑷畾涔夋彃妲� - 鏄剧ず涓烘爣绛� --> <template @@ -168,7 +167,6 @@ import Coal from "./mould/coal.vue"; import coalQualityMaintenance from "./mould/coalQualityMaintenance.vue"; import coalMeiZhiZiDuanWeiHu from "./mould/coalMeiZhiZiDuanWeiHu.vue"; -import Descriptions from "@/components/dialog/Descriptions.vue"; // ===== API 鏈嶅姟瀵煎叆 ===== import { delSupply, getSupply } from "@/api/basicInformation/supplier.js"; @@ -186,16 +184,12 @@ import { getCoalFieldList, getCoalPlanList, + delCoalPlan, } from "@/api/basicInformation/coalQualityMaintenance"; - +import { useDelete } from "@/hooks/useDelete.js"; const { proxy } = getCurrentInstance(); // ===== 鍝嶅簲寮忕姸鎬佺鐞� ===== -// 寮圭獥鎺у埗鐘舵�� -const showDialog = ref(false); -const currentViewData = ref({}); // 褰撳墠鏌ョ湅鐨勬暟鎹� - - const dialogFormVisible = ref(false); const form = ref({}); const title = ref(""); @@ -721,57 +715,22 @@ * 鎵归噺鍒犻櫎澶勭悊 * @description 鎵归噺鍒犻櫎閫変腑鐨勮褰� */ -const handleDelete = async () => { - if (selectedRows.value.length === 0) { - ElMessage.warning("璇烽�夋嫨瑕佸垹闄ょ殑鏁版嵁"); - return; - } - - const deleteIds = selectedRows.value.map((item) => item.id); - - try { - await ElMessageBox.confirm("纭畾鍒犻櫎閫変腑鐨勬暟鎹悧锛�", "鎻愮ず", { - confirmButtonText: "纭畾", - cancelButtonText: "鍙栨秷", - type: "warning", - }); - - const deleteApiMap = { + const deleteApiMap = { supplier: delSupply, coal: delCoalInfo, - coalQualityMaintenance: () => { - throw new Error("delCoalQuality API not imported"); - }, + coalQualityMaintenance: delCoalPlan, customer: delCustomer, coalMeiZhiZiDuanWeiHu: deleteCoalField, }; - - const deleteApi = deleteApiMap[tabName.value]; - if (!deleteApi) { - ElMessage.error("鍒犻櫎鎺ュ彛鏈厤缃�"); - return; - } - console.log(deleteIds); - const res = await deleteApi(deleteIds); - - if (res.code !== 200 && res.msg !== "鎿嶄綔鎴愬姛") { - ElMessage.error("鍒犻櫎澶辫触锛�" + res.msg); - return; - } - - ElMessage.success("鍒犻櫎鎴愬姛"); - await getList(); - } catch (error) { - if (error.message !== "cancel") { - console.error("鍒犻櫎鎿嶄綔澶辫触:", error); - ElMessage.error("鍒犻櫎澶辫触锛岃绋嶅悗鍐嶈瘯"); - } else { - ElMessage.info("宸插彇娑堝垹闄ゆ搷浣�"); - } - } finally { - selectedRows.value = []; - } -}; +const {handleDeleteBatch :handleDelete} = useDelete({ + deleteApi: () => deleteApiMap[tabName.value], + selectedRows: selectedRows, + getList: () => getList, + tableData: tableData, + total: total, + confirmText: "纭鍒犻櫎閫変腑鐨勬暟鎹悧锛�", + successText: "鍒犻櫎鎴愬姛", +}) /** * 鍏抽棴寮圭獥澶勭悊 -- Gitblit v1.9.3