Skip to content

Commit

Permalink
后台操作日志
Browse files Browse the repository at this point in the history
  • Loading branch information
Yurunsoft committed Aug 28, 2023
1 parent a0727ba commit 4f7a3ff
Show file tree
Hide file tree
Showing 12 changed files with 361 additions and 9 deletions.
10 changes: 10 additions & 0 deletions admin/src/router/modules/management.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ const management: AuthRoute.Route = {
requiresAuth: true,
icon: 'ic:round-manage-accounts'
}
},
{
name: 'management_operation_log',
path: '/management/operation/log',
component: 'self',
meta: {
title: '后台操作日志',
requiresAuth: true,
icon: 'ic:round-manage-accounts'
}
}
],
meta: {
Expand Down
2 changes: 0 additions & 2 deletions admin/src/service/api/config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { request } from '../request';

export const ENUM_ALL = { text: '全部', value: 0 };

export async function config() {
return request.get('/config/public');
}
Expand Down
22 changes: 22 additions & 0 deletions admin/src/service/api/management.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,25 @@ export const deleteAdminMember = async (id: number) => {
id
});
};

export const fetchAdminOperationLogList = async (
memberId = 0,
object = '',
status = 0,
beginTime = 0,
endTime = 0,
page = 1,
limit = 15
) => {
return request.get<AdminOperationLog.LogListResponse>('/admin/adminOperationLog/list', {
params: {
memberId,
object,
status,
beginTime,
endTime,
page,
limit
}
});
};
16 changes: 9 additions & 7 deletions admin/src/store/modules/common/enum.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
import { ENUM_ALL, adminEnumValues, enumValues } from '~/src/service/api/config';
import { adminEnumValues, enumValues } from '~/src/service/api/config';

export async function useEnums(names: string[], withAll = false) {
export const ENUM_ALL = { text: '全部', value: 0 };

export async function useEnums(names: string[], withAll = false, allItem: any = ENUM_ALL) {
const { data } = await enumValues(names);
const result: any = (data as any).data;
if (withAll) {
for (const key of Object.keys(result)) {
parseEnumWithAll(result[key]);
parseEnumWithAll(result[key], allItem);
}
}
return result;
}

export async function useAdminEnums(names: string[], withAll = false) {
export async function useAdminEnums(names: string[], withAll = false, allItem: any = ENUM_ALL) {
const { data } = await adminEnumValues(names);
const result: any = (data as any).data;
if (withAll) {
for (const key of Object.keys(result)) {
parseEnumWithAll(result[key]);
parseEnumWithAll(result[key], allItem);
}
}
return result;
}

export function parseEnumWithAll(enums: Array<any>) {
export function parseEnumWithAll(enums: Array<any>, allItem: any = ENUM_ALL) {
const result = enums.map(item => item);
result.unshift(ENUM_ALL);
result.unshift(allItem);
return result;
}
22 changes: 22 additions & 0 deletions admin/src/typings/admin-operation-log.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
declare namespace AdminOperationLog {
interface Log {
id: number;
memberId: number;
object: string;
objectText: string;
status: number;
statusText: string;
message: string;
ip: string;
time: number;
memberInfo: {
recordId: string;
nickname: string;
};
}

type LogListResponse = {
list: Log[];
} & Api.BaseResponse &
Api.PaginationResponse;
}
3 changes: 3 additions & 0 deletions admin/src/typings/page-route.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ declare namespace PageRoute {
| 'management'
| 'management_admin'
| 'management_admin_member'
| 'management_operation'
| 'management_operation_log'
| 'member'
| 'member_list';

Expand Down Expand Up @@ -74,6 +76,7 @@ declare namespace PageRoute {
| 'exception_404'
| 'exception_500'
| 'management_admin_member'
| 'management_operation_log'
| 'member_list'
>;
}
1 change: 1 addition & 0 deletions admin/src/views/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ export const views: Record<
exception_404: () => import('./exception/404/index.vue'),
exception_500: () => import('./exception/500/index.vue'),
management_admin_member: () => import('./management/admin_member/index.vue'),
management_operation_log: () => import('./management/operation_log/index.vue'),
member_list: () => import('./member/list/index.vue')
};
161 changes: 161 additions & 0 deletions admin/src/views/management/operation_log/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
<template>
<div class="overflow-hidden">
<n-card title="后台操作日志" :bordered="false" class="h-full rounded-8px shadow-sm">
<div class="flex-col h-full">
<n-form label-placement="left" :show-feedback="false" class="pb-2.5">
<n-space class="flex flex-row flex-wrap">
<n-form-item label="对象">
<n-select
v-model:value="listParams.object"
class="!w-[140px]"
:options="parseEnumWithAll(enums.AdminOperationLogObject ?? [], { text: '全部', value: '' })"
label-field="text"
value-field="value"
/>
</n-form-item>
<n-form-item label="状态">
<n-select
v-model:value="listParams.status"
class="!w-[140px]"
:options="parseEnumWithAll(enums.AdminOperationLogStatus ?? [])"
label-field="text"
value-field="value"
/>
</n-form-item>
<n-form-item label="时间">
<NDatePicker v-model:value="listParams.timeRange" class="pr-2 flex-1" type="daterange" clearable />
</n-form-item>
<n-form-item>
<n-button attr-type="submit" type="primary" @click="getTableData">
<n-icon :component="SearchSharp" size="20" />
查询
</n-button>
</n-form-item>
</n-space>
</n-form>
<n-data-table
:columns="columns"
:data="tableData"
:loading="loading"
:pagination="pagination"
:row-key="row => row.id"
scroll-x="1200"
flex-height
remote
class="flex-1-hidden"
/>
</div>
</n-card>
</div>
</template>
<script setup lang="tsx">
import { ref } from 'vue';
import type { Ref } from 'vue';
import type { DataTableColumns } from 'naive-ui';
import dayjs from 'dayjs';
import { SearchSharp } from '@vicons/ionicons5';
import { fetchAdminOperationLogList } from '@/service';
import { useLoading } from '@/hooks';
import { defaultPaginationProps } from '~/src/utils';
import { useAdminEnums, parseEnumWithAll } from '~/src/store';
const { loading, startLoading, endLoading } = useLoading(false);
const enums = ref<any>({});
const listParams = ref({
memberId: 0,
object: '',
status: 0,
timeRange: ref<[number, number] | null>(null)
});
const tableData = ref<AdminOperationLog.Log[]>([]);
const pagination = defaultPaginationProps(getTableData);
function setTableData(response: AdminOperationLog.LogListResponse) {
tableData.value = response.list;
pagination.pageCount = response.pageCount;
pagination.itemCount = response.total;
}
async function getTableData() {
startLoading();
try {
const { data } = await fetchAdminOperationLogList(
listParams.value.memberId,
listParams.value.object,
listParams.value.status,
listParams.value.timeRange ? parseInt((listParams.value.timeRange[0] / 1000).toString()) : 0,
listParams.value.timeRange ? parseInt((listParams.value.timeRange[1] / 1000 + 86399).toString()) : 0,
pagination.page,
pagination.pageSize
);
if (data) {
setTableData(data);
}
} finally {
endLoading();
}
}
const columns: Ref<DataTableColumns<AdminOperationLog.Log>> = ref([
{
key: 'id',
title: 'ID',
width: 100
},
{
key: 'member',
title: '用户',
width: 140,
render: row => {
return (
<>
<p>ID:{row.memberId}</p>
<p>昵称:{row.memberInfo.nickname}</p>
</>
);
}
},
{
key: 'objectText',
title: '对象',
width: 120
},
{
key: 'statusText',
title: '状态',
width: 100
},
{
key: 'message',
title: '消息',
width: 300
},
{
key: 'info',
title: '信息',
width: 220,
render: row => {
return (
<>
<p>IP:{row.ip}</p>
<p>时间:{row.time > 0 ? dayjs(row.time).format('YYYY-MM-DD HH:mm:ss.SSS') : ''}</p>
</>
);
}
}
]) as Ref<DataTableColumns<AdminOperationLog.Log>>;
async function init() {
enums.value = await useAdminEnums(['AdminOperationLogObject', 'AdminOperationLogStatus']);
getTableData();
}
// 初始化
init();
</script>
<style scoped></style>
28 changes: 28 additions & 0 deletions server/Module/Admin/ApiController/AdminOperationLogController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace app\Module\Admin\ApiController;

use app\Module\Admin\Annotation\AdminLoginRequired;
use app\Module\Admin\Service\AdminOperationLogService;
use Imi\Aop\Annotation\Inject;
use Imi\Server\Http\Controller\HttpController;
use Imi\Server\Http\Route\Annotation\Action;
use Imi\Server\Http\Route\Annotation\Controller;

#[Controller(prefix: '/admin/adminOperationLog/')]
class AdminOperationLogController extends HttpController
{
#[Inject()]
protected AdminOperationLogService $adminOperationLogService;

#[
Action,
AdminLoginRequired()
]
public function list(int $memberId = 0, string $object = '', int $status = 0, int $beginTime = 0, int $endTime = 0, int $page = 1, int $limit = 15): array
{
return $this->adminOperationLogService->list($memberId, $object, $status, $beginTime, $endTime, $page, $limit);
}
}
28 changes: 28 additions & 0 deletions server/Module/Admin/Enum/OperationLogObject.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace app\Module\Admin\Enum;

use app\Module\Config\Annotation\AdminPublicEnum;
use Imi\Enum\Annotation\EnumItem;
use Imi\Enum\BaseEnum;

#[AdminPublicEnum(name: 'AdminOperationLogObject')]
class OperationLogObject extends BaseEnum
{
#[EnumItem(text: 'AI聊天')]
public const CHAT = 'chat';

#[EnumItem(text: '模型训练项目')]
public const EMBEDDING_PROJECT = 'embeddingProject';

#[EnumItem(text: '模型对话')]
public const EMBEDDING_QA = 'embeddingQA';

#[EnumItem(text: '前台用户')]
public const MEMBER = 'member';

#[EnumItem(text: '后台用户')]
public const ADMIN_MEMBER = 'adminMember';
}
Loading

0 comments on commit 4f7a3ff

Please sign in to comment.