zhang_12370
5 天以前 1c4e88c1cb0639663f77a33dbab26c3cac71ad93
开发通用 删除 优化文档管理模块
已修改5个文件
458 ■■■■ 文件已修改
src/hooks/useDelete.js 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/hooks/useFormData.js 326 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/archiveManagement/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/archiveManagement/mould/archiveDialog.vue 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicInformation/index.vue 67 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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函数或返回API函数的函数
 * @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;
  /**
   * 获取实际的删除API函数
   * 支持直接传入函数或返回函数的函数
   */
  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);
      // 获取当前的删除API函数
      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();
          }
        }
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() {
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) {
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({
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: "删除成功",
})
/**
 * 关闭弹窗处理