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"
|
|
|
|
|
},
|
2025-02-19 01:45:55 +08:00
|
|
|
|
{
|
|
|
|
|
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);
|
2025-02-19 01:45:55 +08:00
|
|
|
|
}
|
|
|
|
|
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>
|