461 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<QueryResult[]>([]);
/**
* 加载状态
*/
const loading = ref(false);
/**
* 已选数量
*/
const selectedNum = ref<number>(0);
/**
* 分页参数
*/
const pagination = reactive<PaginationProps>({
total: 0,
pageSize: 10,
currentPage: 1,
background: true,
pageSizes: [10, 20, 30, 40, 50]
});
// 上传文件区域显示状态
const showUploadArea = ref(false);
const fileList = ref<UploadUserFile[]>([]);
/**上传成功后文件列表 */
const fileIds = ref([]);
const fileId = ref<string>("");
/**上传按钮状态 */
const uploadStatus = ref<boolean>(false);
/**
* 查询结果
*/
const queryResult = ref<QueryCodeResult>();
const activeCollapse = ref(["baseInfo"]);
/**列表值 */
const rowInfo = reactive<QueryResult>({
query_text: "",
status: 0,
id: "",
result_text: []
});
/**抽屉状态 */
const drawerStatus = ref<boolean>(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);
// 创建 <a> 元素并触发下载
const link = document.createElement("a");
link.href = url;
link.download = "上传模版.xlsx"; // 设置下载文件名,确保后缀名正确
document.body.appendChild(link); // 将 <a> 元素添加到 DOM 中
link.click(); // 模拟点击下载
// 清理 URL 对象
URL.revokeObjectURL(url);
document.body.removeChild(link); // 移除 <a> 元素
} 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
};
};