mirror of
https://github.com/certd/certd.git
synced 2026-07-12 16:27:34 +08:00
chore: audit log first
This commit is contained in:
@@ -19,6 +19,7 @@ import sysauthority from "./certd/sys-authority";
|
||||
import syscname from "./certd/sys-cname";
|
||||
import tutorial from "./certd/tutorial";
|
||||
import cron from "./certd/cron";
|
||||
import audit from "./certd/audit";
|
||||
|
||||
// Note: @ is reserved in locale messages; use {'@'} when needed.
|
||||
export default {
|
||||
@@ -43,4 +44,5 @@ export default {
|
||||
...syscname,
|
||||
...tutorial,
|
||||
...cron,
|
||||
...audit,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
export default {
|
||||
"certd.auditLog": "Audit Log",
|
||||
"certd.sysResources.auditLog": "Audit Log",
|
||||
};
|
||||
@@ -19,6 +19,7 @@ import sysauthority from "./certd/sys-authority";
|
||||
import syscname from "./certd/sys-cname";
|
||||
import tutorial from "./certd/tutorial";
|
||||
import cron from "./certd/cron";
|
||||
import audit from "./certd/audit";
|
||||
|
||||
// Note: @ is reserved in locale messages; use {'@'} when needed.
|
||||
export default {
|
||||
@@ -43,4 +44,5 @@ export default {
|
||||
...syscname,
|
||||
...tutorial,
|
||||
...cron,
|
||||
...audit,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
export default {
|
||||
"certd.auditLog": "操作日志",
|
||||
"certd.sysResources.auditLog": "操作日志",
|
||||
};
|
||||
@@ -287,6 +287,17 @@ export const certdResources = [
|
||||
isMenu: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "certd.auditLog",
|
||||
name: "AuditLog",
|
||||
path: "/certd/audit",
|
||||
component: "/certd/audit/index.vue",
|
||||
meta: {
|
||||
icon: "ion:document-text-outline",
|
||||
auth: true,
|
||||
keepAlive: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "certd.userSecurity",
|
||||
name: "UserSecurity",
|
||||
|
||||
@@ -410,6 +410,18 @@ export const sysResources = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "certd.sysResources.auditLog",
|
||||
name: "SysAuditLog",
|
||||
path: "/sys/audit",
|
||||
component: "/sys/audit/index.vue",
|
||||
meta: {
|
||||
icon: "ion:document-text-outline",
|
||||
permission: "sys:settings:view",
|
||||
keepAlive: true,
|
||||
auth: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "certd.sysResources.netTest",
|
||||
name: "NetTest",
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { request } from "/src/api/service";
|
||||
|
||||
const apiPrefix = "/pi/audit";
|
||||
|
||||
export function createAuditApi() {
|
||||
return {
|
||||
async GetList(query: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/page",
|
||||
method: "post",
|
||||
data: query,
|
||||
});
|
||||
},
|
||||
async DelObj(id: number) {
|
||||
return await request({
|
||||
url: apiPrefix + "/delete",
|
||||
method: "post",
|
||||
params: { id },
|
||||
});
|
||||
},
|
||||
async GetDict() {
|
||||
return await request({
|
||||
url: apiPrefix + "/dict",
|
||||
method: "post",
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
import { CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, UserPageQuery, UserPageRes, dict } from "@fast-crud/fast-crud";
|
||||
|
||||
const typeDict = dict({
|
||||
url: "/pi/audit/dict",
|
||||
getData: async () => {
|
||||
const { createAuditApi } = await import("./api");
|
||||
const api = createAuditApi();
|
||||
const res = await api.GetDict();
|
||||
return res.types || [];
|
||||
},
|
||||
});
|
||||
|
||||
const actionDict = dict({
|
||||
url: "/pi/audit/dict",
|
||||
getData: async () => {
|
||||
const { createAuditApi } = await import("./api");
|
||||
const api = createAuditApi();
|
||||
const res = await api.GetDict();
|
||||
return res.actions || [];
|
||||
},
|
||||
});
|
||||
|
||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||
const api = context.api;
|
||||
|
||||
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||
return await api.GetList(query);
|
||||
};
|
||||
const delRequest = async (req: DelReq) => {
|
||||
return await api.DelObj(req.row.id);
|
||||
};
|
||||
|
||||
return {
|
||||
crudOptions: {
|
||||
request: { pageRequest, delRequest },
|
||||
actionbar: {
|
||||
buttons: {
|
||||
add: { show: false },
|
||||
},
|
||||
},
|
||||
rowHandle: {
|
||||
width: 120,
|
||||
fixed: "right",
|
||||
buttons: {
|
||||
view: { show: false },
|
||||
edit: { show: false },
|
||||
remove: { show: true },
|
||||
},
|
||||
},
|
||||
columns: {
|
||||
id: {
|
||||
title: "ID",
|
||||
type: "number",
|
||||
column: { width: 80 },
|
||||
form: { show: false },
|
||||
},
|
||||
createTime: {
|
||||
title: "操作时间",
|
||||
type: "datetime",
|
||||
search: {
|
||||
show: true,
|
||||
component: {
|
||||
name: "a-range-picker",
|
||||
vModel: ["createTime_start", "createTime_end"],
|
||||
},
|
||||
},
|
||||
column: { width: 170, sorter: true },
|
||||
form: { show: false },
|
||||
},
|
||||
type: {
|
||||
title: "操作类型",
|
||||
type: "dict-select",
|
||||
dict: typeDict,
|
||||
search: { show: true },
|
||||
column: { width: 120 },
|
||||
form: { show: false },
|
||||
},
|
||||
action: {
|
||||
title: "操作动作",
|
||||
type: "dict-select",
|
||||
dict: actionDict,
|
||||
search: { show: true },
|
||||
column: { width: 100 },
|
||||
form: { show: false },
|
||||
},
|
||||
content: {
|
||||
title: "内容",
|
||||
type: "text",
|
||||
search: { show: true },
|
||||
column: { minWidth: 300 },
|
||||
form: { show: false },
|
||||
},
|
||||
ipAddress: {
|
||||
title: "IP地址",
|
||||
type: "text",
|
||||
column: { width: 140 },
|
||||
form: { show: false },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<fs-page>
|
||||
<template #header>
|
||||
<div class="title">
|
||||
操作日志
|
||||
<span class="sub">查看您的操作记录</span>
|
||||
</div>
|
||||
</template>
|
||||
<fs-crud ref="crudRef" v-bind="crudBinding" />
|
||||
</fs-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useFs } from "@fast-crud/fast-crud";
|
||||
import createCrudOptions from "./crud";
|
||||
import { createAuditApi } from "./api";
|
||||
import { useMounted } from "/@/use/use-mounted";
|
||||
|
||||
defineOptions({ name: "AuditLog" });
|
||||
|
||||
const api = createAuditApi();
|
||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { api } });
|
||||
useMounted(() => crudExpose.doRefresh());
|
||||
</script>
|
||||
@@ -0,0 +1,35 @@
|
||||
import { request } from "/src/api/service";
|
||||
|
||||
const apiPrefix = "/sys/audit";
|
||||
|
||||
export function createSysAuditApi() {
|
||||
return {
|
||||
async GetList(query: any) {
|
||||
return await request({
|
||||
url: apiPrefix + "/page",
|
||||
method: "post",
|
||||
data: query,
|
||||
});
|
||||
},
|
||||
async DelObj(id: number) {
|
||||
return await request({
|
||||
url: apiPrefix + "/delete",
|
||||
method: "post",
|
||||
params: { id },
|
||||
});
|
||||
},
|
||||
async Clean(retentionDays: number) {
|
||||
return await request({
|
||||
url: apiPrefix + "/clean",
|
||||
method: "post",
|
||||
data: { retentionDays },
|
||||
});
|
||||
},
|
||||
async GetDict() {
|
||||
return await request({
|
||||
url: apiPrefix + "/dict",
|
||||
method: "post",
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
import { CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, UserPageQuery, UserPageRes, dict } from "@fast-crud/fast-crud";
|
||||
|
||||
const typeDict = dict({
|
||||
url: "/sys/audit/dict",
|
||||
getData: async () => {
|
||||
const { createSysAuditApi } = await import("./api");
|
||||
const api = createSysAuditApi();
|
||||
const res = await api.GetDict();
|
||||
return res.types || [];
|
||||
},
|
||||
});
|
||||
|
||||
const actionDict = dict({
|
||||
url: "/sys/audit/dict",
|
||||
getData: async () => {
|
||||
const { createSysAuditApi } = await import("./api");
|
||||
const api = createSysAuditApi();
|
||||
const res = await api.GetDict();
|
||||
return res.actions || [];
|
||||
},
|
||||
});
|
||||
|
||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||
const api = context.api;
|
||||
|
||||
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||
return await api.GetList(query);
|
||||
};
|
||||
const delRequest = async (req: DelReq) => {
|
||||
return await api.DelObj(req.row.id);
|
||||
};
|
||||
|
||||
const cleanExpired = async () => {
|
||||
await api.Clean(90);
|
||||
crudExpose.doRefresh();
|
||||
};
|
||||
|
||||
return {
|
||||
crudOptions: {
|
||||
request: { pageRequest, delRequest },
|
||||
actionbar: {
|
||||
buttons: {
|
||||
add: { show: false },
|
||||
clean: {
|
||||
text: "清理过期日志(90天)",
|
||||
type: "default",
|
||||
click: cleanExpired,
|
||||
},
|
||||
},
|
||||
},
|
||||
rowHandle: {
|
||||
width: 120,
|
||||
fixed: "right",
|
||||
buttons: {
|
||||
view: { show: false },
|
||||
edit: { show: false },
|
||||
remove: { show: true },
|
||||
},
|
||||
},
|
||||
search: {
|
||||
initialForm: {
|
||||
sort: { prop: "id", asc: false },
|
||||
},
|
||||
},
|
||||
columns: {
|
||||
id: {
|
||||
title: "ID",
|
||||
type: "number",
|
||||
column: { width: 80 },
|
||||
form: { show: false },
|
||||
},
|
||||
createTime: {
|
||||
title: "操作时间",
|
||||
type: "datetime",
|
||||
search: {
|
||||
show: true,
|
||||
component: {
|
||||
name: "a-range-picker",
|
||||
vModel: ["createTime_start", "createTime_end"],
|
||||
},
|
||||
},
|
||||
column: { width: 170, sorter: true },
|
||||
form: { show: false },
|
||||
},
|
||||
userName: {
|
||||
title: "操作人",
|
||||
type: "text",
|
||||
search: { show: true },
|
||||
column: { width: 120 },
|
||||
form: { show: false },
|
||||
},
|
||||
type: {
|
||||
title: "操作类型",
|
||||
type: "dict-select",
|
||||
dict: typeDict,
|
||||
search: { show: true },
|
||||
column: { width: 120 },
|
||||
form: { show: false },
|
||||
},
|
||||
action: {
|
||||
title: "操作动作",
|
||||
type: "dict-select",
|
||||
dict: actionDict,
|
||||
search: { show: true },
|
||||
column: { width: 100 },
|
||||
form: { show: false },
|
||||
},
|
||||
content: {
|
||||
title: "内容",
|
||||
type: "text",
|
||||
search: { show: true },
|
||||
column: { minWidth: 300 },
|
||||
form: { show: false },
|
||||
},
|
||||
ipAddress: {
|
||||
title: "IP地址",
|
||||
type: "text",
|
||||
column: { width: 140 },
|
||||
form: { show: false },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<fs-page>
|
||||
<template #header>
|
||||
<div class="title">
|
||||
操作日志
|
||||
<span class="sub">查看所有用户的操作记录</span>
|
||||
</div>
|
||||
</template>
|
||||
<fs-crud ref="crudRef" v-bind="crudBinding" />
|
||||
</fs-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useFs } from "@fast-crud/fast-crud";
|
||||
import createCrudOptions from "./crud";
|
||||
import { createSysAuditApi } from "./api";
|
||||
import { useMounted } from "/@/use/use-mounted";
|
||||
|
||||
defineOptions({ name: "SysAuditLog" });
|
||||
|
||||
const api = createSysAuditApi();
|
||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { api } });
|
||||
useMounted(() => crudExpose.doRefresh());
|
||||
</script>
|
||||
Reference in New Issue
Block a user