136 lines
6.2 KiB
Vue
136 lines
6.2 KiB
Vue
<template>
|
||
<div class="ai-access-log-page">
|
||
<el-card class="!border-none" shadow="never">
|
||
<el-form :inline="true">
|
||
<el-form-item label="时间">
|
||
<el-date-picker
|
||
v-model="timeRange"
|
||
type="datetimerange"
|
||
range-separator="至"
|
||
start-placeholder="开始时间"
|
||
end-placeholder="结束时间"
|
||
value-format="YYYY-MM-DD HH:mm:ss"
|
||
clearable
|
||
@change="resetPage"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="结果">
|
||
<el-select v-model="queryParams.status" clearable placeholder="全部" class="w-[120px]" @change="resetPage">
|
||
<el-option v-for="(label, value) in STATUS" :key="value" :label="label" :value="value" />
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="数据资源">
|
||
<el-input v-model="queryParams.resource" placeholder="如 tcm.diagnosis" clearable class="w-[180px]" @keyup.enter="resetPage" @clear="resetPage" />
|
||
</el-form-item>
|
||
<el-form-item label="记录ID">
|
||
<el-input v-model="queryParams.record_id" placeholder="如诊单ID" clearable class="w-[130px]" @keyup.enter="resetPage" @clear="resetPage" />
|
||
</el-form-item>
|
||
<el-form-item label="任务号">
|
||
<el-input v-model="queryParams.client_task_id" placeholder="行知任务号" clearable class="w-[200px]" @keyup.enter="resetPage" @clear="resetPage" />
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button type="primary" @click="resetPage">查询</el-button>
|
||
<el-button @click="handleReset">重置</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
<div class="page-hint">
|
||
记录每一次 AI 查询:谁、通过哪个客户端任务、查了哪个数据资源、返回了哪些记录。按“记录ID”可以查某个诊单被哪些账号通过 AI 看过。
|
||
</div>
|
||
</el-card>
|
||
|
||
<el-card class="!border-none mt-3" shadow="never">
|
||
<el-table :data="pager.lists" v-loading="pager.loading" size="default" stripe>
|
||
<el-table-column label="时间" width="165" prop="create_time_text" />
|
||
<el-table-column label="账号" min-width="120">
|
||
<template #default="{ row }">
|
||
<div>{{ row.admin_name || (row.admin_id ? '#' + row.admin_id : '—') }}</div>
|
||
<div class="cell-sub">{{ row.ip }}</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="工具" width="170" prop="tool" />
|
||
<el-table-column label="数据资源" min-width="200">
|
||
<template #default="{ row }">
|
||
<div>{{ row.resource_name || row.resource || '—' }}</div>
|
||
<div class="cell-sub">{{ row.resource }}</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="结果" width="90" align="center">
|
||
<template #default="{ row }">
|
||
<el-tag :type="row.status === 'ok' ? 'success' : 'warning'" size="small">{{ STATUS[row.status] || row.status }}</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="条数" width="70" align="right" prop="result_rows" />
|
||
<el-table-column label="记录ID / 原因" min-width="200">
|
||
<template #default="{ row }">
|
||
<el-tooltip v-if="row.record_ids" :content="row.record_ids" placement="top">
|
||
<span class="ellipsis">{{ row.record_ids }}</span>
|
||
</el-tooltip>
|
||
<span v-else class="cell-sub">{{ row.message }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="参数" min-width="220">
|
||
<template #default="{ row }">
|
||
<el-tooltip v-if="row.arguments" :content="row.arguments" placement="top">
|
||
<span class="ellipsis">{{ row.arguments }}</span>
|
||
</el-tooltip>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="耗时" width="80" align="right">
|
||
<template #default="{ row }">{{ row.duration_ms }}ms</template>
|
||
</el-table-column>
|
||
<el-table-column label="任务号" min-width="160" prop="client_task_id" />
|
||
</el-table>
|
||
<div class="flex justify-end mt-4">
|
||
<pagination v-model="pager" @change="getLists" />
|
||
</div>
|
||
</el-card>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts" name="aiMcpAccessLog">
|
||
import { aiAccessLogLists } from '@/api/ai_mcp'
|
||
import { usePaging } from '@/hooks/usePaging'
|
||
import { onMounted, reactive, ref, watch } from 'vue'
|
||
|
||
const STATUS: Record<string, string> = { ok: '成功', denied: '拒绝', invalid: '参数错误', limited: '超限', error: '失败' }
|
||
const timeRange = ref<[string, string] | null>(null)
|
||
const queryParams = reactive({ start_time: '', end_time: '', status: '', resource: '', record_id: '', client_task_id: '' })
|
||
|
||
watch(timeRange, (val) => {
|
||
queryParams.start_time = val?.[0] ?? ''
|
||
queryParams.end_time = val?.[1] ?? ''
|
||
})
|
||
|
||
const { pager, getLists, resetPage, resetParams } = usePaging({
|
||
fetchFun: aiAccessLogLists,
|
||
params: queryParams
|
||
})
|
||
|
||
const handleReset = () => {
|
||
timeRange.value = null
|
||
resetParams()
|
||
}
|
||
|
||
onMounted(() => getLists())
|
||
</script>
|
||
|
||
<style scoped>
|
||
.page-hint {
|
||
color: var(--el-text-color-secondary);
|
||
font-size: 13px;
|
||
line-height: 1.6;
|
||
}
|
||
.cell-sub {
|
||
color: var(--el-text-color-secondary);
|
||
font-size: 12px;
|
||
}
|
||
.ellipsis {
|
||
display: inline-block;
|
||
max-width: 100%;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
vertical-align: bottom;
|
||
}
|
||
</style>
|