import { message } from "@/utils/message"; import editForm from "../components/form.vue"; import { type Ref, ref, reactive, h } from "vue"; import * as XLSX from "xlsx"; import type { PaginationProps } from "@pureadmin/table"; import type { QueryCodeResult, QueryResult, QueryResultItem } from "types/code"; import { ElMessageBox, type UploadProps, type UploadUserFile } from "element-plus"; import { getQueryCodeAPI, getQueryTemplateAPI, postAddCodeFeedbackAPI, postCodeInfoAPI } from "@/api/code"; import { deleteFileAPI, postUploadFileAPI } from "@/api/file"; import { getKeyList, cloneDeep } from "@pureadmin/utils"; import { addDialog } from "@/components/ReDialog"; export const useIndex = (tableRef: Ref) => { /** * 查询表单 */ const form = reactive({ query_text: "" }); /** * 表单Ref */ const formRef = ref(null); /** * 数据列表 */ const dataList = ref([]); /** * 加载状态 */ const loading = ref(false); /** * 已选数量 */ const selectedNum = ref(0); /** * 分页参数 */ const pagination = reactive({ total: 0, pageSize: 10, currentPage: 1, background: true, pageSizes: [10, 20, 30, 40, 50] }); // 上传文件区域显示状态 const showUploadArea = ref(false); const fileList = ref([]); /**上传成功后文件列表 */ const fileIds = ref([]); const fileId = ref(""); /**上传按钮状态 */ const uploadStatus = ref(false); /** * 查询结果 */ const queryResult = ref(); const activeCollapse = ref(["baseInfo"]); /**列表值 */ const rowInfo = reactive({ query_text: "", status: 0, id: "", result_text: [] }); /**抽屉状态 */ const drawerStatus = ref(false); /** * 表格列设置 */ const columns: TableColumnList = [ { label: "勾选列", // 如果需要表格多选,此处label必须设置 type: "selection", fixed: "left", reserveSelection: true // 数据刷新后保留选项 }, { label: "查询ID", prop: "id" }, { label: "查询文本", prop: "query_text" }, { label: "匹配编码", prop: "result_text", formatter: ({ result_text }) => { if (result_text.length > 0) { return result_text[0]["code"].replace(/(\d{2})/g, "$1.").slice(0, -1); } return ""; } }, { label: "编码描述", prop: "result_text", formatter: ({ result_text }) => { if (result_text.length > 0) { return result_text[0]["description"]; } return ""; } }, { label: "操作", fixed: "right", width: 250, slot: "operation" } ]; /** * 初次查询 */ const onSearch = async () => { loading.value = true; const res = await postCodeInfoAPI({ query_text: form.query_text }); if (res.success) { queryResult.value = res.data; dataList.value = res.data.response_result; pagination.total = res.data.result_count; } message(res.msg, { type: res.success ? "success" : "error" }); loading.value = false; }; /** * 重置表单 * @param formEl 表单ref * @returns */ const resetForm = (formEl: any) => { if (!formEl) return; formEl.resetFields(); onSearch(); }; /** 当CheckBox选择项发生变化时会触发该事件 */ const handleSelectionChange = async (val: any) => { selectedNum.value = val.length; // 重置表格高度 tableRef.value.setAdaptive(); }; /** 取消选择 */ const onSelectionCancel = async () => { selectedNum.value = 0; // 用于多选表格,清空用户的选择 tableRef.value.getTableRef().clearSelection(); }; /**下载模版文件 */ const onDownloadTemplate = async () => { try { const blob = await getQueryTemplateAPI(); // 生成下载链接 // @ts-ignore const url = URL.createObjectURL(blob); // 创建 元素并触发下载 const link = document.createElement("a"); link.href = url; link.download = "上传模版.xlsx"; // 设置下载文件名,确保后缀名正确 document.body.appendChild(link); // 将 元素添加到 DOM 中 link.click(); // 模拟点击下载 // 清理 URL 对象 URL.revokeObjectURL(url); document.body.removeChild(link); // 移除 元素 } catch (error) { console.error("下载模板失败:", error); } }; /** 上传文件前 */ const beforeUpload = async file => { const isExcel = file.type === "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" || // xlsx file.type === "application/vnd.ms-excel" || // xls file.name.endsWith(".xlsx") || // 兼容部分浏览器 file.name.endsWith(".xls"); // 兼容部分浏览器 // const maxSize = 20 * 1024 * 1024; // 20MB 限制 if (!isExcel) { message("只能上传 xlsx 或 xls 文件!", { type: "error" }); return false; } /* if (file.size > maxSize) { message("文件大小应在 20MB 以内!", { type: "error" }); return false; } */ return true; }; /**处理文件上传 */ const handleUpload = async () => { if (fileList.value.length === 0) { message("请先上传文件!", { type: "error", duration: 5000 }); return; } uploadStatus.value = true; for (const file of fileList.value) { if (file.status === "success") { const data = await getQueryCodeAPI(fileId.value); if (data.success) { message("查询成功!", { type: "success" }); queryResult.value = data.data; dataList.value = data.data.response_result; pagination.total = data.data.result_count; } continue; } try { const res = await postUploadFileAPI({ file: file.raw }); if (res.success) { file.status = "success"; fileId.value = res.data.id; message(`${res.data.name}上传成功!`, { type: "success" }); fileIds.value.push(res.data); const data = await getQueryCodeAPI(fileId.value); if (data.success) { message(`查询成功!`, { type: "success" }); queryResult.value = data.data; dataList.value = data.data.response_result; pagination.total = data.data.result_count; } } else { file.status = "fail"; } } catch (error) { console.error(error); } } uploadStatus.value = false; }; /**移除文件 */ const beforeRemove: UploadProps["beforeRemove"] = async uploadFile => { return ElMessageBox.confirm(`是否移除 ${uploadFile.name} ?`).then( async () => { if (uploadFile.status === "success") { const fileId = fileIds.value.filter( item => item.filename === uploadFile.name )[0]["fileId"]; const res = await deleteFileAPI(fileId); if (res.code === 200) { message(res.msg, { type: "success" }); return true; } else { message(res.msg, { type: "error" }); return false; } } else { return true; } }, () => false ); }; const handleDetail = (row: QueryResultItem) => { drawerStatus.value = true; Object.assign(rowInfo, row); }; /**导出为excel */ const exportToExcel = (dataList: QueryCodeResult[], filename: string) => { if (dataList.length) { const headers = [ "序号", "查询批次ID", "查询文本(总)", "查询统计", "结果统计", "查询状态", "耗时(毫秒)", "操作时间", "待查询文本ID", "待查询文本", "查询结果状态" ]; for (let i = 1; i <= 5; i++) { headers.push( `匹配结果ID${i}`, `匹配编码${i}`, `匹配结果${i}`, `匹配率(百分比)${i}` ); } const data = []; let index = 1; for (const jsonData of dataList) { const batchId = jsonData.id; const queryText = jsonData.query; const queryCount = jsonData.query_count; const resultCount = jsonData.result_count; const status = jsonData.status === 1 ? "成功" : "失败"; const costTime = jsonData.cost_time; const operationTime = jsonData.operation_time; jsonData.response_result.forEach(response => { const queryId = response.id; const queryTextDetail = response.query_text; const queryStatus = response.status === 1 ? "成功" : "失败"; const row = [ index++, batchId, queryText, queryCount, resultCount, status, costTime, operationTime, queryId, queryTextDetail, queryStatus ]; for (let i = 0; i < 5; i++) { if (i < response.result_text.length) { const match = response.result_text[i]; row.push( match.id, match.code, match.description, match.match_rate ); } else { row.push("", "", "", ""); } } data.push(row); }); } const worksheet = XLSX.utils.aoa_to_sheet([headers, ...data]); const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, worksheet, "Query Results"); XLSX.writeFile(workbook, `${filename}.xlsx`); message("导出成功!", { type: "success" }); } }; /**批量导出 */ const onbatchExport = async () => { // 获取当前选中的行 const curSelected = tableRef.value.getTableRef().getSelectionRows(); let dataJson = cloneDeep(queryResult.value); // 深拷贝,避免修改原数据 const ids = getKeyList(curSelected, "id"); let dataList = dataJson.response_result; // 拷贝的数据 let selecteList = dataList.filter((item: QueryResult) => ids.includes(item.id) ); // 筛选出选中的数据 // 仅赋值导出的数据,不修改原始数据 let exportData = { ...dataJson, response_result: selecteList }; exportToExcel([exportData], "查询结果"); }; /**处理反馈 */ /**处理反馈 */ const handleFeedback = async ( way: string = "反馈", row: QueryResultItem, query_text?: string, code?: string ) => { addDialog({ title: way, props: { formInline: { way: way, code_id: row?.id ?? "", code: row?.code ?? "", description: row?.description ?? "", feedback_code: way === "反馈" ? (row?.code ?? "") : code, feedback_description: way === "反馈" ? (row?.description ?? "") : query_text } }, width: "45%", draggable: true, fullscreenIcon: true, closeOnClickModal: false, contentRenderer: () => h(editForm, { formInline: { way: way, code_id: row?.id ?? "", code: row?.code ?? "", description: row?.description ?? "", feedback_code: way === "反馈" ? (row?.code ?? "") : code, feedback_description: way === "反馈" ? (row?.description ?? "") : query_text }, ref: formRef }), beforeSure: async (done, {}) => { const FormData = formRef.value.newFormInline; let id = way === "反馈" ? (row?.id ?? "") : ""; const res = await postAddCodeFeedbackAPI({ code_id: id, feedback_description: FormData.feedback_description, feedback_code: FormData.feedback_code }); if (res.success) { message(res.msg, { type: "success" }); done(); } else { message(res.msg, { type: "error" }); } } }); }; return { form, dataList, loading, pagination, columns, queryResult, selectedNum, showUploadArea, fileIds, fileList, uploadStatus, rowInfo, drawerStatus, activeCollapse, beforeUpload, handleUpload, beforeRemove, onSearch, resetForm, handleSelectionChange, onSelectionCancel, onDownloadTemplate, handleDetail, exportToExcel, onbatchExport, handleFeedback }; };