461 lines
12 KiB
TypeScript
461 lines
12 KiB
TypeScript
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
|
||
};
|
||
};
|