Introducing new features. 增加日志管理

This commit is contained in:
aeizzz 2023-02-06 10:28:19 +08:00
parent 39ed45f6a2
commit d877385d0d
8 changed files with 224 additions and 32 deletions

25
src/api/admin/log.ts Normal file
View File

@ -0,0 +1,25 @@
import request from "/@/utils/request";
export const pageList = (params?: Object) => {
return request({
url: '/admin/log/page',
method: "get",
params
})
}
export const delObjs = (ids: string) => {
return request({
url: '/admin/log/',
method: 'delete',
data: ids
})
}
export const delObj = (id:string) => {
return request({
url: '/admin/log/' + id,
method: 'delete'
})
}

View File

@ -1,7 +1,5 @@
import { ElMessage } from "element-plus";
import other from "../utils/other";
import { useMessage } from "./message";
import request from "/@/utils/request";
export interface BasicTableProps {
// 是否在创建页面时,调用数据列表接口
@ -22,6 +20,8 @@ export interface BasicTableProps {
pageList?: (...arg: any) => Promise<any>
// loading
loading?: Boolean
selectObjs: any[]
}
export interface Pagination {
@ -59,7 +59,8 @@ export function useTable(options?: BasicTableProps) {
layout: "total, sizes, prev, pager, next, jumper"
} as Pagination,
dataListSelections: [],
loading: false
loading: false,
selectObjs: []
}
const mergeDefaultOptions = (options: any, props: any): BasicTableProps => {
@ -137,6 +138,7 @@ export function useTable(options?: BasicTableProps) {
return other.downBlobFile(url, query, fileName)
}
return {
getDataList,
sizeChangeHandle,

View File

@ -84,6 +84,7 @@ export function setFilterRouteEnd() {
let filterRouteEnd: any = formatTwoStageRoutes(formatFlatteningRoutes(dynamicRoutes));
// notFoundAndNoPower 防止 404、401 不在 layout 布局中不设置的话404、401 界面将全屏显示
// 关联问题 No match found for location with path 'xxx'
console.log(filterRouteEnd,'filterRouteEnd')
filterRouteEnd[0].children = [...filterRouteEnd[0].children, ...notFoundAndNoPower];
return filterRouteEnd;
}
@ -96,6 +97,7 @@ export function setFilterRouteEnd() {
*/
export async function setAddRoute() {
await setFilterRouteEnd().forEach((route: RouteRecordRaw) => {
console.log(route,'route')
router.addRoute(route);
});
}

View File

@ -225,12 +225,14 @@ export function downBlobFile(url:any, query: any, fileName:string) {
return;
}
const link = document.createElement("a");
// @ts-ignore
link.href = URL.createObjectURL(blob);
// @ts-ignore
link.download = fileName;
document.body.appendChild(link);
link.click();
window.setTimeout(function () {
// @ts-ignore
URL.revokeObjectURL(blob);
document.body.removeChild(link);
}, 0);

View File

@ -0,0 +1,15 @@
export default {
syslog: {
index: 'index',
logType: 'logType',
title: 'title',
remoteAddr: 'remoteAddr',
method: 'method',
serviceId: 'serviceId',
time: 'time',
createTime: 'createTime',
action: 'action',
inputLogTypeTip: 'select logType',
inputCreateTimeTip: 'select createTime'
}
}

View File

@ -0,0 +1,16 @@
export default {
syslog: {
index: '序号',
logType: '类型',
title: '标题',
remoteAddr: 'IP地址',
method: '请求方式',
serviceId: '客户端',
time: '请求时间',
createTime: '创建时间',
action: '操作',
inputLogTypeTip: '请选择类型',
inputCreateTimeTip: '选择时间'
},
}

View File

@ -0,0 +1,144 @@
<template>
<el-card class="layout-padding-auto" shadow="hover">
<el-row v-show="showSearch" class="mb8">
<el-form :model="state.queryForm" ref="queryRef" :inline="true">
<el-form-item :label="$t('syslog.logType')" prop="logType">
<el-select v-model="state.queryForm.logType" :placeholder="$t('syslog.inputLogTypeTip')" clearable class="w100">
<el-option v-for="item in log_type" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item :label="$t('syslog.createTime')" prop="createTime" :placeholder="$t('syslog.inputCreateTimeTip')">
<el-input v-model="state.queryForm.createTime" clearable
style="width: 240px" @keyup.enter="getDataList" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="getDataList">{{ $t('common.queryBtn') }}</el-button>
<el-button icon="Refresh" @click="resetQuery">{{ $t('common.resetBtn') }}</el-button>
</el-form-item>
</el-form>
</el-row>
<el-row>
<div class="mb8" style="width: 100%">
<el-button size="default" icon="Download" type="primary" class="ml10" @click="exportExcel"
v-auth="'sys_user_export'">
{{ $t('common.exportBtn') }}
</el-button>
<el-button size="default" :disabled="multiple" icon="Delete" type="primary" class="ml10"
v-auth="'sys_user_del'" @click="handleDelete(undefined)">
{{ $t('common.delBtn') }}
</el-button>
<right-toolbar v-model:showSearch="showSearch" class="ml10" style="float: right;margin-right: 20px"
@queryTable="getDataList"></right-toolbar>
</div>
</el-row>
<el-table v-loading="state.loading" :data="state.dataList" style="width: 100%"
@selection-change="handleSelectionChange">
<el-table-column align="center" type="selection" width="50"/>
<el-table-column :label="$t('syslog.index')" type="index" width="80"/>
<el-table-column :label="$t('syslog.logType')" show-overflow-tooltip>
<template #default="scope">
<dict-tag :options="log_type" :value="scope.row.logType"></dict-tag>
</template>
</el-table-column>
<el-table-column :label="$t('syslog.title')" prop="title" show-overflow-tooltip></el-table-column>
<el-table-column :label="$t('syslog.remoteAddr')" prop="remoteAddr" show-overflow-tooltip></el-table-column>
<el-table-column :label="$t('syslog.remoteAddr')" prop="remoteAddr" show-overflow-tooltip></el-table-column>
<el-table-column :label="$t('syslog.method')" prop="method" show-overflow-tooltip></el-table-column>
<el-table-column :label="$t('syslog.serviceId')" prop="serviceId" show-overflow-tooltip></el-table-column>
<el-table-column :label="$t('syslog.time')" prop="time" show-overflow-tooltip></el-table-column>
<el-table-column :label="$t('syslog.createTime')" prop="createTime"
show-overflow-tooltip></el-table-column>
<el-table-column :label="$t('sysuser.action')" width="100">
<template #default="scope">
<el-button v-auth="'sys_user_del'" size="small" text type="primary" @click="handleDelete(scope.row)">
{{ $t('common.delBtn') }}
</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-bind="state.pagination" @size-change="sizeChangeHandle" @current-change="currentChangeHandle">
</pagination>
</el-card>
</template>
<script lang="ts" setup>
import { BasicTableProps, useTable } from "/@/hooks/table";
import { pageList, delObj } from "/@/api/admin/log";
import { useI18n } from 'vue-i18n'
import {useMessage, useMessageBox} from "/@/hooks/message";
import {useDict} from "/@/hooks/dict";
const { log_type } = useDict('log_type')
const { t } = useI18n()
//
const queryRef = ref();
const showSearch = ref(true)
// rows
const selectObjs = ref([]);
//
const multiple = ref(true);
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: {
logType: '',
createTime: ''
},
selectObjs: [],
pageList: pageList // H
});
// table hook
const {
downBlobFile,
getDataList,
currentChangeHandle,
sizeChangeHandle
} = useTable(state)
//
const resetQuery = () => {
queryRef.value.resetFields()
getDataList()
}
//
const handleSelectionChange = (val: any) => {
selectObjs.value = val
multiple.value = !val.length
}
// excel
const exportExcel = () => {
downBlobFile('/admin/log/export', state.queryForm, 'log.xlsx')
}
//
const handleDelete = (row: any) => {
if (!row) {
selectObjs.value.forEach(val => {
handleDelete(val)
});
return
}
useMessageBox().confirm(`${t('common.delConfirmText')}${row.id} ?`).then(() => {
//
delObj(row.id).then(() => {
getDataList();
useMessage().success(t('common.delSuccessText'))
}).catch(err => {
useMessage().error(err.msg)
})
})
};
</script>
<style scoped>
</style>

View File

@ -2,8 +2,8 @@
<div class="system-menu-container layout-pd">
<el-card shadow="hover">
<div class="mb15">
<el-input size="default" placeholder="请输入菜单名称" style="max-width: 180px" v-model="state.search.menuName"> </el-input>
<el-button size="default" icon="search" type="primary" class="ml10" @click="getTableData">
<el-input size="default" placeholder="请输入菜单名称" style="max-width: 180px" v-model="state.queryForm.menuName"> </el-input>
<el-button size="default" icon="search" type="primary" class="ml10" @click="getDataList">
查询
</el-button>
<el-button size="default" icon="folder-add" type="success" class="ml10" @click="onOpenAddMenu">
@ -11,8 +11,8 @@
</el-button>
</div>
<el-table
:data="state.tableData.data"
v-loading="state.tableData.loading"
:data="state.dataList"
v-loading="state.loading"
style="width: 100%"
row-key="path"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
@ -43,43 +43,33 @@
</el-table-column>
</el-table>
</el-card>
<MenuDialog ref="menuDialogRef" @refresh="getTableData()" />
<MenuDialog ref="menuDialogRef" @refresh="getDataList()" />
</div>
</template>
<script setup lang="ts" name="systemMenu">
import { defineAsyncComponent, ref, onMounted, reactive } from 'vue';
import { RouteRecordRaw } from 'vue-router';
import { ElMessageBox, ElMessage } from 'element-plus';
import { pageList } from '/@/api/admin/menu'
import type { menuData } from './menu'
import { useTable, BasicTableProps } from "/@/hooks/table";
//
const MenuDialog = defineAsyncComponent(() => import('./form.vue'));
//
const menuDialogRef = ref<InstanceType<typeof MenuDialog>>();
const state = reactive({
tableData: {
data: [] as menuData[],
loading: true,
},
search: {
const state: BasicTableProps = reactive<BasicTableProps>({
pageList: pageList, // H
queryForm: {
menuName: ''
}
},
isPage: false
});
//
const getTableData = () => {
state.tableData.loading = true;
pageList(state.search).then(res => {
state.tableData.data = res.data
})
const {
getDataList,
} = useTable(state)
setTimeout(() => {
state.tableData.loading = false;
}, 500);
};
//
const onOpenAddMenu = (type: string) => {
menuDialogRef.value.openDialog(type);
@ -97,12 +87,8 @@ const onTabelRowDel = (row: RouteRecordRaw) => {
})
.then(() => {
ElMessage.success('删除成功');
getTableData();
getDataList()
})
.catch(() => {});
};
//
onMounted(() => {
getTableData();
});
</script>