脚本管理改成树结构

This commit is contained in:
whyour 2021-11-11 00:10:05 +08:00
parent 606bac2e43
commit 50dd235e39
2 changed files with 44 additions and 20 deletions

View File

@ -18,14 +18,33 @@ export default (app: Router) => {
const fileList = fs.readdirSync(config.scriptPath, 'utf-8'); const fileList = fs.readdirSync(config.scriptPath, 'utf-8');
res.send({ res.send({
code: 200, code: 200,
data: fileList data: fileList.map((x) => {
.filter((x) => { if (fs.lstatSync(config.scriptPath + x).isDirectory()) {
return !fs.lstatSync(config.scriptPath + x).isDirectory(); const childFileList = fs.readdirSync(
}) config.scriptPath + x,
.map((x) => { 'utf-8',
);
return {
title: x,
value: x,
key: x,
disabled: true,
children: childFileList.map((y) => {
const statObj = fs.statSync(`${config.scriptPath}${x}/${y}`);
return {
title: y,
value: y,
key: y,
mtime: statObj.mtimeMs,
parent: x,
};
}),
};
} else {
const statObj = fs.statSync(config.scriptPath + x); const statObj = fs.statSync(config.scriptPath + x);
return { title: x, value: x, key: x, mtime: statObj.mtimeMs }; return { title: x, value: x, key: x, mtime: statObj.mtimeMs };
}), }
}),
}); });
} catch (e) { } catch (e) {
logger.error('🔥 error: %o', e); logger.error('🔥 error: %o', e);
@ -39,8 +58,9 @@ export default (app: Router) => {
async (req: Request, res: Response, next: NextFunction) => { async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger'); const logger: Logger = Container.get('logger');
try { try {
const path = req.query.path ? `${req.query.path}/` : '';
const content = getFileContentByName( const content = getFileContentByName(
`${config.scriptPath}${req.params.file}`, `${config.scriptPath}${path}${req.params.file}`,
); );
res.send({ code: 200, data: content }); res.send({ code: 200, data: content });
} catch (e) { } catch (e) {
@ -112,17 +132,19 @@ export default (app: Router) => {
celebrate({ celebrate({
body: Joi.object({ body: Joi.object({
filename: Joi.string().required(), filename: Joi.string().required(),
path: Joi.string().allow(''),
content: Joi.string().required(), content: Joi.string().required(),
}), }),
}), }),
async (req: Request, res: Response, next: NextFunction) => { async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger'); const logger: Logger = Container.get('logger');
try { try {
let { filename, content } = req.body as { let { filename, content, path } = req.body as {
filename: string; filename: string;
content: string; content: string;
path: string;
}; };
const filePath = `${config.scriptPath}${filename}`; const filePath = `${config.scriptPath}${path}/${filename}`;
fs.writeFileSync(filePath, content); fs.writeFileSync(filePath, content);
return res.send({ code: 200 }); return res.send({ code: 200 });
} catch (e) { } catch (e) {

View File

@ -69,7 +69,7 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
const [isEditing, setIsEditing] = useState(false); const [isEditing, setIsEditing] = useState(false);
const editorRef = useRef<any>(null); const editorRef = useRef<any>(null);
const [isAddFileModalVisible, setIsAddFileModalVisible] = useState(false); const [isAddFileModalVisible, setIsAddFileModalVisible] = useState(false);
const [dropdownIsVisible, setDropdownIsVisible] = useState(false); const [currentNode, setCurrentNode] = useState<any>();
const getScripts = () => { const getScripts = () => {
setLoading(true); setLoading(true);
@ -85,9 +85,11 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
}; };
const getDetail = (node: any) => { const getDetail = (node: any) => {
request.get(`${config.apiPrefix}scripts/${node.value}`).then((data) => { request
setValue(data.data); .get(`${config.apiPrefix}scripts/${node.value}?path=${node.parent || ''}`)
}); .then((data) => {
setValue(data.data);
});
}; };
const onSelect = (value: any, node: any) => { const onSelect = (value: any, node: any) => {
@ -99,6 +101,7 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
setMode(isPhone && newMode === 'typescript' ? 'javascript' : newMode); setMode(isPhone && newMode === 'typescript' ? 'javascript' : newMode);
setSelect(value); setSelect(value);
setTitle(node.parent || node.value); setTitle(node.parent || node.value);
setCurrentNode(node);
getDetail(node); getDetail(node);
}; };
@ -165,11 +168,12 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
const content = editorRef.current const content = editorRef.current
? editorRef.current.getValue().replace(/\r\n/g, '\n') ? editorRef.current.getValue().replace(/\r\n/g, '\n')
: value; : value;
return new Promise((resolve) => { return new Promise((resolve, reject) => {
request request
.put(`${config.apiPrefix}scripts`, { .put(`${config.apiPrefix}scripts`, {
data: { data: {
filename: select, filename: select,
path: currentNode.parent || '',
content, content,
}, },
}) })
@ -182,7 +186,8 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
message.error(_data); message.error(_data);
} }
resolve(null); resolve(null);
}); })
.catch((e) => reject(e));
}); });
}, },
onCancel() { onCancel() {
@ -270,6 +275,7 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
const { tree } = getFilterData(word.toLocaleLowerCase(), data); const { tree } = getFilterData(word.toLocaleLowerCase(), data);
setFilterData(tree); setFilterData(tree);
setSelect(''); setSelect('');
setCurrentNode(null);
setTitle('请选择脚本文件'); setTitle('请选择脚本文件');
setValue('请选择脚本文件'); setValue('请选择脚本文件');
}, [data]); }, [data]);
@ -322,11 +328,7 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
key="value" key="value"
onSelect={onSelect} onSelect={onSelect}
/>, />,
<Dropdown <Dropdown overlay={menu} trigger={['click']}>
overlay={menu}
trigger={['click']}
onVisibleChange={(visible) => setDropdownIsVisible(visible)}
>
<Button type="primary" icon={<EllipsisOutlined />} /> <Button type="primary" icon={<EllipsisOutlined />} />
</Dropdown>, </Dropdown>,
] ]