mirror of
https://github.com/whyour/qinglong.git
synced 2025-05-23 06:46:09 +08:00
脚本管理支持新增文件
This commit is contained in:
parent
646443deb5
commit
0baf0d23ae
|
@ -23,7 +23,8 @@ export default (app: Router) => {
|
||||||
return !fs.lstatSync(config.scriptPath + x).isDirectory();
|
return !fs.lstatSync(config.scriptPath + x).isDirectory();
|
||||||
})
|
})
|
||||||
.map((x) => {
|
.map((x) => {
|
||||||
return { title: x, value: x, key: x };
|
const statObj = fs.statSync(config.scriptPath + x);
|
||||||
|
return { title: x, value: x, key: x, mtime: statObj.mtimeMs };
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -54,34 +55,46 @@ export default (app: Router) => {
|
||||||
celebrate({
|
celebrate({
|
||||||
body: Joi.object({
|
body: Joi.object({
|
||||||
filename: Joi.string().required(),
|
filename: Joi.string().required(),
|
||||||
path: Joi.string().required(),
|
path: Joi.string().allow(''),
|
||||||
content: Joi.string().required(),
|
content: Joi.string().allow(''),
|
||||||
|
originFilename: 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, path, content } = req.body as {
|
let { filename, path, content, originFilename } = req.body as {
|
||||||
filename: string;
|
filename: string;
|
||||||
path: string;
|
path: string;
|
||||||
content: string;
|
content: string;
|
||||||
|
originFilename: string;
|
||||||
};
|
};
|
||||||
|
if (!path) {
|
||||||
|
path = config.scriptPath;
|
||||||
|
}
|
||||||
if (!path.endsWith('/')) {
|
if (!path.endsWith('/')) {
|
||||||
path += '/';
|
path += '/';
|
||||||
}
|
}
|
||||||
if (config.writePathList.every((x) => !path.startsWith(x))) {
|
if (config.writePathList.every((x) => !path.startsWith(x))) {
|
||||||
return res.send({
|
return res.send({
|
||||||
code: 400,
|
code: 430,
|
||||||
data: '文件路径错误,可保存目录/ql/scripts、/ql/config、/ql/jbot、/ql/bak',
|
data: '文件路径禁止访问',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const originFilePath = `${path}${originFilename.replace(/\//g, '')}`;
|
||||||
const filePath = `${path}${filename.replace(/\//g, '')}`;
|
const filePath = `${path}${filename.replace(/\//g, '')}`;
|
||||||
const bakPath = '/ql/bak';
|
if (fs.existsSync(originFilePath)) {
|
||||||
if (fs.existsSync(filePath)) {
|
if (!fs.existsSync(config.bakPath)) {
|
||||||
if (!fs.existsSync(bakPath)) {
|
fs.mkdirSync(config.bakPath);
|
||||||
fs.mkdirSync(bakPath);
|
}
|
||||||
|
fs.copyFileSync(
|
||||||
|
originFilePath,
|
||||||
|
`${config.bakPath}${originFilename.replace(/\//g, '')}`,
|
||||||
|
);
|
||||||
|
if (filename !== originFilename) {
|
||||||
|
fs.unlinkSync(originFilePath);
|
||||||
}
|
}
|
||||||
fs.copyFileSync(filePath, bakPath);
|
|
||||||
}
|
}
|
||||||
fs.writeFileSync(filePath, content);
|
fs.writeFileSync(filePath, content);
|
||||||
return res.send({ code: 200 });
|
return res.send({ code: 200 });
|
||||||
|
@ -139,4 +152,35 @@ export default (app: Router) => {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
route.post(
|
||||||
|
'/scripts/download',
|
||||||
|
celebrate({
|
||||||
|
body: Joi.object({
|
||||||
|
filename: Joi.string().required(),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
async (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
const logger: Logger = Container.get('logger');
|
||||||
|
try {
|
||||||
|
let { filename } = req.body as {
|
||||||
|
filename: string;
|
||||||
|
};
|
||||||
|
const filePath = `${config.scriptPath}${filename}`;
|
||||||
|
// const stats = fs.statSync(filePath);
|
||||||
|
// res.set({
|
||||||
|
// 'Content-Type': 'application/octet-stream', //告诉浏览器这是一个二进制文件
|
||||||
|
// 'Content-Disposition': 'attachment; filename=' + filename, //告诉浏览器这是一个需要下载的文件
|
||||||
|
// 'Content-Length': stats.size //文件大小
|
||||||
|
// });
|
||||||
|
// fs.createReadStream(filePath).pipe(res);
|
||||||
|
return res.download(filePath, filename, (err) => {
|
||||||
|
return next(err);
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
logger.error('🔥 error: %o', e);
|
||||||
|
return next(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { createRandomString } from './util';
|
||||||
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
|
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
|
||||||
|
|
||||||
const envFound = dotenv.config();
|
const envFound = dotenv.config();
|
||||||
const rootPath = path.resolve(__dirname, '../../');
|
const rootPath = process.cwd();
|
||||||
const envFile = path.join(rootPath, 'config/env.sh');
|
const envFile = path.join(rootPath, 'config/env.sh');
|
||||||
const confFile = path.join(rootPath, 'config/config.sh');
|
const confFile = path.join(rootPath, 'config/config.sh');
|
||||||
const sampleFile = path.join(rootPath, 'sample/config.sample.sh');
|
const sampleFile = path.join(rootPath, 'sample/config.sample.sh');
|
||||||
|
@ -15,6 +15,7 @@ const authConfigFile = path.join(rootPath, 'config/auth.json');
|
||||||
const extraFile = path.join(rootPath, 'config/extra.sh');
|
const extraFile = path.join(rootPath, 'config/extra.sh');
|
||||||
const configPath = path.join(rootPath, 'config/');
|
const configPath = path.join(rootPath, 'config/');
|
||||||
const scriptPath = path.join(rootPath, 'scripts/');
|
const scriptPath = path.join(rootPath, 'scripts/');
|
||||||
|
const bakPath = path.join(rootPath, 'bak/');
|
||||||
const samplePath = path.join(rootPath, 'sample/');
|
const samplePath = path.join(rootPath, 'sample/');
|
||||||
const logPath = path.join(rootPath, 'log/');
|
const logPath = path.join(rootPath, 'log/');
|
||||||
const authError = '错误的用户名密码,请重试';
|
const authError = '错误的用户名密码,请重试';
|
||||||
|
@ -46,6 +47,7 @@ export default {
|
||||||
api: {
|
api: {
|
||||||
prefix: '/api',
|
prefix: '/api',
|
||||||
},
|
},
|
||||||
|
rootPath,
|
||||||
configString,
|
configString,
|
||||||
loginFaild,
|
loginFaild,
|
||||||
authError,
|
authError,
|
||||||
|
@ -72,5 +74,6 @@ export default {
|
||||||
'crontab.list',
|
'crontab.list',
|
||||||
'env.sh',
|
'env.sh',
|
||||||
],
|
],
|
||||||
writePathList: ['/ql/scripts/', '/ql/config/', '/ql/jbot/', '/ql/bak/'],
|
writePathList: [configPath, scriptPath],
|
||||||
|
bakPath,
|
||||||
};
|
};
|
||||||
|
|
1
bak/bv.log
Normal file
1
bak/bv.log
Normal file
|
@ -0,0 +1 @@
|
||||||
|
123123123
|
8
bak/bv3.log
Normal file
8
bak/bv3.log
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
123123123sdfasdfdjflsdjflad
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
所肩负的拉三季度福利静安寺两地分居阿临时冻结发了;阿克苏剪短发拉加快速度联发科;就的说法
|
||||||
|
|
||||||
|
阿斯顿发斯蒂芬是打发斯蒂芬阿斯顿发斯蒂芬
|
||||||
|
// 阿斯顿发双方都
|
|
@ -41,7 +41,7 @@ function getFilterData(keyword: string, data: any) {
|
||||||
const Log = ({ headerStyle, isPhone, theme }: any) => {
|
const Log = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
const [title, setTitle] = useState('请选择日志文件');
|
const [title, setTitle] = useState('请选择日志文件');
|
||||||
const [value, setValue] = useState('请选择日志文件');
|
const [value, setValue] = useState('请选择日志文件');
|
||||||
const [select, setSelect] = useState();
|
const [select, setSelect] = useState<any>();
|
||||||
const [data, setData] = useState<any[]>([]);
|
const [data, setData] = useState<any[]>([]);
|
||||||
const [filterData, setFilterData] = useState<any[]>([]);
|
const [filterData, setFilterData] = useState<any[]>([]);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
@ -84,6 +84,9 @@ const Log = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSelect = (value: any, node: any) => {
|
const onSelect = (value: any, node: any) => {
|
||||||
|
if (node.key === select || !value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
setValue('加载中...');
|
setValue('加载中...');
|
||||||
setSelect(value);
|
setSelect(value);
|
||||||
setTitle(node.parent || node.value);
|
setTitle(node.parent || node.value);
|
||||||
|
@ -147,6 +150,7 @@ const Log = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
treeData={filterData}
|
treeData={filterData}
|
||||||
showIcon={true}
|
showIcon={true}
|
||||||
height={height}
|
height={height}
|
||||||
|
selectedKeys={[select]}
|
||||||
showLine={{ showLeafIcon: true }}
|
showLine={{ showLeafIcon: true }}
|
||||||
onSelect={onTreeSelect}
|
onSelect={onTreeSelect}
|
||||||
></Tree>
|
></Tree>
|
||||||
|
|
|
@ -41,7 +41,6 @@ const EditModal = ({
|
||||||
const [saveModalVisible, setSaveModalVisible] = useState<boolean>(false);
|
const [saveModalVisible, setSaveModalVisible] = useState<boolean>(false);
|
||||||
const [settingModalVisible, setSettingModalVisible] =
|
const [settingModalVisible, setSettingModalVisible] =
|
||||||
useState<boolean>(false);
|
useState<boolean>(false);
|
||||||
const [isNewFile, setIsNewFile] = useState<boolean>(false);
|
|
||||||
const [log, setLog] = useState<string>('');
|
const [log, setLog] = useState<string>('');
|
||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
const editorRef = useRef<any>(null);
|
const editorRef = useRef<any>(null);
|
||||||
|
@ -54,7 +53,6 @@ const EditModal = ({
|
||||||
const newMode = LangMap[value.slice(-3)] || '';
|
const newMode = LangMap[value.slice(-3)] || '';
|
||||||
setFileName(value);
|
setFileName(value);
|
||||||
setLanguage(newMode);
|
setLanguage(newMode);
|
||||||
setIsNewFile(false);
|
|
||||||
getDetail(node);
|
getDetail(node);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -64,23 +62,14 @@ const EditModal = ({
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const createFile = () => {
|
|
||||||
setFileName(`未命名${prefixMap[language]}`);
|
|
||||||
setIsNewFile(true);
|
|
||||||
setValue('');
|
|
||||||
};
|
|
||||||
|
|
||||||
const run = () => {};
|
const run = () => {};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!currentFile) {
|
if (currentFile) {
|
||||||
createFile();
|
|
||||||
} else {
|
|
||||||
setFileName(currentFile);
|
setFileName(currentFile);
|
||||||
setValue(content as string);
|
setValue(content as string);
|
||||||
}
|
}
|
||||||
setIsNewFile(!currentFile);
|
}, [currentFile, content]);
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Drawer
|
<Drawer
|
||||||
|
@ -131,13 +120,6 @@ const EditModal = ({
|
||||||
>
|
>
|
||||||
设置
|
设置
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
|
||||||
type="primary"
|
|
||||||
style={{ marginRight: 8 }}
|
|
||||||
onClick={createFile}
|
|
||||||
>
|
|
||||||
新建文件
|
|
||||||
</Button>
|
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
style={{ marginRight: 8 }}
|
style={{ marginRight: 8 }}
|
||||||
|
@ -178,8 +160,12 @@ const EditModal = ({
|
||||||
handleCancel={() => {
|
handleCancel={() => {
|
||||||
setSaveModalVisible(false);
|
setSaveModalVisible(false);
|
||||||
}}
|
}}
|
||||||
isNewFile={isNewFile}
|
file={{
|
||||||
file={{ content: editorRef.current && editorRef.current.getValue().replace(/\r\n/g, '\n'), filename: fileName }}
|
content:
|
||||||
|
editorRef.current &&
|
||||||
|
editorRef.current.getValue().replace(/\r\n/g, '\n'),
|
||||||
|
filename: fileName,
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<SettingModal
|
<SettingModal
|
||||||
visible={settingModalVisible}
|
visible={settingModalVisible}
|
||||||
|
|
68
src/pages/script/editNameModal.tsx
Normal file
68
src/pages/script/editNameModal.tsx
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { Modal, message, Input, Form } from 'antd';
|
||||||
|
import { request } from '@/utils/http';
|
||||||
|
import config from '@/utils/config';
|
||||||
|
|
||||||
|
const EditScriptNameModal = ({
|
||||||
|
handleCancel,
|
||||||
|
visible,
|
||||||
|
}: {
|
||||||
|
visible: boolean;
|
||||||
|
handleCancel: (file: { filename: string }) => void;
|
||||||
|
}) => {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
const handleOk = async (values: any) => {
|
||||||
|
setLoading(true);
|
||||||
|
request
|
||||||
|
.post(`${config.apiPrefix}scripts`, {
|
||||||
|
data: { filename: values.filename, content: '' },
|
||||||
|
})
|
||||||
|
.then(({ code, data }) => {
|
||||||
|
if (code === 200) {
|
||||||
|
message.success('保存文件成功');
|
||||||
|
handleCancel({ filename: values.filename });
|
||||||
|
} else {
|
||||||
|
message.error(data);
|
||||||
|
}
|
||||||
|
setLoading(false);
|
||||||
|
})
|
||||||
|
.finally(() => setLoading(false));
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
form.resetFields();
|
||||||
|
}, [visible]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
title="新建文件"
|
||||||
|
visible={visible}
|
||||||
|
forceRender
|
||||||
|
onOk={() => {
|
||||||
|
form
|
||||||
|
.validateFields()
|
||||||
|
.then((values) => {
|
||||||
|
handleOk(values);
|
||||||
|
})
|
||||||
|
.catch((info) => {
|
||||||
|
console.log('Validate Failed:', info);
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
onCancel={() => handleCancel()}
|
||||||
|
confirmLoading={loading}
|
||||||
|
>
|
||||||
|
<Form form={form} layout="vertical" name="edit_name_modal">
|
||||||
|
<Form.Item
|
||||||
|
name="filename"
|
||||||
|
rules={[{ required: true, message: '请输入文件名' }]}
|
||||||
|
>
|
||||||
|
<Input placeholder="请输入文件名" />
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default EditScriptNameModal;
|
|
@ -7,6 +7,7 @@ import {
|
||||||
Modal,
|
Modal,
|
||||||
message,
|
message,
|
||||||
Typography,
|
Typography,
|
||||||
|
Tooltip,
|
||||||
} from 'antd';
|
} from 'antd';
|
||||||
import config from '@/utils/config';
|
import config from '@/utils/config';
|
||||||
import { PageContainer } from '@ant-design/pro-layout';
|
import { PageContainer } from '@ant-design/pro-layout';
|
||||||
|
@ -16,6 +17,16 @@ import styles from './index.module.less';
|
||||||
import EditModal from './editModal';
|
import EditModal from './editModal';
|
||||||
import { Controlled as CodeMirror } from 'react-codemirror2';
|
import { Controlled as CodeMirror } from 'react-codemirror2';
|
||||||
import SplitPane from 'react-split-pane';
|
import SplitPane from 'react-split-pane';
|
||||||
|
import {
|
||||||
|
DeleteOutlined,
|
||||||
|
DownloadOutlined,
|
||||||
|
EditOutlined,
|
||||||
|
FormOutlined,
|
||||||
|
PlusOutlined,
|
||||||
|
PlusSquareOutlined,
|
||||||
|
SearchOutlined,
|
||||||
|
} from '@ant-design/icons';
|
||||||
|
import EditScriptNameModal from './editNameModal';
|
||||||
|
|
||||||
const { Text } = Typography;
|
const { Text } = Typography;
|
||||||
|
|
||||||
|
@ -53,15 +64,17 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
const [searchValue, setSearchValue] = useState('');
|
const [searchValue, setSearchValue] = useState('');
|
||||||
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 getScripts = () => {
|
const getScripts = () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
request
|
request
|
||||||
.get(`${config.apiPrefix}scripts/files`)
|
.get(`${config.apiPrefix}scripts/files`)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
setData(data.data);
|
const sortData = data.data.sort((a: any, b: any) => b.mtime - a.mtime);
|
||||||
setFilterData(data.data);
|
setData(sortData);
|
||||||
onSelect(data.data[0].value, data.data[0]);
|
setFilterData(sortData);
|
||||||
|
onSelect(sortData[0].value, sortData[0]);
|
||||||
})
|
})
|
||||||
.finally(() => setLoading(false));
|
.finally(() => setLoading(false));
|
||||||
};
|
};
|
||||||
|
@ -102,6 +115,7 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
setIsEditing(false);
|
||||||
onSelect(keys[0], e.node);
|
onSelect(keys[0], e.node);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -207,6 +221,42 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const addFile = () => {
|
||||||
|
setIsAddFileModalVisible(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const addFileModalClose = (
|
||||||
|
{ filename }: { filename: string } = { filename: '' },
|
||||||
|
) => {
|
||||||
|
if (filename) {
|
||||||
|
const newData = [...data];
|
||||||
|
const _file = { title: filename, key: filename, value: filename };
|
||||||
|
newData.unshift(_file);
|
||||||
|
setData(newData);
|
||||||
|
onSelect(_file.value, _file);
|
||||||
|
}
|
||||||
|
setIsAddFileModalVisible(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const downloadFile = () => {
|
||||||
|
request
|
||||||
|
.post(`${config.apiPrefix}scripts/download`, {
|
||||||
|
data: {
|
||||||
|
filename: select,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((_data: any) => {
|
||||||
|
const blob = new Blob([_data], { type: 'application/json' });
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = select;
|
||||||
|
document.documentElement.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.documentElement.removeChild(a);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const word = searchValue || '';
|
const word = searchValue || '';
|
||||||
const { tree } = getFilterData(word.toLocaleLowerCase(), data);
|
const { tree } = getFilterData(word.toLocaleLowerCase(), data);
|
||||||
|
@ -255,12 +305,30 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
</Button>,
|
</Button>,
|
||||||
]
|
]
|
||||||
: [
|
: [
|
||||||
<Button type="primary" onClick={editFile}>
|
<Tooltip title="新建">
|
||||||
编辑
|
<Button
|
||||||
</Button>,
|
type="primary"
|
||||||
<Button type="primary" onClick={deleteFile}>
|
onClick={addFile}
|
||||||
删除
|
icon={<PlusOutlined />}
|
||||||
</Button>,
|
/>
|
||||||
|
</Tooltip>,
|
||||||
|
<Tooltip title="编辑">
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
onClick={editFile}
|
||||||
|
icon={<EditOutlined />}
|
||||||
|
/>
|
||||||
|
</Tooltip>,
|
||||||
|
<Tooltip title="删除">
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
onClick={deleteFile}
|
||||||
|
icon={<DeleteOutlined />}
|
||||||
|
/>
|
||||||
|
</Tooltip>,
|
||||||
|
// <Tooltip title="下载">
|
||||||
|
// <Button type="primary" onClick={downloadFile} icon={<DownloadOutlined />} />
|
||||||
|
// </Tooltip>,
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
@ -338,6 +406,10 @@ const Script = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
setIsLogModalVisible(false);
|
setIsLogModalVisible(false);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<EditScriptNameModal
|
||||||
|
visible={isAddFileModalVisible}
|
||||||
|
handleCancel={addFileModalClose}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</PageContainer>
|
</PageContainer>
|
||||||
);
|
);
|
||||||
|
|
|
@ -7,19 +7,17 @@ const SaveModal = ({
|
||||||
file,
|
file,
|
||||||
handleCancel,
|
handleCancel,
|
||||||
visible,
|
visible,
|
||||||
isNewFile,
|
|
||||||
}: {
|
}: {
|
||||||
file?: any;
|
file?: any;
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
handleCancel: (cks?: any[]) => void;
|
handleCancel: (cks?: any[]) => void;
|
||||||
isNewFile: boolean;
|
|
||||||
}) => {
|
}) => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
const handleOk = async (values: any) => {
|
const handleOk = async (values: any) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const payload = { ...file, ...values };
|
const payload = { ...file, ...values, originFilename: file.filename };
|
||||||
request
|
request
|
||||||
.post(`${config.apiPrefix}scripts`, {
|
.post(`${config.apiPrefix}scripts`, {
|
||||||
data: payload,
|
data: payload,
|
||||||
|
@ -71,12 +69,8 @@ const SaveModal = ({
|
||||||
>
|
>
|
||||||
<Input placeholder="请输入文件名" />
|
<Input placeholder="请输入文件名" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item name="path" label="保存目录">
|
||||||
name="path"
|
<Input placeholder="请输入保存目录,默认scripts目录" />
|
||||||
label="保存目录"
|
|
||||||
rules={[{ required: true, message: '请输入保存目录' }]}
|
|
||||||
>
|
|
||||||
<Input placeholder="请输入保存目录" />
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user