// @/API/admin.ts import { api8000 } from '@/utils/request'; import { ElMessage } from 'element-plus'; import 'element-plus/es/components/message/style/css'; // 🔹 获取表格数据 export const table = (params: { table: string }) => { return api8000({ url: "/admin/table", method: "GET", params: params, }) .then((res) => { // 适配后端返回的直接数组格式 return { data: Array.isArray(res.data) ? res.data : [] }; }) .catch((err) => { if (err.response?.status === 401) throw err; throw new Error(err.message || "获取数据失败"); }); }; // 🔹 新增数据 export const addItem = (data: { table: string; item: Record; }) => { return api8000({ url: "/admin/add_item", method: "POST", params: { table: data.table }, data: data.item, }).catch((error) => { if (error.response?.status === 400 && error.response.data.detail === "重复数据") { ElMessage.error("数据重复,请重新添加"); } throw error; }); }; // 🔹 更新数据 export const updateItem = (data: { table: string; id: number; update_data: Record; }) => { return api8000({ url: "/admin/update_item", method: "PUT", params: { table: data.table, id: data.id }, data: data.update_data, }).catch((error) => { if (error.response?.status === 400 && error.response.data.detail === "重复数据") { ElMessage.error("数据重复,无法更新"); } throw error; }); }; // 🔹 删除数据 export const deleteItemApi = (params: { table: string; id: number; }) => { return api8000({ url: "/admin/delete_item", method: "DELETE", params: params, }); }; // 🔹 导出数据 export const exportData = (table: string, format: string = "xlsx") => { return api8000({ url: "/admin/export_data", method: "GET", params: { table, fmt: format }, responseType: "blob", }) .then((response) => { const contentDisposition = response.headers["content-disposition"]; if (!contentDisposition) { throw new Error("无法获取文件名"); } const filenameMatch = contentDisposition.match(/filename=([^;]+)/); const filename = filenameMatch ? decodeURIComponent(filenameMatch[1]) : `${table}_data.${format === "xlsx" ? "xlsx" : "csv"}`; const blob = new Blob([response.data], { type: format === "xlsx" ? "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" : "text/csv", }); const url = window.URL.createObjectURL(blob); const link = document.createElement("a"); link.href = url; link.download = filename; link.click(); window.URL.revokeObjectURL(url); }) .catch((error) => { console.error("❌ 导出数据失败:", error); throw error; }); }; // 🔹 导入数据 export const importData = (table: string, file: File) => { // 1. 前置校验提示(文件为空/格式错误) if (!file || file.size === 0) { const errorMsg = "❌ 请选择非空的Excel/CSV文件,空文件无法导入"; console.error(errorMsg); throw new Error(errorMsg); } const validExtensions = ['xlsx', 'csv']; const fileExtension = file.name.split('.').pop()?.toLowerCase(); if (!fileExtension || !validExtensions.includes(fileExtension)) { const errorMsg = `❌ 仅支持 .xlsx 和 .csv 格式文件,当前文件格式为 .${fileExtension || '未知'}`; console.error(errorMsg); throw new Error(errorMsg); } // 2. 创建FormData(与后端参数名对齐) const formData = new FormData(); formData.append('table', table); formData.append('file', file); return api8000({ url: "/admin/import_data", method: "POST", data: formData, headers: { 'Content-Type': 'multipart/form-data' } }) .then((response) => { const { total_data, new_data, duplicate_data } = response.data; let successMsg = ""; if (total_data === 0) { successMsg = "✅ 文件导入成功,但文件中无有效数据(空内容)"; } else { successMsg = `✅ 数据导入成功!共${total_data}条数据,新增${new_data}条,重复${duplicate_data}条`; } console.log(successMsg, "详情:", response.data); ElMessage.success(successMsg); return response.data; }) .catch((error) => { let errorMsg = "❌ 导入失败,请稍后重试"; if (error.response?.data) { const resData = error.response.data; if (resData.detail?.duplicate_count && resData.detail?.duplicates) { const { duplicate_count, duplicates, check_fields } = resData.detail; const duplicateDetails = duplicates.map((item: any) => `第${item.row_number}行:${check_fields.map((f: string) => `${f}=${item.duplicate_fields[f] || '空值'}`).join(',')}` ).join('\n'); errorMsg = `❌ 检测到${duplicate_count}条重复数据(基于${check_fields.join('、')}字段):\n${duplicateDetails}`; } else if (resData.detail) { errorMsg = `❌ ${resData.detail.message || resData.detail}`; } else if (resData.message) { errorMsg = `❌ ${resData.message}`; } } else if (!error.response) { errorMsg = "❌ 网络异常或服务器无响应,请检查网络连接后重试"; } else { errorMsg = "❌ 未知错误,可能是文件损坏或服务器繁忙"; } console.error(errorMsg, "错误详情:", error); ElMessage.error(errorMsg); throw new Error(errorMsg); }); }; // 🔹 下载模板 export const downloadTemplate = (table: string, format: string = "excel") => { return api8000({ url: "/admin/download_template", method: "GET", params: { table, format }, responseType: "blob", }) .then((response) => { const contentDisposition = response.headers["content-disposition"]; if (!contentDisposition) { throw new Error("无法获取文件名"); } const filenameMatch = contentDisposition.match(/filename=([^;]+)/); const filename = filenameMatch ? decodeURIComponent(filenameMatch[1]) : `${table}_template.${format === "excel" ? "xlsx" : "csv"}`; const blob = new Blob([response.data], { type: format === "excel" ? "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" : "text/csv", }); const url = window.URL.createObjectURL(blob); const link = document.createElement("a"); link.href = url; link.download = filename; link.click(); window.URL.revokeObjectURL(url); }) .catch((error) => { console.error("❌ 下载模板失败:", error); throw error; }); };