mirror of
https://github.com/whyour/qinglong.git
synced 2026-06-13 14:37:28 +08:00
增加任务统计
This commit is contained in:
parent
c0b7527148
commit
e8ac195c96
370
back/api/dashboard.ts
Normal file
370
back/api/dashboard.ts
Normal file
|
|
@ -0,0 +1,370 @@
|
||||||
|
import { Router, Request, Response, NextFunction } from 'express';
|
||||||
|
import { Container } from 'typedi';
|
||||||
|
import { fn, col, where, Op } from 'sequelize';
|
||||||
|
import { CrontabModel } from '../data/cron';
|
||||||
|
import { CrontabStatModel } from '../data/cronStats';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import os from 'os';
|
||||||
|
|
||||||
|
const route = Router();
|
||||||
|
|
||||||
|
export default (app: Router) => {
|
||||||
|
app.use('/dashboard', route);
|
||||||
|
|
||||||
|
route.post('/record', async (req: Request, res: Response) => {
|
||||||
|
try {
|
||||||
|
const { ref_id, code, elapsed } = req.body;
|
||||||
|
if (!ref_id) return res.send({ code: 400, message: 'ref_id required' });
|
||||||
|
|
||||||
|
const today = dayjs().format('YYYY-MM-DD');
|
||||||
|
const isSuccess = code === 0 ? 1 : 0;
|
||||||
|
const isFail = code !== 0 ? 1 : 0;
|
||||||
|
const elapsedMs = (Number(elapsed) || 0) * 1000;
|
||||||
|
|
||||||
|
const existing = await CrontabStatModel.findOne({
|
||||||
|
where: { ref_id: Number(ref_id), date: today },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existing) {
|
||||||
|
await CrontabStatModel.update(
|
||||||
|
{
|
||||||
|
run_count: (existing.run_count || 0) + 1,
|
||||||
|
success_count: (existing.success_count || 0) + isSuccess,
|
||||||
|
fail_count: (existing.fail_count || 0) + isFail,
|
||||||
|
total_time: (existing.total_time || 0) + elapsedMs,
|
||||||
|
max_time: Math.max(existing.max_time || 0, elapsedMs),
|
||||||
|
},
|
||||||
|
{ where: { id: existing.id } },
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
await CrontabStatModel.create({
|
||||||
|
ref_id: Number(ref_id),
|
||||||
|
date: today,
|
||||||
|
run_count: 1,
|
||||||
|
success_count: isSuccess,
|
||||||
|
fail_count: isFail,
|
||||||
|
total_time: elapsedMs,
|
||||||
|
max_time: elapsedMs,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
res.send({ code: 200 });
|
||||||
|
} catch (e) {
|
||||||
|
res.send({ code: 500 });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
route.get(
|
||||||
|
'/overview',
|
||||||
|
async (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
try {
|
||||||
|
const today = dayjs().format('YYYY-MM-DD');
|
||||||
|
|
||||||
|
const [total, enabled, disabled, stats] = await Promise.all([
|
||||||
|
CrontabModel.count(),
|
||||||
|
CrontabModel.count({ where: { isDisabled: 0 } }),
|
||||||
|
CrontabModel.count({ where: { isDisabled: 1 } }),
|
||||||
|
CrontabStatModel.findOne({
|
||||||
|
attributes: [
|
||||||
|
[fn('SUM', col('run_count')), 'total_runs'],
|
||||||
|
[fn('SUM', col('success_count')), 'total_success'],
|
||||||
|
[fn('SUM', col('fail_count')), 'total_fail'],
|
||||||
|
[fn('SUM', col('total_time')), 'total_time'],
|
||||||
|
],
|
||||||
|
where: { date: today },
|
||||||
|
raw: true,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const row = stats as any;
|
||||||
|
const totalRuns = Number(row?.total_runs) || 0;
|
||||||
|
const totalSuccess = Number(row?.total_success) || 0;
|
||||||
|
const totalFail = Number(row?.total_fail) || 0;
|
||||||
|
const totalTime = Number(row?.total_time) || 0;
|
||||||
|
|
||||||
|
res.send({
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
total,
|
||||||
|
enabled,
|
||||||
|
disabled,
|
||||||
|
todayRuns: totalRuns,
|
||||||
|
todaySuccess: totalSuccess,
|
||||||
|
todayFail: totalFail,
|
||||||
|
successRate: totalRuns > 0 ? ((totalSuccess / totalRuns) * 100).toFixed(1) : '0',
|
||||||
|
avgTime: totalRuns > 0 ? Math.round(totalTime / totalRuns) : 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
next(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
route.get(
|
||||||
|
'/trend',
|
||||||
|
async (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
try {
|
||||||
|
const days = parseInt(req.query.days as string) || 7;
|
||||||
|
const dates: string[] = [];
|
||||||
|
for (let i = days - 1; i >= 0; i--) {
|
||||||
|
dates.push(dayjs().subtract(i, 'day').format('YYYY-MM-DD'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const rows = (await CrontabStatModel.findAll({
|
||||||
|
attributes: [
|
||||||
|
'date',
|
||||||
|
[fn('SUM', col('run_count')), 'total_runs'],
|
||||||
|
[fn('SUM', col('success_count')), 'total_success'],
|
||||||
|
[fn('SUM', col('fail_count')), 'total_fail'],
|
||||||
|
],
|
||||||
|
where: {
|
||||||
|
date: { [Op.in]: dates },
|
||||||
|
},
|
||||||
|
group: ['date'],
|
||||||
|
order: [['date', 'ASC']],
|
||||||
|
raw: true,
|
||||||
|
})) as any[];
|
||||||
|
|
||||||
|
const dataMap: Record<string, any> = {};
|
||||||
|
rows.forEach((r: any) => {
|
||||||
|
dataMap[r.date] = {
|
||||||
|
total: Number(r.total_runs) || 0,
|
||||||
|
success: Number(r.total_success) || 0,
|
||||||
|
fail: Number(r.total_fail) || 0,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = dates.map((d) => ({
|
||||||
|
date: dayjs(d).format('MM-DD'),
|
||||||
|
...(dataMap[d] || { total: 0, success: 0, fail: 0 }),
|
||||||
|
}));
|
||||||
|
|
||||||
|
res.send({ code: 200, data });
|
||||||
|
} catch (e) {
|
||||||
|
next(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
route.get(
|
||||||
|
'/top-time',
|
||||||
|
async (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
try {
|
||||||
|
const today = dayjs().format('YYYY-MM-DD');
|
||||||
|
|
||||||
|
const rows = (await CrontabStatModel.findAll({
|
||||||
|
attributes: [
|
||||||
|
'ref_id',
|
||||||
|
[fn('SUM', col('total_time')), 'total_time'],
|
||||||
|
[fn('SUM', col('run_count')), 'run_count'],
|
||||||
|
[fn('MAX', col('max_time')), 'max_time'],
|
||||||
|
],
|
||||||
|
where: { date: today, run_count: { [Op.gt]: 0 } },
|
||||||
|
group: ['ref_id'],
|
||||||
|
order: [[fn('SUM', col('total_time')), 'DESC']],
|
||||||
|
limit: 5,
|
||||||
|
raw: true,
|
||||||
|
})) as any[];
|
||||||
|
|
||||||
|
const ids = rows.map((r) => Number(r.ref_id));
|
||||||
|
const crons = await CrontabModel.findAll({
|
||||||
|
where: { id: { [Op.in]: ids } },
|
||||||
|
raw: true,
|
||||||
|
});
|
||||||
|
const nameMap: Record<number, string> = {};
|
||||||
|
crons.forEach((c: any) => { nameMap[c.id] = c.name || c.command; });
|
||||||
|
|
||||||
|
const data = rows.map((r: any, i) => ({
|
||||||
|
rank: i + 1,
|
||||||
|
name: nameMap[Number(r.ref_id)] || `任务#${r.ref_id}`,
|
||||||
|
avgTime: Math.round(Number(r.total_time) / Number(r.run_count)),
|
||||||
|
maxTime: Number(r.max_time),
|
||||||
|
}));
|
||||||
|
|
||||||
|
res.send({ code: 200, data });
|
||||||
|
} catch (e) {
|
||||||
|
next(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
route.get(
|
||||||
|
'/top-count',
|
||||||
|
async (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
try {
|
||||||
|
const today = dayjs().format('YYYY-MM-DD');
|
||||||
|
|
||||||
|
const rows = (await CrontabStatModel.findAll({
|
||||||
|
attributes: [
|
||||||
|
'ref_id',
|
||||||
|
[fn('SUM', col('run_count')), 'run_count'],
|
||||||
|
[fn('SUM', col('total_time')), 'total_time'],
|
||||||
|
[fn('SUM', col('success_count')), 'success_count'],
|
||||||
|
],
|
||||||
|
where: { date: today, run_count: { [Op.gt]: 0 } },
|
||||||
|
group: ['ref_id'],
|
||||||
|
order: [[fn('SUM', col('run_count')), 'DESC']],
|
||||||
|
limit: 5,
|
||||||
|
raw: true,
|
||||||
|
})) as any[];
|
||||||
|
|
||||||
|
const ids = rows.map((r) => Number(r.ref_id));
|
||||||
|
const crons = await CrontabModel.findAll({
|
||||||
|
where: { id: { [Op.in]: ids } },
|
||||||
|
raw: true,
|
||||||
|
});
|
||||||
|
const nameMap: Record<number, string> = {};
|
||||||
|
crons.forEach((c: any) => { nameMap[c.id] = c.name || c.command; });
|
||||||
|
|
||||||
|
const data = rows.map((r: any, i) => ({
|
||||||
|
rank: i + 1,
|
||||||
|
name: nameMap[Number(r.ref_id)] || `任务#${r.ref_id}`,
|
||||||
|
runCount: Number(r.run_count),
|
||||||
|
avgTime: Math.round(Number(r.total_time) / Number(r.run_count)),
|
||||||
|
successRate:
|
||||||
|
Number(r.run_count) > 0
|
||||||
|
? ((Number(r.success_count) / Number(r.run_count)) * 100).toFixed(1)
|
||||||
|
: '0',
|
||||||
|
}));
|
||||||
|
|
||||||
|
res.send({ code: 200, data });
|
||||||
|
} catch (e) {
|
||||||
|
next(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
route.get(
|
||||||
|
'/runtime',
|
||||||
|
async (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
try {
|
||||||
|
const runningCrons = await CrontabModel.findAll({
|
||||||
|
where: {
|
||||||
|
status: 0, // running
|
||||||
|
},
|
||||||
|
raw: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const queuedCrons = await CrontabModel.findAll({
|
||||||
|
where: {
|
||||||
|
status: 3, // queued
|
||||||
|
},
|
||||||
|
raw: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const running = runningCrons.map((c: any) => ({
|
||||||
|
id: c.id,
|
||||||
|
name: c.name || c.command || `任务#${c.id}`,
|
||||||
|
pid: c.pid,
|
||||||
|
elapsed: c.last_execution_time
|
||||||
|
? Math.floor((Date.now() / 1000) - c.last_execution_time)
|
||||||
|
: 0,
|
||||||
|
logPath: c.log_path,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const dayAgo = dayjs().subtract(24, 'hour').unix();
|
||||||
|
const idleTasks = await CrontabModel.findAll({
|
||||||
|
where: {
|
||||||
|
isDisabled: 0,
|
||||||
|
status: 1,
|
||||||
|
last_execution_time: { [Op.lt]: dayAgo },
|
||||||
|
},
|
||||||
|
order: [['last_execution_time', 'ASC']],
|
||||||
|
limit: 5,
|
||||||
|
raw: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
res.send({
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
runningCount: running.length,
|
||||||
|
queuedCount: queuedCrons.length,
|
||||||
|
running,
|
||||||
|
idleTasks: idleTasks.map((c: any) => ({
|
||||||
|
id: c.id,
|
||||||
|
name: c.name || c.command || `任务#${c.id}`,
|
||||||
|
lastRun: c.last_execution_time
|
||||||
|
? dayjs.unix(c.last_execution_time).format('MM-DD HH:mm')
|
||||||
|
: '-',
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
next(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
route.get(
|
||||||
|
'/labels',
|
||||||
|
async (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
try {
|
||||||
|
const today = dayjs().format('YYYY-MM-DD');
|
||||||
|
const [crons, stats] = (await Promise.all([
|
||||||
|
CrontabModel.findAll({ where: { isDisabled: 0 }, raw: true }),
|
||||||
|
CrontabStatModel.findAll({ where: { date: today }, raw: true }),
|
||||||
|
])) as any[];
|
||||||
|
|
||||||
|
const statMap: Record<number, any> = {};
|
||||||
|
stats.forEach((s: any) => { statMap[s.ref_id] = s; });
|
||||||
|
|
||||||
|
const labelMap: Record<string, { count: number; runs: number; success: number; totalTime: number }> = {};
|
||||||
|
crons.forEach((c: any) => {
|
||||||
|
let rawLabels = c.labels;
|
||||||
|
if (typeof rawLabels === 'string') rawLabels = JSON.parse(rawLabels);
|
||||||
|
const labels: string[] = Array.isArray(rawLabels) && rawLabels.length > 0 ? rawLabels : ['未分类'];
|
||||||
|
const st = statMap[c.id];
|
||||||
|
labels.forEach((label: string) => {
|
||||||
|
if (!labelMap[label]) labelMap[label] = { count: 0, runs: 0, success: 0, totalTime: 0 };
|
||||||
|
labelMap[label].count += 1;
|
||||||
|
if (st) {
|
||||||
|
labelMap[label].runs += Number(st.run_count) || 0;
|
||||||
|
labelMap[label].success += Number(st.success_count) || 0;
|
||||||
|
labelMap[label].totalTime += Number(st.total_time) || 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = Object.entries(labelMap)
|
||||||
|
.map(([label, v]) => ({
|
||||||
|
label,
|
||||||
|
count: v.count,
|
||||||
|
todayRuns: v.runs,
|
||||||
|
successRate: v.runs > 0 ? ((v.success / v.runs) * 100).toFixed(1) : '0',
|
||||||
|
avgTime: v.runs > 0 ? Math.round(v.totalTime / v.runs) : 0,
|
||||||
|
}))
|
||||||
|
.sort((a, b) => b.todayRuns - a.todayRuns);
|
||||||
|
|
||||||
|
res.send({ code: 200, data });
|
||||||
|
} catch (e) {
|
||||||
|
next(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
route.get(
|
||||||
|
'/system',
|
||||||
|
async (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
try {
|
||||||
|
const memUsage = process.memoryUsage();
|
||||||
|
res.send({
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
platform: os.platform(),
|
||||||
|
uptime: Math.floor(os.uptime()),
|
||||||
|
memTotal: os.totalmem(),
|
||||||
|
memFree: os.freemem(),
|
||||||
|
memUsagePercent: ((1 - os.freemem() / os.totalmem()) * 100).toFixed(1),
|
||||||
|
heapUsed: Math.round(memUsage.heapUsed / 1024 / 1024),
|
||||||
|
heapTotal: Math.round(memUsage.heapTotal / 1024 / 1024),
|
||||||
|
loadAvg: os.loadavg().map((v) => Number(v.toFixed(2))),
|
||||||
|
cpus: os.cpus().length,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
next(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -10,6 +10,7 @@ import dependence from './dependence';
|
||||||
import system from './system';
|
import system from './system';
|
||||||
import subscription from './subscription';
|
import subscription from './subscription';
|
||||||
import update from './update';
|
import update from './update';
|
||||||
|
import dashboard from './dashboard';
|
||||||
import health from './health';
|
import health from './health';
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
|
|
@ -25,6 +26,7 @@ export default () => {
|
||||||
system(app);
|
system(app);
|
||||||
subscription(app);
|
subscription(app);
|
||||||
update(app);
|
update(app);
|
||||||
|
dashboard(app);
|
||||||
health(app);
|
health(app);
|
||||||
|
|
||||||
return app;
|
return app;
|
||||||
|
|
|
||||||
71
back/data/cronStats.ts
Normal file
71
back/data/cronStats.ts
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
import { DataTypes, Model } from 'sequelize';
|
||||||
|
import { sequelize } from '.';
|
||||||
|
|
||||||
|
export class CrontabStat {
|
||||||
|
id?: number;
|
||||||
|
ref_id!: number;
|
||||||
|
date!: string;
|
||||||
|
run_count?: number;
|
||||||
|
success_count?: number;
|
||||||
|
fail_count?: number;
|
||||||
|
total_time?: number;
|
||||||
|
max_time?: number;
|
||||||
|
|
||||||
|
constructor(options: CrontabStat) {
|
||||||
|
this.id = options.id;
|
||||||
|
this.ref_id = options.ref_id;
|
||||||
|
this.date = options.date;
|
||||||
|
this.run_count = options.run_count || 0;
|
||||||
|
this.success_count = options.success_count || 0;
|
||||||
|
this.fail_count = options.fail_count || 0;
|
||||||
|
this.total_time = options.total_time || 0;
|
||||||
|
this.max_time = options.max_time || 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CrontabStatInstance extends Model<CrontabStat, CrontabStat>, CrontabStat {}
|
||||||
|
|
||||||
|
export const CrontabStatModel = sequelize.define<CrontabStatInstance>(
|
||||||
|
'CrontabStat',
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
autoIncrement: true,
|
||||||
|
},
|
||||||
|
ref_id: {
|
||||||
|
type: DataTypes.NUMBER,
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
date: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
run_count: {
|
||||||
|
type: DataTypes.NUMBER,
|
||||||
|
defaultValue: 0,
|
||||||
|
},
|
||||||
|
success_count: {
|
||||||
|
type: DataTypes.NUMBER,
|
||||||
|
defaultValue: 0,
|
||||||
|
},
|
||||||
|
fail_count: {
|
||||||
|
type: DataTypes.NUMBER,
|
||||||
|
defaultValue: 0,
|
||||||
|
},
|
||||||
|
total_time: {
|
||||||
|
type: DataTypes.NUMBER,
|
||||||
|
defaultValue: 0,
|
||||||
|
},
|
||||||
|
max_time: {
|
||||||
|
type: DataTypes.NUMBER,
|
||||||
|
defaultValue: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
indexes: [
|
||||||
|
{ unique: true, fields: ['ref_id', 'date'] },
|
||||||
|
{ fields: ['date'] },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
@ -24,7 +24,7 @@ export interface AppToken {
|
||||||
expiration: number;
|
expiration: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AppScope = 'envs' | 'crons' | 'configs' | 'scripts' | 'logs' | 'system';
|
export type AppScope = 'envs' | 'crons' | 'configs' | 'scripts' | 'logs' | 'system' | 'dashboard';
|
||||||
|
|
||||||
export interface AppInstance extends Model<App, App>, App {}
|
export interface AppInstance extends Model<App, App>, App {}
|
||||||
export const AppModel = sequelize.define<AppInstance>('App', {
|
export const AppModel = sequelize.define<AppInstance>('App', {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { AppModel } from '../data/open';
|
||||||
import { SystemModel } from '../data/system';
|
import { SystemModel } from '../data/system';
|
||||||
import { SubscriptionModel } from '../data/subscription';
|
import { SubscriptionModel } from '../data/subscription';
|
||||||
import { CrontabViewModel } from '../data/cronView';
|
import { CrontabViewModel } from '../data/cronView';
|
||||||
|
import { CrontabStatModel } from '../data/cronStats';
|
||||||
import { sequelize } from '../data';
|
import { sequelize } from '../data';
|
||||||
|
|
||||||
export default async () => {
|
export default async () => {
|
||||||
|
|
@ -17,6 +18,7 @@ export default async () => {
|
||||||
await EnvModel.sync();
|
await EnvModel.sync();
|
||||||
await SubscriptionModel.sync();
|
await SubscriptionModel.sync();
|
||||||
await CrontabViewModel.sync();
|
await CrontabViewModel.sync();
|
||||||
|
await CrontabStatModel.sync();
|
||||||
|
|
||||||
// 初始化新增字段
|
// 初始化新增字段
|
||||||
const migrations = [
|
const migrations = [
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,15 @@ export default async () => {
|
||||||
if (!systemApp) {
|
if (!systemApp) {
|
||||||
systemApp = await AppModel.create({
|
systemApp = await AppModel.create({
|
||||||
name: 'system',
|
name: 'system',
|
||||||
scopes: ['crons', 'system'],
|
scopes: ['crons', 'system', 'dashboard'],
|
||||||
client_id: createRandomString(12, 12),
|
client_id: createRandomString(12, 12),
|
||||||
client_secret: createRandomString(24, 24),
|
client_secret: createRandomString(24, 24),
|
||||||
});
|
});
|
||||||
|
} else if (!systemApp.scopes.includes('dashboard')) {
|
||||||
|
await AppModel.update(
|
||||||
|
{ scopes: [...systemApp.scopes, 'dashboard'] },
|
||||||
|
{ where: { name: 'system' } },
|
||||||
|
);
|
||||||
}
|
}
|
||||||
const [systemConfig] = await SystemModel.findOrCreate({
|
const [systemConfig] = await SystemModel.findOrCreate({
|
||||||
where: { type: AuthDataType.systemConfig },
|
where: { type: AuthDataType.systemConfig },
|
||||||
|
|
|
||||||
|
|
@ -573,7 +573,6 @@ export default class CronService {
|
||||||
JSON.stringify(params),
|
JSON.stringify(params),
|
||||||
code,
|
code,
|
||||||
);
|
);
|
||||||
// Close the stream after task completion
|
|
||||||
await logStreamManager.closeStream(absolutePath);
|
await logStreamManager.closeStream(absolutePath);
|
||||||
await CrontabModel.update(
|
await CrontabModel.update(
|
||||||
{ status: CrontabStatus.idle, pid: undefined },
|
{ status: CrontabStatus.idle, pid: undefined },
|
||||||
|
|
|
||||||
41
package.json
41
package.json
|
|
@ -73,12 +73,16 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@ant-design/plots": "^2.6.8",
|
||||||
|
"@bufbuild/protobuf": "^2.10.0",
|
||||||
"@grpc/grpc-js": "^1.14.0",
|
"@grpc/grpc-js": "^1.14.0",
|
||||||
"@grpc/proto-loader": "^0.8.0",
|
"@grpc/proto-loader": "^0.8.0",
|
||||||
|
"@keyv/sqlite": "^4.0.1",
|
||||||
"@otplib/preset-default": "^12.0.1",
|
"@otplib/preset-default": "^12.0.1",
|
||||||
"body-parser": "^1.20.3",
|
"body-parser": "^1.20.3",
|
||||||
"celebrate": "^15.0.3",
|
"celebrate": "^15.0.3",
|
||||||
"chokidar": "^4.0.1",
|
"chokidar": "^4.0.1",
|
||||||
|
"compression": "^1.7.4",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"cron-parser": "^5.4.0",
|
"cron-parser": "^5.4.0",
|
||||||
"cross-spawn": "^7.0.6",
|
"cross-spawn": "^7.0.6",
|
||||||
|
|
@ -88,51 +92,48 @@
|
||||||
"express-jwt": "^8.4.1",
|
"express-jwt": "^8.4.1",
|
||||||
"express-rate-limit": "^7.4.1",
|
"express-rate-limit": "^7.4.1",
|
||||||
"express-urlrewrite": "^2.0.3",
|
"express-urlrewrite": "^2.0.3",
|
||||||
"undici": "^7.9.0",
|
"helmet": "^8.1.0",
|
||||||
"hpagent": "^1.2.0",
|
"hpagent": "^1.2.0",
|
||||||
"http-proxy-middleware": "^3.0.3",
|
"http-proxy-middleware": "^3.0.3",
|
||||||
"iconv-lite": "^0.6.3",
|
"iconv-lite": "^0.6.3",
|
||||||
|
"ip2region": "2.3.0",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
|
"keyv": "^5.2.3",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"multer": "2.1.1",
|
"multer": "2.1.1",
|
||||||
"node-schedule": "^2.1.0",
|
"node-schedule": "^2.1.0",
|
||||||
"nodemailer": "^8.0.1",
|
"nodemailer": "^8.0.1",
|
||||||
"p-queue-cjs": "7.3.4",
|
"p-queue-cjs": "7.3.4",
|
||||||
"@bufbuild/protobuf": "^2.10.0",
|
"proper-lockfile": "^4.1.2",
|
||||||
"ps-tree": "^1.2.0",
|
"ps-tree": "^1.2.0",
|
||||||
"reflect-metadata": "^0.2.2",
|
"reflect-metadata": "^0.2.2",
|
||||||
|
"request-ip": "3.3.0",
|
||||||
"sequelize": "^6.37.5",
|
"sequelize": "^6.37.5",
|
||||||
"sockjs": "^0.3.24",
|
"sockjs": "^0.3.24",
|
||||||
"sqlite3": "git+https://github.com/whyour/node-sqlite3.git#v1.0.3",
|
"sqlite3": "git+https://github.com/whyour/node-sqlite3.git#v1.0.3",
|
||||||
"toad-scheduler": "^3.0.1",
|
"toad-scheduler": "^3.0.1",
|
||||||
"typedi": "^0.10.0",
|
"typedi": "^0.10.0",
|
||||||
|
"undici": "^7.9.0",
|
||||||
"uuid": "^11.0.3",
|
"uuid": "^11.0.3",
|
||||||
"winston": "^3.17.0",
|
"winston": "^3.17.0",
|
||||||
"winston-daily-rotate-file": "^5.0.0",
|
"winston-daily-rotate-file": "^5.0.0"
|
||||||
"request-ip": "3.3.0",
|
|
||||||
"ip2region": "2.3.0",
|
|
||||||
"keyv": "^5.2.3",
|
|
||||||
"@keyv/sqlite": "^4.0.1",
|
|
||||||
"proper-lockfile": "^4.1.2",
|
|
||||||
"compression": "^1.7.4",
|
|
||||||
"helmet": "^8.1.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"moment": "2.30.1",
|
|
||||||
"@ant-design/icons": "^5.0.1",
|
"@ant-design/icons": "^5.0.1",
|
||||||
"@ant-design/pro-layout": "6.38.22",
|
"@ant-design/pro-layout": "6.38.22",
|
||||||
"@codemirror/view": "6.39.16",
|
|
||||||
"@codemirror/state": "6.5.4",
|
"@codemirror/state": "6.5.4",
|
||||||
|
"@codemirror/view": "6.39.16",
|
||||||
"@monaco-editor/react": "4.2.1",
|
"@monaco-editor/react": "4.2.1",
|
||||||
"@react-hook/resize-observer": "^2.0.2",
|
"@react-hook/resize-observer": "^2.0.2",
|
||||||
"react-router-dom": "6.26.1",
|
|
||||||
"@types/body-parser": "^1.19.2",
|
"@types/body-parser": "^1.19.2",
|
||||||
|
"@types/compression": "^1.7.2",
|
||||||
"@types/cors": "^2.8.12",
|
"@types/cors": "^2.8.12",
|
||||||
"@types/cross-spawn": "^6.0.2",
|
"@types/cross-spawn": "^6.0.2",
|
||||||
"@types/express": "^4.17.13",
|
"@types/express": "^4.17.13",
|
||||||
"@types/express-jwt": "^6.0.4",
|
"@types/express-jwt": "^6.0.4",
|
||||||
"@types/file-saver": "2.0.2",
|
"@types/file-saver": "2.0.2",
|
||||||
|
"@types/helmet": "^4.0.0",
|
||||||
"@types/js-yaml": "^4.0.5",
|
"@types/js-yaml": "^4.0.5",
|
||||||
"@types/jsonwebtoken": "^8.5.8",
|
"@types/jsonwebtoken": "^8.5.8",
|
||||||
"@types/lodash": "^4.14.185",
|
"@types/lodash": "^4.14.185",
|
||||||
|
|
@ -140,17 +141,17 @@
|
||||||
"@types/node": "^17.0.21",
|
"@types/node": "^17.0.21",
|
||||||
"@types/node-schedule": "^1.3.2",
|
"@types/node-schedule": "^1.3.2",
|
||||||
"@types/nodemailer": "^6.4.4",
|
"@types/nodemailer": "^6.4.4",
|
||||||
|
"@types/proper-lockfile": "^4.1.4",
|
||||||
|
"@types/ps-tree": "^1.1.6",
|
||||||
"@types/qrcode.react": "^1.0.2",
|
"@types/qrcode.react": "^1.0.2",
|
||||||
"@types/react": "^18.0.20",
|
"@types/react": "^18.0.20",
|
||||||
"@types/react-copy-to-clipboard": "^5.0.4",
|
"@types/react-copy-to-clipboard": "^5.0.4",
|
||||||
"@types/react-dom": "^18.0.6",
|
"@types/react-dom": "^18.0.6",
|
||||||
|
"@types/request-ip": "0.0.41",
|
||||||
"@types/serve-handler": "^6.1.1",
|
"@types/serve-handler": "^6.1.1",
|
||||||
"@types/sockjs": "^0.3.33",
|
"@types/sockjs": "^0.3.33",
|
||||||
"@types/sockjs-client": "^1.5.1",
|
"@types/sockjs-client": "^1.5.1",
|
||||||
"@types/uuid": "^8.3.4",
|
"@types/uuid": "^8.3.4",
|
||||||
"@types/request-ip": "0.0.41",
|
|
||||||
"@types/proper-lockfile": "^4.1.4",
|
|
||||||
"@types/ps-tree": "^1.1.6",
|
|
||||||
"@uiw/codemirror-extensions-langs": "^4.21.9",
|
"@uiw/codemirror-extensions-langs": "^4.21.9",
|
||||||
"@uiw/react-codemirror": "^4.21.9",
|
"@uiw/react-codemirror": "^4.21.9",
|
||||||
"@umijs/max": "^4.4.4",
|
"@umijs/max": "^4.4.4",
|
||||||
|
|
@ -162,9 +163,9 @@
|
||||||
"axios": "^1.4.0",
|
"axios": "^1.4.0",
|
||||||
"compression-webpack-plugin": "9.2.0",
|
"compression-webpack-plugin": "9.2.0",
|
||||||
"concurrently": "^7.0.0",
|
"concurrently": "^7.0.0",
|
||||||
"react-hotkeys-hook": "^4.6.1",
|
|
||||||
"file-saver": "2.0.2",
|
"file-saver": "2.0.2",
|
||||||
"lint-staged": "^13.0.3",
|
"lint-staged": "^13.0.3",
|
||||||
|
"moment": "2.30.1",
|
||||||
"monaco-editor": "0.33.0",
|
"monaco-editor": "0.33.0",
|
||||||
"nodemon": "^3.0.1",
|
"nodemon": "^3.0.1",
|
||||||
"prettier": "^2.5.1",
|
"prettier": "^2.5.1",
|
||||||
|
|
@ -180,7 +181,9 @@
|
||||||
"react-dnd": "^16.0.1",
|
"react-dnd": "^16.0.1",
|
||||||
"react-dnd-html5-backend": "^16.0.1",
|
"react-dnd-html5-backend": "^16.0.1",
|
||||||
"react-dom": "18.3.1",
|
"react-dom": "18.3.1",
|
||||||
|
"react-hotkeys-hook": "^4.6.1",
|
||||||
"react-intl-universal": "^2.12.0",
|
"react-intl-universal": "^2.12.0",
|
||||||
|
"react-router-dom": "6.26.1",
|
||||||
"react-split-pane": "^0.1.92",
|
"react-split-pane": "^0.1.92",
|
||||||
"sockjs-client": "^1.6.0",
|
"sockjs-client": "^1.6.0",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
|
|
@ -188,8 +191,6 @@
|
||||||
"tslib": "^2.4.0",
|
"tslib": "^2.4.0",
|
||||||
"typescript": "5.2.2",
|
"typescript": "5.2.2",
|
||||||
"vh-check": "^2.0.5",
|
"vh-check": "^2.0.5",
|
||||||
"virtualizedtableforantd4": "1.3.0",
|
"virtualizedtableforantd4": "1.3.0"
|
||||||
"@types/compression": "^1.7.2",
|
|
||||||
"@types/helmet": "^4.0.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
580
pnpm-lock.yaml
580
pnpm-lock.yaml
|
|
@ -1,11 +1,18 @@
|
||||||
lockfileVersion: '6.0'
|
lockfileVersion: '6.0'
|
||||||
|
|
||||||
|
settings:
|
||||||
|
autoInstallPeers: true
|
||||||
|
excludeLinksFromLockfile: false
|
||||||
|
|
||||||
overrides:
|
overrides:
|
||||||
sqlite3: git+https://github.com/whyour/node-sqlite3.git#v1.0.3
|
sqlite3: git+https://github.com/whyour/node-sqlite3.git#v1.0.3
|
||||||
'@codemirror/state': 6.5.4
|
'@codemirror/state': 6.5.4
|
||||||
'@codemirror/view': 6.39.16
|
'@codemirror/view': 6.39.16
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@ant-design/plots':
|
||||||
|
specifier: ^2.6.8
|
||||||
|
version: 2.6.8(react-dom@18.3.1)(react@18.3.1)
|
||||||
'@bufbuild/protobuf':
|
'@bufbuild/protobuf':
|
||||||
specifier: ^2.10.0
|
specifier: ^2.10.0
|
||||||
version: 2.10.0
|
version: 2.10.0
|
||||||
|
|
@ -384,6 +391,22 @@ packages:
|
||||||
resolution: {integrity: sha512-0vr5GCwM7xlAl6NxG1lPbABO+SYioNJL3HVy2FA8wTlsIMoZvQwcwsxTw6eLQCiN9V2UQ8kBtfz8DW8utVVE5w==}
|
resolution: {integrity: sha512-0vr5GCwM7xlAl6NxG1lPbABO+SYioNJL3HVy2FA8wTlsIMoZvQwcwsxTw6eLQCiN9V2UQ8kBtfz8DW8utVVE5w==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@ant-design/charts-util@0.0.3(react-dom@18.3.1)(react@18.3.1):
|
||||||
|
resolution: {integrity: sha512-x1H7UT6t4dXAyGRoHqlOnEsEqBSTANFGTZEAMI0CWYhYUpp13n0o9grl9oPtoL6FEQMjUBTY+zGJKlHkz8smMw==}
|
||||||
|
peerDependencies:
|
||||||
|
react: '>=16.8.4 || 18'
|
||||||
|
react-dom: '>=16.8.4 || 18'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
react:
|
||||||
|
optional: true
|
||||||
|
react-dom:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
lodash: 4.17.21
|
||||||
|
react: 18.3.1
|
||||||
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@ant-design/colors@6.0.0:
|
/@ant-design/colors@6.0.0:
|
||||||
resolution: {integrity: sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==}
|
resolution: {integrity: sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -469,6 +492,27 @@ packages:
|
||||||
resolution: {integrity: sha512-MLm1FUpg02fP615ShQnCUN9la2E4RylDxKyolkGqAWTIHO4HyGM0A5x71AMALEyP/bC+UEEWBGSQ+D4/8hQ+ww==}
|
resolution: {integrity: sha512-MLm1FUpg02fP615ShQnCUN9la2E4RylDxKyolkGqAWTIHO4HyGM0A5x71AMALEyP/bC+UEEWBGSQ+D4/8hQ+ww==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@ant-design/plots@2.6.8(react-dom@18.3.1)(react@18.3.1):
|
||||||
|
resolution: {integrity: sha512-QsunUs2d5rbq/1BwVhga/siA5H50OaG23YopMYwPD4sPsza6NQzPQ8FM3elNIsD/BIk298tihqX1cJ/MmvVJbQ==}
|
||||||
|
peerDependencies:
|
||||||
|
react: '>=16.8.4 || 18'
|
||||||
|
react-dom: '>=16.8.4 || 18'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
react:
|
||||||
|
optional: true
|
||||||
|
react-dom:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@ant-design/charts-util': 0.0.3(react-dom@18.3.1)(react@18.3.1)
|
||||||
|
'@antv/event-emitter': 0.1.3
|
||||||
|
'@antv/g': 6.3.1
|
||||||
|
'@antv/g2': 5.4.8
|
||||||
|
'@antv/g2-extension-plot': 0.2.2
|
||||||
|
lodash: 4.17.21
|
||||||
|
react: 18.3.1
|
||||||
|
react-dom: 18.3.1(react@18.3.1)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@ant-design/pro-card@2.9.2(antd@4.24.16)(react-dom@18.3.1)(react@18.3.1):
|
/@ant-design/pro-card@2.9.2(antd@4.24.16)(react-dom@18.3.1)(react@18.3.1):
|
||||||
resolution: {integrity: sha512-mKOmNb7jc3Pz41RrPY7EFKRWBjLdN4tp9yzmRkS2g8K7P3pW435f7Ip6rc+58FWDzbZa8lElTGPxAoFB/dq7LA==}
|
resolution: {integrity: sha512-mKOmNb7jc3Pz41RrPY7EFKRWBjLdN4tp9yzmRkS2g8K7P3pW435f7Ip6rc+58FWDzbZa8lElTGPxAoFB/dq7LA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
@ -903,6 +947,184 @@ packages:
|
||||||
resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==}
|
resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@antv/component@2.1.11:
|
||||||
|
resolution: {integrity: sha512-dTdz8VAd3rpjOaGEZTluz82mtzrP4XCtNlNQyrxY7VNRNcjtvpTLDn57bUL2lRu1T+iklKvgbE2llMriWkq9vQ==}
|
||||||
|
dependencies:
|
||||||
|
'@antv/g': 6.3.1
|
||||||
|
'@antv/scale': 0.4.16
|
||||||
|
'@antv/util': 3.3.11
|
||||||
|
svg-path-parser: 1.1.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@antv/coord@0.4.7:
|
||||||
|
resolution: {integrity: sha512-UTbrMLhwJUkKzqJx5KFnSRpU3BqrdLORJbwUbHK2zHSCT3q3bjcFA//ZYLVfIlwqFDXp/hzfMyRtp0c77A9ZVA==}
|
||||||
|
dependencies:
|
||||||
|
'@antv/scale': 0.4.16
|
||||||
|
'@antv/util': 2.0.17
|
||||||
|
gl-matrix: 3.4.4
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@antv/event-emitter@0.1.3:
|
||||||
|
resolution: {integrity: sha512-4ddpsiHN9Pd4UIlWuKVK1C4IiZIdbwQvy9i7DUSI3xNJ89FPUFt8lxDYj8GzzfdllV0NkJTRxnG+FvLk0llidg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@antv/expr@1.0.2:
|
||||||
|
resolution: {integrity: sha512-vrfdmPHkTuiS5voVutKl2l06w1ihBh9A8SFdQPEE+2KMVpkymzGOF1eWpfkbGZ7tiFE15GodVdhhHomD/hdIwg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@antv/g-canvas@2.2.0:
|
||||||
|
resolution: {integrity: sha512-h7zVBBo2aO64DuGKvq9sG+yTU3sCUb9DALCVm7nz8qGPs8hhLuFOkKPEzUDNfNYZGJUGzY8UDtJ3QRGRFcvEQg==}
|
||||||
|
dependencies:
|
||||||
|
'@antv/g-lite': 2.7.0
|
||||||
|
'@antv/g-math': 3.1.0
|
||||||
|
'@antv/util': 3.3.11
|
||||||
|
'@babel/runtime': 7.28.6
|
||||||
|
gl-matrix: 3.4.4
|
||||||
|
tslib: 2.8.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@antv/g-lite@2.7.0:
|
||||||
|
resolution: {integrity: sha512-uSzgHYa5bwR5L2Au7/5tsOhFmXKZKLPBH90+Q9bP9teVs5VT4kOAi0isPSpDI8uhdDC2/VrfTWu5K9HhWI6FWw==}
|
||||||
|
dependencies:
|
||||||
|
'@antv/g-math': 3.1.0
|
||||||
|
'@antv/util': 3.3.11
|
||||||
|
'@antv/vendor': 1.0.11
|
||||||
|
'@babel/runtime': 7.28.6
|
||||||
|
eventemitter3: 5.0.1
|
||||||
|
gl-matrix: 3.4.4
|
||||||
|
tslib: 2.8.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@antv/g-math@3.1.0:
|
||||||
|
resolution: {integrity: sha512-DtN1Gj/yI0UiK18nSBsZX8RK0LszGwqfb+cBYWgE+ddyTm8dZnW4tPUhV7QXePsS6/A5hHC+JFpAAK7OEGo5ZQ==}
|
||||||
|
dependencies:
|
||||||
|
'@antv/util': 3.3.11
|
||||||
|
'@babel/runtime': 7.28.6
|
||||||
|
gl-matrix: 3.4.4
|
||||||
|
tslib: 2.8.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@antv/g-plugin-dragndrop@2.1.1:
|
||||||
|
resolution: {integrity: sha512-+aesDUJVQDs6UJ2bOBbDlaGAPCfHmU0MbrMTlQlfpwNplWueqtgVAZ3L57oZ2ZGHRWUHiRwZGPjXMBM3O2LELw==}
|
||||||
|
dependencies:
|
||||||
|
'@antv/g-lite': 2.7.0
|
||||||
|
'@antv/util': 3.3.11
|
||||||
|
'@babel/runtime': 7.28.6
|
||||||
|
tslib: 2.8.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@antv/g2-extension-plot@0.2.2:
|
||||||
|
resolution: {integrity: sha512-KJXCXO7as+h0hDqirGXf1omrNuYzQmY3VmBmp7lIvkepbQ7sz3pPwy895r1FWETGF3vTk5UeFcAF5yzzBHWgbw==}
|
||||||
|
dependencies:
|
||||||
|
'@antv/g2': 5.4.8
|
||||||
|
'@antv/util': 3.3.11
|
||||||
|
'@antv/vendor': 1.0.11
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@antv/g2@5.4.8:
|
||||||
|
resolution: {integrity: sha512-IvgIpwmT4M5/QAd3Mn2WiHIDeBqFJ4WA2gcZhRRSZuZ2KmgCqZWZwwIT0hc+kIGxwYeDoCQqf//t6FMVu3ryBg==}
|
||||||
|
dependencies:
|
||||||
|
'@antv/component': 2.1.11
|
||||||
|
'@antv/coord': 0.4.7
|
||||||
|
'@antv/event-emitter': 0.1.3
|
||||||
|
'@antv/expr': 1.0.2
|
||||||
|
'@antv/g': 6.3.1
|
||||||
|
'@antv/g-canvas': 2.2.0
|
||||||
|
'@antv/g-plugin-dragndrop': 2.1.1
|
||||||
|
'@antv/scale': 0.5.2
|
||||||
|
'@antv/util': 3.3.11
|
||||||
|
'@antv/vendor': 1.0.11
|
||||||
|
flru: 1.0.2
|
||||||
|
pdfast: 0.2.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@antv/g@6.3.1:
|
||||||
|
resolution: {integrity: sha512-WYEKqy86LHB2PzTmrZXrIsIe+3Epeds2f68zceQ+BJtRoGki7Sy4IhlC8LrUMztgfT1t3d/0L745NWZwITroKA==}
|
||||||
|
dependencies:
|
||||||
|
'@antv/g-lite': 2.7.0
|
||||||
|
'@antv/util': 3.3.11
|
||||||
|
'@babel/runtime': 7.28.6
|
||||||
|
gl-matrix: 3.4.4
|
||||||
|
html2canvas: 1.4.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@antv/scale@0.4.16:
|
||||||
|
resolution: {integrity: sha512-5wg/zB5kXHxpTV5OYwJD3ja6R8yTiqIOkjOhmpEJiowkzRlbEC/BOyMvNUq5fqFIHnMCE9woO7+c3zxEQCKPjw==}
|
||||||
|
dependencies:
|
||||||
|
'@antv/util': 3.3.11
|
||||||
|
color-string: 1.9.1
|
||||||
|
fecha: 4.2.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@antv/scale@0.5.2:
|
||||||
|
resolution: {integrity: sha512-rTHRAwvpHWC5PGZF/mJ2ZuTDqwwvVBDRph0Uu5PV9BXwzV7K8+9lsqGJ+XHVLxe8c6bKog5nlzvV/dcYb0d5Ow==}
|
||||||
|
dependencies:
|
||||||
|
'@antv/util': 3.3.11
|
||||||
|
color-string: 1.9.1
|
||||||
|
fecha: 4.2.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@antv/util@2.0.17:
|
||||||
|
resolution: {integrity: sha512-o6I9hi5CIUvLGDhth0RxNSFDRwXeywmt6ExR4+RmVAzIi48ps6HUy+svxOCayvrPBN37uE6TAc2KDofRo0nK9Q==}
|
||||||
|
dependencies:
|
||||||
|
csstype: 3.2.3
|
||||||
|
tslib: 2.8.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@antv/util@3.3.11:
|
||||||
|
resolution: {integrity: sha512-FII08DFM4ABh2q5rPYdr0hMtKXRgeZazvXaFYCs7J7uTcWDHUhczab2qOCJLNDugoj8jFag1djb7wS9ehaRYBg==}
|
||||||
|
dependencies:
|
||||||
|
fast-deep-equal: 3.1.3
|
||||||
|
gl-matrix: 3.4.4
|
||||||
|
tslib: 2.8.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@antv/vendor@1.0.11:
|
||||||
|
resolution: {integrity: sha512-LmhPEQ+aapk3barntaiIxJ5VHno/Tyab2JnfdcPzp5xONh/8VSfed4bo/9xKo5HcUAEydko38vYLfj6lJliLiw==}
|
||||||
|
dependencies:
|
||||||
|
'@types/d3-array': 3.2.2
|
||||||
|
'@types/d3-color': 3.1.3
|
||||||
|
'@types/d3-dispatch': 3.0.7
|
||||||
|
'@types/d3-dsv': 3.0.7
|
||||||
|
'@types/d3-ease': 3.0.2
|
||||||
|
'@types/d3-fetch': 3.0.7
|
||||||
|
'@types/d3-force': 3.0.10
|
||||||
|
'@types/d3-format': 3.0.4
|
||||||
|
'@types/d3-geo': 3.1.0
|
||||||
|
'@types/d3-hierarchy': 3.1.7
|
||||||
|
'@types/d3-interpolate': 3.0.4
|
||||||
|
'@types/d3-path': 3.1.1
|
||||||
|
'@types/d3-quadtree': 3.0.6
|
||||||
|
'@types/d3-random': 3.0.3
|
||||||
|
'@types/d3-scale': 4.0.9
|
||||||
|
'@types/d3-scale-chromatic': 3.1.0
|
||||||
|
'@types/d3-shape': 3.1.8
|
||||||
|
'@types/d3-time': 3.0.4
|
||||||
|
'@types/d3-timer': 3.0.2
|
||||||
|
d3-array: 3.2.4
|
||||||
|
d3-color: 3.1.0
|
||||||
|
d3-dispatch: 3.0.1
|
||||||
|
d3-dsv: 3.0.1
|
||||||
|
d3-ease: 3.0.1
|
||||||
|
d3-fetch: 3.0.1
|
||||||
|
d3-force: 3.0.0
|
||||||
|
d3-force-3d: 3.0.6
|
||||||
|
d3-format: 3.1.2
|
||||||
|
d3-geo: 3.1.1
|
||||||
|
d3-geo-projection: 4.0.0
|
||||||
|
d3-hierarchy: 3.1.2
|
||||||
|
d3-interpolate: 3.0.1
|
||||||
|
d3-path: 3.1.0
|
||||||
|
d3-quadtree: 3.0.1
|
||||||
|
d3-random: 3.0.1
|
||||||
|
d3-regression: 1.3.10
|
||||||
|
d3-scale: 4.0.2
|
||||||
|
d3-scale-chromatic: 3.1.0
|
||||||
|
d3-shape: 3.2.0
|
||||||
|
d3-time: 3.1.0
|
||||||
|
d3-timer: 3.0.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@babel/code-frame@7.26.2:
|
/@babel/code-frame@7.26.2:
|
||||||
resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==}
|
resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
@ -1351,7 +1573,6 @@ packages:
|
||||||
/@babel/runtime@7.28.6:
|
/@babel/runtime@7.28.6:
|
||||||
resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==}
|
resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@babel/template@7.25.9:
|
/@babel/template@7.25.9:
|
||||||
resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==}
|
resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==}
|
||||||
|
|
@ -1409,8 +1630,8 @@ packages:
|
||||||
resolution: {integrity: sha512-1dNIOmiM0z4BIBwxmxEfA1yoxh1MF/6KPBbh20a5vphGV0ictKlgQsbJs6D6SkR6iJpGbpwRsa6PFMNlg9T9pQ==}
|
resolution: {integrity: sha512-1dNIOmiM0z4BIBwxmxEfA1yoxh1MF/6KPBbh20a5vphGV0ictKlgQsbJs6D6SkR6iJpGbpwRsa6PFMNlg9T9pQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@codemirror/language': ^6.0.0
|
'@codemirror/language': ^6.0.0
|
||||||
'@codemirror/state': ^6.0.0
|
'@codemirror/state': 6.5.4
|
||||||
'@codemirror/view': ^6.0.0
|
'@codemirror/view': 6.39.16
|
||||||
'@lezer/common': ^1.0.0
|
'@lezer/common': ^1.0.0
|
||||||
dependencies:
|
dependencies:
|
||||||
'@codemirror/language': 6.10.6
|
'@codemirror/language': 6.10.6
|
||||||
|
|
@ -3666,8 +3887,8 @@ packages:
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@codemirror/autocomplete': ^6.0.0
|
'@codemirror/autocomplete': ^6.0.0
|
||||||
'@codemirror/language': ^6.0.0
|
'@codemirror/language': ^6.0.0
|
||||||
'@codemirror/state': ^6.0.0
|
'@codemirror/state': 6.5.4
|
||||||
'@codemirror/view': ^6.0.0
|
'@codemirror/view': 6.39.16
|
||||||
'@lezer/common': ^1.0.0
|
'@lezer/common': ^1.0.0
|
||||||
'@lezer/highlight': ^1.0.0
|
'@lezer/highlight': ^1.0.0
|
||||||
'@lezer/lr': ^1.0.0
|
'@lezer/lr': ^1.0.0
|
||||||
|
|
@ -3686,8 +3907,8 @@ packages:
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@codemirror/autocomplete': ^6.0.0
|
'@codemirror/autocomplete': ^6.0.0
|
||||||
'@codemirror/language': ^6.0.0
|
'@codemirror/language': ^6.0.0
|
||||||
'@codemirror/state': ^6.0.0
|
'@codemirror/state': 6.5.4
|
||||||
'@codemirror/view': ^6.0.0
|
'@codemirror/view': 6.39.16
|
||||||
'@lezer/common': ^1.0.0
|
'@lezer/common': ^1.0.0
|
||||||
'@lezer/highlight': ^1.0.0
|
'@lezer/highlight': ^1.0.0
|
||||||
'@lezer/lr': ^1.0.0
|
'@lezer/lr': ^1.0.0
|
||||||
|
|
@ -3718,8 +3939,8 @@ packages:
|
||||||
'@codemirror/lang-html': ^6.2.0
|
'@codemirror/lang-html': ^6.2.0
|
||||||
'@codemirror/lang-javascript': ^6.1.1
|
'@codemirror/lang-javascript': ^6.1.1
|
||||||
'@codemirror/language': ^6.0.0
|
'@codemirror/language': ^6.0.0
|
||||||
'@codemirror/state': ^6.0.0
|
'@codemirror/state': 6.5.4
|
||||||
'@codemirror/view': ^6.0.0
|
'@codemirror/view': 6.39.16
|
||||||
'@lezer/common': ^1.0.0
|
'@lezer/common': ^1.0.0
|
||||||
'@lezer/highlight': ^1.0.0
|
'@lezer/highlight': ^1.0.0
|
||||||
'@lezer/javascript': ^1.2.0
|
'@lezer/javascript': ^1.2.0
|
||||||
|
|
@ -4082,6 +4303,92 @@ packages:
|
||||||
'@types/node': 17.0.45
|
'@types/node': 17.0.45
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/d3-array@3.2.2:
|
||||||
|
resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-color@3.1.3:
|
||||||
|
resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-dispatch@3.0.7:
|
||||||
|
resolution: {integrity: sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-dsv@3.0.7:
|
||||||
|
resolution: {integrity: sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-ease@3.0.2:
|
||||||
|
resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-fetch@3.0.7:
|
||||||
|
resolution: {integrity: sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==}
|
||||||
|
dependencies:
|
||||||
|
'@types/d3-dsv': 3.0.7
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-force@3.0.10:
|
||||||
|
resolution: {integrity: sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-format@3.0.4:
|
||||||
|
resolution: {integrity: sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-geo@3.1.0:
|
||||||
|
resolution: {integrity: sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==}
|
||||||
|
dependencies:
|
||||||
|
'@types/geojson': 7946.0.16
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-hierarchy@3.1.7:
|
||||||
|
resolution: {integrity: sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-interpolate@3.0.4:
|
||||||
|
resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==}
|
||||||
|
dependencies:
|
||||||
|
'@types/d3-color': 3.1.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-path@3.1.1:
|
||||||
|
resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-quadtree@3.0.6:
|
||||||
|
resolution: {integrity: sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-random@3.0.3:
|
||||||
|
resolution: {integrity: sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-scale-chromatic@3.1.0:
|
||||||
|
resolution: {integrity: sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-scale@4.0.9:
|
||||||
|
resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==}
|
||||||
|
dependencies:
|
||||||
|
'@types/d3-time': 3.0.4
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-shape@3.1.8:
|
||||||
|
resolution: {integrity: sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==}
|
||||||
|
dependencies:
|
||||||
|
'@types/d3-path': 3.1.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-time@3.0.4:
|
||||||
|
resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/d3-timer@3.0.2:
|
||||||
|
resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@types/debug@4.1.12:
|
/@types/debug@4.1.12:
|
||||||
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
|
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -4124,6 +4431,10 @@ packages:
|
||||||
resolution: {integrity: sha512-xbqnZmGrCEqi/KUzOkeUSe77p7APvLuyellGaAoeww3CHJ1AbjQWjPSCFtKIzZn8L7LpEax4NXnC+gfa6nM7IA==}
|
resolution: {integrity: sha512-xbqnZmGrCEqi/KUzOkeUSe77p7APvLuyellGaAoeww3CHJ1AbjQWjPSCFtKIzZn8L7LpEax4NXnC+gfa6nM7IA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/geojson@7946.0.16:
|
||||||
|
resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@types/graceful-fs@4.1.9:
|
/@types/graceful-fs@4.1.9:
|
||||||
resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==}
|
resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -4539,8 +4850,8 @@ packages:
|
||||||
'@codemirror/language': '>=6.0.0'
|
'@codemirror/language': '>=6.0.0'
|
||||||
'@codemirror/lint': '>=6.0.0'
|
'@codemirror/lint': '>=6.0.0'
|
||||||
'@codemirror/search': '>=6.0.0'
|
'@codemirror/search': '>=6.0.0'
|
||||||
'@codemirror/state': '>=6.0.0'
|
'@codemirror/state': 6.5.4
|
||||||
'@codemirror/view': '>=6.0.0'
|
'@codemirror/view': 6.39.16
|
||||||
dependencies:
|
dependencies:
|
||||||
'@codemirror/autocomplete': 6.20.1
|
'@codemirror/autocomplete': 6.20.1
|
||||||
'@codemirror/commands': 6.7.1
|
'@codemirror/commands': 6.7.1
|
||||||
|
|
@ -4599,9 +4910,9 @@ packages:
|
||||||
resolution: {integrity: sha512-caYKGV6TfGLRV1HHD3p0G3FiVzKL1go7wes5XT2nWjB0+dTdyzyb81MKRSacptgZcotujfNO6QXn65uhETRAMw==}
|
resolution: {integrity: sha512-caYKGV6TfGLRV1HHD3p0G3FiVzKL1go7wes5XT2nWjB0+dTdyzyb81MKRSacptgZcotujfNO6QXn65uhETRAMw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@babel/runtime': '>=7.11.0'
|
'@babel/runtime': '>=7.11.0'
|
||||||
'@codemirror/state': '>=6.0.0'
|
'@codemirror/state': 6.5.4
|
||||||
'@codemirror/theme-one-dark': '>=6.0.0'
|
'@codemirror/theme-one-dark': '>=6.0.0'
|
||||||
'@codemirror/view': '>=6.0.0'
|
'@codemirror/view': 6.39.16
|
||||||
codemirror: '>=6.0.0'
|
codemirror: '>=6.0.0'
|
||||||
react: '>=16.8.0 || 18'
|
react: '>=16.8.0 || 18'
|
||||||
react-dom: '>=16.8.0 || 18'
|
react-dom: '>=16.8.0 || 18'
|
||||||
|
|
@ -5390,6 +5701,7 @@ packages:
|
||||||
/agentkeepalive@4.6.0:
|
/agentkeepalive@4.6.0:
|
||||||
resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==}
|
resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==}
|
||||||
engines: {node: '>= 8.0.0'}
|
engines: {node: '>= 8.0.0'}
|
||||||
|
requiresBuild: true
|
||||||
dependencies:
|
dependencies:
|
||||||
humanize-ms: 1.2.1
|
humanize-ms: 1.2.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
@ -6018,6 +6330,11 @@ packages:
|
||||||
resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==}
|
resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/base64-arraybuffer@1.0.2:
|
||||||
|
resolution: {integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==}
|
||||||
|
engines: {node: '>= 0.6.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/base64-js@1.5.1:
|
/base64-js@1.5.1:
|
||||||
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
||||||
|
|
||||||
|
|
@ -6554,7 +6871,6 @@ packages:
|
||||||
/commander@7.2.0:
|
/commander@7.2.0:
|
||||||
resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
|
resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/commander@8.3.0:
|
/commander@8.3.0:
|
||||||
resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==}
|
resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==}
|
||||||
|
|
@ -6873,6 +7189,12 @@ packages:
|
||||||
postcss-selector-parser: 6.1.2
|
postcss-selector-parser: 6.1.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/css-line-break@2.1.0:
|
||||||
|
resolution: {integrity: sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==}
|
||||||
|
dependencies:
|
||||||
|
utrie: 1.0.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/css-loader@6.7.1:
|
/css-loader@6.7.1:
|
||||||
resolution: {integrity: sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==}
|
resolution: {integrity: sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==}
|
||||||
engines: {node: '>= 12.13.0'}
|
engines: {node: '>= 12.13.0'}
|
||||||
|
|
@ -6961,6 +7283,10 @@ packages:
|
||||||
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
|
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/csstype@3.2.3:
|
||||||
|
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/current-script-polyfill@1.0.0:
|
/current-script-polyfill@1.0.0:
|
||||||
resolution: {integrity: sha512-qv8s+G47V6Hq+g2kRE5th+ASzzrL7b6l+tap1DHKK25ZQJv3yIFhH96XaQ7NGL+zRW3t/RDbweJf/dJDe5Z5KA==}
|
resolution: {integrity: sha512-qv8s+G47V6Hq+g2kRE5th+ASzzrL7b6l+tap1DHKK25ZQJv3yIFhH96XaQ7NGL+zRW3t/RDbweJf/dJDe5Z5KA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
@ -6969,10 +7295,175 @@ packages:
|
||||||
resolution: {integrity: sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==}
|
resolution: {integrity: sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/d3-array@3.2.4:
|
||||||
|
resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dependencies:
|
||||||
|
internmap: 2.0.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-binarytree@1.0.2:
|
||||||
|
resolution: {integrity: sha512-cElUNH+sHu95L04m92pG73t2MEJXKu+GeKUN1TJkFsu93E5W8E9Sc3kHEGJKgenGvj19m6upSn2EunvMgMD2Yw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-color@3.1.0:
|
||||||
|
resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-dispatch@3.0.1:
|
||||||
|
resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-dsv@3.0.1:
|
||||||
|
resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
commander: 7.2.0
|
||||||
|
iconv-lite: 0.6.3
|
||||||
|
rw: 1.3.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-ease@3.0.1:
|
||||||
|
resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-fetch@3.0.1:
|
||||||
|
resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dependencies:
|
||||||
|
d3-dsv: 3.0.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-force-3d@3.0.6:
|
||||||
|
resolution: {integrity: sha512-4tsKHUPLOVkyfEffZo1v6sFHvGFwAIIjt/W8IThbp08DYAsXZck+2pSHEG5W1+gQgEvFLdZkYvmJAbRM2EzMnA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dependencies:
|
||||||
|
d3-binarytree: 1.0.2
|
||||||
|
d3-dispatch: 3.0.1
|
||||||
|
d3-octree: 1.1.0
|
||||||
|
d3-quadtree: 3.0.1
|
||||||
|
d3-timer: 3.0.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-force@3.0.0:
|
||||||
|
resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dependencies:
|
||||||
|
d3-dispatch: 3.0.1
|
||||||
|
d3-quadtree: 3.0.1
|
||||||
|
d3-timer: 3.0.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-format@3.1.2:
|
||||||
|
resolution: {integrity: sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-geo-projection@4.0.0:
|
||||||
|
resolution: {integrity: sha512-p0bK60CEzph1iqmnxut7d/1kyTmm3UWtPlwdkM31AU+LW+BXazd5zJdoCn7VFxNCHXRngPHRnsNn5uGjLRGndg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
commander: 7.2.0
|
||||||
|
d3-array: 3.2.4
|
||||||
|
d3-geo: 3.1.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-geo@3.1.1:
|
||||||
|
resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dependencies:
|
||||||
|
d3-array: 3.2.4
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-hierarchy@3.1.2:
|
||||||
|
resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-interpolate@3.0.1:
|
||||||
|
resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dependencies:
|
||||||
|
d3-color: 3.1.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-octree@1.1.0:
|
||||||
|
resolution: {integrity: sha512-F8gPlqpP+HwRPMO/8uOu5wjH110+6q4cgJvgJT6vlpy3BEaDIKlTZrgHKZSp/i1InRpVfh4puY/kvL6MxK930A==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-path@3.1.0:
|
||||||
|
resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/d3-polygon@1.0.6:
|
/d3-polygon@1.0.6:
|
||||||
resolution: {integrity: sha512-k+RF7WvI08PC8reEoXa/w2nSg5AUMTi+peBD9cmFc+0ixHfbs4QmxxkarVal1IkVkgxVuk9JSHhJURHiyHKAuQ==}
|
resolution: {integrity: sha512-k+RF7WvI08PC8reEoXa/w2nSg5AUMTi+peBD9cmFc+0ixHfbs4QmxxkarVal1IkVkgxVuk9JSHhJURHiyHKAuQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/d3-quadtree@3.0.1:
|
||||||
|
resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-random@3.0.1:
|
||||||
|
resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-regression@1.3.10:
|
||||||
|
resolution: {integrity: sha512-PF8GWEL70cHHWpx2jUQXc68r1pyPHIA+St16muk/XRokETzlegj5LriNKg7o4LR0TySug4nHYPJNNRz/W+/Niw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-scale-chromatic@3.1.0:
|
||||||
|
resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dependencies:
|
||||||
|
d3-color: 3.1.0
|
||||||
|
d3-interpolate: 3.0.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-scale@4.0.2:
|
||||||
|
resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dependencies:
|
||||||
|
d3-array: 3.2.4
|
||||||
|
d3-format: 3.1.2
|
||||||
|
d3-interpolate: 3.0.1
|
||||||
|
d3-time: 3.1.0
|
||||||
|
d3-time-format: 4.1.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-shape@3.2.0:
|
||||||
|
resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dependencies:
|
||||||
|
d3-path: 3.1.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-time-format@4.1.0:
|
||||||
|
resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dependencies:
|
||||||
|
d3-time: 3.1.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-time@3.1.0:
|
||||||
|
resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dependencies:
|
||||||
|
d3-array: 3.2.4
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/d3-timer@3.0.1:
|
||||||
|
resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/d@1.0.2:
|
/d@1.0.2:
|
||||||
resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==}
|
resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==}
|
||||||
engines: {node: '>=0.12'}
|
engines: {node: '>=0.12'}
|
||||||
|
|
@ -7998,7 +8489,6 @@ packages:
|
||||||
|
|
||||||
/eventemitter3@5.0.1:
|
/eventemitter3@5.0.1:
|
||||||
resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
|
resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/events-okam@3.3.0:
|
/events-okam@3.3.0:
|
||||||
resolution: {integrity: sha512-6iR7z9hAJEwrT+D2Ywg6Fx62HSmN86OlcvPdrnq1JBeFr30dMF6l+j7M3VabjHfIi2KMtF8rO0J1rIZEfwMAwg==}
|
resolution: {integrity: sha512-6iR7z9hAJEwrT+D2Ywg6Fx62HSmN86OlcvPdrnq1JBeFr30dMF6l+j7M3VabjHfIi2KMtF8rO0J1rIZEfwMAwg==}
|
||||||
|
|
@ -8153,7 +8643,6 @@ packages:
|
||||||
|
|
||||||
/fast-deep-equal@3.1.3:
|
/fast-deep-equal@3.1.3:
|
||||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/fast-glob@3.2.12:
|
/fast-glob@3.2.12:
|
||||||
resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==}
|
resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==}
|
||||||
|
|
@ -8309,6 +8798,11 @@ packages:
|
||||||
deprecated: flatten is deprecated in favor of utility frameworks such as lodash.
|
deprecated: flatten is deprecated in favor of utility frameworks such as lodash.
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/flru@1.0.2:
|
||||||
|
resolution: {integrity: sha512-kWyh8ADvHBFz6ua5xYOPnUroZTT/bwWfrCeL0Wj1dzG4/YOmOcfJ99W8dOVyyynJN35rZ9aCOtHChqQovV7yog==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/flubber@0.4.2:
|
/flubber@0.4.2:
|
||||||
resolution: {integrity: sha512-79RkJe3rA4nvRCVc2uXjj7U/BAUq84TS3KHn6c0Hr9K64vhj83ZNLUziNx4pJoBumSPhOl5VjH+Z0uhi+eE8Uw==}
|
resolution: {integrity: sha512-79RkJe3rA4nvRCVc2uXjj7U/BAUq84TS3KHn6c0Hr9K64vhj83ZNLUziNx4pJoBumSPhOl5VjH+Z0uhi+eE8Uw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -8556,6 +9050,10 @@ packages:
|
||||||
resolution: {integrity: sha512-LF8VeHeR7v+wAbXqfgRlTSX/1BJR9Q1vEMR8JAz1cEg6GX07+zyj3sAdDvYjj/xnlIfVuGgj4qBei1K3hKH+PA==}
|
resolution: {integrity: sha512-LF8VeHeR7v+wAbXqfgRlTSX/1BJR9Q1vEMR8JAz1cEg6GX07+zyj3sAdDvYjj/xnlIfVuGgj4qBei1K3hKH+PA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/gl-matrix@3.4.4:
|
||||||
|
resolution: {integrity: sha512-latSnyDNt/8zYUB6VIJ6PCh2jBjJX6gnDsoCZ7LyW7GkqrD51EWwa9qCoGixj8YqBtETQK/xY7OmpTF8xz1DdQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/glob-parent@5.1.2:
|
/glob-parent@5.1.2:
|
||||||
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
|
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
|
|
@ -8851,6 +9349,14 @@ packages:
|
||||||
tapable: 2.2.1
|
tapable: 2.2.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/html2canvas@1.4.1:
|
||||||
|
resolution: {integrity: sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==}
|
||||||
|
engines: {node: '>=8.0.0'}
|
||||||
|
dependencies:
|
||||||
|
css-line-break: 2.1.0
|
||||||
|
text-segmentation: 1.0.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
/htmlparser2@6.1.0:
|
/htmlparser2@6.1.0:
|
||||||
resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==}
|
resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -8862,6 +9368,7 @@ packages:
|
||||||
|
|
||||||
/http-cache-semantics@4.2.0:
|
/http-cache-semantics@4.2.0:
|
||||||
resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==}
|
resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==}
|
||||||
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
|
@ -9074,6 +9581,11 @@ packages:
|
||||||
side-channel: 1.0.6
|
side-channel: 1.0.6
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/internmap@2.0.3:
|
||||||
|
resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/intersection-observer@0.12.2:
|
/intersection-observer@0.12.2:
|
||||||
resolution: {integrity: sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg==}
|
resolution: {integrity: sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
@ -9109,6 +9621,7 @@ packages:
|
||||||
/ip-address@10.1.0:
|
/ip-address@10.1.0:
|
||||||
resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==}
|
resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==}
|
||||||
engines: {node: '>= 12'}
|
engines: {node: '>= 12'}
|
||||||
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
|
@ -9590,7 +10103,6 @@ packages:
|
||||||
|
|
||||||
/js-tokens@4.0.0:
|
/js-tokens@4.0.0:
|
||||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/js-yaml@3.14.1:
|
/js-yaml@3.14.1:
|
||||||
resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==}
|
resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==}
|
||||||
|
|
@ -10045,7 +10557,6 @@ packages:
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dependencies:
|
dependencies:
|
||||||
js-tokens: 4.0.0
|
js-tokens: 4.0.0
|
||||||
dev: true
|
|
||||||
|
|
||||||
/lower-case@2.0.2:
|
/lower-case@2.0.2:
|
||||||
resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
|
resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==}
|
||||||
|
|
@ -11107,6 +11618,10 @@ packages:
|
||||||
sha.js: 2.4.11
|
sha.js: 2.4.11
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/pdfast@0.2.0:
|
||||||
|
resolution: {integrity: sha512-cq6TTu6qKSFUHwEahi68k/kqN2mfepjkGrG9Un70cgdRRKLKY6Rf8P8uvP2NvZktaQZNF3YE7agEkLj0vGK9bA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/performance-now@2.1.0:
|
/performance-now@2.1.0:
|
||||||
resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==}
|
resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
@ -12918,7 +13433,6 @@ packages:
|
||||||
loose-envify: 1.4.0
|
loose-envify: 1.4.0
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
scheduler: 0.23.2
|
scheduler: 0.23.2
|
||||||
dev: true
|
|
||||||
|
|
||||||
/react-easy-crop@5.2.0(react-dom@18.3.1)(react@18.3.1):
|
/react-easy-crop@5.2.0(react-dom@18.3.1)(react@18.3.1):
|
||||||
resolution: {integrity: sha512-gjb7jN+WnwfgpbNUI2jSwyoIxF1sJ0PVSNVgEysAgF1rj8AqR75fqmdvqZ6PFVgEX3rT1G4HJELesiQXr2ZvAg==}
|
resolution: {integrity: sha512-gjb7jN+WnwfgpbNUI2jSwyoIxF1sJ0PVSNVgEysAgF1rj8AqR75fqmdvqZ6PFVgEX3rT1G4HJELesiQXr2ZvAg==}
|
||||||
|
|
@ -13189,7 +13703,6 @@ packages:
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
dependencies:
|
dependencies:
|
||||||
loose-envify: 1.4.0
|
loose-envify: 1.4.0
|
||||||
dev: true
|
|
||||||
|
|
||||||
/reactcss@1.2.3(react@18.3.1):
|
/reactcss@1.2.3(react@18.3.1):
|
||||||
resolution: {integrity: sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==}
|
resolution: {integrity: sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==}
|
||||||
|
|
@ -13485,6 +13998,10 @@ packages:
|
||||||
queue-microtask: 1.2.3
|
queue-microtask: 1.2.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/rw@1.3.3:
|
||||||
|
resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/rxjs@7.8.1:
|
/rxjs@7.8.1:
|
||||||
resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==}
|
resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -13534,7 +14051,6 @@ packages:
|
||||||
resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==}
|
resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
loose-envify: 1.4.0
|
loose-envify: 1.4.0
|
||||||
dev: true
|
|
||||||
|
|
||||||
/schema-utils@3.3.0:
|
/schema-utils@3.3.0:
|
||||||
resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==}
|
resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==}
|
||||||
|
|
@ -13853,6 +14369,7 @@ packages:
|
||||||
/socks@2.8.7:
|
/socks@2.8.7:
|
||||||
resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==}
|
resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==}
|
||||||
engines: {node: '>= 10.0.0', npm: '>= 3.0.0'}
|
engines: {node: '>= 10.0.0', npm: '>= 3.0.0'}
|
||||||
|
requiresBuild: true
|
||||||
dependencies:
|
dependencies:
|
||||||
ip-address: 10.1.0
|
ip-address: 10.1.0
|
||||||
smart-buffer: 4.2.0
|
smart-buffer: 4.2.0
|
||||||
|
|
@ -14349,6 +14866,10 @@ packages:
|
||||||
resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==}
|
resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/svg-path-parser@1.1.0:
|
||||||
|
resolution: {integrity: sha512-jGCUqcQyXpfe38R7RFfhrMyfXcBmpMNJI/B+4CE9/Unkh98UporAc461GTthv+TVDuZXsBx7/WiwJb1Oh4tt4A==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/svg-path-properties@0.2.2:
|
/svg-path-properties@0.2.2:
|
||||||
resolution: {integrity: sha512-GmrB+b6woz6CCdQe6w1GHs/1lt25l7SR5hmhF8jRdarpv/OgjLyuQygLu1makJapixeb1aQhP/Oa1iKi93o/aQ==}
|
resolution: {integrity: sha512-GmrB+b6woz6CCdQe6w1GHs/1lt25l7SR5hmhF8jRdarpv/OgjLyuQygLu1makJapixeb1aQhP/Oa1iKi93o/aQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
@ -14468,6 +14989,12 @@ packages:
|
||||||
resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==}
|
resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/text-segmentation@1.0.3:
|
||||||
|
resolution: {integrity: sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==}
|
||||||
|
dependencies:
|
||||||
|
utrie: 1.0.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/text-table@0.2.0:
|
/text-table@0.2.0:
|
||||||
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
|
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
@ -14647,7 +15174,6 @@ packages:
|
||||||
|
|
||||||
/tslib@2.8.1:
|
/tslib@2.8.1:
|
||||||
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/tsutils@3.21.0(typescript@5.2.2):
|
/tsutils@3.21.0(typescript@5.2.2):
|
||||||
resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
|
resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
|
||||||
|
|
@ -15084,6 +15610,12 @@ packages:
|
||||||
resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
|
resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
|
||||||
engines: {node: '>= 0.4.0'}
|
engines: {node: '>= 0.4.0'}
|
||||||
|
|
||||||
|
/utrie@1.0.2:
|
||||||
|
resolution: {integrity: sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==}
|
||||||
|
dependencies:
|
||||||
|
base64-arraybuffer: 1.0.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/uuid@11.0.3:
|
/uuid@11.0.3:
|
||||||
resolution: {integrity: sha512-d0z310fCWv5dJwnX1Y/MncBAqGMKEzlBb1AOf7z9K8ALnd0utBX/msg/fA0+sbyN1ihbMsLhrBlnl1ak7Wa0rg==}
|
resolution: {integrity: sha512-d0z310fCWv5dJwnX1Y/MncBAqGMKEzlBb1AOf7z9K8ALnd0utBX/msg/fA0+sbyN1ihbMsLhrBlnl1ak7Wa0rg==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
@ -15509,7 +16041,3 @@ packages:
|
||||||
- encoding
|
- encoding
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
settings:
|
|
||||||
autoInstallPeers: true
|
|
||||||
excludeLinksFromLockfile: false
|
|
||||||
|
|
|
||||||
14
shell/api.sh
14
shell/api.sh
|
|
@ -220,4 +220,18 @@ update_auth_config() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
record_cron_stat() {
|
||||||
|
local ref_id="$1"
|
||||||
|
local exit_code="${2:-0}"
|
||||||
|
local elapsed="${3:-0}"
|
||||||
|
[[ $ref_id ]] && [[ $ref_id -gt 0 ]] 2>/dev/null || return
|
||||||
|
|
||||||
|
curl -s --noproxy "*" "http://0.0.0.0:${ql_port:-5700}/open/dashboard/record" \
|
||||||
|
-X POST \
|
||||||
|
-H "Authorization: Bearer ${__ql_token__}" \
|
||||||
|
-H "Content-Type: application/json;charset=UTF-8" \
|
||||||
|
--data-raw "{\"ref_id\":$ref_id,\"code\":$exit_code,\"elapsed\":$elapsed}" \
|
||||||
|
--compressed
|
||||||
|
}
|
||||||
|
|
||||||
get_token
|
get_token
|
||||||
|
|
|
||||||
|
|
@ -294,6 +294,7 @@ fi
|
||||||
set_u_on="false"
|
set_u_on="false"
|
||||||
check_nounset
|
check_nounset
|
||||||
main "${task_shell_params[@]}"
|
main "${task_shell_params[@]}"
|
||||||
|
_task_exit_code=$?
|
||||||
if [[ "$set_u_on" == 'true' ]]; then
|
if [[ "$set_u_on" == 'true' ]]; then
|
||||||
set -u
|
set -u
|
||||||
fi
|
fi
|
||||||
|
|
@ -305,4 +306,4 @@ if [[ $isJsOrPythonFile == 'true' ]]; then
|
||||||
fi
|
fi
|
||||||
run_task_after "${task_shell_params[@]}"
|
run_task_after "${task_shell_params[@]}"
|
||||||
clear_env
|
clear_env
|
||||||
handle_task_end "${task_shell_params[@]}"
|
handle_task_end "${task_shell_params[@]}" "$_task_exit_code"
|
||||||
|
|
|
||||||
|
|
@ -388,18 +388,25 @@ handle_task_end() {
|
||||||
local end_time=$(format_time "$time_format" "$etime")
|
local end_time=$(format_time "$time_format" "$etime")
|
||||||
local end_timestamp=$(format_timestamp "$time_format" "$etime")
|
local end_timestamp=$(format_timestamp "$time_format" "$etime")
|
||||||
local diff_time=$(($end_timestamp - $begin_timestamp))
|
local diff_time=$(($end_timestamp - $begin_timestamp))
|
||||||
local suffix=""
|
local exit_code="${@: -1}"
|
||||||
[[ "${MANUAL:=}" == "true" ]] && suffix="(手动停止)"
|
|
||||||
|
|
||||||
[[ "$diff_time" == 0 ]] && diff_time=1
|
[[ "$diff_time" == 0 ]] && diff_time=1
|
||||||
|
|
||||||
if [[ $ID ]]; then
|
if [[ $ID ]]; then
|
||||||
local error=$(update_cron "\"$ID\"" "1" "$$" "$log_path" "$begin_timestamp" "$diff_time")
|
local error=$(update_cron "\"$ID\"" "1" "$$" "$log_path" "$begin_timestamp" "$diff_time")
|
||||||
if [[ $error ]]; then
|
if [[ $error ]]; then
|
||||||
error_message=", 任务状态更新失败(${error})"
|
error_message=", 状态更新失败(${error})"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
echo -e "\n## 执行结束$suffix... $end_time 耗时 $diff_time 秒${error_message:=} "
|
|
||||||
|
record_cron_stat "$ID" "${exit_code:-0}" "$diff_time"
|
||||||
|
|
||||||
|
if [[ "${MANUAL:=}" == "true" ]]; then
|
||||||
|
echo -e "\n## 已停止 ⏹... $end_time 耗时 $diff_time 秒${error_message:=} "
|
||||||
|
elif [[ $exit_code -eq 0 ]]; then
|
||||||
|
echo -e "\n## 完成 ✅... $end_time 耗时 $diff_time 秒${error_message:=} "
|
||||||
|
else
|
||||||
|
echo -e "\n## 失败 ❌ (退出码 ${exit_code})... $end_time 耗时 $diff_time 秒${error_message:=} "
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
init_env
|
init_env
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import intl from 'react-intl-universal';
|
import intl from 'react-intl-universal';
|
||||||
import { SettingOutlined } from '@ant-design/icons';
|
import { SettingOutlined, DashboardOutlined } from '@ant-design/icons';
|
||||||
import IconFont from '@/components/iconfont';
|
import IconFont from '@/components/iconfont';
|
||||||
import { BasicLayoutProps } from '@ant-design/pro-layout';
|
import { BasicLayoutProps } from '@ant-design/pro-layout';
|
||||||
|
|
||||||
|
|
@ -24,6 +24,12 @@ export default {
|
||||||
hideInMenu: true,
|
hideInMenu: true,
|
||||||
component: '@/pages/error/index',
|
component: '@/pages/error/index',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/dashboard',
|
||||||
|
name: intl.get('统计面板'),
|
||||||
|
icon: <DashboardOutlined />,
|
||||||
|
component: '@/pages/dashboard/index',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/crontab',
|
path: '/crontab',
|
||||||
name: intl.get('定时任务'),
|
name: intl.get('定时任务'),
|
||||||
|
|
|
||||||
|
|
@ -212,6 +212,7 @@ body {
|
||||||
&.crontab-wrapper,
|
&.crontab-wrapper,
|
||||||
&.log-wrapper,
|
&.log-wrapper,
|
||||||
&.env-wrapper,
|
&.env-wrapper,
|
||||||
|
&.dashboard-wrapper,
|
||||||
&.config-wrapper {
|
&.config-wrapper {
|
||||||
.CodeMirror {
|
.CodeMirror {
|
||||||
width: calc(100vw - 24px);
|
width: calc(100vw - 24px);
|
||||||
|
|
|
||||||
|
|
@ -556,5 +556,34 @@
|
||||||
"批量": "Batch",
|
"批量": "Batch",
|
||||||
"全局SSH私钥": "Global SSH Private Key",
|
"全局SSH私钥": "Global SSH Private Key",
|
||||||
"用于访问所有私有仓库的全局SSH私钥": "Global SSH private key for accessing all private repositories",
|
"用于访问所有私有仓库的全局SSH私钥": "Global SSH private key for accessing all private repositories",
|
||||||
"请输入完整的SSH私钥内容": "Please enter the complete SSH private key content"
|
"请输入完整的SSH私钥内容": "Please enter the complete SSH private key content",
|
||||||
|
"统计面板": "Dashboard",
|
||||||
|
"总任务": "Total Tasks",
|
||||||
|
"今日执行": "Today Runs",
|
||||||
|
"今日成功": "Success",
|
||||||
|
"今日失败": "Failed",
|
||||||
|
"成功率": "Success Rate",
|
||||||
|
"平均耗时": "Avg Time",
|
||||||
|
"近 7 日趋势": "7-Day Trend",
|
||||||
|
"今日耗时 Top 5": "Top 5 by Time",
|
||||||
|
"今日执行次数 Top 5": "Top 5 by Runs",
|
||||||
|
"实时运行态": "Runtime",
|
||||||
|
"系统资源": "System",
|
||||||
|
"排队中": "Queued",
|
||||||
|
"暂无运行中任务": "No running tasks",
|
||||||
|
"暂无数据": "No data",
|
||||||
|
"总执行": "Total",
|
||||||
|
"次数": "Runs",
|
||||||
|
"最长单次": "Max Time",
|
||||||
|
"已运行": "Elapsed",
|
||||||
|
"系统运行": "System Uptime",
|
||||||
|
"内存使用": "Memory",
|
||||||
|
"堆内存": "Heap",
|
||||||
|
"CPU 核心": "CPU Cores",
|
||||||
|
"负载 1m": "Load 1m",
|
||||||
|
"平台": "Platform",
|
||||||
|
"24小时未运行": "Idle 24h+",
|
||||||
|
"标签统计": "Label Stats",
|
||||||
|
"任务数": "Tasks",
|
||||||
|
"内存": "Memory"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -556,5 +556,34 @@
|
||||||
"批量": "批量",
|
"批量": "批量",
|
||||||
"全局SSH私钥": "全局SSH私钥",
|
"全局SSH私钥": "全局SSH私钥",
|
||||||
"用于访问所有私有仓库的全局SSH私钥": "用于访问所有私有仓库的全局SSH私钥",
|
"用于访问所有私有仓库的全局SSH私钥": "用于访问所有私有仓库的全局SSH私钥",
|
||||||
"请输入完整的SSH私钥内容": "请输入完整的SSH私钥内容"
|
"请输入完整的SSH私钥内容": "请输入完整的SSH私钥内容",
|
||||||
|
"统计面板": "统计面板",
|
||||||
|
"总任务": "总任务",
|
||||||
|
"今日执行": "今日执行",
|
||||||
|
"今日成功": "今日成功",
|
||||||
|
"今日失败": "今日失败",
|
||||||
|
"成功率": "成功率",
|
||||||
|
"平均耗时": "平均耗时",
|
||||||
|
"近 7 日趋势": "近 7 日趋势",
|
||||||
|
"今日耗时 Top 5": "今日耗时 Top 5",
|
||||||
|
"今日执行次数 Top 5": "今日执行次数 Top 5",
|
||||||
|
"实时运行态": "实时运行态",
|
||||||
|
"系统资源": "系统资源",
|
||||||
|
"排队中": "排队中",
|
||||||
|
"暂无运行中任务": "暂无运行中任务",
|
||||||
|
"暂无数据": "暂无数据",
|
||||||
|
"总执行": "总执行",
|
||||||
|
"次数": "次数",
|
||||||
|
"最长单次": "最长单次",
|
||||||
|
"已运行": "已运行",
|
||||||
|
"系统运行": "系统运行",
|
||||||
|
"内存使用": "内存使用",
|
||||||
|
"堆内存": "堆内存",
|
||||||
|
"CPU 核心": "CPU 核心",
|
||||||
|
"负载 1m": "负载 1m",
|
||||||
|
"平台": "平台",
|
||||||
|
"24小时未运行": "24小时未运行",
|
||||||
|
"标签统计": "标签统计",
|
||||||
|
"任务数": "任务数",
|
||||||
|
"内存": "内存"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
359
src/pages/dashboard/index.tsx
Normal file
359
src/pages/dashboard/index.tsx
Normal file
|
|
@ -0,0 +1,359 @@
|
||||||
|
import { useEffect, useState, useCallback } from 'react';
|
||||||
|
import { Card, Col, Row, Statistic, Table, Tag, Spin, Empty } from 'antd';
|
||||||
|
import {
|
||||||
|
CheckCircleOutlined,
|
||||||
|
CloseCircleOutlined,
|
||||||
|
ClockCircleOutlined,
|
||||||
|
ThunderboltOutlined,
|
||||||
|
StopOutlined,
|
||||||
|
BarChartOutlined,
|
||||||
|
} from '@ant-design/icons';
|
||||||
|
import { PageContainer } from '@ant-design/pro-layout';
|
||||||
|
import { useOutletContext } from '@umijs/max';
|
||||||
|
import { Area, Gauge } from '@ant-design/plots';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
import { SharedContext } from '@/layouts';
|
||||||
|
import { request } from '@/utils/http';
|
||||||
|
import CronLogModal from '../crontab/logModal';
|
||||||
|
|
||||||
|
interface Overview {
|
||||||
|
total: number;
|
||||||
|
enabled: number;
|
||||||
|
disabled: number;
|
||||||
|
todayRuns: number;
|
||||||
|
todaySuccess: number;
|
||||||
|
todayFail: number;
|
||||||
|
successRate: string;
|
||||||
|
avgTime: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TrendItem {
|
||||||
|
date: string;
|
||||||
|
total: number;
|
||||||
|
success: number;
|
||||||
|
fail: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TopItem {
|
||||||
|
rank: number;
|
||||||
|
name: string;
|
||||||
|
avgTime?: number;
|
||||||
|
maxTime?: number;
|
||||||
|
runCount?: number;
|
||||||
|
successRate?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Runtime {
|
||||||
|
runningCount: number;
|
||||||
|
queuedCount: number;
|
||||||
|
running: Array<{ id: number; name: string; pid: number; elapsed: number; logPath: string }>;
|
||||||
|
idleTasks: Array<{ id: number; name: string; lastRun: string }>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SystemInfo {
|
||||||
|
platform: string;
|
||||||
|
uptime: number;
|
||||||
|
memTotal: number;
|
||||||
|
memFree: number;
|
||||||
|
memUsagePercent: string;
|
||||||
|
heapUsed: number;
|
||||||
|
heapTotal: number;
|
||||||
|
loadAvg: number[];
|
||||||
|
cpus: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatBytes = (bytes: number) => {
|
||||||
|
if (bytes === 0) return '0 B';
|
||||||
|
const k = 1024;
|
||||||
|
const sizes = ['B', 'KB', 'MB', 'GB'];
|
||||||
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||||
|
return `${(bytes / Math.pow(k, i)).toFixed(1)} ${sizes[i]}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatSeconds = (s: number) => {
|
||||||
|
if (s < 60) return `${s}s`;
|
||||||
|
if (s < 3600) return `${Math.floor(s / 60)}m ${s % 60}s`;
|
||||||
|
const h = Math.floor(s / 3600);
|
||||||
|
const m = Math.floor((s % 3600) / 60);
|
||||||
|
return `${h}h ${m}m`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const REFRESH_INTERVAL = 30000;
|
||||||
|
|
||||||
|
const Dashboard = () => {
|
||||||
|
const { headerStyle, theme } = useOutletContext<SharedContext>();
|
||||||
|
const isDark = theme === 'vs-dark';
|
||||||
|
const [overview, setOverview] = useState<Overview | null>(null);
|
||||||
|
const [trend, setTrend] = useState<TrendItem[]>([]);
|
||||||
|
const [topTime, setTopTime] = useState<TopItem[]>([]);
|
||||||
|
const [topCount, setTopCount] = useState<TopItem[]>([]);
|
||||||
|
const [runtime, setRuntime] = useState<Runtime | null>(null);
|
||||||
|
const [system, setSystem] = useState<SystemInfo | null>(null);
|
||||||
|
const [labels, setLabels] = useState<any[]>([]);
|
||||||
|
const [logCron, setLogCron] = useState<any>(null);
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
|
||||||
|
const fetchData = useCallback(async () => {
|
||||||
|
try {
|
||||||
|
const [overviewRes, trendRes, topTimeRes, topCountRes, runtimeRes, systemRes, labelsRes] =
|
||||||
|
await Promise.allSettled([
|
||||||
|
request.get('/api/dashboard/overview'),
|
||||||
|
request.get('/api/dashboard/trend'),
|
||||||
|
request.get('/api/dashboard/top-time'),
|
||||||
|
request.get('/api/dashboard/top-count'),
|
||||||
|
request.get('/api/dashboard/runtime'),
|
||||||
|
request.get('/api/dashboard/system'),
|
||||||
|
request.get('/api/dashboard/labels'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (overviewRes.status === 'fulfilled' && overviewRes.value.code === 200)
|
||||||
|
setOverview(overviewRes.value.data);
|
||||||
|
if (trendRes.status === 'fulfilled' && trendRes.value.code === 200)
|
||||||
|
setTrend(trendRes.value.data);
|
||||||
|
if (topTimeRes.status === 'fulfilled' && topTimeRes.value.code === 200)
|
||||||
|
setTopTime(topTimeRes.value.data);
|
||||||
|
if (topCountRes.status === 'fulfilled' && topCountRes.value.code === 200)
|
||||||
|
setTopCount(topCountRes.value.data);
|
||||||
|
if (runtimeRes.status === 'fulfilled' && runtimeRes.value.code === 200)
|
||||||
|
setRuntime(runtimeRes.value.data);
|
||||||
|
if (systemRes.status === 'fulfilled' && systemRes.value.code === 200)
|
||||||
|
setSystem(systemRes.value.data);
|
||||||
|
if (labelsRes.status === 'fulfilled' && labelsRes.value.code === 200)
|
||||||
|
setLabels(labelsRes.value.data);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('[dashboard] fetch error', e);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let timer: ReturnType<typeof setTimeout>;
|
||||||
|
const poll = async () => {
|
||||||
|
await fetchData();
|
||||||
|
timer = setTimeout(poll, REFRESH_INTERVAL);
|
||||||
|
};
|
||||||
|
fetchData();
|
||||||
|
timer = setTimeout(poll, REFRESH_INTERVAL);
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
}, [fetchData]);
|
||||||
|
|
||||||
|
const trendConfig = {
|
||||||
|
data: trend.flatMap((d) => [
|
||||||
|
{ date: d.date, value: d.total, type: intl.get('总执行') },
|
||||||
|
{ date: d.date, value: d.success, type: intl.get('成功') },
|
||||||
|
{ date: d.date, value: d.fail, type: intl.get('失败') },
|
||||||
|
]),
|
||||||
|
xField: 'date',
|
||||||
|
yField: 'value',
|
||||||
|
seriesField: 'type',
|
||||||
|
smooth: true,
|
||||||
|
height: 260,
|
||||||
|
color: ['#1677ff', '#52c41a', '#ff4d4f'],
|
||||||
|
legend: { position: 'top' as const },
|
||||||
|
theme: isDark ? 'dark' : 'light',
|
||||||
|
xAxis: {
|
||||||
|
label: { style: { fill: isDark ? '#aaa' : '#333' } },
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
label: { style: { fill: isDark ? '#aaa' : '#333' } },
|
||||||
|
grid: { line: { style: { stroke: isDark ? '#333' : '#eee' } } },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const runtimePagination = {
|
||||||
|
pageSize: 5,
|
||||||
|
showSizeChanger: false,
|
||||||
|
showTotal: (total: number) => `共 ${total} 个`,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (loading) return <Spin size="large" style={{ display: 'block', marginTop: 100 }} />;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageContainer
|
||||||
|
title={intl.get('统计面板')}
|
||||||
|
header={{ style: headerStyle }}
|
||||||
|
className={'ql-container-wrapper dashboard-wrapper'}
|
||||||
|
>
|
||||||
|
<Row gutter={[16, 16]}>
|
||||||
|
<Col xs={12} sm={8} md={6} lg={3}>
|
||||||
|
<Card size="small"><Statistic title={intl.get('总任务')} value={overview?.total || 0} prefix={<BarChartOutlined />} /></Card>
|
||||||
|
</Col>
|
||||||
|
<Col xs={12} sm={8} md={6} lg={3}>
|
||||||
|
<Card size="small"><Statistic title={intl.get('已启用')} value={overview?.enabled || 0} valueStyle={{ color: '#1677ff' }} prefix={<CheckCircleOutlined />} /></Card>
|
||||||
|
</Col>
|
||||||
|
<Col xs={12} sm={8} md={6} lg={3}>
|
||||||
|
<Card size="small"><Statistic title={intl.get('今日执行')} value={overview?.todayRuns || 0} valueStyle={{ color: '#1677ff' }} prefix={<ThunderboltOutlined />} /></Card>
|
||||||
|
</Col>
|
||||||
|
<Col xs={12} sm={8} md={6} lg={3}>
|
||||||
|
<Card size="small"><Statistic title={intl.get('成功率')} value={`${overview?.successRate || '0'}%`} valueStyle={{ color: '#52c41a' }} /></Card>
|
||||||
|
</Col>
|
||||||
|
<Col xs={12} sm={8} md={6} lg={3}>
|
||||||
|
<Card size="small"><Statistic title={intl.get('今日成功')} value={overview?.todaySuccess || 0} valueStyle={{ color: '#52c41a' }} prefix={<CheckCircleOutlined />} /></Card>
|
||||||
|
</Col>
|
||||||
|
<Col xs={12} sm={8} md={6} lg={3}>
|
||||||
|
<Card size="small"><Statistic title={intl.get('今日失败')} value={overview?.todayFail || 0} valueStyle={{ color: '#ff4d4f' }} prefix={<CloseCircleOutlined />} /></Card>
|
||||||
|
</Col>
|
||||||
|
<Col xs={12} sm={8} md={6} lg={3}>
|
||||||
|
<Card size="small"><Statistic title={intl.get('平均耗时')} value={overview?.avgTime ? `${(overview.avgTime / 1000).toFixed(1)}s` : '-'} prefix={<ClockCircleOutlined />} /></Card>
|
||||||
|
</Col>
|
||||||
|
<Col xs={12} sm={8} md={6} lg={3}>
|
||||||
|
<Card size="small"><Statistic title={intl.get('已禁用')} value={overview?.disabled || 0} prefix={<StopOutlined />} /></Card>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
<Row gutter={[16, 16]} style={{ marginTop: 16 }}>
|
||||||
|
<Col span={24}>
|
||||||
|
<Card title={intl.get('近 7 日趋势')} size="small">
|
||||||
|
{trend.length > 0 ? <Area {...trendConfig} /> : <Empty description={intl.get('暂无数据')} />}
|
||||||
|
</Card>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
<Row gutter={[16, 16]} style={{ marginTop: 16 }}>
|
||||||
|
<Col xs={24} lg={12}>
|
||||||
|
<Card title={intl.get('今日耗时 Top 5')} size="small">
|
||||||
|
<Table
|
||||||
|
dataSource={topTime}
|
||||||
|
rowKey="rank"
|
||||||
|
pagination={false}
|
||||||
|
size="small"
|
||||||
|
columns={[
|
||||||
|
{ title: '#', dataIndex: 'rank', width: 40 },
|
||||||
|
{ title: intl.get('定时任务'), dataIndex: 'name', ellipsis: true },
|
||||||
|
{ title: intl.get('平均耗时'), dataIndex: 'avgTime', width: 100, render: (v: number) => v ? `${(v / 1000).toFixed(1)}s` : '-' },
|
||||||
|
{ title: intl.get('最长单次'), dataIndex: 'maxTime', width: 100, render: (v: number) => v ? `${(v / 1000).toFixed(1)}s` : '-' },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
|
</Col>
|
||||||
|
<Col xs={24} lg={12}>
|
||||||
|
<Card title={intl.get('今日执行次数 Top 5')} size="small">
|
||||||
|
<Table
|
||||||
|
dataSource={topCount}
|
||||||
|
rowKey="rank"
|
||||||
|
pagination={false}
|
||||||
|
size="small"
|
||||||
|
columns={[
|
||||||
|
{ title: '#', dataIndex: 'rank', width: 40 },
|
||||||
|
{ title: intl.get('定时任务'), dataIndex: 'name', ellipsis: true },
|
||||||
|
{ title: intl.get('次数'), dataIndex: 'runCount', width: 60 },
|
||||||
|
{ title: intl.get('平均耗时'), dataIndex: 'avgTime', width: 100, render: (v: number) => v ? `${(v / 1000).toFixed(1)}s` : '-' },
|
||||||
|
{ title: intl.get('成功率'), dataIndex: 'successRate', width: 80, render: (v: string) => `${v}%` },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
{labels.length > 0 && (
|
||||||
|
<Row gutter={[16, 16]} style={{ marginTop: 16 }}>
|
||||||
|
<Col span={24}>
|
||||||
|
<Card title={intl.get('标签统计')} size="small">
|
||||||
|
<Table
|
||||||
|
dataSource={labels}
|
||||||
|
rowKey="label"
|
||||||
|
pagination={false}
|
||||||
|
size="small"
|
||||||
|
columns={[
|
||||||
|
{ title: intl.get('标签'), dataIndex: 'label', width: 150, render: (v: string) => <Tag>{v}</Tag> },
|
||||||
|
{ title: intl.get('任务数'), dataIndex: 'count', width: 80 },
|
||||||
|
{ title: intl.get('今日执行'), dataIndex: 'todayRuns', width: 100 },
|
||||||
|
{ title: intl.get('成功率'), dataIndex: 'successRate', width: 100, render: (v: string) => `${v}%` },
|
||||||
|
{ title: intl.get('平均耗时'), dataIndex: 'avgTime', width: 120, render: (v: number) => v ? `${(v / 1000).toFixed(1)}s` : '-' },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Row gutter={[16, 16]} style={{ marginTop: 16 }}>
|
||||||
|
<Col xs={24} lg={12}>
|
||||||
|
<Card
|
||||||
|
title={intl.get('实时运行态')}
|
||||||
|
size="small"
|
||||||
|
extra={
|
||||||
|
<>
|
||||||
|
<Tag color="processing">{intl.get('运行中')} {runtime?.runningCount || 0}</Tag>
|
||||||
|
<Tag color="warning">{intl.get('排队中')} {runtime?.queuedCount || 0}</Tag>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Table
|
||||||
|
dataSource={runtime?.running || []}
|
||||||
|
rowKey="id"
|
||||||
|
pagination={runtime && runtime.running.length > 5 ? runtimePagination : false}
|
||||||
|
size="small"
|
||||||
|
locale={{ emptyText: <Empty description={intl.get('暂无运行中任务')} /> }}
|
||||||
|
columns={[
|
||||||
|
{ title: intl.get('定时任务'), dataIndex: 'name', ellipsis: true },
|
||||||
|
{ title: 'PID', dataIndex: 'pid', width: 80 },
|
||||||
|
{ title: intl.get('已运行'), dataIndex: 'elapsed', width: 100, render: (v: number) => v ? formatSeconds(v) : '-' },
|
||||||
|
{ title: intl.get('日志'), dataIndex: 'id', width: 60, render: (id, record) => <a onClick={() => { localStorage.setItem('logCron', String(id)); setLogCron({ id, name: record.name }); }}>{intl.get('查看')}</a> },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
{runtime?.idleTasks && runtime.idleTasks.length > 0 && (
|
||||||
|
<>
|
||||||
|
<div style={{ marginTop: 12, fontSize: 13, color: '#ff7a00' }}>
|
||||||
|
{intl.get('24小时未运行')} ({runtime.idleTasks.length})
|
||||||
|
</div>
|
||||||
|
<Table
|
||||||
|
dataSource={runtime.idleTasks}
|
||||||
|
rowKey="id"
|
||||||
|
pagination={false}
|
||||||
|
size="small"
|
||||||
|
showHeader={false}
|
||||||
|
columns={[
|
||||||
|
{ dataIndex: 'name', ellipsis: true },
|
||||||
|
{ dataIndex: 'lastRun', width: 110, render: (v: string) => <span style={{ color: '#999' }}>{v}</span> },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Card>
|
||||||
|
</Col>
|
||||||
|
|
||||||
|
<Col xs={24} lg={12}>
|
||||||
|
<Card title={intl.get('系统资源')} size="small">
|
||||||
|
{system && (
|
||||||
|
<Row gutter={[16, 16]} align="middle">
|
||||||
|
<Col span={12}>
|
||||||
|
<Gauge
|
||||||
|
height={300}
|
||||||
|
data={{
|
||||||
|
target: Number(system.memUsagePercent),
|
||||||
|
total: 100,
|
||||||
|
name: '内存使用率',
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
textY: '70%',
|
||||||
|
textContent: (target: number, total: number) => {
|
||||||
|
return `${intl.get('内存')}:${target}%`;
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
<Col span={12}>
|
||||||
|
<Statistic title={intl.get('系统运行')} value={formatSeconds(system.uptime)} />
|
||||||
|
<Statistic title={intl.get('堆内存')} value={`${system.heapUsed} MB`} valueStyle={{ fontSize: 16 }} />
|
||||||
|
<div style={{ marginTop: 8, color: '#888', fontSize: 12 }}>
|
||||||
|
{intl.get('负载 1m')}: {system.loadAvg?.[0] || '-'} | CPU: {system.cpus} {intl.get('核心')} | {system.platform}
|
||||||
|
</div>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
)}
|
||||||
|
</Card>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
{logCron && (
|
||||||
|
<CronLogModal
|
||||||
|
cron={logCron}
|
||||||
|
handleCancel={() => setLogCron(null)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</PageContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Dashboard;
|
||||||
|
|
@ -109,7 +109,7 @@ const Login = () => {
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
reloadUser(true);
|
reloadUser(true);
|
||||||
history.push('/crontab');
|
history.push('/dashboard');
|
||||||
} else if (code === 410) {
|
} else if (code === 410) {
|
||||||
setWaitTime(data);
|
setWaitTime(data);
|
||||||
} else if (code === 420) {
|
} else if (code === 420) {
|
||||||
|
|
@ -136,7 +136,7 @@ const Login = () => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const isAuth = localStorage.getItem(config.authKey);
|
const isAuth = localStorage.getItem(config.authKey);
|
||||||
if (isAuth) {
|
if (isAuth) {
|
||||||
history.push('/crontab');
|
history.push('/dashboard');
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user