日志管理支持删除日志文件和目录

This commit is contained in:
whyour 2022-09-23 20:09:10 +08:00
parent 25b03d4345
commit dfc706e16d
6 changed files with 136 additions and 27 deletions

View File

@ -3,8 +3,9 @@ import { Container } from 'typedi';
import { Logger } from 'winston';
import * as fs from 'fs';
import config from '../config';
import { getFileContentByName, readDirs } from '../config/util';
import { emptyDir, getFileContentByName, readDirs } from '../config/util';
import { join } from 'path';
import { celebrate, Joi } from 'celebrate';
const route = Router();
const blacklist = ['.tmp'];
@ -45,4 +46,34 @@ export default (app: Router) => {
}
},
);
route.delete(
'/',
celebrate({
body: Joi.object({
filename: Joi.string().required(),
path: Joi.string().allow(''),
type: Joi.string().optional()
}),
}),
async (req: Request, res: Response, next: NextFunction) => {
try {
let { filename, path, type } = req.body as {
filename: string;
path: string;
type: string;
};
const filePath = join(config.logPath, path, filename);
if (type === 'directory') {
emptyDir(filePath);
} else {
fs.unlinkSync(filePath);
}
res.send({ code: 200 });
} catch (e) {
return next(e);
}
},
);
};

View File

@ -68,18 +68,18 @@ export default {
icon: <IconFont type="ql-icon-dependence" />,
component: '@/pages/dependence/index',
},
{
path: '/log',
name: '日志管理',
icon: <IconFont type="ql-icon-log" />,
component: '@/pages/log/index',
},
{
path: '/diff',
name: '对比工具',
icon: <IconFont type="ql-icon-diff" />,
component: '@/pages/diff/index',
},
{
path: '/log',
name: '任务日志',
icon: <IconFont type="ql-icon-log" />,
component: '@/pages/log/index',
},
{
path: '/setting',
name: '系统设置',

View File

@ -1,5 +1,5 @@
import { useState, useEffect, useCallback, Key, useRef } from 'react';
import { TreeSelect, Tree, Input, Empty } from 'antd';
import { TreeSelect, Tree, Input, Empty, Button, message, Modal, Tooltip, Typography } from 'antd';
import config from '@/utils/config';
import { PageContainer } from '@ant-design/pro-layout';
import Editor from '@monaco-editor/react';
@ -9,6 +9,11 @@ import { Controlled as CodeMirror } from 'react-codemirror2';
import SplitPane from 'react-split-pane';
import { useOutletContext } from '@umijs/max';
import { SharedContext } from '@/layouts';
import { DeleteOutlined } from '@ant-design/icons';
import { depthFirstSearch } from '@/utils';
import { debounce } from 'lodash';
const { Text } = Typography;
function getFilterData(keyword: string, data: any) {
const expandedKeys: string[] = [];
@ -49,6 +54,8 @@ const Log = () => {
const [height, setHeight] = useState<number>();
const treeDom = useRef<any>();
const [expandedKeys, setExpandedKeys] = useState<string[]>([]);
const [currentNode, setCurrentNode] = useState<any>();
const [searchValue, setSearchValue] = useState('');
const getLogs = () => {
setLoading(true);
@ -77,9 +84,16 @@ const Log = () => {
if (node.key === select || !value) {
return;
}
setValue('加载中...');
setCurrentNode(node);
setSelect(value);
setTitle(node.key);
if (node.type === 'directory') {
setValue('请选择日志文件');
return;
}
setValue('加载中...');
getLog(node);
};
@ -90,16 +104,75 @@ const Log = () => {
const onSearch = useCallback(
(e) => {
const keyword = e.target.value;
debounceSearch(keyword);
},
[data, setFilterData],
);
const debounceSearch = useCallback(
debounce((keyword) => {
setSearchValue(keyword);
const { tree, expandedKeys } = getFilterData(
keyword.toLocaleLowerCase(),
data,
);
setFilterData(tree);
setExpandedKeys(expandedKeys);
},
}, 300),
[data, setFilterData],
);
const deleteFile = () => {
Modal.confirm({
title: `确认删除`,
content: (
<>
<Text style={{ wordBreak: 'break-all' }} type="warning">
{select}
</Text>
{currentNode.type === 'directory' ? '夹下所以日志':''}
</>
),
onOk() {
request
.delete(`${config.apiPrefix}logs`, {
data: {
filename: currentNode.title,
path: currentNode.parent || '',
type: currentNode.type
},
})
.then(({ code }) => {
if (code === 200) {
message.success(`删除成功`);
let newData = [...data];
if (currentNode.parent) {
newData = depthFirstSearch(newData, (c) => c.key === currentNode.key);
} else {
const index = newData.findIndex(
(x) => x.key === currentNode.key,
);
if (index !== -1) {
newData.splice(index, 1);
}
}
setData(newData);
}
});
},
onCancel() {
console.log('Cancel');
},
});
};
useEffect(() => {
const word = searchValue || '';
const { tree } = getFilterData(word.toLocaleLowerCase(), data);
setFilterData(tree);
}, [data]);
useEffect(() => {
getLogs();
if (treeDom && treeDom.current) {
@ -113,7 +186,7 @@ const Log = () => {
title={title}
loading={loading}
extra={
isPhone && [
isPhone ? [
<TreeSelect
className="log-select"
value={select}
@ -124,6 +197,15 @@ const Log = () => {
showSearch
onSelect={onSelect}
/>,
] : [
<Tooltip title="删除">
<Button
type="primary"
disabled={!select}
onClick={deleteFile}
icon={<DeleteOutlined />}
/>
</Tooltip>,
]
}
header={{
@ -144,6 +226,7 @@ const Log = () => {
></Input.Search>
<div className={styles['left-tree-scroller']} ref={treeDom}>
<Tree
expandAction="click"
className={styles['left-tree']}
treeData={filterData}
showIcon={true}

View File

@ -283,17 +283,7 @@ const Script = () => {
message.success(`删除成功`);
let newData = [...data];
if (currentNode.parent) {
const parentNodeIndex = newData.findIndex(
(x) => x.key === currentNode.parent,
);
const parentNode = newData[parentNodeIndex];
const index = parentNode.children.findIndex(
(y) => y.key === currentNode.key,
);
if (index !== -1 && parentNodeIndex !== -1) {
parentNode.children.splice(index, 1);
newData.splice(parentNodeIndex, 1, { ...parentNode });
}
newData = depthFirstSearch(newData, (c) => c.key === currentNode.key);
} else {
const index = newData.findIndex(
(x) => x.key === currentNode.key,

View File

@ -56,7 +56,7 @@ export default {
value: 'scripts',
},
{
name: '任务日志',
name: '日志管理',
value: 'logs',
},
{
@ -74,7 +74,7 @@ export default {
subscriptions: '订阅管理',
configs: '配置文件',
scripts: '脚本管理',
logs: '任务日志',
logs: '日志管理',
dependencies: '依赖管理',
system: '系统信息',
},
@ -263,7 +263,7 @@ export default {
'/config': '配置文件',
'/script': '脚本管理',
'/diff': '对比工具',
'/log': '任务日志',
'/log': '日志管理',
'/setting': '系统设置',
'/error': '错误日志',
},

View File

@ -244,7 +244,7 @@ export function exportJson(name: string, data: string) {
export function depthFirstSearch<
T extends Record<string, any> & { children?: T[] },
>(children: T[], condition: (column: T) => boolean, item: T) {
>(children: T[], condition: (column: T) => boolean, item?: T) {
const c = [...children];
const keys = [];
@ -252,6 +252,11 @@ export function depthFirstSearch<
if (!cls) return;
for (let i = 0; i < cls?.length; i++) {
if (condition(cls[i])) {
if (!item) {
cls.splice(i, 1);
return;
}
if (cls[i].children) {
cls[i].children!.unshift(item);
} else {