mirror of
https://github.com/whyour/qinglong.git
synced 2025-05-22 22:36:06 +08:00
修复脚本管理删除、新建增加选择父目录
This commit is contained in:
parent
68cc792d6c
commit
96b0127811
|
@ -120,6 +120,9 @@ export default (app: Router) => {
|
||||||
if (!path.endsWith('/')) {
|
if (!path.endsWith('/')) {
|
||||||
path += '/';
|
path += '/';
|
||||||
}
|
}
|
||||||
|
if (!path.startsWith('/')) {
|
||||||
|
path = `${config.scriptPath}${path}`;
|
||||||
|
}
|
||||||
if (config.writePathList.every((x) => !path.startsWith(x))) {
|
if (config.writePathList.every((x) => !path.startsWith(x))) {
|
||||||
return res.send({
|
return res.send({
|
||||||
code: 430,
|
code: 430,
|
||||||
|
@ -184,15 +187,17 @@ export default (app: Router) => {
|
||||||
celebrate({
|
celebrate({
|
||||||
body: Joi.object({
|
body: Joi.object({
|
||||||
filename: Joi.string().required(),
|
filename: Joi.string().required(),
|
||||||
|
path: Joi.string().allow(''),
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
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 } = req.body as {
|
let { filename, path } = req.body as {
|
||||||
filename: string;
|
filename: string;
|
||||||
|
path: string;
|
||||||
};
|
};
|
||||||
const filePath = `${config.scriptPath}${filename}`;
|
const filePath = `${config.scriptPath}${path}/${filename}`;
|
||||||
fs.unlinkSync(filePath);
|
fs.unlinkSync(filePath);
|
||||||
res.send({ code: 200 });
|
res.send({ code: 200 });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -39,17 +39,11 @@ copy_dep() {
|
||||||
reload_pm2() {
|
reload_pm2() {
|
||||||
pm2 l &>/dev/null
|
pm2 l &>/dev/null
|
||||||
|
|
||||||
if test -z "$(pm2 info panel 1>/dev/null)"; then
|
pm2 delete panel --source-map-support --time &>/dev/null
|
||||||
pm2 reload panel --source-map-support --time &>/dev/null
|
pm2 start $dir_root/build/app.js -n panel --source-map-support --time &>/dev/null
|
||||||
else
|
|
||||||
pm2 start $dir_root/build/app.js -n panel --source-map-support --time &>/dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test -z "$(pm2 info schedule 1>/dev/null)"; then
|
pm2 delete schedule --source-map-support --time &>/dev/null
|
||||||
pm2 reload schedule --source-map-support --time &>/dev/null
|
pm2 start $dir_root/build/schedule.js -n schedule --source-map-support --time &>/dev/null
|
||||||
else
|
|
||||||
pm2 start $dir_root/build/schedule.js -n schedule --source-map-support --time &>/dev/null
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pm2_log() {
|
pm2_log() {
|
||||||
|
|
|
@ -318,17 +318,11 @@ patch_version() {
|
||||||
reload_pm2() {
|
reload_pm2() {
|
||||||
pm2 l &>/dev/null
|
pm2 l &>/dev/null
|
||||||
|
|
||||||
if [[ $(pm2 info panel 2>/dev/null) ]]; then
|
pm2 delete panel --source-map-support --time &>/dev/null
|
||||||
pm2 reload panel --source-map-support --time &>/dev/null
|
pm2 start $dir_root/build/app.js -n panel --source-map-support --time &>/dev/null
|
||||||
else
|
|
||||||
pm2 start $dir_root/build/app.js -n panel --source-map-support --time &>/dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $(pm2 info schedule 2>/dev/null) ]]; then
|
pm2 delete schedule --source-map-support --time &>/dev/null
|
||||||
pm2 reload schedule --source-map-support --time &>/dev/null
|
pm2 start $dir_root/build/schedule.js -n schedule --source-map-support --time &>/dev/null
|
||||||
else
|
|
||||||
pm2 start $dir_root/build/schedule.js -n schedule --source-map-support --time &>/dev/null
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
## 对比脚本
|
## 对比脚本
|
||||||
|
|
|
@ -1,28 +1,42 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { Modal, message, Input, Form } from 'antd';
|
import { Modal, message, Input, Form, Select } from 'antd';
|
||||||
import { request } from '@/utils/http';
|
import { request } from '@/utils/http';
|
||||||
import config from '@/utils/config';
|
import config from '@/utils/config';
|
||||||
|
|
||||||
|
const { Option } = Select;
|
||||||
|
|
||||||
const EditScriptNameModal = ({
|
const EditScriptNameModal = ({
|
||||||
handleCancel,
|
handleCancel,
|
||||||
|
treeData,
|
||||||
visible,
|
visible,
|
||||||
}: {
|
}: {
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
handleCancel: (file?: { filename: string }) => void;
|
treeData: any[];
|
||||||
|
handleCancel: (file?: {
|
||||||
|
filename: string;
|
||||||
|
path: string;
|
||||||
|
key: string;
|
||||||
|
}) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [dirs, setDirs] = useState<any[]>([]);
|
||||||
|
|
||||||
const handleOk = async (values: any) => {
|
const handleOk = async (values: any) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
values.path = values.path || '';
|
||||||
request
|
request
|
||||||
.post(`${config.apiPrefix}scripts`, {
|
.post(`${config.apiPrefix}scripts`, {
|
||||||
data: { filename: values.filename, content: '' },
|
data: { filename: values.filename, path: values.path, content: '' },
|
||||||
})
|
})
|
||||||
.then(({ code, data }) => {
|
.then(({ code, data }) => {
|
||||||
if (code === 200) {
|
if (code === 200) {
|
||||||
message.success('保存文件成功');
|
message.success('保存文件成功');
|
||||||
handleCancel({ filename: values.filename });
|
handleCancel({
|
||||||
|
filename: values.filename,
|
||||||
|
path: values.path,
|
||||||
|
key: `${values.path}-${values.filename}`,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
message.error(data);
|
message.error(data);
|
||||||
}
|
}
|
||||||
|
@ -33,6 +47,8 @@ const EditScriptNameModal = ({
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
form.resetFields();
|
form.resetFields();
|
||||||
|
const originDirs = treeData.filter((x) => x.disabled);
|
||||||
|
setDirs([{ key: '' }, ...originDirs]);
|
||||||
}, [visible]);
|
}, [visible]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -56,10 +72,22 @@ const EditScriptNameModal = ({
|
||||||
<Form form={form} layout="vertical" name="edit_name_modal">
|
<Form form={form} layout="vertical" name="edit_name_modal">
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="filename"
|
name="filename"
|
||||||
|
label="文件名"
|
||||||
rules={[{ required: true, message: '请输入文件名' }]}
|
rules={[{ required: true, message: '请输入文件名' }]}
|
||||||
>
|
>
|
||||||
<Input placeholder="请输入文件名" />
|
<Input placeholder="请输入文件名" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label="父目录"
|
||||||
|
name="path"
|
||||||
|
initialValue={dirs && dirs.length > 0 ? dirs[0].key : ''}
|
||||||
|
>
|
||||||
|
<Select placeholder="请选择父目录">
|
||||||
|
{dirs.map((x) => (
|
||||||
|
<Option value={x.key}>{x.key || '根'}</Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|
|
@ -113,7 +113,7 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
setValue('加载中...');
|
setValue('加载中...');
|
||||||
const newMode = value ? LangMap[value.slice(-3)] : '';
|
const newMode = value ? LangMap[value.slice(-3)] : '';
|
||||||
setMode(isPhone && newMode === 'typescript' ? 'javascript' : newMode);
|
setMode(isPhone && newMode === 'typescript' ? 'javascript' : newMode);
|
||||||
setSelect(value);
|
setSelect(node.key);
|
||||||
setTitle(node.parent || node.value);
|
setTitle(node.parent || node.value);
|
||||||
setCurrentNode(node);
|
setCurrentNode(node);
|
||||||
getDetail(node);
|
getDetail(node);
|
||||||
|
@ -167,7 +167,7 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
const cancelEdit = () => {
|
const cancelEdit = () => {
|
||||||
setIsEditing(false);
|
setIsEditing(false);
|
||||||
setValue('加载中...');
|
setValue('加载中...');
|
||||||
getDetail({ value: select });
|
getDetail(currentNode);
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveFile = () => {
|
const saveFile = () => {
|
||||||
|
@ -177,7 +177,7 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
<>
|
<>
|
||||||
确认保存文件
|
确认保存文件
|
||||||
<Text style={{ wordBreak: 'break-all' }} type="warning">
|
<Text style={{ wordBreak: 'break-all' }} type="warning">
|
||||||
{select}
|
{currentNode.value}
|
||||||
</Text>{' '}
|
</Text>{' '}
|
||||||
,保存后不可恢复
|
,保存后不可恢复
|
||||||
</>
|
</>
|
||||||
|
@ -190,7 +190,7 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
request
|
request
|
||||||
.put(`${config.apiPrefix}scripts`, {
|
.put(`${config.apiPrefix}scripts`, {
|
||||||
data: {
|
data: {
|
||||||
filename: select,
|
filename: currentNode.value,
|
||||||
path: currentNode.parent || '',
|
path: currentNode.parent || '',
|
||||||
content,
|
content,
|
||||||
},
|
},
|
||||||
|
@ -230,15 +230,30 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
request
|
request
|
||||||
.delete(`${config.apiPrefix}scripts`, {
|
.delete(`${config.apiPrefix}scripts`, {
|
||||||
data: {
|
data: {
|
||||||
filename: select,
|
filename: currentNode.value,
|
||||||
|
path: currentNode.parent || '',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then((_data: any) => {
|
.then((_data: any) => {
|
||||||
if (_data.code === 200) {
|
if (_data.code === 200) {
|
||||||
message.success(`删除成功`);
|
message.success(`删除成功`);
|
||||||
let newData = [...data];
|
let newData = [...data];
|
||||||
const index = newData.findIndex((x) => x.value === select);
|
if (currentNode.parent) {
|
||||||
newData.splice(index, 1);
|
const parentNodeIndex = newData.findIndex(
|
||||||
|
(x) => x.key === currentNode.parent,
|
||||||
|
);
|
||||||
|
const parentNode = newData[parentNodeIndex];
|
||||||
|
const index = parentNode.children.findIndex(
|
||||||
|
(y) => y.key === currentNode.key,
|
||||||
|
);
|
||||||
|
parentNode.children.splice(index, 1);
|
||||||
|
newData.splice(parentNodeIndex, 1, { ...parentNode });
|
||||||
|
} else {
|
||||||
|
const index = newData.findIndex(
|
||||||
|
(x) => x.key === currentNode.key,
|
||||||
|
);
|
||||||
|
newData.splice(index, 1);
|
||||||
|
}
|
||||||
setData(newData);
|
setData(newData);
|
||||||
} else {
|
} else {
|
||||||
message.error(_data);
|
message.error(_data);
|
||||||
|
@ -256,12 +271,27 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const addFileModalClose = (
|
const addFileModalClose = (
|
||||||
{ filename }: { filename: string } = { filename: '' },
|
{ filename, path, key }: { filename: string; path: string; key: string } = {
|
||||||
|
filename: '',
|
||||||
|
path: '',
|
||||||
|
key: '',
|
||||||
|
},
|
||||||
) => {
|
) => {
|
||||||
if (filename) {
|
if (filename) {
|
||||||
const newData = [...data];
|
const newData = [...data];
|
||||||
const _file = { title: filename, key: filename, value: filename };
|
const _file = { title: filename, key, value: filename, parent: path };
|
||||||
newData.unshift(_file);
|
if (path) {
|
||||||
|
const parentNodeIndex = newData.findIndex((x) => x.key === path);
|
||||||
|
const parentNode = newData[parentNodeIndex];
|
||||||
|
if (parentNode.children && parentNode.children.length > 0) {
|
||||||
|
parentNode.children.unshift(_file);
|
||||||
|
} else {
|
||||||
|
parentNode.children = [_file];
|
||||||
|
}
|
||||||
|
newData.splice(parentNodeIndex, 1, { ...parentNode });
|
||||||
|
} else {
|
||||||
|
newData.unshift(_file);
|
||||||
|
}
|
||||||
setData(newData);
|
setData(newData);
|
||||||
onSelect(_file.value, _file);
|
onSelect(_file.value, _file);
|
||||||
setIsEditing(true);
|
setIsEditing(true);
|
||||||
|
@ -273,7 +303,7 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
request
|
request
|
||||||
.post(`${config.apiPrefix}scripts/download`, {
|
.post(`${config.apiPrefix}scripts/download`, {
|
||||||
data: {
|
data: {
|
||||||
filename: select,
|
filename: currentNode.value,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then((_data: any) => {
|
.then((_data: any) => {
|
||||||
|
@ -281,7 +311,7 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
const url = URL.createObjectURL(blob);
|
const url = URL.createObjectURL(blob);
|
||||||
const a = document.createElement('a');
|
const a = document.createElement('a');
|
||||||
a.href = url;
|
a.href = url;
|
||||||
a.download = select;
|
a.download = currentNode.value;
|
||||||
document.documentElement.appendChild(a);
|
document.documentElement.appendChild(a);
|
||||||
a.click();
|
a.click();
|
||||||
document.documentElement.removeChild(a);
|
document.documentElement.removeChild(a);
|
||||||
|
@ -319,10 +349,20 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
<Menu.Item key="add" icon={<PlusOutlined />} onClick={addFile}>
|
<Menu.Item key="add" icon={<PlusOutlined />} onClick={addFile}>
|
||||||
添加
|
添加
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key="edit" icon={<EditOutlined />} onClick={editFile}>
|
<Menu.Item
|
||||||
|
key="edit"
|
||||||
|
icon={<EditOutlined />}
|
||||||
|
onClick={editFile}
|
||||||
|
disabled={!select}
|
||||||
|
>
|
||||||
编辑
|
编辑
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key="delete" icon={<DeleteOutlined />} onClick={deleteFile}>
|
<Menu.Item
|
||||||
|
key="delete"
|
||||||
|
icon={<DeleteOutlined />}
|
||||||
|
onClick={deleteFile}
|
||||||
|
disabled={!select}
|
||||||
|
>
|
||||||
删除
|
删除
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
</Menu>
|
</Menu>
|
||||||
|
@ -368,6 +408,7 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
</Tooltip>,
|
</Tooltip>,
|
||||||
<Tooltip title="编辑">
|
<Tooltip title="编辑">
|
||||||
<Button
|
<Button
|
||||||
|
disabled={!select}
|
||||||
type="primary"
|
type="primary"
|
||||||
onClick={editFile}
|
onClick={editFile}
|
||||||
icon={<EditOutlined />}
|
icon={<EditOutlined />}
|
||||||
|
@ -376,6 +417,7 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
<Tooltip title="删除">
|
<Tooltip title="删除">
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
|
disabled={!select}
|
||||||
onClick={deleteFile}
|
onClick={deleteFile}
|
||||||
icon={<DeleteOutlined />}
|
icon={<DeleteOutlined />}
|
||||||
/>
|
/>
|
||||||
|
@ -459,6 +501,7 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
/>
|
/>
|
||||||
<EditScriptNameModal
|
<EditScriptNameModal
|
||||||
visible={isAddFileModalVisible}
|
visible={isAddFileModalVisible}
|
||||||
|
treeData={data}
|
||||||
handleCancel={addFileModalClose}
|
handleCancel={addFileModalClose}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user