391 lines
12 KiB
Vue
Raw Normal View History

2025-02-17 16:26:57 +08:00
<template>
<div class="main">
<el-card v-if="queryInfo" shadow="never" class="mt-2">
<el-descriptions title="查询基本信息" border :column="4">
<el-descriptions-item align="center" label="操作时间">{{
dayjs(queryInfo.operation_time).format("YYYY-MM-DD HH:mm:ss")
}}</el-descriptions-item>
<el-descriptions-item align="center" label="耗时"
>{{ queryInfo.cost_time.toFixed(2) }} ms</el-descriptions-item
>
<el-descriptions-item align="center" label="查询统计">{{
queryInfo.query_count
}}</el-descriptions-item>
<el-descriptions-item align="center" label="结果统计">{{
queryInfo.result_count
}}</el-descriptions-item>
</el-descriptions>
</el-card>
<PureTableBar title="查询结果" :columns="columns">
<template #buttons>
2025-02-18 02:03:59 +08:00
<el-button
type="primary"
:icon="useRenderIcon(Export)"
@click="exportToExcel([queryInfo], '查询结果')"
>
{{ t("buttons:ExportAll") }}
2025-02-17 16:26:57 +08:00
</el-button>
</template>
<template v-slot="{ size, dynamicColumns }">
<div
v-if="selectedNum > 0"
v-motion-fade
class="bg-[var(--el-fill-color-light)] w-full h-[46px] mb-2 pl-4 flex items-center"
>
<div class="flex-auto">
<span
style="font-size: var(--el-font-size-base)"
class="text-[rgba(42,46,54,0.5)] dark:text-[rgba(220,220,242,0.5)]"
>
已选 {{ selectedNum }}
</span>
<el-button type="primary" text @click="onSelectionCancel">
{{ t("buttons:Deselect") }}
</el-button>
</div>
2025-02-18 02:03:59 +08:00
<el-popconfirm title="是否确认导出?" @confirm="onbatchExport">
2025-02-17 16:26:57 +08:00
<template #reference>
2025-02-18 02:03:59 +08:00
<el-button type="primary" text class="mr-1">
{{ t("buttons:ExportInBatches") }}
2025-02-17 16:26:57 +08:00
</el-button>
</template>
</el-popconfirm>
</div>
<pure-table
ref="tableRef"
row-key="id"
adaptive
border
stripe
:adaptiveConfig="{ offsetBottom: 45 }"
align-whole="center"
table-layout="auto"
:loading="loading"
:data="dataList"
:columns="dynamicColumns"
:pagination="pagination"
:paginationSmall="size === 'small' ? true : false"
:header-cell-style="{
background: 'var(--el-fill-color-light)',
color: 'var(--el-text-color-primary)'
}"
@selection-change="handleSelectionChange"
>
<template #operation="{ row }">
<el-button
class="reset-margin"
link
type="primary"
:size="size"
:icon="useRenderIcon(EditPen)"
@click="handleDetail(row)"
>
{{ t("buttons:Details") }}
</el-button>
</template>
</pure-table>
</template>
</PureTableBar>
<el-drawer v-model="drawerStatus" title="查询详情" :size="`50%`" show-close>
<el-collapse v-model="activeCollapse" :accordion="false">
<!-- 基本信息 -->
<el-collapse-item title="基本信息" name="baseInfo">
<el-descriptions border>
<el-descriptions-item align="center" label="查询文本">{{
rowInfo.query_text
}}</el-descriptions-item>
</el-descriptions>
</el-collapse-item>
<!-- 查询结果 -->
<el-collapse-item
v-for="(item, index) in rowInfo.result_text"
:key="item.id"
:title="`匹配结果${index + 1}`"
:name="`result${index + 1}`"
>
<el-descriptions border :column="1">
<el-descriptions-item align="center" label="编码ID">{{
item.id
}}</el-descriptions-item>
<el-descriptions-item align="center" label="海关编码">{{
2025-02-19 02:25:44 +08:00
item.code.replace(/(\d{2})/g, "$1.").slice(0, -1)
2025-02-17 16:26:57 +08:00
}}</el-descriptions-item>
<el-descriptions-item align="center" label="编码描述">{{
item.description
}}</el-descriptions-item>
<el-descriptions-item align="center" label="匹配率">{{
item.match_rate ? `${item.match_rate}%` : "0%"
}}</el-descriptions-item>
</el-descriptions>
</el-collapse-item>
</el-collapse>
</el-drawer>
</div>
</template>
<script setup lang="ts">
defineOptions({
name: "QueryCodedetails"
});
import { ref, reactive, onMounted, h } from "vue";
import { useRouter, useRoute } from "vue-router";
import dayjs from "dayjs";
import { useI18n } from "vue-i18n";
2025-02-18 02:03:59 +08:00
import * as XLSX from "xlsx";
import { cloneDeep, getKeyList, isEmpty, isString } from "@pureadmin/utils";
2025-02-17 16:26:57 +08:00
import { PureTableBar } from "@/components/RePureTableBar";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import EditPen from "@iconify-icons/ep/edit-pen";
2025-02-18 02:03:59 +08:00
import Export from "@iconify-icons/ri/download-2-line";
2025-02-17 16:26:57 +08:00
import type {
QueryCodeLogInfo,
QueryResult,
QueryResultItem
} from "types/code";
import { getCodeLogInfoAPI } from "@/api/code";
import { PaginationProps } from "@pureadmin/table";
2025-02-18 02:03:59 +08:00
import { message } from "@/utils/message";
2025-02-17 16:26:57 +08:00
const { t } = useI18n();
const route = useRoute();
const router = useRouter();
const getParameter = isEmpty(route.params) ? route.query : route.params;
console.log(getParameter);
// /**初始化加载页面 */
// function init() {
// Object.keys(getParameter).forEach(param => {
// if (!isString(getParameter[param])) {
// getParameter[param] = getParameter[param].toString();
// } else {
// getParameter["detailsId"] = "";
// }
// });
// useMultiTagsStoreHook().handleTags("push", {
// path: "/code/log/details/:detailsId",
// name: "QueryCodedetails",
// params: getParameter,
// meta: {
// title: $t("menus:QueryCodedetails")
// },
// dynamicLevel: 1
// });
// router.push({
// name: "QueryCodedetails",
// params: getParameter
// });
// }
// init();
const activeCollapse = ref(["baseInfo"]);
/**
* 查询结果
*/
const queryInfo = ref<QueryCodeLogInfo>();
/**
* 数据列表
*/
const dataList = ref<QueryResult[]>([]);
const tableRef = ref();
/**抽屉状态 */
const drawerStatus = ref<boolean>(false);
const loading = ref(true);
const selectedNum = ref(0);
const pagination = reactive<PaginationProps>({
total: 0,
pageSize: 10,
currentPage: 1,
background: true,
pageSizes: [10, 20, 30, 40, 50]
});
/**列表值 */
const rowInfo = reactive<QueryResult>({
query_text: "",
status: 0,
id: "",
result_text: []
});
/**
* 表格列设置
*/
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) {
2025-02-19 02:25:44 +08:00
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 "";
}
},
2025-02-17 16:26:57 +08:00
{
label: "操作",
fixed: "right",
width: 250,
slot: "operation"
}
];
/**获取查询结果 */
const getQueryInfo = async () => {
const res = await getCodeLogInfoAPI(getParameter.detailsId as string);
if (res.success) {
queryInfo.value = res.data;
dataList.value = JSON.parse(
res.data.response_result.replace(/'/g, '"').replace(/None/g, "null")
);
loading.value = false;
}
};
const handleDetail = (row: QueryResultItem) => {
drawerStatus.value = true;
Object.assign(rowInfo, row);
};
/** 当CheckBox选择项发生变化时会触发该事件 */
const handleSelectionChange = async (val: any) => {
selectedNum.value = val.length;
// 重置表格高度
tableRef.value.setAdaptive();
};
/** 取消选择 */
const onSelectionCancel = async () => {
selectedNum.value = 0;
// 用于多选表格,清空用户的选择
tableRef.value.getTableRef().clearSelection();
};
2025-02-18 02:03:59 +08:00
/**导出为excel */
const exportToExcel = (dataList: QueryCodeLogInfo[], filename: string) => {
if (dataList.length) {
const headers = [
"序号",
"查询批次ID",
"查询人ID",
"查询人账号",
"查询人昵称",
"查询人部门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 opeartion_id = jsonData.operator_id;
const opeartion_name = jsonData.operator_name;
const opeartion_nickname = jsonData.operator_nickname;
const department_id = jsonData.department_id;
const department_name = jsonData.department_name;
const queryText = jsonData.request_params;
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 = JSON.parse(
jsonData.response_result.replace(/'/g, '"').replace(/None/g, "null")
);
// @ts-ignore
jsonData.response_result.forEach(response => {
const queryId = response.id;
const queryTextDetail = response.query_text;
const queryStatus = response.status === 1 ? "成功" : "失败";
const row = [
index++,
batchId,
opeartion_id,
opeartion_name,
opeartion_nickname,
department_id,
department_name,
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(queryInfo.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], "查询结果");
};
2025-02-17 16:26:57 +08:00
onMounted(async () => {
await getQueryInfo();
});
</script>