mirror of
https://github.com/whyour/qinglong.git
synced 2025-07-27 14:46:06 +08:00
Merge branch 'whyour-develop' into develop
This commit is contained in:
commit
7115b8e6a1
|
@ -13,9 +13,6 @@ export default defineConfig({
|
|||
outputPath: 'static/dist',
|
||||
fastRefresh: true,
|
||||
favicons: [`https://qn.whyour.cn/favicon.svg`],
|
||||
mfsu: {
|
||||
strategy: 'eager',
|
||||
},
|
||||
publicPath: process.env.NODE_ENV === 'production' ? './' : '/',
|
||||
proxy: {
|
||||
[`${baseUrl}api/public`]: {
|
||||
|
|
|
@ -387,28 +387,22 @@ export function emptyDir(path: string) {
|
|||
fs.rmdirSync(path);
|
||||
}
|
||||
|
||||
export function promiseExec(command: string): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
exec(
|
||||
command,
|
||||
{ maxBuffer: 200 * 1024 * 1024, encoding: 'utf8' },
|
||||
(err, stdout, stderr) => {
|
||||
resolve(stdout || stderr || JSON.stringify(err));
|
||||
},
|
||||
);
|
||||
});
|
||||
export async function promiseExec(command: string): Promise<string> {
|
||||
try {
|
||||
const { stderr, stdout } = await promisify(exec)(command, { maxBuffer: 200 * 1024 * 1024, encoding: 'utf8' });
|
||||
return stdout || stderr;
|
||||
} catch (error) {
|
||||
return JSON.stringify(error);
|
||||
}
|
||||
}
|
||||
|
||||
export function promiseExecSuccess(command: string): Promise<string> {
|
||||
return new Promise((resolve) => {
|
||||
exec(
|
||||
command,
|
||||
{ maxBuffer: 200 * 1024 * 1024, encoding: 'utf8' },
|
||||
(err, stdout, stderr) => {
|
||||
resolve(stdout || '');
|
||||
},
|
||||
);
|
||||
});
|
||||
export async function promiseExecSuccess(command: string): Promise<string> {
|
||||
try {
|
||||
const { stdout } = await promisify(exec)(command, { maxBuffer: 200 * 1024 * 1024, encoding: 'utf8' });
|
||||
return stdout || '';
|
||||
} catch (error) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
export function parseHeaders(headers: string) {
|
||||
|
@ -501,7 +495,7 @@ export async function killTask(pid: number) {
|
|||
[pid, ...pids].forEach((x) => {
|
||||
process.kill(x, 2);
|
||||
});
|
||||
} catch (error) {}
|
||||
} catch (error) { }
|
||||
} else {
|
||||
process.kill(pid, 2);
|
||||
}
|
||||
|
|
|
@ -7,10 +7,11 @@ import linkDeps from './deps';
|
|||
import initTask from './initTask';
|
||||
|
||||
export default async ({ expressApp }: { expressApp: Application }) => {
|
||||
await depInjectorLoader();
|
||||
try {
|
||||
depInjectorLoader();
|
||||
Logger.info('✌️ Dependency Injector loaded');
|
||||
|
||||
await expressLoader({ app: expressApp });
|
||||
expressLoader({ app: expressApp });
|
||||
Logger.info('✌️ Express loaded');
|
||||
|
||||
await initData();
|
||||
|
@ -21,4 +22,8 @@ export default async ({ expressApp }: { expressApp: Application }) => {
|
|||
|
||||
initTask();
|
||||
Logger.info('✌️ init task loaded');
|
||||
} catch (error) {
|
||||
Logger.info('✌️ depInjectorLoader expressLoader initData linkDeps failed');
|
||||
Logger.error(error);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -125,6 +125,6 @@ export default async () => {
|
|||
Logger.info('✌️ DB loaded');
|
||||
} catch (error) {
|
||||
Logger.info('✌️ DB load failed');
|
||||
Logger.info(error);
|
||||
Logger.error(error);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -37,7 +37,7 @@ async function linkCommand() {
|
|||
if (fs.existsSync(target)) {
|
||||
fs.unlinkSync(target);
|
||||
}
|
||||
fs.symlink(source, target, (err) => {});
|
||||
fs.symlink(source, target, (err) => { });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ const check = async (
|
|||
`tail -n 300 ~/.pm2/logs/schedule-error.log`,
|
||||
);
|
||||
return callback(
|
||||
new Error(`${scheduleErrLog || ''}\n${panelErrLog || ''}\n${res}`),
|
||||
new Error(`${scheduleErrLog || ''}\n${panelErrLog || ''}\n${res}`.trim()),
|
||||
);
|
||||
|
||||
default:
|
||||
|
|
|
@ -161,7 +161,7 @@ export default class CronService {
|
|||
case 'In':
|
||||
q[Op.or] = [
|
||||
{
|
||||
[property]: value,
|
||||
[property]: Array.isArray(value) ? value : [value],
|
||||
},
|
||||
property === 'status' && value.includes(2)
|
||||
? { isDisabled: 1 }
|
||||
|
@ -172,7 +172,7 @@ export default class CronService {
|
|||
q[Op.and] = [
|
||||
{
|
||||
[property]: {
|
||||
[Op.notIn]: value,
|
||||
[Op.notIn]: Array.isArray(value) ? value : [value],
|
||||
},
|
||||
},
|
||||
property === 'status' && value.includes(2)
|
||||
|
|
|
@ -458,7 +458,7 @@ class WeCom:
|
|||
return respone["errmsg"]
|
||||
|
||||
def send_mpnews(self, title, message, media_id, touser="@all"):
|
||||
send_url = f"https://{self.HOST}/cgi-bin/message/send?access_token={self.get_access_token()}"
|
||||
send_url = f"https://{self.ORIGIN}/cgi-bin/message/send?access_token={self.get_access_token()}"
|
||||
send_values = {
|
||||
"touser": touser,
|
||||
"msgtype": "mpnews",
|
||||
|
|
|
@ -14,7 +14,7 @@ single_hanle() {
|
|||
## 选择python3还是node
|
||||
define_program() {
|
||||
local file_param=$1
|
||||
if [[ $file_param == *.js ]]; then
|
||||
if [[ $file_param == *.js ]] || [[ $file_param == *.mjs ]]; then
|
||||
which_program="node"
|
||||
elif [[ $file_param == *.py ]] || [[ $file_param == *.pyc ]]; then
|
||||
which_program="python3"
|
||||
|
|
10
src/app.ts
10
src/app.ts
|
@ -3,13 +3,17 @@ import intl from 'react-intl-universal';
|
|||
|
||||
export function rootContainer(container: any) {
|
||||
const locales = {
|
||||
'en-US': require('./locales/en-US.json'),
|
||||
'zh-CN': require('./locales/zh-CN.json'),
|
||||
'en': require('./locales/en-US.json'),
|
||||
'zh': require('./locales/zh-CN.json'),
|
||||
};
|
||||
let currentLocale = intl.determineLocale({
|
||||
urlLocaleKey: 'lang',
|
||||
cookieLocaleKey: 'lang',
|
||||
});
|
||||
}).slice(0, 2);
|
||||
|
||||
if (!currentLocale || !Object.keys(locales).includes(currentLocale)) {
|
||||
currentLocale = 'zh';
|
||||
}
|
||||
|
||||
intl.init({ currentLocale, locales });
|
||||
return container;
|
||||
|
|
|
@ -13,7 +13,7 @@ export default function Name<
|
|||
options: Options<TData, [TParams]>;
|
||||
}) {
|
||||
const { loading, data } = useRequest(service, options);
|
||||
console.log(loading, data);
|
||||
|
||||
return (
|
||||
<Spin spinning={loading}>
|
||||
<Typography.Text ellipsis={true}>{data?.data?.name}</Typography.Text>
|
||||
|
|
|
@ -396,16 +396,57 @@
|
|||
"关联订阅": "Associate Subscription",
|
||||
"订阅": "Subscription",
|
||||
"创建": "Create",
|
||||
"创建订阅成功": "Subscription created successfully",
|
||||
"gotify的url地址,例如 https://push.example.de:8080": "Gotify URL address, e.g., https://push.example.de:8080",
|
||||
"BARK推送图标,自定义推送图标 (需iOS15或以上才能显示)": "BARK push icon, custom push icon (requires iOS 15 or above to display)",
|
||||
"BARK推送铃声,铃声列表去APP查看复制填写": "BARK push ringtone, check the ringtone list in the APP and copy it",
|
||||
"BARK推送消息的分组, 默认为qinglong": "BARK push message grouping, default is qinglong",
|
||||
"telegram代理配置认证参数, 用户名与密码用英文冒号连接 user:password": "Telegram proxy configuration authentication parameters, connect username and password with a colon, e.g., user:password",
|
||||
"企业微信机器人的 webhook(详见文档 https://work.weixin.qq.com/api/doc/90000/90136/91770),例如:693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa": "WeChat Work Bot webhook (see documentation at https://work.weixin.qq.com/api/doc/90000/90136/91770), e.g., 693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa",
|
||||
"corpid,corpsecret,touser(注:多个成员ID使用|隔开),agentid,消息类型(选填,不填默认文本消息类型) 注意用,号隔开(英文输入法的逗号),例如:wwcfrs,B-76WERQ,qinglong,1000001,2COat": "corpid, corpsecret, touser (note: separate multiple member IDs with |), agentid, message type (optional, defaults to text message type) – separated by commas (`,`), e.g., wwcfrs, B-76WERQ, qinglong, 1000001, 2COat",
|
||||
"密钥key,智能微秘书个人中心获取apikey,申请地址:https://wechat.aibotk.com/signup?from=ql": "Key, obtain the API key from the Smart WeChat Assistant's personal center, apply at: https://wechat.aibotk.com/signup?from=ql",
|
||||
"一对多推送的“群组编码”(一对多推送下面->您的群组(如无则新建)->群组编码,如果您是创建群组人。也需点击“查看二维码”扫描绑定,否则不能接受群组消息推送)": "The 'Group Code' for one-to-many push (under one-to-many push->Your Group (create one if none exists)->Group Code. If you are the creator of the group, you also need to click 'View QR Code' for scanning and binding, otherwise you cannot receive group message push)",
|
||||
"同时删除关联任务和脚本": "Delete associated tasks and scripts as well",
|
||||
"夹及其子文件": "Folder and its sub-files"
|
||||
"未找到": "Not Found",
|
||||
"保存成功": "Saved successfully",
|
||||
"删除成功": "Deleted successfully",
|
||||
"批量删除成功": "Batch deleted successfully",
|
||||
"启动中...": "Starting...",
|
||||
"任务未运行": "Task not running",
|
||||
"更新任务成功": "Task updated successfully",
|
||||
"创建任务成功": "Task created successfully",
|
||||
"编辑任务": "Edit Task",
|
||||
"Cron表达式格式有误": "Incorrect Cron Expression Format",
|
||||
"添加Labels成功": "Labels added successfully",
|
||||
"删除Labels成功": "Labels deleted successfully",
|
||||
"编辑视图": "Edit View",
|
||||
"排序方式": "Sort Order",
|
||||
"开始时间": "Start Time",
|
||||
"安装": "Install",
|
||||
"结束时间": "End Time",
|
||||
"编辑依赖": "Edit Dependency",
|
||||
"更新环境变量名称成功": "Environment Variable Name updated successfully",
|
||||
"更新变量成功": "Variable updated successfully",
|
||||
"创建变量成功": "Variable created successfully",
|
||||
"编辑变量": "Edit Variable",
|
||||
"加载中...": "Loading...",
|
||||
"夹下所以日志": "Folder and All Subfiles",
|
||||
"创建文件夹成功": "Folder created successfully",
|
||||
"创建文件成功": "File created successfully",
|
||||
"夹及其子文件": "Folder and Its Subfiles",
|
||||
"更新名称成功": "Name updated successfully",
|
||||
"保存文件成功": "File saved successfully",
|
||||
"更新应用成功": "Application updated successfully",
|
||||
"创建应用成功": "Application created successfully",
|
||||
"编辑应用": "Edit Application",
|
||||
"检查更新中...": "Checking for updates...",
|
||||
"失败,请检查": "Failed, please check",
|
||||
"更新失败,请检查网络及日志或稍后再试": "Update failed, please check network and logs or try again later",
|
||||
"更新包下载成功": "Update package download successful",
|
||||
"重置secret": "Reset secret",
|
||||
"重置成功": "Reset successful",
|
||||
"通知发送成功": "Notification sent successfully",
|
||||
"通知关闭成功": "Notification closed successfully",
|
||||
"测试中...": "Testing...",
|
||||
"上传": "Upload",
|
||||
"下载": "Download",
|
||||
"更新成功": "Update successful",
|
||||
"激活成功": "Activation successful",
|
||||
"验证失败": "Validation failed",
|
||||
"更新订阅成功": "Subscription updated successfully",
|
||||
"创建订阅成功": "Subscription created successfully",
|
||||
"编辑订阅": "Edit Subscription",
|
||||
"Subscription表达式格式有误": "Incorrect Subscription Expression Format",
|
||||
"一对多推送的“群组编码”(一对多推送下面->您的群组(如无则新建)->群组编码,如果您是创建群组人。也需点击“查看二维码”扫描绑定,否则不能接受群组消息推送)": "The 'Group Code' for One-to-Many Push (Below One-to-Many Push->Your Group (if not, create one)->Group Code, if you are the creator of the group, you also need to click 'View QR Code' to scan and bind, otherwise you cannot receive group messages)",
|
||||
"登录已过期,请重新登录": "Login session has expired, please log in again"
|
||||
}
|
||||
|
|
|
@ -147,7 +147,7 @@
|
|||
"启动中,请稍后...": "启动中,请稍后...",
|
||||
"欢迎使用": "欢迎使用",
|
||||
"欢迎使用青龙": "欢迎使用青龙",
|
||||
"支持python3、javascript、shell、typescript 的定时任务管理面板": "支持python3、javaScript、shell、typescript 的定时任务管理面板",
|
||||
"支持python3、javascript、shell、typescript 的定时任务管理面板": "支持python3、javascript、shell、typescript 的定时任务管理面板",
|
||||
"开始安装": "开始安装",
|
||||
"账户设置": "账户设置",
|
||||
"用户名": "用户名",
|
||||
|
@ -396,5 +396,57 @@
|
|||
"关联订阅": "关联订阅",
|
||||
"订阅": "订阅",
|
||||
"创建": "创建",
|
||||
"同时删除关联任务和脚本": "同时删除关联任务和脚本"
|
||||
"同时删除关联任务和脚本": "同时删除关联任务和脚本",
|
||||
"未找到": "未找到",
|
||||
"保存成功": "保存成功",
|
||||
"删除成功": "删除成功",
|
||||
"批量删除成功": "批量删除成功",
|
||||
"启动中...": "启动中...",
|
||||
"任务未运行": "任务未运行",
|
||||
"更新任务成功": "更新任务成功",
|
||||
"创建任务成功": "创建任务成功",
|
||||
"编辑任务": "编辑任务",
|
||||
"Cron表达式格式有误": "Cron表达式格式有误",
|
||||
"添加Labels成功": "添加Labels成功",
|
||||
"删除Labels成功": "删除Labels成功",
|
||||
"编辑视图": "编辑视图",
|
||||
"排序方式": "排序方式",
|
||||
"开始时间": "开始时间",
|
||||
"安装": "安装",
|
||||
"结束时间": "结束时间",
|
||||
"编辑依赖": "编辑依赖",
|
||||
"更新环境变量名称成功": "更新环境变量名称成功",
|
||||
"更新变量成功": "更新变量成功",
|
||||
"创建变量成功": "创建变量成功",
|
||||
"编辑变量": "编辑变量",
|
||||
"加载中...": "加载中...",
|
||||
"夹下所以日志": "夹下所以日志",
|
||||
"创建文件夹成功": "创建文件夹成功",
|
||||
"创建文件成功": "创建文件成功",
|
||||
"夹及其子文件": "夹及其子文件",
|
||||
"更新名称成功": "更新名称成功",
|
||||
"保存文件成功": "保存文件成功",
|
||||
"更新应用成功": "更新应用成功",
|
||||
"创建应用成功": "创建应用成功",
|
||||
"编辑应用": "编辑应用",
|
||||
"检查更新中...": "检查更新中...",
|
||||
"失败,请检查": "失败,请检查",
|
||||
"更新失败,请检查网络及日志或稍后再试": "更新失败,请检查网络及日志或稍后再试",
|
||||
"更新包下载成功": "更新包下载成功",
|
||||
"重置secret": "重置secret",
|
||||
"重置成功": "重置成功",
|
||||
"通知发送成功": "通知发送成功",
|
||||
"通知关闭成功": "通知关闭成功",
|
||||
"测试中...": "测试中...",
|
||||
"上传": "上传",
|
||||
"下载": "下载",
|
||||
"更新成功": "更新成功",
|
||||
"激活成功": "激活成功",
|
||||
"验证失败": "验证失败",
|
||||
"更新订阅成功": "更新订阅成功",
|
||||
"创建订阅成功": "创建订阅成功",
|
||||
"编辑订阅": "编辑订阅",
|
||||
"Subscription表达式格式有误": "Subscription表达式格式有误",
|
||||
"一对多推送的“群组编码”(一对多推送下面->您的群组(如无则新建)->群组编码,如果您是创建群组人。也需点击“查看二维码”扫描绑定,否则不能接受群组消息推送)": "一对多推送的“群组编码”(一对多推送下面->您的群组(如无则新建)->群组编码,如果您是创建群组人。也需点击“查看二维码”扫描绑定,否则不能接受群组消息推送)",
|
||||
"登录已过期,请重新登录": "登录已过期,请重新登录"
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ const Config = () => {
|
|||
.post(`${config.apiPrefix}configs/save`, { content, name: select })
|
||||
.then(({ code, data }) => {
|
||||
if (code === 200) {
|
||||
message.success('保存成功');
|
||||
message.success(intl.get('保存成功'));
|
||||
}
|
||||
setConfirmLoading(false);
|
||||
});
|
||||
|
|
|
@ -30,7 +30,7 @@ import config from '@/utils/config';
|
|||
import CronLogModal from './logModal';
|
||||
import Editor from '@monaco-editor/react';
|
||||
import IconFont from '@/components/iconfont';
|
||||
import { getCommandScript } from '@/utils';
|
||||
import { getCommandScript, getEditorMode } from '@/utils';
|
||||
import VirtualList from 'rc-virtual-list';
|
||||
import useScrollHeight from '@/hooks/useScrollHeight';
|
||||
|
||||
|
@ -46,12 +46,6 @@ const tabList = [
|
|||
tab: intl.get('脚本'),
|
||||
},
|
||||
];
|
||||
const LangMap: any = {
|
||||
'.py': 'python',
|
||||
'.js': 'javascript',
|
||||
'.sh': 'shell',
|
||||
'.ts': 'typescript',
|
||||
};
|
||||
|
||||
interface LogItem {
|
||||
directory: string;
|
||||
|
@ -109,7 +103,7 @@ const CronDetailModal = ({
|
|||
),
|
||||
script: scriptInfo.filename && (
|
||||
<Editor
|
||||
language={LangMap[scriptInfo.filename.slice(-3)] || ''}
|
||||
language={getEditorMode(scriptInfo.filename)}
|
||||
theme={theme}
|
||||
value={value}
|
||||
options={{
|
||||
|
|
|
@ -447,7 +447,7 @@ const Crontab = () => {
|
|||
.delete(`${config.apiPrefix}crons`, { data: [record.id] })
|
||||
.then(({ code, data }) => {
|
||||
if (code === 200) {
|
||||
message.success('删除成功');
|
||||
message.success(intl.get('删除成功'));
|
||||
const result = [...value];
|
||||
const i = result.findIndex((x) => x.id === record.id);
|
||||
if (i !== -1) {
|
||||
|
@ -729,7 +729,7 @@ const Crontab = () => {
|
|||
.delete(`${config.apiPrefix}crons`, { data: selectedRowIds })
|
||||
.then(({ code, data }) => {
|
||||
if (code === 200) {
|
||||
message.success('批量删除成功');
|
||||
message.success(intl.get('批量删除成功'));
|
||||
setSelectedRowIds([]);
|
||||
getCrons();
|
||||
}
|
||||
|
@ -905,6 +905,11 @@ const Crontab = () => {
|
|||
setViewConf(view ? view : null);
|
||||
};
|
||||
|
||||
const [vt] = useVT(
|
||||
() => ({ scroll: { y: tableScrollHeight } }),
|
||||
[tableScrollHeight],
|
||||
);
|
||||
|
||||
return (
|
||||
<PageContainer
|
||||
className="ql-container-wrapper crontab-wrapper ql-container-wrapper-has-tab"
|
||||
|
@ -1041,6 +1046,7 @@ const Crontab = () => {
|
|||
rowSelection={rowSelection}
|
||||
rowClassName={getRowClassName}
|
||||
onChange={onPageChange}
|
||||
components={isPhone || pageConf.size < 50 ? undefined : vt}
|
||||
/>
|
||||
</div>
|
||||
<CronLogModal
|
||||
|
|
|
@ -26,7 +26,7 @@ const CronLogModal = ({
|
|||
data?: string;
|
||||
logUrl?: string;
|
||||
}) => {
|
||||
const [value, setValue] = useState<string>('启动中...');
|
||||
const [value, setValue] = useState<string>(intl.get('启动中...'));
|
||||
const [loading, setLoading] = useState<any>(true);
|
||||
const [executing, setExecuting] = useState<any>(true);
|
||||
const [isPhone, setIsPhone] = useState(false);
|
||||
|
|
|
@ -99,7 +99,7 @@ const CronModal = ({
|
|||
if (!value || cronParse.parseExpression(value).hasNext()) {
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
return Promise.reject('Cron表达式格式有误');
|
||||
return Promise.reject(intl.get('Cron表达式格式有误'));
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
@ -157,7 +157,7 @@ const ViewManageModal = ({
|
|||
.delete(`${config.apiPrefix}crons/views`, { data: [record.id] })
|
||||
.then(({ code, data }) => {
|
||||
if (code === 200) {
|
||||
message.success('删除成功');
|
||||
message.success(intl.get('删除成功'));
|
||||
cronViewChange();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -400,7 +400,7 @@ const Dependence = () => {
|
|||
const { type, message, references } = socketMessage;
|
||||
if (
|
||||
type === 'installDependence' &&
|
||||
message.includes('开始时间') &&
|
||||
message.includes(intl.get('开始时间')) &&
|
||||
references.length > 0
|
||||
) {
|
||||
const result = [...value];
|
||||
|
@ -409,7 +409,7 @@ const Dependence = () => {
|
|||
if (index !== -1) {
|
||||
result.splice(index, 1, {
|
||||
...value[index],
|
||||
status: message.includes('安装') ? Status.安装中 : Status.删除中,
|
||||
status: message.includes(intl.get('安装')) ? Status.安装中 : Status.删除中,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -417,14 +417,14 @@ const Dependence = () => {
|
|||
}
|
||||
if (
|
||||
type === 'installDependence' &&
|
||||
message.includes('结束时间') &&
|
||||
message.includes(intl.get('结束时间')) &&
|
||||
references.length > 0
|
||||
) {
|
||||
let status;
|
||||
if (message.includes('安装')) {
|
||||
status = message.includes('成功') ? Status.已安装 : Status.安装失败;
|
||||
if (message.includes(intl.get('安装'))) {
|
||||
status = message.includes(intl.get('成功')) ? Status.已安装 : Status.安装失败;
|
||||
} else {
|
||||
status = message.includes('成功') ? Status.已删除 : Status.删除失败;
|
||||
status = message.includes(intl.get('成功')) ? Status.已删除 : Status.删除失败;
|
||||
}
|
||||
const result = [...value];
|
||||
for (let i = 0; i < references.length; i++) {
|
||||
|
|
|
@ -56,8 +56,8 @@ const DependenceLogModal = ({
|
|||
) {
|
||||
const log = (data.log || []).join('') as string;
|
||||
setValue(log);
|
||||
setExecuting(!log.includes('结束时间'));
|
||||
setIsRemoveFailed(log.includes('删除失败'));
|
||||
setExecuting(!log.includes(intl.get('结束时间')));
|
||||
setIsRemoveFailed(log.includes(intl.get('删除失败')));
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
|
@ -103,9 +103,9 @@ const DependenceLogModal = ({
|
|||
references.length > 0 &&
|
||||
references.includes(dependence.id)
|
||||
) {
|
||||
if (message.includes('结束时间')) {
|
||||
if (message.includes(intl.get('结束时间'))) {
|
||||
setExecuting(false);
|
||||
setIsRemoveFailed(message.includes('删除失败'));
|
||||
setIsRemoveFailed(message.includes(intl.get('删除失败')));
|
||||
}
|
||||
setValue(`${value}${message}`);
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ const Diff = () => {
|
|||
})
|
||||
.then(({ code, data }) => {
|
||||
if (code === 200) {
|
||||
message.success('保存成功');
|
||||
message.success(intl.get('保存成功'));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
2
src/pages/env/editNameModal.tsx
vendored
2
src/pages/env/editNameModal.tsx
vendored
|
@ -25,7 +25,7 @@ const EditNameModal = ({
|
|||
});
|
||||
|
||||
if (code === 200) {
|
||||
message.success('更新环境变量名称成功');
|
||||
message.success(intl.get('更新环境变量名称成功'));
|
||||
handleCancel();
|
||||
}
|
||||
setLoading(false);
|
||||
|
|
6
src/pages/env/index.tsx
vendored
6
src/pages/env/index.tsx
vendored
|
@ -254,7 +254,7 @@ const Env = () => {
|
|||
.then(({ code, data }) => {
|
||||
if (code === 200) {
|
||||
message.success(
|
||||
`${record.status === Status.已禁用 ? intl.get('启用') : intl.get('禁用')}成功`,
|
||||
`${record.status === Status.已禁用 ? intl.get('启用') : intl.get('禁用')}${intl.get('成功')}`,
|
||||
);
|
||||
const newStatus =
|
||||
record.status === Status.已禁用 ? Status.已启用 : Status.已禁用;
|
||||
|
@ -300,7 +300,7 @@ const Env = () => {
|
|||
.delete(`${config.apiPrefix}envs`, { data: [record.id] })
|
||||
.then(({ code, data }) => {
|
||||
if (code === 200) {
|
||||
message.success('删除成功');
|
||||
message.success(intl.get('删除成功'));
|
||||
const result = [...value];
|
||||
result.splice(index, 1);
|
||||
setValue(result);
|
||||
|
@ -420,7 +420,7 @@ const Env = () => {
|
|||
.delete(`${config.apiPrefix}envs`, { data: selectedRowIds })
|
||||
.then(({ code, data }) => {
|
||||
if (code === 200) {
|
||||
message.success('批量删除成功');
|
||||
message.success(intl.get('批量删除成功'));
|
||||
setSelectedRowIds([]);
|
||||
getEnvs();
|
||||
}
|
||||
|
|
|
@ -9,17 +9,22 @@ import { SharedContext } from '@/layouts';
|
|||
import { Alert, Typography } from 'antd';
|
||||
|
||||
const Error = () => {
|
||||
const { user, theme, reloadUser } = useOutletContext<SharedContext>();
|
||||
const { user } = useOutletContext<SharedContext>();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [data, setData] = useState('暂无日志');
|
||||
const [data, setData] = useState(intl.get('暂无日志'));
|
||||
const retryTimes = useRef(1);
|
||||
|
||||
const getLog = (needLoading: boolean = true) => {
|
||||
const getHealthStatus = (needLoading: boolean = true) => {
|
||||
needLoading && setLoading(true);
|
||||
request
|
||||
.get(`${config.apiPrefix}public/health`)
|
||||
.then(({ error, data }) => {
|
||||
if (data?.status === 1) {
|
||||
if (retryTimes.current > 1) {
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (retryTimes.current > 3) {
|
||||
|
@ -28,7 +33,7 @@ const Error = () => {
|
|||
}
|
||||
retryTimes.current += 1;
|
||||
setTimeout(() => {
|
||||
getLog(false);
|
||||
getHealthStatus(false);
|
||||
}, 3000);
|
||||
})
|
||||
.finally(() => needLoading && setLoading(false));
|
||||
|
@ -41,7 +46,7 @@ const Error = () => {
|
|||
}, [user]);
|
||||
|
||||
useEffect(() => {
|
||||
getLog();
|
||||
getHealthStatus();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
@ -69,7 +74,7 @@ const Error = () => {
|
|||
<div>{intl.get('2. 容器内执行 ql -l check、ql -l update')}</div>
|
||||
<div>
|
||||
{intl.get(
|
||||
'3. 如果无法解决,容器内执行 pm2 logs,拷贝执行结果',
|
||||
'3. 如果无法解决,容器内执行 pm2 logs,拷贝执行结果'
|
||||
)}
|
||||
<Typography.Link href="https://github.com/whyour/qinglong/issues/new?assignees=&labels=&template=bug_report.yml">
|
||||
{intl.get('提交 issue')}
|
||||
|
|
|
@ -75,7 +75,7 @@ const Log = () => {
|
|||
return;
|
||||
}
|
||||
|
||||
setValue('加载中...');
|
||||
setValue(intl.get('加载中...'));
|
||||
getLog(node);
|
||||
};
|
||||
|
||||
|
|
|
@ -187,7 +187,9 @@ const Login = () => {
|
|||
<Form layout="vertical" onFinish={handleOk}>
|
||||
<FormItem name="username" label={intl.get('用户名')} hasFeedback>
|
||||
<Input
|
||||
placeholder={`${intl.get('用户名')}${isDemoEnv ? ': admin' : ''}`}
|
||||
placeholder={`${intl.get('用户名')}${
|
||||
isDemoEnv ? ': admin' : ''
|
||||
}`}
|
||||
autoFocus
|
||||
/>
|
||||
</FormItem>
|
||||
|
|
|
@ -8,21 +8,9 @@ import Editor from '@monaco-editor/react';
|
|||
import SaveModal from './saveModal';
|
||||
import SettingModal from './setting';
|
||||
import { useTheme } from '@/utils/hooks';
|
||||
import { logEnded } from '@/utils';
|
||||
import { getEditorMode, logEnded } from '@/utils';
|
||||
|
||||
const { Option } = Select;
|
||||
const LangMap: any = {
|
||||
'.py': 'python',
|
||||
'.js': 'javascript',
|
||||
'.sh': 'shell',
|
||||
'.ts': 'typescript',
|
||||
};
|
||||
const prefixMap: any = {
|
||||
python: '.py',
|
||||
javascript: '.js',
|
||||
shell: '.sh',
|
||||
typescript: '.ts',
|
||||
};
|
||||
|
||||
const EditModal = ({
|
||||
treeData,
|
||||
|
@ -65,7 +53,7 @@ const EditModal = ({
|
|||
return;
|
||||
}
|
||||
|
||||
const newMode = LangMap[value.slice(-3)] || '';
|
||||
const newMode = getEditorMode(value);
|
||||
setCNode(node);
|
||||
setLanguage(newMode);
|
||||
getDetail(node);
|
||||
|
@ -145,7 +133,7 @@ const EditModal = ({
|
|||
setCNode(currentNode);
|
||||
setValue(content as string);
|
||||
setSelectedKey(currentNode.key);
|
||||
const newMode = LangMap[currentNode.title.slice(-3)] || '';
|
||||
const newMode = getEditorMode(currentNode.title);
|
||||
setLanguage(newMode);
|
||||
}
|
||||
}, [content, currentNode]);
|
||||
|
|
|
@ -37,7 +37,7 @@ import EditScriptNameModal from './editNameModal';
|
|||
import debounce from 'lodash/debounce';
|
||||
import { history, useOutletContext, useLocation } from '@umijs/max';
|
||||
import { parse } from 'query-string';
|
||||
import { depthFirstSearch, findNode } from '@/utils';
|
||||
import { depthFirstSearch, findNode, getEditorMode } from '@/utils';
|
||||
import { SharedContext } from '@/layouts';
|
||||
import useFilterTreeData from '@/hooks/useFilterTreeData';
|
||||
import uniq from 'lodash/uniq';
|
||||
|
@ -46,13 +46,6 @@ import RenameModal from './renameModal';
|
|||
|
||||
const { Text } = Typography;
|
||||
|
||||
const LangMap: any = {
|
||||
'.py': 'python',
|
||||
'.js': 'javascript',
|
||||
'.sh': 'shell',
|
||||
'.ts': 'typescript',
|
||||
};
|
||||
|
||||
const Script = () => {
|
||||
const { headerStyle, isPhone, theme, socketMessage } =
|
||||
useOutletContext<SharedContext>();
|
||||
|
@ -133,9 +126,9 @@ const Script = () => {
|
|||
return;
|
||||
}
|
||||
|
||||
const newMode = value ? LangMap[value.slice(-3)] : '';
|
||||
const newMode = getEditorMode(value);
|
||||
setMode(isPhone && newMode === 'typescript' ? 'javascript' : newMode);
|
||||
setValue('加载中...');
|
||||
setValue(intl.get('加载中...'));
|
||||
getDetail(node);
|
||||
};
|
||||
|
||||
|
@ -201,7 +194,7 @@ const Script = () => {
|
|||
|
||||
const cancelEdit = () => {
|
||||
setIsEditing(false);
|
||||
setValue('加载中...');
|
||||
setValue(intl.get('加载中...'));
|
||||
getDetail(currentNode);
|
||||
};
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ const RenameModal = ({
|
|||
);
|
||||
|
||||
if (code === 200) {
|
||||
message.success('更新名称成功');
|
||||
message.success(intl.get('更新名称成功'));
|
||||
handleCancel();
|
||||
}
|
||||
setLoading(false);
|
||||
|
|
|
@ -23,7 +23,7 @@ const SaveModal = ({
|
|||
.post(`${config.apiPrefix}scripts`, payload)
|
||||
.then(({ code, data }) => {
|
||||
if (code === 200) {
|
||||
message.success('保存文件成功');
|
||||
message.success(intl.get('保存文件成功'));
|
||||
handleCancel(data);
|
||||
}
|
||||
setLoading(false);
|
||||
|
|
|
@ -23,7 +23,7 @@ const SettingModal = ({
|
|||
.post(`${config.apiPrefix}scripts`, payload)
|
||||
.then(({ code, data }) => {
|
||||
if (code === 200) {
|
||||
message.success('保存文件成功');
|
||||
message.success(intl.get('保存文件成功'));
|
||||
handleCancel(data);
|
||||
}
|
||||
setLoading(false);
|
||||
|
|
|
@ -10,6 +10,7 @@ const { Link } = Typography;
|
|||
enum TVersion {
|
||||
'develop' = '开发版',
|
||||
'master' = '正式版',
|
||||
'debian' = '正式版'
|
||||
}
|
||||
|
||||
const About = ({ systemInfo }: { systemInfo: SharedContext['systemInfo'] }) => {
|
||||
|
|
|
@ -14,7 +14,7 @@ const CheckUpdate = ({ socketMessage, systemInfo }: any) => {
|
|||
const checkUpgrade = () => {
|
||||
if (updateLoading) return;
|
||||
setUpdateLoading(true);
|
||||
message.loading('检查更新中...', 0);
|
||||
message.loading(intl.get('检查更新中...'), 0);
|
||||
request
|
||||
.put(`${config.apiPrefix}system/update-check`)
|
||||
.then(({ code, data }) => {
|
||||
|
@ -177,7 +177,7 @@ const CheckUpdate = ({ socketMessage, systemInfo }: any) => {
|
|||
}
|
||||
|
||||
const newMessage = `${value}${_message}`;
|
||||
const updateFailed = newMessage.includes('失败');
|
||||
const updateFailed = newMessage.includes(intl.get('失败'));
|
||||
|
||||
modalRef.current.update({
|
||||
maskClosable: updateFailed,
|
||||
|
@ -198,8 +198,8 @@ const CheckUpdate = ({ socketMessage, systemInfo }: any) => {
|
|||
),
|
||||
});
|
||||
|
||||
if (updateFailed && !value.includes('失败,请检查')) {
|
||||
message.error('更新失败,请检查网络及日志或稍后再试');
|
||||
if (updateFailed && !value.includes(intl.get('失败,请检查'))) {
|
||||
message.error(intl.get('更新失败,请检查网络及日志或稍后再试'));
|
||||
}
|
||||
|
||||
setValue(newMessage);
|
||||
|
@ -209,7 +209,7 @@ const CheckUpdate = ({ socketMessage, systemInfo }: any) => {
|
|||
.getElementById('log-identifier')!
|
||||
.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||||
|
||||
if (_message.includes('更新包下载成功')) {
|
||||
if (_message.includes(intl.get('更新包下载成功'))) {
|
||||
setTimeout(() => {
|
||||
showReloadModal();
|
||||
}, 1000);
|
||||
|
|
|
@ -154,7 +154,7 @@ const Setting = () => {
|
|||
.delete(`${config.apiPrefix}apps`, { data: [record.id] })
|
||||
.then(({ code, data }) => {
|
||||
if (code === 200) {
|
||||
message.success('删除成功');
|
||||
message.success(intl.get('删除成功'));
|
||||
const result = [...dataSource];
|
||||
result.splice(index, 1);
|
||||
setDataSource(result);
|
||||
|
@ -188,7 +188,7 @@ const Setting = () => {
|
|||
.put(`${config.apiPrefix}apps/${record.id}/reset-secret`)
|
||||
.then(({ code, data }) => {
|
||||
if (code === 200) {
|
||||
message.success('重置成功');
|
||||
message.success(intl.get('重置成功'));
|
||||
handleApp(data);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -41,8 +41,8 @@ const Other = ({
|
|||
const [form] = Form.useForm();
|
||||
const modalRef = useRef<any>();
|
||||
const [exportLoading, setExportLoading] = useState(false);
|
||||
const showUploadProgress = useProgress('上传');
|
||||
const showDownloadProgress = useProgress('下载');
|
||||
const showUploadProgress = useProgress(intl.get('上传'));
|
||||
const showDownloadProgress = useProgress(intl.get('下载'));
|
||||
|
||||
const {
|
||||
enable: enableDarkMode,
|
||||
|
@ -85,7 +85,7 @@ const Other = ({
|
|||
.put(`${config.apiPrefix}system/config`, systemConfig)
|
||||
.then(({ code, data }) => {
|
||||
if (code === 200) {
|
||||
message.success('更新成功');
|
||||
message.success(intl.get('更新成功'));
|
||||
}
|
||||
})
|
||||
.catch((error: any) => {
|
||||
|
@ -162,7 +162,7 @@ const Other = ({
|
|||
return (
|
||||
<Form layout="vertical" form={form}>
|
||||
<Form.Item
|
||||
label={intl.get('主题设置')}
|
||||
label={intl.get('主题')}
|
||||
name="theme"
|
||||
initialValue={defaultTheme}
|
||||
>
|
||||
|
|
|
@ -67,12 +67,12 @@ const SecuritySettings = ({ user, userChange }: any) => {
|
|||
.then(({ code, data }) => {
|
||||
if (code === 200) {
|
||||
if (data) {
|
||||
message.success('激活成功');
|
||||
message.success(intl.get('激活成功'));
|
||||
setTwoFactoring(false);
|
||||
setTwoFactorActivated(true);
|
||||
userChange();
|
||||
} else {
|
||||
message.success('验证失败');
|
||||
message.success(intl.get('验证失败'));
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -366,7 +366,7 @@ const Subscription = () => {
|
|||
})
|
||||
.then(({ code, data }) => {
|
||||
if (code === 200) {
|
||||
message.success('删除成功');
|
||||
message.success(intl.get('删除成功'));
|
||||
const result = [...value];
|
||||
const i = result.findIndex((x) => x.id === record.id);
|
||||
if (i !== -1) {
|
||||
|
|
|
@ -23,7 +23,7 @@ const SubscriptionLogModal = ({
|
|||
data?: string;
|
||||
logUrl?: string;
|
||||
}) => {
|
||||
const [value, setValue] = useState<string>('启动中...');
|
||||
const [value, setValue] = useState<string>(intl.get('启动中...'));
|
||||
const [loading, setLoading] = useState<any>(true);
|
||||
const [executing, setExecuting] = useState<any>(true);
|
||||
const [isPhone, setIsPhone] = useState(false);
|
||||
|
|
|
@ -392,7 +392,7 @@ const SubscriptionModal = ({
|
|||
) {
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
return Promise.reject('Subscription表达式格式有误');
|
||||
return Promise.reject(intl.get('Subscription表达式格式有误'));
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
@ -105,7 +105,7 @@ export default {
|
|||
gotify: [
|
||||
{
|
||||
label: 'gotifyUrl',
|
||||
tip: intl.get('gotify的url地址,例如 https://push.example.de:8080'),
|
||||
tip: intl.get('gotify的url地址,例如 https://push.example.de:8080'),
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
|
@ -126,16 +126,14 @@ export default {
|
|||
goCqHttpBot: [
|
||||
{
|
||||
label: 'goCqHttpBotUrl',
|
||||
tip: intl.get(
|
||||
'推送到个人QQ: http://127.0.0.1/send_private_msg,群:http://127.0.0.1/send_group_msg',
|
||||
tip: intl.get('推送到个人QQ: http://127.0.0.1/send_private_msg,群:http://127.0.0.1/send_group_msg',
|
||||
),
|
||||
required: true,
|
||||
},
|
||||
{ label: 'goCqHttpBotToken', tip: intl.get('访问密钥'), required: true },
|
||||
{
|
||||
label: 'goCqHttpBotQq',
|
||||
tip: intl.get(
|
||||
'如果GOBOT_URL设置 /send_private_msg 则需要填入 user_id=个人QQ 相反如果是 /send_group_msg 则需要填入 group_id=QQ群',
|
||||
tip: intl.get('如果GOBOT_URL设置 /send_private_msg 则需要填入 user_id=个人QQ 相反如果是 /send_group_msg 则需要填入 group_id=QQ群',
|
||||
),
|
||||
required: true,
|
||||
},
|
||||
|
@ -155,26 +153,24 @@ export default {
|
|||
},
|
||||
{
|
||||
label: 'pushDeerUrl',
|
||||
tip: intl.get(
|
||||
'PushDeer的自架API endpoint,默认是 https://api2.pushdeer.com/message/push',
|
||||
tip: intl.get('PushDeer的自架API endpoint,默认是 https://api2.pushdeer.com/message/push',
|
||||
),
|
||||
},
|
||||
],
|
||||
bark: [
|
||||
{
|
||||
label: 'barkPush',
|
||||
tip: intl.get(
|
||||
'Bark的信息IP/设备码,例如:https://api.day.app/XXXXXXXX',
|
||||
tip: intl.get('Bark的信息IP/设备码,例如:https://api.day.app/XXXXXXXX',
|
||||
),
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: 'barkIcon',
|
||||
tip: intl.get('BARK推送图标,自定义推送图标 (需iOS15或以上才能显示)'),
|
||||
tip: intl.get('BARK推送图标,自定义推送图标 (需iOS15或以上才能显示)'),
|
||||
},
|
||||
{
|
||||
label: 'barkSound',
|
||||
tip: intl.get('BARK推送铃声,铃声列表去APP查看复制填写'),
|
||||
tip: intl.get('BARK推送铃声,铃声列表去APP查看复制填写'),
|
||||
},
|
||||
{
|
||||
label: 'barkGroup',
|
||||
|
@ -184,8 +180,7 @@ export default {
|
|||
telegramBot: [
|
||||
{
|
||||
label: 'telegramBotToken',
|
||||
tip: intl.get(
|
||||
'telegram机器人的token,例如:1077xxx4424:AAFjv0FcqxxxxxxgEMGfi22B4yh15R5uw',
|
||||
tip: intl.get('telegram机器人的token,例如:1077xxx4424:AAFjv0FcqxxxxxxgEMGfi22B4yh15R5uw',
|
||||
),
|
||||
required: true,
|
||||
},
|
||||
|
@ -198,8 +193,7 @@ export default {
|
|||
{ label: 'telegramBotProxyPort', tip: intl.get('代理端口') },
|
||||
{
|
||||
label: 'telegramBotProxyAuth',
|
||||
tip: intl.get(
|
||||
'telegram代理配置认证参数, 用户名与密码用英文冒号连接 user:password',
|
||||
tip: intl.get('telegram代理配置认证参数,用户名与密码用英文冒号连接 user:password',
|
||||
),
|
||||
},
|
||||
{
|
||||
|
@ -210,23 +204,20 @@ export default {
|
|||
dingtalkBot: [
|
||||
{
|
||||
label: 'dingtalkBotToken',
|
||||
tip: intl.get(
|
||||
'钉钉机器人webhook token,例如:5a544165465465645d0f31dca676e7bd07415asdasd',
|
||||
tip: intl.get('钉钉机器人webhook token,例如:5a544165465465645d0f31dca676e7bd07415asdasd',
|
||||
),
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: 'dingtalkBotSecret',
|
||||
tip: intl.get(
|
||||
'密钥,机器人安全设置页面,加签一栏下面显示的SEC开头的字符串',
|
||||
tip: intl.get('密钥,机器人安全设置页面,加签一栏下面显示的SEC开头的字符串',
|
||||
),
|
||||
},
|
||||
],
|
||||
weWorkBot: [
|
||||
{
|
||||
label: 'weWorkBotKey',
|
||||
tip: intl.get(
|
||||
'企业微信机器人的 webhook(详见文档 https://work.weixin.qq.com/api/doc/90000/90136/91770),例如:693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa',
|
||||
tip: intl.get('企业微信机器人的webhook(详见文档 https://work.weixin.qq.com/api/doc/90000/90136/91770),例如:693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa',
|
||||
),
|
||||
required: true,
|
||||
},
|
||||
|
@ -238,8 +229,7 @@ export default {
|
|||
weWorkApp: [
|
||||
{
|
||||
label: 'weWorkAppKey',
|
||||
tip: intl.get(
|
||||
'corpid,corpsecret,touser(注:多个成员ID使用|隔开),agentid,消息类型(选填,不填默认文本消息类型) 注意用,号隔开(英文输入法的逗号),例如:wwcfrs,B-76WERQ,qinglong,1000001,2COat',
|
||||
tip: intl.get('corpid、corpsecret、touser(注:多个成员ID使用|隔开)、agentid、消息类型(选填,不填默认文本消息类型) 注意用,号隔开(英文输入法的逗号),例如:wwcfrs,B-76WERQ,qinglong,1000001,2COat',
|
||||
),
|
||||
required: true,
|
||||
},
|
||||
|
@ -251,8 +241,7 @@ export default {
|
|||
aibotk: [
|
||||
{
|
||||
label: 'aibotkKey',
|
||||
tip: intl.get(
|
||||
'密钥key,智能微秘书个人中心获取apikey,申请地址:https://wechat.aibotk.com/signup?from=ql',
|
||||
tip: intl.get('密钥key,智能微秘书个人中心获取apikey,申请地址:https://wechat.aibotk.com/signup?from=ql',
|
||||
),
|
||||
required: true,
|
||||
},
|
||||
|
@ -268,8 +257,7 @@ export default {
|
|||
},
|
||||
{
|
||||
label: 'aibotkName',
|
||||
tip: intl.get(
|
||||
'要发送的用户昵称或群名,如果目标是群,需要填群名,如果目标是好友,需要填好友昵称',
|
||||
tip: intl.get('要发送的用户昵称或群名,如果目标是群,需要填群名,如果目标是好友,需要填好友昵称',
|
||||
),
|
||||
required: true,
|
||||
},
|
||||
|
@ -277,8 +265,7 @@ export default {
|
|||
iGot: [
|
||||
{
|
||||
label: 'iGotPushKey',
|
||||
tip: intl.get(
|
||||
'iGot的信息推送key,例如:https://push.hellyw.com/XXXXXXXX',
|
||||
tip: intl.get('iGot的信息推送key,例如:https://push.hellyw.com/XXXXXXXX',
|
||||
),
|
||||
required: true,
|
||||
},
|
||||
|
@ -286,23 +273,20 @@ export default {
|
|||
pushPlus: [
|
||||
{
|
||||
label: 'pushPlusToken',
|
||||
tip: intl.get(
|
||||
'微信扫码登录后一对一推送或一对多推送下面的token(您的Token),不提供PUSH_PLUS_USER则默认为一对一推送,参考 https://www.pushplus.plus/',
|
||||
tip: intl.get('微信扫码登录后一对一推送或一对多推送下面的token(您的Token),不提供PUSH_PLUS_USER则默认为一对一推送,参考 https://www.pushplus.plus/',
|
||||
),
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
label: 'pushPlusUser',
|
||||
tip: intl.get(
|
||||
'一对多推送的“群组编码”(一对多推送下面->您的群组(如无则新建)->群组编码,如果您是创建群组人。也需点击“查看二维码”扫描绑定,否则不能接受群组消息推送)',
|
||||
tip: intl.get('一对多推送的“群组编码”(一对多推送下面->您的群组(如无则创建)->群组编码,如果您是创建群组人。也需点击“查看二维码”扫描绑定,否则不能接受群组消息推送)',
|
||||
),
|
||||
},
|
||||
],
|
||||
lark: [
|
||||
{
|
||||
label: 'larkKey',
|
||||
tip: intl.get(
|
||||
'飞书群组机器人:https://www.feishu.cn/hc/zh-CN/articles/360024984973',
|
||||
tip: intl.get('飞书群组机器人:https://www.feishu.cn/hc/zh-CN/articles/360024984973',
|
||||
),
|
||||
required: true,
|
||||
},
|
||||
|
@ -310,8 +294,7 @@ export default {
|
|||
email: [
|
||||
{
|
||||
label: 'emailService',
|
||||
tip: intl.get(
|
||||
'邮箱服务名称,比如126、163、Gmail、QQ等,支持列表https://nodemailer.com/smtp/well-known/',
|
||||
tip: intl.get('邮箱服务名称,比如126、163、Gmail、QQ等,支持列表https://nodemailer.com/smtp/well-known/',
|
||||
),
|
||||
required: true,
|
||||
},
|
||||
|
@ -344,8 +327,7 @@ export default {
|
|||
},
|
||||
{
|
||||
label: 'webhookUrl',
|
||||
tip: intl.get(
|
||||
'请求链接以http或者https开头。url或者body中必须包含$title,$content可选,对应api内容的位置',
|
||||
tip: intl.get('请求链接以http或者https开头。url或者body中必须包含$title,$content可选,对应api内容的位置',
|
||||
),
|
||||
required: true,
|
||||
placeholder: 'https://xxx.cn/api?content=$title\n',
|
||||
|
@ -357,8 +339,7 @@ export default {
|
|||
},
|
||||
{
|
||||
label: 'webhookBody',
|
||||
tip: intl.get(
|
||||
'请求体格式key1: value1,多个换行分割。url或者body中必须包含$title,$content可选,对应api内容的位置',
|
||||
tip: intl.get('请求体格式key1: value1,多个换行分割。url或者body中必须包含$title,$content可选,对应api内容的位置',
|
||||
),
|
||||
placeholder: 'key1: $title\nkey2: $content',
|
||||
},
|
||||
|
|
|
@ -1 +1,9 @@
|
|||
export const LOG_END_SYMBOL = ' ';
|
||||
|
||||
export const LANG_MAP = {
|
||||
'.py': 'python',
|
||||
'.js': 'javascript',
|
||||
'.mjs': 'javascript',
|
||||
'.sh': 'shell',
|
||||
'.ts': 'typescript',
|
||||
};
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import intl from 'react-intl-universal'
|
||||
import { message } from 'antd';
|
||||
import config from './config';
|
||||
import { history } from '@umijs/max';
|
||||
|
@ -32,7 +33,7 @@ const errorHandler = function (error: AxiosError) {
|
|||
history.push('/error');
|
||||
} else if (responseStatus === 401) {
|
||||
if (history.location.pathname !== '/login') {
|
||||
message.error('登录已过期,请重新登录');
|
||||
message.error(intl.get('登录已过期,请重新登录'));
|
||||
localStorage.removeItem(config.authKey);
|
||||
history.push('/login');
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import intl from 'react-intl-universal';
|
||||
import { LOG_END_SYMBOL } from './const';
|
||||
import { LANG_MAP, LOG_END_SYMBOL } from './const';
|
||||
import cron_parser from 'cron-parser';
|
||||
|
||||
export default function browserType() {
|
||||
|
@ -335,7 +335,18 @@ export function parseCrontab(schedule: string): Date {
|
|||
if (time) {
|
||||
return time.next().toDate();
|
||||
}
|
||||
} catch (error) {}
|
||||
} catch (error) { }
|
||||
|
||||
return new Date('1970');
|
||||
}
|
||||
|
||||
export function getExtension(filename: string) {
|
||||
if (!filename) return '';
|
||||
const arr = filename.split('.');
|
||||
return `.${arr[arr.length - 1]}`;
|
||||
}
|
||||
|
||||
export function getEditorMode(filename: string) {
|
||||
const extension = getExtension(filename) as keyof typeof LANG_MAP;
|
||||
return LANG_MAP[extension];
|
||||
}
|
16
version.yaml
16
version.yaml
|
@ -1,6 +1,12 @@
|
|||
version: 2.15.20
|
||||
changeLogLink: https://t.me/jiao_long/386
|
||||
publishTime: 2023-07-22 16:00
|
||||
version: 2.16.0
|
||||
changeLogLink: https://t.me/jiao_long/388
|
||||
publishTime: 2023-08-06 16:00
|
||||
changeLog: |
|
||||
1. 修复判断 linux 依赖已安装逻辑
|
||||
2. 修复未启动完成时,页面提示 500
|
||||
1. 多语言支持英文界面
|
||||
2. 定时任务增加关联订阅
|
||||
3. 删除订阅支持自动删除任务和脚本
|
||||
4. 定时任务支持运行 mjs 后缀文件
|
||||
5. PushMe消息通道增加 params 参数
|
||||
6. 修复 6 位 cron 不以 task 开头定时任务运行失败
|
||||
7. 修复任务详情日志列表过多卡顿
|
||||
8. 修复定时任务列表虚拟滚动
|
||||
|
|
Loading…
Reference in New Issue
Block a user