up.
This commit is contained in:
parent
e60702340b
commit
9c2e5a7b0b
@ -58,7 +58,7 @@ class MenuController extends BaseController
|
|||||||
'path' => $data['path'],
|
'path' => $data['path'],
|
||||||
'component' => $data['component'],
|
'component' => $data['component'],
|
||||||
'authority' => $data['authority'],
|
'authority' => $data['authority'],
|
||||||
'sortNumber' => $data['sortNumber'],
|
'sort_number' => $data['sortNumber'],
|
||||||
'hide' => $data['hide'],
|
'hide' => $data['hide'],
|
||||||
'meta' => $data['meta'],
|
'meta' => $data['meta'],
|
||||||
]);
|
]);
|
||||||
|
|||||||
@ -5,7 +5,6 @@ namespace app\controller\admin\system;
|
|||||||
use app\BaseController;
|
use app\BaseController;
|
||||||
use app\entity\SysRequestRecord;
|
use app\entity\SysRequestRecord;
|
||||||
use app\service\CurdService;
|
use app\service\CurdService;
|
||||||
use think\db\exception\DbException;
|
|
||||||
use think\response\Json;
|
use think\response\Json;
|
||||||
|
|
||||||
class RequestRecordController extends BaseController
|
class RequestRecordController extends BaseController
|
||||||
@ -13,19 +12,32 @@ class RequestRecordController extends BaseController
|
|||||||
/**
|
/**
|
||||||
* 分页查询请求日志记录
|
* 分页查询请求日志记录
|
||||||
* @return Json
|
* @return Json
|
||||||
* @throws DbException
|
|
||||||
*/
|
*/
|
||||||
public function page(): Json
|
public function page(): Json
|
||||||
{
|
{
|
||||||
$model = SysRequestRecord::withSearch(['createTime'], [
|
ini_set('memory_limit', '512M');
|
||||||
'createTime' => [
|
try {
|
||||||
$this->request->get('createTimeStart/s', ''),
|
/*
|
||||||
$this->request->get('createTimeEnd/s', '')
|
* 这里有两个字段数据太大,提到详情里面做查询
|
||||||
],
|
*/
|
||||||
]);
|
$model = SysRequestRecord::withoutField('request_headers,response_data')->withSearch(['createTime'], [
|
||||||
|
'createTime' => [
|
||||||
$paginate = CurdService::getPaginate($this->request, $model);
|
$this->request->get('createTimeStart/s', ''),
|
||||||
|
$this->request->get('createTimeEnd/s', '')
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
$paginate = CurdService::getPaginate($this->request, $model);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return $this->writeError($e->getMessage());
|
||||||
|
}
|
||||||
return $this->writeSuccess('ok', $paginate);
|
return $this->writeSuccess('ok', $paginate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function info(): Json
|
||||||
|
{
|
||||||
|
ini_set('memory_limit', '512M');
|
||||||
|
$id = $this->request->get('id');
|
||||||
|
$data = SysRequestRecord::find($id);
|
||||||
|
return $this->writeSuccess('ok', $data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -25,6 +25,10 @@ class ContextMiddleware extends middleware
|
|||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected $noHttpLog = [
|
||||||
|
'GET@/adminapi/system/request-record'
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 结束
|
* 结束
|
||||||
* @param Response $response
|
* @param Response $response
|
||||||
@ -36,8 +40,8 @@ class ContextMiddleware extends middleware
|
|||||||
$log = (array)$this->app->config->get('admin.httpLog');
|
$log = (array)$this->app->config->get('admin.httpLog');
|
||||||
|
|
||||||
$logOpen = $log['open'] ?? false;
|
$logOpen = $log['open'] ?? false;
|
||||||
|
$logOpen = false;
|
||||||
if (!$logOpen) {
|
if (!$logOpen || in_array($request->method() . '@' . $request->pathinfo(),$this->noHttpLog)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$request_start_time = $request->time(true);
|
$request_start_time = $request->time(true);
|
||||||
|
|||||||
@ -55,6 +55,7 @@ Route::group("adminapi", function () {
|
|||||||
Route::get('login-record/page', [LoginRecordController::class, "page"])->name("system.pageLoginRecords");
|
Route::get('login-record/page', [LoginRecordController::class, "page"])->name("system.pageLoginRecords");
|
||||||
Route::get('operate-record/page', [OperateRecordController::class, "page"])->name("system.pageOperateRecords");
|
Route::get('operate-record/page', [OperateRecordController::class, "page"])->name("system.pageOperateRecords");
|
||||||
Route::get('request-record/page', [RequestRecordController::class, "page"])->name("system.pageRequestRecords");
|
Route::get('request-record/page', [RequestRecordController::class, "page"])->name("system.pageRequestRecords");
|
||||||
|
Route::get('request-record/info', [RequestRecordController::class, "info"])->name("system.pageRequestInfo");
|
||||||
/*
|
/*
|
||||||
* 缓存管理
|
* 缓存管理
|
||||||
*/
|
*/
|
||||||
|
|||||||
30
z_ele/src/api/system/request-record/index.ts
Normal file
30
z_ele/src/api/system/request-record/index.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import request from '@/utils/request';
|
||||||
|
import type { ApiResult, PageResult } from '@/api';
|
||||||
|
import type { RequestRecord, RequestRecordParam } from './model';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询请求日志
|
||||||
|
*/
|
||||||
|
export async function pageRequestRecords(params: RequestRecordParam) {
|
||||||
|
const res = await request.get<ApiResult<PageResult<RequestRecord>>>(
|
||||||
|
'/system/request-record/page',
|
||||||
|
{ params }
|
||||||
|
);
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
return res.data.data;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.data.message));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 获取请求日志详情
|
||||||
|
*/
|
||||||
|
export async function getRequestRecordInfo(id: number) {
|
||||||
|
const res = await request.get<ApiResult<RequestRecord>>(
|
||||||
|
'/system/request-record/info?id=' + id
|
||||||
|
);
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
return res.data.data;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.data.message));
|
||||||
|
}
|
||||||
|
|
||||||
57
z_ele/src/api/system/request-record/model/index.ts
Normal file
57
z_ele/src/api/system/request-record/model/index.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import { PageParam } from '@/api';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作日志
|
||||||
|
*/
|
||||||
|
export interface RequestRecord {
|
||||||
|
/** 操作日志id */
|
||||||
|
id?: number;
|
||||||
|
/** 用户id */
|
||||||
|
userId?: number;
|
||||||
|
/** 操作模块 */
|
||||||
|
module: string;
|
||||||
|
/** 操作功能 */
|
||||||
|
description: string;
|
||||||
|
/** 请求地址 */
|
||||||
|
url: string;
|
||||||
|
/** 请求方式 */
|
||||||
|
requestMethod: string;
|
||||||
|
/** 调用方法 */
|
||||||
|
method: string;
|
||||||
|
/** 请求参数 */
|
||||||
|
params: string;
|
||||||
|
/** 返回结果 */
|
||||||
|
result: string;
|
||||||
|
/** 异常信息 */
|
||||||
|
error: string;
|
||||||
|
/** 消耗时间, 单位毫秒 */
|
||||||
|
spendTime: number;
|
||||||
|
/** 操作系统 */
|
||||||
|
os: string;
|
||||||
|
/** 设备名称 */
|
||||||
|
device: string;
|
||||||
|
/** 浏览器类型 */
|
||||||
|
browser: string;
|
||||||
|
/** ip地址 */
|
||||||
|
ip: string;
|
||||||
|
/** 状态, 0成功, 1异常 */
|
||||||
|
status: number;
|
||||||
|
/** 操作时间 */
|
||||||
|
createTime: string;
|
||||||
|
/** 用户昵称 */
|
||||||
|
nickname: string;
|
||||||
|
/** 用户账号 */
|
||||||
|
username: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作日志搜索条件
|
||||||
|
*/
|
||||||
|
export interface RequestRecordParam extends PageParam {
|
||||||
|
/** contextId */
|
||||||
|
contextId?: string;
|
||||||
|
/** 开始时间 */
|
||||||
|
createTimeStart?: string;
|
||||||
|
/** 截至时间 */
|
||||||
|
createTimeEnd?: string;
|
||||||
|
}
|
||||||
@ -219,3 +219,34 @@ export function doWithTransition(
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将字节数转换为易读的存储单位(GB, MB, KB, B)
|
||||||
|
* @param bytes 字节数量
|
||||||
|
* @param precision 可选参数,指定保留的小数位数(默认2位)
|
||||||
|
* @returns 格式化的字符串结果(如 '1.23GB', '500B')
|
||||||
|
*/
|
||||||
|
export function formatBytes(bytes: number, precision: number = 2): string {
|
||||||
|
// 定义单位常量
|
||||||
|
const UNITS = ['B', 'KB', 'MB', 'GB'];
|
||||||
|
const UNIT_SCALE = 1024;
|
||||||
|
|
||||||
|
// 处理无效输入
|
||||||
|
if (isNaN(bytes) || !isFinite(bytes)) return '0B';
|
||||||
|
if (bytes === 0) return '0B';
|
||||||
|
|
||||||
|
// 计算单位级别
|
||||||
|
const level = Math.floor(Math.log(bytes) / Math.log(UNIT_SCALE));
|
||||||
|
|
||||||
|
// 获取转换后的值和对应单位
|
||||||
|
const unit = UNITS[Math.min(level, UNITS.length - 1)];
|
||||||
|
const value = bytes / Math.pow(UNIT_SCALE, level);
|
||||||
|
|
||||||
|
// 智能处理小数部分:
|
||||||
|
// 1. 当结果为整数时省略小数部分
|
||||||
|
// 2. 保留指定精度但去除末尾多余的0
|
||||||
|
const formattedValue = value.toFixed(precision).replace(/(\.0+|0+)$/, '');
|
||||||
|
|
||||||
|
return `${formattedValue}${unit}`;
|
||||||
|
}
|
||||||
|
|||||||
@ -0,0 +1,121 @@
|
|||||||
|
<!-- 详情弹窗 -->
|
||||||
|
<template>
|
||||||
|
<ele-modal title="请求详情" :width="960" v-model="visible">
|
||||||
|
<el-descriptions
|
||||||
|
v-if="data"
|
||||||
|
:border="true"
|
||||||
|
:column="mobile ? 1 : 2"
|
||||||
|
class="detail-table"
|
||||||
|
>
|
||||||
|
<el-descriptions-item label="ContextId">
|
||||||
|
<div>{{ data.contextId }}</div>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="IP地址">
|
||||||
|
<div>{{ data.requestIp }}</div>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="请求时间">
|
||||||
|
<div>{{ data.requestTime }}<span style="color:#9e9e9e;"> - {{ data.requestEndTime }}</span></div>
|
||||||
|
</el-descriptions-item>
|
||||||
|
|
||||||
|
<el-descriptions-item label="接口耗时">
|
||||||
|
<div v-if="!isNaN(data.runningTime)">{{ data.runningTime / 1000 }}s</div>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="请求方式">
|
||||||
|
<div>{{ data.requestMethod }}</div>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="状态码">
|
||||||
|
<el-tag
|
||||||
|
size="small"
|
||||||
|
:type="data.responseCode === 200 ? 'success' : 'danger'"
|
||||||
|
:disable-transitions="true"
|
||||||
|
>
|
||||||
|
{{ data.responseCode }}
|
||||||
|
</el-tag>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="请求地址" :span="2">
|
||||||
|
<div style="word-break: break-all">{{ data.requestDomain }}{{ data.requestPath }}</div>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="规则名称" :span="2">
|
||||||
|
<div style="word-break: break-all">{{ data.ruleName }}</div>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="路由地址" :span="2">
|
||||||
|
<div style="word-break: break-all">{{ data.ruleRoute }}</div>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="请求头信息" :span="2">
|
||||||
|
<ele-ellipsis :max-line="4" :tooltip="ellipsisTooltipProps">
|
||||||
|
{{ data.requestHeaders }}
|
||||||
|
</ele-ellipsis>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="请求参数" :span="2">
|
||||||
|
<ele-ellipsis :max-line="4" :tooltip="ellipsisTooltipProps">
|
||||||
|
{{ data.requestBody }}
|
||||||
|
</ele-ellipsis>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="返回类型" :span="1">
|
||||||
|
<ele-ellipsis :max-line="4" :tooltip="ellipsisTooltipProps">
|
||||||
|
{{ data.responseType }}
|
||||||
|
</ele-ellipsis>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="运行消耗" :span="1">
|
||||||
|
<ele-ellipsis :max-line="4" :tooltip="ellipsisTooltipProps">
|
||||||
|
{{ formatBytes(data.runningMemoryUsage) }} / {{ data.runningMemoryLimit }}
|
||||||
|
</ele-ellipsis>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="返回结果" :span="2">
|
||||||
|
<ele-ellipsis :max-line="4" :tooltip="ellipsisTooltipProps">
|
||||||
|
{{ data.responseData }}
|
||||||
|
</ele-ellipsis>
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</ele-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { reactive } from 'vue';
|
||||||
|
import type { EleTooltipProps } from 'ele-admin-plus/es/ele-app/plus';
|
||||||
|
import type { OperationRecord } from '@/api/system/operation-record/model';
|
||||||
|
import { useMobile } from '@/utils/use-mobile';
|
||||||
|
import {formatBytes} from "@/utils/common";
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
/** 修改回显的数据 */
|
||||||
|
data: OperationRecord;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
/** 弹窗是否打开 */
|
||||||
|
const visible = defineModel({ type: Boolean });
|
||||||
|
|
||||||
|
/** 文字省略组件的提示组件的属性 */
|
||||||
|
const ellipsisTooltipProps = reactive<EleTooltipProps>({
|
||||||
|
popperStyle: {
|
||||||
|
width: '580px',
|
||||||
|
maxWidth: '90%',
|
||||||
|
wordBreak: 'break-all'
|
||||||
|
},
|
||||||
|
bodyStyle: {
|
||||||
|
maxWidth: 'calc(100vw - 32px)',
|
||||||
|
maxHeight: '252px',
|
||||||
|
overflowY: 'auto',
|
||||||
|
'--ele-scrollbar-color': '#5e5e5e',
|
||||||
|
'--ele-scrollbar-hover-color': '#707070',
|
||||||
|
'--ele-scrollbar-size': '8px'
|
||||||
|
},
|
||||||
|
offset: 4,
|
||||||
|
placement: 'top'
|
||||||
|
});
|
||||||
|
|
||||||
|
/** 是否是移动端 */
|
||||||
|
const { mobile } = useMobile();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.detail-table :deep(td.el-descriptions__label.el-descriptions__cell) {
|
||||||
|
width: 88px;
|
||||||
|
text-align: right;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-table :deep(.el-descriptions__content > div) {
|
||||||
|
max-height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,65 @@
|
|||||||
|
<!-- 搜索表单 -->
|
||||||
|
<template>
|
||||||
|
<ele-card :body-style="{ paddingBottom: '2px' }">
|
||||||
|
<el-form label-width="72px" @keyup.enter="search" @submit.prevent="">
|
||||||
|
<el-row :gutter="8">
|
||||||
|
<el-col :lg="6" :md="18" :sm="17" :xs="24">
|
||||||
|
<el-form-item label="上下文ID">
|
||||||
|
<el-input v-model="form.contextId" maxlength="32" placeholder=""></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="请求时间">
|
||||||
|
<el-date-picker
|
||||||
|
unlink-panels
|
||||||
|
type="datetimerange"
|
||||||
|
v-model="dateRange"
|
||||||
|
range-separator="-"
|
||||||
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
start-placeholder="开始时间"
|
||||||
|
end-placeholder="结束时间"
|
||||||
|
class="ele-fluid"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :lg="4" :md="6" :sm="7" :xs="24">
|
||||||
|
<el-form-item label-width="6px">
|
||||||
|
<div style="white-space: nowrap">
|
||||||
|
<el-button type="primary" @click="search">查询</el-button>
|
||||||
|
<el-button @click="reset">重置</el-button>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
</ele-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { useFormData } from '@/utils/use-form-data';
|
||||||
|
import type { RequestRecordParam } from '@/api/system/request-record/model';
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'search', where?: RequestRecordParam): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
/** 表单数据 */
|
||||||
|
const [form, resetFields] = useFormData<RequestRecordParam>({
|
||||||
|
contextId: ""
|
||||||
|
});
|
||||||
|
|
||||||
|
/** 日期范围 */
|
||||||
|
const dateRange = ref<[string, string]>(['', '']);
|
||||||
|
|
||||||
|
/** 搜索 */
|
||||||
|
const search = () => {
|
||||||
|
const [createTimeStart, createTimeEnd] = dateRange.value || [];
|
||||||
|
emit('search', { ...form, createTimeStart, createTimeEnd });
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 重置 */
|
||||||
|
const reset = () => {
|
||||||
|
resetFields();
|
||||||
|
dateRange.value = ['', ''];
|
||||||
|
search();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
199
z_ele/src/views/system/request-record/index.vue
Normal file
199
z_ele/src/views/system/request-record/index.vue
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
<template>
|
||||||
|
<ele-page>
|
||||||
|
<request-record-search @search="reload" />
|
||||||
|
<ele-card :body-style="{ paddingTop: '8px' }">
|
||||||
|
<ele-pro-table
|
||||||
|
ref="tableRef"
|
||||||
|
row-key="id"
|
||||||
|
:columns="columns"
|
||||||
|
:datasource="datasource"
|
||||||
|
:show-overflow-tooltip="true"
|
||||||
|
:highlight-current-row="true"
|
||||||
|
:export-config="{ fileName: '请求日志数据' }"
|
||||||
|
cache-key="systemOperationRecordTable"
|
||||||
|
>
|
||||||
|
|
||||||
|
<template #requestPath="{ row }">
|
||||||
|
<el-tag size="small">{{ row.requestMethod }}</el-tag>
|
||||||
|
<span style="margin-left: 10px;">{{ row.requestPath }}</span>
|
||||||
|
</template>
|
||||||
|
<template #responseCode="{ row }">
|
||||||
|
<el-tag
|
||||||
|
size="small"
|
||||||
|
:type="row.responseCode === 200 ? 'success' : 'danger'"
|
||||||
|
:disable-transitions="true"
|
||||||
|
>
|
||||||
|
{{ row.responseCode }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
<template #action="{ row }">
|
||||||
|
<el-link type="primary" underline="never" @click="openDetail(row)">
|
||||||
|
详情
|
||||||
|
</el-link>
|
||||||
|
</template>
|
||||||
|
</ele-pro-table>
|
||||||
|
</ele-card>
|
||||||
|
<!-- 详情弹窗 -->
|
||||||
|
<request-record-detail v-model="showInfo" :data="current" />
|
||||||
|
</ele-page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import type { EleProTable } from 'ele-admin-plus';
|
||||||
|
import type {
|
||||||
|
DatasourceFunction,
|
||||||
|
Columns
|
||||||
|
} from 'ele-admin-plus/es/ele-pro-table/types';
|
||||||
|
import RequestRecordSearch from './components/request-record-search.vue';
|
||||||
|
import RequestRecordDetail from './components/request-record-detail.vue';
|
||||||
|
import {
|
||||||
|
getRequestRecordInfo,
|
||||||
|
pageRequestRecords
|
||||||
|
} from '@/api/system/request-record';
|
||||||
|
import type {
|
||||||
|
RequestRecord,
|
||||||
|
RequestRecordParam
|
||||||
|
} from '@/api/system/request-record/model';
|
||||||
|
import {formatBytes} from "@/utils/common";
|
||||||
|
|
||||||
|
defineOptions({ name: 'SystemRequestRecord' });
|
||||||
|
|
||||||
|
/** 表格实例 */
|
||||||
|
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
|
||||||
|
|
||||||
|
/** 表格列配置 */
|
||||||
|
const columns = ref<Columns>([
|
||||||
|
{
|
||||||
|
type: 'index',
|
||||||
|
columnKey: 'index',
|
||||||
|
width: 50,
|
||||||
|
align: 'center' /* ,
|
||||||
|
fixed: 'left' */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'contextId',
|
||||||
|
label: 'ContextId',
|
||||||
|
width: 280
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'requestPath',
|
||||||
|
label: 'Request',
|
||||||
|
slot: 'requestPath',
|
||||||
|
minWidth: 220
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'ruleName',
|
||||||
|
label: '规则名称',
|
||||||
|
minWidth: 110
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'ruleRoute',
|
||||||
|
label: '路由地址',
|
||||||
|
minWidth: 210
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'responseCode',
|
||||||
|
label: '状态码',
|
||||||
|
width: 100,
|
||||||
|
align: 'center',
|
||||||
|
slot: 'responseCode',
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
text: '正常',
|
||||||
|
value: '1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '异常',
|
||||||
|
value: '2'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
filterMultiple: false,
|
||||||
|
formatter: (row) => (row.responseCode == 200 ? '正常' : '异常')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'runningTime',
|
||||||
|
label: '耗时',
|
||||||
|
sortable: 'custom',
|
||||||
|
width: 100,
|
||||||
|
formatter: (row) => `${row.runningTime / 1000}s`,
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'runningMemoryUsage',
|
||||||
|
label: '内存消耗',
|
||||||
|
width: 110,
|
||||||
|
sortable: 'custom',
|
||||||
|
align: 'center',
|
||||||
|
formatter: (row) => formatBytes(row.runningMemoryUsage),
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'requestTime',
|
||||||
|
label: '请求时间',
|
||||||
|
align: 'center',
|
||||||
|
width: 180
|
||||||
|
},
|
||||||
|
{
|
||||||
|
columnKey: 'action',
|
||||||
|
label: '操作',
|
||||||
|
width: 90,
|
||||||
|
align: 'center',
|
||||||
|
slot: 'action' /* ,
|
||||||
|
fixed: 'right' */,
|
||||||
|
hideInPrint: true,
|
||||||
|
hideInExport: true
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
/** 当前选中数据 */
|
||||||
|
const current = ref<RequestRecord>({
|
||||||
|
module: '',
|
||||||
|
description: '',
|
||||||
|
url: '',
|
||||||
|
requestMethod: '',
|
||||||
|
method: '',
|
||||||
|
params: '',
|
||||||
|
result: '',
|
||||||
|
error: '',
|
||||||
|
spendTime: 0,
|
||||||
|
os: '',
|
||||||
|
device: '',
|
||||||
|
browser: '',
|
||||||
|
ip: '',
|
||||||
|
status: 0,
|
||||||
|
createTime: '',
|
||||||
|
nickname: '',
|
||||||
|
username: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
/** 是否显示查看弹窗 */
|
||||||
|
const showInfo = ref(false);
|
||||||
|
|
||||||
|
/** 表格数据源 */
|
||||||
|
const datasource: DatasourceFunction = ({
|
||||||
|
pages,
|
||||||
|
where,
|
||||||
|
orders,
|
||||||
|
filters
|
||||||
|
}) => {
|
||||||
|
return pageRequestRecords({
|
||||||
|
...where,
|
||||||
|
...orders,
|
||||||
|
...filters,
|
||||||
|
...pages
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 刷新表格 */
|
||||||
|
const reload = (where?: RequestRecordParam) => {
|
||||||
|
tableRef.value?.reload?.({ page: 1, where });
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 详情 */
|
||||||
|
const openDetail = async (row: RequestRecord) => {
|
||||||
|
current.value = await getRequestRecordInfo(row.id);
|
||||||
|
showInfo.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
</script>
|
||||||
Loading…
Reference in New Issue
Block a user