-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
361 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
28
server/Module/Admin/ApiController/AdminOperationLogController.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'; | ||
} |
Oops, something went wrong.