初始版本提交

This commit is contained in:
yaoyn
2024-02-05 09:15:37 +08:00
parent b52d4414be
commit 445292105f
1848 changed files with 236859 additions and 75 deletions

View File

@ -0,0 +1,37 @@
<template>
<div class="overflow-hidden bg-white" :style="{ 'border-right': '1px solid #e5e7eb' }">
<BasicTree
:title="t('日志类型')"
:toolbar="false"
:search="false"
:treeData="treeData"
:selectedKeys="['1']"
@select="handleSelect"
/>
</div>
</template>
<script lang="ts">
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
import { defineComponent, onMounted } from 'vue';
import { BasicTree } from '/@/components/Tree';
import { treeData } from './data';
export default defineComponent({
name: 'DeptTree',
components: { BasicTree },
emits: ['select'],
setup(_, { emit }) {
function handleSelect(keys: string) {
let obj = treeData.find((o) => {
return o.key == keys[0];
});
emit('select', obj);
}
onMounted(() => {});
return { treeData, handleSelect, t };
},
});
</script>

View File

@ -0,0 +1,35 @@
import { TreeItem } from '/@/components/Tree';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
export const treeData: TreeItem[] = [
{
title: t('登录日志'),
icon: 'ant-design:audit-outlined',
key: '1',
},
{
title: t('访问日志'),
icon: 'ant-design:exception-outlined',
key: '2',
},
{
title: t('操作日志'),
icon: 'ant-design:file-protect-outlined',
key: '3',
},
{
title: t('异常日志'),
icon: 'ant-design:file-search-outlined',
key: '4',
},
// {
// title: '接口日志',
// icon: 'ant-design:file-sync-outlined',
// key: '5',
// },
// {
// title: '表单日志',
// icon: 'ant-design:file-text-outlined',
// key: '5',
// },
];

View File

@ -0,0 +1,89 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" :title="t('清空')" @ok="handleSubmit">
<BasicForm @register="registerForm" />
</BasicModal>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { FormSchema } from '/@/components/Table';
import { useMessage } from '/@/hooks/web/useMessage';
import { clearLog } from '/@/api/system/log';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
export const accountFormSchema: FormSchema[] = [
{
label: t('保留时间'),
field: 'type',
component: 'Select',
required: true,
componentProps: {
options: [
{
label: t('保留近一周'),
value: '0',
},
{
label: t('保留近一个月'),
value: '1',
},
{
label: t('保留近三个月'),
value: '2',
},
{
label: t('不保留,全部删除'),
value: '3',
},
],
},
colProps: { span: 24 },
},
];
export default defineComponent({
name: 'ClearModel',
components: { BasicModal, BasicForm },
emits: ['success', 'register'],
setup(_, { emit }) {
const { notification } = useMessage();
const [registerForm, { resetFields, validate }] = useForm({
labelWidth: 100,
schemas: accountFormSchema,
showActionButtonGroup: false,
actionColOptions: {
span: 23,
},
});
const [registerModal, { setModalProps, closeModal }] = useModalInner(() => {
resetFields();
setModalProps({ confirmLoading: false });
});
async function handleSubmit() {
try {
const values = await validate();
setModalProps({ confirmLoading: true });
await clearLog(values.type);
notification.success({
message: t('清空日志'),
description: t('成功'),
}); //提示消息
closeModal();
emit('success');
} catch (error) {
setModalProps({ confirmLoading: false });
}
}
return { registerModal, registerForm, handleSubmit, t };
},
});
</script>

View File

@ -0,0 +1,202 @@
<template>
<PageWrapper dense contentFullHeight fixedHeight contentClass="flex">
<DeptTree class="w-3/20" @select="handleSelect" />
<BasicTable @register="registerTable" class="w-17/20">
<template #toolbar>
<a-button type="error" v-auth="'log:empty'" @click="handleClear">{{ t('清空') }}</a-button>
<a-button type="primary" v-auth="'log:export'" @click="handleExport">{{
t('导出')
}}</a-button>
<a-button type="primary" v-auth="'log:batchDelete'" @click="handleDelete">{{
t('批量删除')
}}</a-button>
</template>
</BasicTable>
<AccountModal @register="registerModal" @success="handleSuccess" />
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import { BasicTable, useTable, FormSchema, BasicColumn } from '/@/components/Table';
import { PageWrapper } from '/@/components/Page';
import { useMessage } from '/@/hooks/web/useMessage';
import { downloadByData } from '/@/utils/file/download';
import { useModal } from '/@/components/Modal';
import AccountModal from './components/logModal.vue';
import DeptTree from './components/DeptTree.vue';
import { deleteLog, exportLog, getLogPageList } from '/@/api/system/log';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
export const searchFormSchema: FormSchema[] = [
{
field: 'keyword',
label: t('关键字'),
component: 'Input',
componentProps: {
placeholder: t('请输入要查询的关键字'),
},
colProps: { lg: 8, md: 24 },
},
{
field: 'createTime',
label: t('日期'),
component: 'RangePicker',
colProps: { lg: 8, md: 24 },
},
];
export const columns: BasicColumn[] = [
{
title: t('操作时间'),
dataIndex: 'createTime',
width: 120,
sorter: true,
align: 'left',
},
{
title: t('操作用户'),
dataIndex: 'username',
width: 120,
sorter: true,
align: 'left',
},
{
title: t('IP地址'),
dataIndex: 'ip',
width: 120,
sorter: true,
align: 'left',
},
{
title: t('类名'),
dataIndex: 'method',
width: 120,
sorter: true,
align: 'left',
},
{
title: t('操作类型'),
dataIndex: 'operation',
width: 180,
sorter: true,
align: 'left',
},
{
title: t('耗时/ms'),
dataIndex: 'time',
width: 180,
sorter: true,
align: 'left',
},
];
export default defineComponent({
name: 'LogManagement',
components: { BasicTable, PageWrapper, DeptTree, AccountModal },
setup() {
const { notification } = useMessage();
const selectDeptId = ref(1);
const [registerModal, { openModal }] = useModal();
const [registerTable, { reload, getSelectRowKeys, setProps }] = useTable({
title: t('登录日志列表'),
api: getLogPageList,
rowKey: 'id',
columns,
formConfig: {
rowProps: {
gutter: 16,
},
schemas: searchFormSchema,
fieldMapToTime: [
['createTime', ['createTimeStart', 'createTimeEnd'], 'YYYY-MM-DD', false],
],
actionColOptions: { span: 24 },
showResetButton: false,
},
rowSelection: {
type: 'checkbox',
},
beforeFetch: (params) => {
//发送请求默认新增 左边树结构所选机构id
return { ...params, category: selectDeptId.value };
},
useSearchForm: true,
showTableSetting: true,
striped: false,
tableSetting: {
size: false,
setting: false,
},
});
function handleClear() {
openModal(true);
}
async function handleExport() {
let rows = warning();
if (!rows) {
return;
}
try {
let res = await exportLog(rows);
downloadByData(
res.data,
t('日志列表.xlsx'),
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
);
} catch (error) {}
}
function handleDelete() {
let rows = warning();
if (!rows) {
return;
}
deleteLog(rows).then(() => {
notification.success({
message: t('批量删除日志成功'),
description: t('成功'),
});
handleSuccess();
});
}
function warning() {
const selectRows = getSelectRowKeys();
if (selectRows.length === 0) {
notification.warning({
message: t('警告'),
description: t('请选择一条数据!'),
}); //提示消息
return false;
} else {
return selectRows;
}
}
function handleSuccess() {
reload({ searchInfo: { category: selectDeptId.value } });
}
function handleSelect(dept) {
selectDeptId.value = dept.key;
setProps({ title: dept.title + t('列表') });
handleSuccess();
}
return {
registerTable,
registerModal,
handleExport,
handleDelete,
handleSuccess,
handleSelect,
handleClear,
t,
};
},
});
</script>