修复创建脚本可能失败

This commit is contained in:
whyour 2025-05-20 01:00:08 +08:00
parent b6ea8565ec
commit 1a185f5682
28 changed files with 213 additions and 279 deletions

View File

@ -116,7 +116,9 @@ export default async () => {
`Neither content nor source specified for ${item.target}`,
);
}
const content = item.content || (await fs.readFile(item.source!));
const content =
item.content ||
(await fs.readFile(item.source!, { encoding: 'utf-8' }));
await writeFileWithLock(item.target, content);
}
}

View File

@ -560,7 +560,10 @@ export default class CronService {
if (logFileExist) {
return await getFileContentByName(`${absolutePath}`);
} else {
return '任务未运行';
return typeof doc.status === 'number' &&
[CrontabStatus.queued, CrontabStatus.running].includes(doc.status)
? '运行中...'
: '任务空闲中';
}
}

View File

@ -13,7 +13,7 @@ function getUniqueLockPath(filePath: string) {
export async function writeFileWithLock(
filePath: string,
content: string | Buffer,
content: string,
options: Parameters<typeof writeFile>[2] = {},
) {
if (typeof options === 'string') {

View File

@ -56,12 +56,10 @@ interface LogItem {
const CronDetailModal = ({
cron = {},
handleCancel,
visible,
theme,
isPhone,
}: {
cron?: any;
visible: boolean;
handleCancel: (needUpdate?: boolean) => void;
theme: string;
isPhone: boolean;
@ -440,7 +438,7 @@ const CronDetailModal = ({
</div>
}
centered
open={visible}
open={true}
forceRender
footer={false}
onCancel={() => handleCancel()}
@ -559,15 +557,16 @@ const CronDetailModal = ({
{contentList[activeTabKey]}
</Card>
</div>
<CronLogModal
visible={isLogModalVisible}
handleCancel={() => {
setIsLogModalVisible(false);
}}
cron={cron}
data={log}
logUrl={logUrl}
/>
{isLogModalVisible && (
<CronLogModal
handleCancel={() => {
setIsLogModalVisible(false);
}}
cron={cron}
data={log}
logUrl={logUrl}
/>
)}
</Modal>
);
};

View File

@ -1037,55 +1037,58 @@ const Crontab = () => {
components={isPhone || pageConf.size < 50 ? undefined : vt}
/>
</div>
<CronLogModal
visible={isLogModalVisible}
handleCancel={() => {
getCronDetail(logCron);
setIsLogModalVisible(false);
}}
cron={logCron}
/>
<CronModal
visible={isModalVisible}
handleCancel={handleCancel}
cron={editedCron}
/>
<CronLabelModal
visible={isLabelModalVisible}
handleCancel={(needUpdate?: boolean) => {
setIsLabelModalVisible(false);
if (needUpdate) {
getCrons();
}
}}
ids={selectedRowIds}
/>
<CronDetailModal
visible={isDetailModalVisible}
handleCancel={() => {
setIsDetailModalVisible(false);
}}
cron={detailCron}
theme={theme}
isPhone={isPhone}
/>
<ViewCreateModal
visible={isCreateViewModalVisible}
handleCancel={(data) => {
setIsCreateViewModalVisible(false);
getCronViews();
}}
/>
<ViewManageModal
cronViews={cronViews}
visible={isViewManageModalVisible}
handleCancel={() => {
setIsViewManageModalVisible(false);
}}
cronViewChange={(data) => {
getCronViews();
}}
/>
{isLogModalVisible && (
<CronLogModal
handleCancel={() => {
getCronDetail(logCron);
setIsLogModalVisible(false);
}}
cron={logCron}
/>
)}
{isModalVisible && (
<CronModal handleCancel={handleCancel} cron={editedCron} />
)}
{isLabelModalVisible && (
<CronLabelModal
handleCancel={(needUpdate?: boolean) => {
setIsLabelModalVisible(false);
if (needUpdate) {
getCrons();
}
}}
ids={selectedRowIds}
/>
)}
{isDetailModalVisible && (
<CronDetailModal
handleCancel={() => {
setIsDetailModalVisible(false);
}}
cron={detailCron}
theme={theme}
isPhone={isPhone}
/>
)}
{isCreateViewModalVisible && (
<ViewCreateModal
handleCancel={(data) => {
setIsCreateViewModalVisible(false);
getCronViews();
}}
/>
)}
{isViewManageModalVisible && (
<ViewManageModal
cronViews={cronViews}
handleCancel={() => {
setIsViewManageModalVisible(false);
}}
cronViewChange={(data) => {
getCronViews();
}}
/>
)}
</PageContainer>
);
};

View File

@ -25,12 +25,10 @@ const { Countdown } = Statistic;
const CronLogModal = ({
cron,
handleCancel,
visible,
data,
logUrl,
}: {
cron?: any;
visible: boolean;
handleCancel: () => void;
data?: string;
logUrl?: string;
@ -120,11 +118,10 @@ const CronLogModal = ({
};
useEffect(() => {
if (cron && cron.id && visible) {
if (cron && cron.id) {
getCronLog(true);
scrollInfoRef.current.down = true;
}
}, [cron, visible]);
}, [cron]);
useEffect(() => {
if (data) {
@ -139,7 +136,7 @@ const CronLogModal = ({
return (
<Modal
title={titleElement()}
open={visible}
open={true}
centered
className="log-modal"
forceRender

View File

@ -12,10 +12,8 @@ import { ScheduleType } from './type';
const CronModal = ({
cron,
handleCancel,
visible,
}: {
cron?: any;
visible: boolean;
handleCancel: (needUpdate?: boolean) => void;
}) => {
const [form] = Form.useForm();
@ -58,11 +56,6 @@ const CronModal = ({
}
};
useEffect(() => {
form.resetFields();
setScheduleType(getScheduleType(cron?.schedule));
}, [cron, visible]);
const handleScheduleTypeChange = (type: ScheduleType) => {
setScheduleType(type);
form.setFieldValue('schedule', '');
@ -146,7 +139,7 @@ const CronModal = ({
return (
<Modal
title={cron?.id ? intl.get('编辑任务') : intl.get('创建任务')}
open={visible}
open={true}
forceRender
centered
maskClosable={false}
@ -251,10 +244,8 @@ const CronModal = ({
const CronLabelModal = ({
ids,
handleCancel,
visible,
}: {
ids: Array<string>;
visible: boolean;
handleCancel: (needUpdate?: boolean) => void;
}) => {
const [form] = Form.useForm();
@ -290,10 +281,6 @@ const CronLabelModal = ({
});
};
useEffect(() => {
form.resetFields();
}, [ids, visible]);
const buttons = [
<Button onClick={() => handleCancel(false)}>{intl.get('取消')}</Button>,
<Button type="primary" danger onClick={() => update('delete')}>
@ -307,7 +294,7 @@ const CronLabelModal = ({
return (
<Modal
title={intl.get('批量修改标签')}
open={visible}
open={true}
footer={buttons}
centered
maskClosable={false}

View File

@ -56,10 +56,8 @@ enum ViewFilterRelation {
const ViewCreateModal = ({
view,
handleCancel,
visible,
}: {
view?: any;
visible: boolean;
handleCancel: (param?: any) => void;
}) => {
const [form] = Form.useForm();
@ -101,17 +99,6 @@ const ViewCreateModal = ({
}
};
useEffect(() => {
if (!view) {
form.resetFields();
}
form.setFieldsValue(
view || {
filters: [{ property: 'command' }],
},
);
}, [view, visible]);
const OperationElement = ({ name, ...others }: { name: number }) => {
const property = form.getFieldValue(['filters', name, 'property']);
return (
@ -172,7 +159,7 @@ const ViewCreateModal = ({
return (
<Modal
title={view ? intl.get('编辑视图') : intl.get('创建视图')}
open={visible}
open={true}
forceRender
width={580}
centered
@ -190,7 +177,16 @@ const ViewCreateModal = ({
onCancel={() => handleCancel()}
confirmLoading={loading}
>
<Form form={form} layout="vertical" name="env_modal">
<Form
form={form}
layout="vertical"
initialValues={
view || {
filters: [{ property: 'command' }],
}
}
name="env_modal"
>
<Form.Item
name="name"
label={intl.get('视图名称')}

View File

@ -68,11 +68,9 @@ const DragableBodyRow = ({
const ViewManageModal = ({
cronViews,
handleCancel,
visible,
cronViewChange,
}: {
cronViews: any[];
visible: boolean;
handleCancel: () => void;
cronViewChange: (data?: any) => void;
}) => {
@ -218,7 +216,7 @@ const ViewManageModal = ({
return (
<Modal
title={intl.get('视图管理')}
open={visible}
open={true}
centered
width={620}
onCancel={() => handleCancel()}
@ -263,14 +261,15 @@ const ViewManageModal = ({
}}
/>
</DndProvider>
<ViewCreateModal
view={editedView}
visible={isCreateViewModalVisible}
handleCancel={(data) => {
setIsCreateViewModalVisible(false);
cronViewChange(data);
}}
/>
{isCreateViewModalVisible && (
<ViewCreateModal
view={editedView}
handleCancel={(data) => {
setIsCreateViewModalVisible(false);
cronViewChange(data);
}}
/>
)}
</Modal>
);
};

View File

@ -618,15 +618,15 @@ const Dependence = () => {
]}
/>
{children}
<DependenceModal
visible={isModalVisible}
handleCancel={handleCancel}
dependence={editedDependence}
defaultType={type}
/>
{logDependence && (
{isModalVisible && (
<DependenceModal
handleCancel={handleCancel}
dependence={editedDependence}
defaultType={type}
/>
)}
{logDependence && isLogModalVisible && (
<DependenceLogModal
visible={isLogModalVisible}
handleCancel={(needRemove?: boolean) => {
setIsLogModalVisible(false);
if (needRemove) {

View File

@ -15,10 +15,8 @@ import { Status } from './type';
const DependenceLogModal = ({
dependence,
handleCancel,
visible,
}: {
dependence?: any;
visible: boolean;
handleCancel: (needRemove?: boolean) => void;
}) => {
const [value, setValue] = useState<string>('');
@ -128,7 +126,7 @@ const DependenceLogModal = ({
return (
<Modal
title={titleElement()}
open={visible}
open={true}
centered
className="log-modal"
forceRender

View File

@ -14,11 +14,9 @@ enum DependenceTypes {
const DependenceModal = ({
dependence,
handleCancel,
visible,
defaultType,
}: {
dependence?: any;
visible: boolean;
handleCancel: (cks?: any[]) => void;
defaultType: string;
}) => {
@ -61,14 +59,10 @@ const DependenceModal = ({
}
};
useEffect(() => {
form.resetFields();
}, [dependence, visible]);
return (
<Modal
title={dependence ? intl.get('编辑依赖') : intl.get('创建依赖')}
open={visible}
open={true}
forceRender
centered
maskClosable={false}

View File

@ -7,10 +7,8 @@ import config from '@/utils/config';
const EditNameModal = ({
ids,
handleCancel,
visible,
}: {
ids?: string[];
visible: boolean;
handleCancel: () => void;
}) => {
const [form] = Form.useForm();
@ -34,14 +32,10 @@ const EditNameModal = ({
}
};
useEffect(() => {
form.resetFields();
}, [ids, visible]);
return (
<Modal
title={intl.get('修改环境变量名称')}
open={visible}
open={true}
forceRender
centered
maskClosable={false}

View File

@ -616,16 +616,15 @@ const Env = () => {
/>
</DndProvider>
</div>
<EnvModal
visible={isModalVisible}
handleCancel={handleCancel}
env={editedEnv}
/>
<EditNameModal
visible={isEditNameModalVisible}
handleCancel={handleEditNameCancel}
ids={selectedRowIds}
/>
{isModalVisible && (
<EnvModal handleCancel={handleCancel} env={editedEnv} />
)}
{isEditNameModalVisible && (
<EditNameModal
handleCancel={handleEditNameCancel}
ids={selectedRowIds}
/>
)}
</PageContainer>
);
};

View File

@ -7,10 +7,8 @@ import config from '@/utils/config';
const EnvModal = ({
env,
handleCancel,
visible,
}: {
env?: any;
visible: boolean;
handleCancel: (cks?: any[]) => void;
}) => {
const [form] = Form.useForm();
@ -55,14 +53,10 @@ const EnvModal = ({
}
};
useEffect(() => {
form.resetFields();
}, [env, visible]);
return (
<Modal
title={env ? intl.get('编辑变量') : intl.get('创建变量')}
open={visible}
open={true}
forceRender
centered
maskClosable={false}

View File

@ -14,6 +14,17 @@ const Error = () => {
const [data, setData] = useState(intl.get('暂无日志'));
const retryTimes = useRef(1);
const loopStatus = (message: string) => {
if (retryTimes.current > 3) {
setData(message);
return;
}
retryTimes.current += 1;
setTimeout(() => {
getHealthStatus(false);
}, 3000);
};
const getHealthStatus = (needLoading: boolean = true) => {
needLoading && setLoading(true);
request
@ -27,19 +38,15 @@ const Error = () => {
}
return;
}
if (retryTimes.current > 3) {
setData(error?.details);
return;
}
retryTimes.current += 1;
setTimeout(() => {
getHealthStatus(false);
}, 3000);
loopStatus(error?.details);
})
.catch((error) => {
const responseStatus = error.response.status;
if (responseStatus === 401) {
history.push('/login');
} else {
loopStatus(error.response?.message || error?.message);
}
})
.finally(() => needLoading && setLoading(false));

View File

@ -25,11 +25,9 @@ const EditModal = ({
currentNode,
content,
handleCancel,
visible,
}: {
treeData?: any;
content?: string;
visible: boolean;
currentNode: any;
handleCancel: () => void;
}) => {
@ -223,7 +221,7 @@ const EditModal = ({
width={'100%'}
headerStyle={{ padding: '11px 24px' }}
onClose={cancel}
open={visible}
open={true}
>
{/* @ts-ignore */}
<SplitPane
@ -256,24 +254,26 @@ const EditModal = ({
<Ansi>{log}</Ansi>
</pre>
</SplitPane>
<SaveModal
visible={saveModalVisible}
handleCancel={() => {
setSaveModalVisible(false);
}}
file={{
content:
editorRef.current &&
editorRef.current.getValue().replace(/\r\n/g, '\n'),
...cNode,
}}
/>
<SettingModal
visible={settingModalVisible}
handleCancel={() => {
setSettingModalVisible(false);
}}
/>
{saveModalVisible && (
<SaveModal
handleCancel={() => {
setSaveModalVisible(false);
}}
file={{
content:
editorRef.current &&
editorRef.current.getValue().replace(/\r\n/g, '\n'),
...cNode,
}}
/>
)}
{settingModalVisible && (
<SettingModal
handleCancel={() => {
setSettingModalVisible(false);
}}
/>
)}
</Drawer>
);
};

View File

@ -19,9 +19,7 @@ const { Option } = Select;
const EditScriptNameModal = ({
handleCancel,
treeData,
visible,
}: {
visible: boolean;
treeData: any[];
handleCancel: (file?: {
filename: string;
@ -53,7 +51,7 @@ const EditScriptNameModal = ({
directory ? intl.get('创建文件夹成功') : intl.get('创建文件成功'),
);
const key = path ? `${path}/` : '';
const filename = file ? file.name : (directory || inputFilename);
const filename = file ? file.name : directory || inputFilename;
handleCancel({
filename,
path,
@ -95,14 +93,10 @@ const EditScriptNameModal = ({
setDirs(dirs);
}, [treeData]);
useEffect(() => {
form.resetFields();
}, [visible]);
return (
<Modal
title={intl.get('创建')}
open={visible}
open={true}
forceRender
centered
maskClosable={false}

View File

@ -710,9 +710,8 @@ const Script = () => {
}}
/>
)}
{isLogModalVisible && (
{isLogModalVisible && isLogModalVisible && (
<EditModal
visible={isLogModalVisible}
treeData={data}
currentNode={currentNode}
content={value}
@ -721,16 +720,18 @@ const Script = () => {
}}
/>
)}
<EditScriptNameModal
visible={isAddFileModalVisible}
treeData={data}
handleCancel={addFileModalClose}
/>
<RenameModal
visible={isRenameFileModalVisible}
handleCancel={handleRenameFileCancel}
currentNode={currentNode}
/>
{isAddFileModalVisible && (
<EditScriptNameModal
treeData={data}
handleCancel={addFileModalClose}
/>
)}
{isRenameFileModalVisible && (
<RenameModal
handleCancel={handleRenameFileCancel}
currentNode={currentNode}
/>
)}
</div>
</PageContainer>
);

View File

@ -7,10 +7,8 @@ import config from '@/utils/config';
const RenameModal = ({
currentNode,
handleCancel,
visible,
}: {
currentNode?: any;
visible: boolean;
handleCancel: () => void;
}) => {
const [form] = Form.useForm();
@ -38,14 +36,10 @@ const RenameModal = ({
}
};
useEffect(() => {
form.resetFields();
}, [currentNode, visible]);
return (
<Modal
title={intl.get('重命名')}
open={visible}
open={true}
forceRender
centered
maskClosable={false}

View File

@ -7,10 +7,8 @@ import config from '@/utils/config';
const SaveModal = ({
file,
handleCancel,
visible,
}: {
file?: any;
visible: boolean;
handleCancel: (cks?: any[]) => void;
}) => {
const [form] = Form.useForm();
@ -32,15 +30,10 @@ const SaveModal = ({
});
};
useEffect(() => {
form.resetFields();
setLoading(false);
}, [file, visible]);
return (
<Modal
title={intl.get('保存文件')}
open={visible}
open={true}
forceRender
centered
maskClosable={false}

View File

@ -7,10 +7,8 @@ import config from '@/utils/config';
const SettingModal = ({
file,
handleCancel,
visible,
}: {
file?: any;
visible: boolean;
handleCancel: (cks?: any[]) => void;
}) => {
const [form] = Form.useForm();
@ -30,15 +28,10 @@ const SettingModal = ({
});
};
useEffect(() => {
form.resetFields();
setLoading(false);
}, [file, visible]);
return (
<Modal
title={intl.get('运行设置')}
open={visible}
open={true}
forceRender
centered
onCancel={() => handleCancel()}

View File

@ -7,10 +7,8 @@ import config from '@/utils/config';
const AppModal = ({
app,
handleCancel,
visible,
}: {
app?: any;
visible: boolean;
handleCancel: (needUpdate?: boolean) => void;
}) => {
const [form] = Form.useForm();
@ -41,14 +39,10 @@ const AppModal = ({
}
};
useEffect(() => {
form.resetFields();
}, [app, visible]);
return (
<Modal
title={app ? intl.get('编辑应用') : intl.get('创建应用')}
open={visible}
open={true}
forceRender
centered
maskClosable={false}

View File

@ -363,11 +363,9 @@ const Setting = () => {
]}
/>
</div>
<AppModal
visible={isModalVisible}
handleCancel={handleCancel}
app={editedApp}
/>
{isModalVisible && (
<AppModal handleCancel={handleCancel} app={editedApp} />
)}
</PageContainer>
);
};

View File

@ -579,18 +579,20 @@ const Subscription = () => {
loading={loading}
rowClassName={getRowClassName}
/>
<SubscriptionModal
visible={isModalVisible}
handleCancel={handleCancel}
subscription={editedSubscription}
/>
<SubscriptionLogModal
visible={isLogModalVisible}
handleCancel={() => {
setIsLogModalVisible(false);
}}
subscription={logSubscription}
/>
{isModalVisible && (
<SubscriptionModal
handleCancel={handleCancel}
subscription={editedSubscription}
/>
)}
{isLogModalVisible && (
<SubscriptionLogModal
handleCancel={() => {
setIsLogModalVisible(false);
}}
subscription={logSubscription}
/>
)}
</PageContainer>
);
};

View File

@ -14,12 +14,10 @@ import Ansi from 'ansi-to-react';
const SubscriptionLogModal = ({
subscription,
handleCancel,
visible,
data,
logUrl,
}: {
subscription?: any;
visible: boolean;
handleCancel: () => void;
data?: string;
logUrl?: string;
@ -79,10 +77,10 @@ const SubscriptionLogModal = ({
};
useEffect(() => {
if (subscription && subscription.id && visible) {
if (subscription && subscription.id) {
getCronLog(true);
}
}, [subscription, visible]);
}, [subscription]);
useEffect(() => {
if (data) {
@ -97,7 +95,7 @@ const SubscriptionLogModal = ({
return (
<Modal
title={titleElement()}
open={visible}
open={true}
centered
className="log-modal"
forceRender

View File

@ -22,17 +22,19 @@ const fileUrlRegx = /([^\/\:]+\/[^\/\.]+)\.[a-z]+$/;
const SubscriptionModal = ({
subscription,
handleCancel,
visible,
}: {
subscription?: any;
visible: boolean;
handleCancel: (needUpdate?: boolean) => void;
}) => {
const [form] = Form.useForm();
const [loading, setLoading] = useState(false);
const [type, setType] = useState('public-repo');
const [scheduleType, setScheduleType] = useState('crontab');
const [pullType, setPullType] = useState<'ssh-key' | 'user-pwd'>('ssh-key');
const [type, setType] = useState(subscription?.type || 'public-repo');
const [scheduleType, setScheduleType] = useState(
subscription?.schedule_type || 'crontab',
);
const [pullType, setPullType] = useState<'ssh-key' | 'user-pwd'>(
subscription?.pull_type || 'ssh-key',
);
const handleOk = async (values: any) => {
setLoading(true);
@ -255,29 +257,17 @@ const SubscriptionModal = ({
};
useEffect(() => {
if (visible) {
window.addEventListener('paste', onPaste);
} else {
window.removeEventListener('paste', onPaste);
}
}, [visible]);
window.addEventListener('paste', onPaste);
useEffect(() => {
form.setFieldsValue(
{ ...subscription, ...formatParams(subscription) } || {},
);
setType((subscription && subscription.type) || 'public-repo');
setScheduleType((subscription && subscription.schedule_type) || 'crontab');
setPullType((subscription && subscription.pull_type) || 'ssh-key');
if (!subscription) {
form.resetFields();
}
}, [subscription, visible]);
return () => {
window.removeEventListener('paste', onPaste);
};
}, []);
return (
<Modal
title={subscription ? intl.get('编辑订阅') : intl.get('创建订阅')}
open={visible}
open={true}
forceRender
centered
maskClosable={false}
@ -294,7 +284,12 @@ const SubscriptionModal = ({
onCancel={() => handleCancel()}
confirmLoading={loading}
>
<Form form={form} name="form_in_modal" layout="vertical">
<Form
form={form}
name="form_in_modal"
layout="vertical"
initialValues={{ ...subscription, ...formatParams(subscription) }}
>
<Form.Item
name="name"
label={intl.get('名称')}

View File

@ -14,7 +14,7 @@ export interface IResponseData {
code?: number;
data?: any;
message?: string;
errors?: any[];
error?: any;
}
export type Override<