391 lines
12 KiB
Vue
391 lines
12 KiB
Vue
<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>
|
||
<el-button
|
||
type="primary"
|
||
:icon="useRenderIcon(Export)"
|
||
@click="exportToExcel([queryInfo], '查询结果')"
|
||
>
|
||
{{ t("buttons:ExportAll") }}
|
||
</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>
|
||
<el-popconfirm title="是否确认导出?" @confirm="onbatchExport">
|
||
<template #reference>
|
||
<el-button type="primary" text class="mr-1">
|
||
{{ t("buttons:ExportInBatches") }}
|
||
</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="海关编码">{{
|
||
item.code.replace(/(\d{2})/g, "$1.").slice(0, -1)
|
||
}}</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";
|
||
import * as XLSX from "xlsx";
|
||
import { cloneDeep, getKeyList, isEmpty, isString } from "@pureadmin/utils";
|
||
import { PureTableBar } from "@/components/RePureTableBar";
|
||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||
import EditPen from "@iconify-icons/ep/edit-pen";
|
||
import Export from "@iconify-icons/ri/download-2-line";
|
||
import type {
|
||
QueryCodeLogInfo,
|
||
QueryResult,
|
||
QueryResultItem
|
||
} from "types/code";
|
||
import { getCodeLogInfoAPI } from "@/api/code";
|
||
import { PaginationProps } from "@pureadmin/table";
|
||
import { message } from "@/utils/message";
|
||
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) {
|
||
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 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();
|
||
};
|
||
/**导出为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], "查询结果");
|
||
};
|
||
onMounted(async () => {
|
||
await getQueryInfo();
|
||
});
|
||
</script>
|