日志和脚本增加文件大小展示,修改脚本管理列表排序

This commit is contained in:
whyour 2023-12-21 09:57:06 +08:00
parent 52a89a21f6
commit f8aba4b1fb
6 changed files with 78 additions and 54 deletions

7
.gitignore vendored
View File

@ -22,11 +22,4 @@
.env
.history
.version.ts
/config
/log
/db
/manual_log
/scripts
/bak
/.tmp

View File

@ -21,12 +21,5 @@ src/.umi-production
src/.umi-test
.env.local
.env
history
version.ts
config
log
db
manual_log
scripts
bak
.tmp
/.tmp

View File

@ -46,6 +46,13 @@ export default (app: Router) => {
config.scriptPath,
config.scriptPath,
blacklist,
(a, b) => {
if (a.type === b.type) {
return a.title.localeCompare(b.title);
} else {
return a.type === 'directory' ? -1 : 1;
}
},
);
}
res.send({

View File

@ -234,12 +234,12 @@ interface IFile {
}
export function dirSort(a: IFile, b: IFile): number {
if (a.type !== b.type) {
return FileType[a.type] < FileType[b.type] ? -1 : 1
} else if (a.mtime !== b.mtime) {
return a.mtime > b.mtime ? -1 : 1
if (a.type === 'file' && b.type === 'file') {
return b.mtime - a.mtime;
} else if (a.type === 'directory' && b.type === 'directory') {
return a.title.localeCompare(b.title);
} else {
return 0;
return a.type === 'directory' ? -1 : 1;
}
}
@ -247,36 +247,39 @@ export async function readDirs(
dir: string,
baseDir: string = '',
blacklist: string[] = [],
sort: (a: IFile, b: IFile) => number = dirSort,
): Promise<IFile[]> {
const relativePath = path.relative(baseDir, dir);
const files = await fs.readdir(dir);
const result: IFile[] = await Promise.all(files
.filter((x) => !blacklist.includes(x))
.map(async (file: string) => {
const subPath = path.join(dir, file);
const stats = await fs.stat(subPath);
const key = path.join(relativePath, file);
if (stats.isDirectory()) {
const result: IFile[] = await Promise.all(
files
.filter((x) => !blacklist.includes(x))
.map(async (file: string) => {
const subPath = path.join(dir, file);
const stats = await fs.stat(subPath);
const key = path.join(relativePath, file);
if (stats.isDirectory()) {
return {
title: file,
key,
type: 'directory',
parent: relativePath,
mtime: stats.mtime.getTime(),
children: (await readDirs(subPath, baseDir)).sort(sort),
};
}
return {
title: file,
type: 'file',
isLeaf: true,
key,
type: 'directory',
parent: relativePath,
size: stats.size,
mtime: stats.mtime.getTime(),
children: (await readDirs(subPath, baseDir)).sort(dirSort),
};
}
return {
title: file,
type: 'file',
isLeaf: true,
key,
parent: relativePath,
size: stats.size,
mtime: stats.mtime.getTime(),
};
}));
return result.sort(dirSort);
}),
);
return result.sort(sort);
}
export async function readDir(
@ -304,7 +307,10 @@ export async function readDir(
export async function promiseExec(command: string): Promise<string> {
try {
const { stderr, stdout } = await promisify(exec)(command, { maxBuffer: 200 * 1024 * 1024, encoding: 'utf8' });
const { stderr, stdout } = await promisify(exec)(command, {
maxBuffer: 200 * 1024 * 1024,
encoding: 'utf8',
});
return stdout || stderr;
} catch (error) {
return JSON.stringify(error);
@ -313,7 +319,10 @@ export async function promiseExec(command: string): Promise<string> {
export async function promiseExecSuccess(command: string): Promise<string> {
try {
const { stdout } = await promisify(exec)(command, { maxBuffer: 200 * 1024 * 1024, encoding: 'utf8' });
const { stdout } = await promisify(exec)(command, {
maxBuffer: 200 * 1024 * 1024,
encoding: 'utf8',
});
return stdout || '';
} catch (error) {
return '';
@ -413,7 +422,7 @@ export async function killTask(pid: number) {
[pid, ...pids].reverse().forEach((x) => {
process.kill(x, 15);
});
} catch (error) { }
} catch (error) {}
} else {
process.kill(pid, 2);
}
@ -440,7 +449,10 @@ export async function parseContentVersion(content: string): Promise<IVersion> {
return load(content) as IVersion;
}
export async function getUniqPath(command: string, id: string): Promise<string> {
export async function getUniqPath(
command: string,
id: string,
): Promise<string> {
if (/^\d+$/.test(id)) {
id = `_${id}`;
} else {
@ -482,7 +494,7 @@ export function safeJSONParse(value?: string) {
try {
return JSON.parse(value);
} catch (error) {
Logger.error('[JSON.parse失败]', error)
Logger.error('[JSON.parse失败]', error);
return {};
}
}
@ -494,6 +506,6 @@ export async function rmPath(path: string) {
await fs.rm(path, { force: true, recursive: true, maxRetries: 5 });
}
} catch (error) {
Logger.error('[rmPath失败]', error)
Logger.error('[rmPath失败]', error);
}
}

View File

@ -1,4 +1,4 @@
import intl from 'react-intl-universal'
import intl from 'react-intl-universal';
import { useState, useEffect, useCallback, Key, useRef } from 'react';
import {
TreeSelect,
@ -31,7 +31,7 @@ const { Text } = Typography;
const Log = () => {
const { headerStyle, isPhone, theme } = useOutletContext<SharedContext>();
const [value, setValue] = useState(intl.get('请选择日志文件'));
const [select, setSelect] = useState<string>('');
const [select, setSelect] = useState<string>(intl.get('请选择日志文件'));
const [data, setData] = useState<any[]>([]);
const [loading, setLoading] = useState(false);
const [height, setHeight] = useState<number>();
@ -117,7 +117,8 @@ const Log = () => {
<Text style={{ wordBreak: 'break-all' }} type="warning">
{select}
</Text>
{intl.get('文件')}{currentNode.type === 'directory' ? intl.get('夹下所以日志') : ''}
{intl.get('文件')}
{currentNode.type === 'directory' ? intl.get('夹下所以日志') : ''}
{intl.get(',删除后不可恢复')}
</>
),
@ -181,7 +182,16 @@ const Log = () => {
return (
<PageContainer
className="ql-container-wrapper log-wrapper"
title={select}
title={
<>
{select}
{currentNode?.type === 'file' && (
<span style={{ marginLeft: 6, fontSize: 12, color: '#999' }}>
{(currentNode.size / 1024).toFixed(3)}KB
</span>
)}
</>
}
loading={loading}
extra={
isPhone

View File

@ -50,7 +50,7 @@ const { Text } = Typography;
const Script = () => {
const { headerStyle, isPhone, theme } = useOutletContext<SharedContext>();
const [value, setValue] = useState(intl.get('请选择脚本文件'));
const [select, setSelect] = useState<string>('');
const [select, setSelect] = useState<string>(intl.get('请选择脚本文件'));
const [data, setData] = useState<any[]>([]);
const [loading, setLoading] = useState(false);
const [mode, setMode] = useState('');
@ -363,7 +363,7 @@ const Script = () => {
};
const initState = () => {
setSelect('');
setSelect(intl.get('请选择脚本文件'));
setCurrentNode(null);
setValue(intl.get('请选择脚本文件'));
};
@ -462,7 +462,16 @@ const Script = () => {
return (
<PageContainer
className="ql-container-wrapper log-wrapper"
title={select}
title={
<>
{select}
{currentNode?.type === 'file' && (
<span style={{ marginLeft: 6, fontSize: 12, color: '#999' }}>
{(currentNode.size / 1024).toFixed(3)}KB
</span>
)}
</>
}
loading={loading}
extra={
isPhone