Files
xk-admin/apps/web-antd/src/views/log/api-log-history/components/modal.vue

155 lines
4.9 KiB
Vue
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.
<script lang="ts" setup>
/**
* Api 访问历史日志详情弹窗
* 列表不带大 JSON,打开时按历史表 id 再拉详情;操作人只用 xk_admin / 患者,不兼容 oldadmin
*/
import { ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { Descriptions, Spin } from 'ant-design-vue';
import { Icon } from '#/components/icon';
import { getIcon } from '#/util/tool';
import {
getApiOpLogOperatorLabel,
getApiOpLogPlatformLabel,
} from '../../api-log/config/platform';
import { getApiOpLogHistoryDetail } from '../api';
const gridApi = ref();
const data = ref<Record<string, any>>({});
const loading = ref(false);
/** 列表行没有 param/result,打开时按 id 拉详情;解析失败则原样展示 */
function formatJson(raw: unknown) {
if (raw == null || raw === '') return '';
if (typeof raw === 'object') return raw;
try {
return JSON.parse(String(raw));
} catch {
return raw;
}
}
const [Modal, modalApi] = useVbenModal({
fullscreenButton: false,
draggable: true,
onCancel() {
modalApi.close();
},
onConfirm: async () => {
modalApi.close();
},
async onOpenChange(isOpen: boolean) {
gridApi.value = isOpen ? modalApi.getData()?.gridApi : null;
if (!isOpen) return;
const { values } = modalApi.getData<Record<string, any>>();
data.value = values || {};
const id = Number(values?.id || 0);
if (!id) return;
loading.value = true;
try {
data.value = (await getApiOpLogHistoryDetail(id)) || values || {};
} catch (error) {
console.error(error);
} finally {
loading.value = false;
}
},
});
</script>
<template>
<Modal class="w-[80%] h-[80%]" title="Api访问历史日志详情">
<Spin :spinning="loading">
<div class="flex flex-col gap-4">
<Descriptions
:column="{ xxl: 2, xl: 2, lg: 2, md: 2, sm: 2, xs: 2 }"
bordered
>
<Descriptions.Item label="ID">{{ data.id }}</Descriptions.Item>
<Descriptions.Item label="接口名称">
{{ data.url_title || '-' }}
</Descriptions.Item>
<Descriptions.Item label="接口说明">
{{ data.url_description || '-' }}
</Descriptions.Item>
<Descriptions.Item label="是否鉴权">
<span v-if="data.url_need_auth === 1">需要鉴权</span>
<span v-else-if="data.url_need_auth === 0">无需鉴权</span>
<span v-else>-</span>
</Descriptions.Item>
<Descriptions.Item label="操作人员">
<span>{{ getApiOpLogOperatorLabel(data) }}</span>
</Descriptions.Item>
<Descriptions.Item label="URL">{{ data.url }}</Descriptions.Item>
<Descriptions.Item label="请求方式">
<span v-if="data.method === 1">GET</span>
<span v-else-if="data.method === 2">POST</span>
<span v-else>未知</span>
</Descriptions.Item>
<Descriptions.Item label="控制器">
{{ data.controller }}
</Descriptions.Item>
<Descriptions.Item label="IP">
IP地址:{{ data.ip }}
<p>归属地:{{ data.ip_address }}</p>
</Descriptions.Item>
<Descriptions.Item label="类型">
{{ data.type === 0 ? '访问成功' : '访问失败' }}
</Descriptions.Item>
<Descriptions.Item label="返回结果代码">
{{ data.result_code }}
</Descriptions.Item>
<Descriptions.Item label="接口来源">
<span>{{ getApiOpLogPlatformLabel(data.platform_type) }}</span>
</Descriptions.Item>
<Descriptions.Item label="设备">
<Icon :icon="getIcon(data.equipment)" :size="20" />
{{ data.equipment }}
</Descriptions.Item>
<Descriptions.Item label="浏览器">
<Icon :icon="getIcon(data.browser)" :size="20" />
{{ data.browser }}
</Descriptions.Item>
<Descriptions.Item label="所属平台">
{{ data.platform?.name || '未绑定' }}
</Descriptions.Item>
<Descriptions.Item label="访问时间">
{{ data.created_at }}
</Descriptions.Item>
<Descriptions.Item label="归档时间">
{{ data.archived_at }}
</Descriptions.Item>
</Descriptions>
<Descriptions
:column="{ xxl: 1, xl: 1, lg: 1, md: 1, sm: 1, xs: 1 }"
bordered
>
<Descriptions.Item label="参数">
<pre>{{ formatJson(data.param) }}</pre>
</Descriptions.Item>
<Descriptions.Item label="结果">
<pre>{{ formatJson(data.result) }}</pre>
</Descriptions.Item>
</Descriptions>
</div>
</Spin>
</Modal>
</template>
<style scoped>
.ant-descriptions-item-label {
font-weight: bold;
}
pre {
padding: 8px;
overflow-x: auto;
white-space: pre-wrap;
border-radius: 4px;
}
</style>