mirror of
https://github.com/whyour/qinglong.git
synced 2025-11-23 00:49:19 +08:00
* Initial plan * Add cron management capabilities to QLAPI - Added GetCrons, GetCronById, EnableCrons, DisableCrons, RunCrons to proto - Implemented gRPC handlers for new cron operations - Updated client.js to expose new methods to scripts - Updated sample to demonstrate new API usage Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> * Add documentation for QLAPI cron management features Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> * Specify pnpm version 8.3.1 in package.json Add packageManager field to enforce pnpm@8.3.1 as requested Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> * Revert pnpm-lock.yaml to original state The lockfile was inadvertently updated during dependency installation for proto generation. Reverting to maintain consistency with pnpm@8.3.1. Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> * Regenerate proto files with correct tool versions Regenerated using protoc v3.17.3 and protoc-gen-ts_proto v2.6.1 to match the original project configuration. Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: whyour <22700758+whyour@users.noreply.github.com>
445 lines
11 KiB
TypeScript
445 lines
11 KiB
TypeScript
import 'reflect-metadata';
|
|
import { Container } from 'typedi';
|
|
import EnvService from '../services/env';
|
|
import { sendUnaryData, ServerUnaryCall } from '@grpc/grpc-js';
|
|
import {
|
|
CreateEnvRequest,
|
|
CronItem,
|
|
DeleteEnvsRequest,
|
|
DisableEnvsRequest,
|
|
EnableEnvsRequest,
|
|
EnvItem,
|
|
EnvResponse,
|
|
EnvsResponse,
|
|
GetEnvByIdRequest,
|
|
GetEnvsRequest,
|
|
MoveEnvRequest,
|
|
Response,
|
|
SystemNotifyRequest,
|
|
UpdateEnvNamesRequest,
|
|
UpdateEnvRequest,
|
|
} from '../protos/api';
|
|
import LoggerInstance from '../loaders/logger';
|
|
import pick from 'lodash/pick';
|
|
import SystemService from '../services/system';
|
|
import CronService from '../services/cron';
|
|
import {
|
|
CronDetailRequest,
|
|
CronDetailResponse,
|
|
CreateCronRequest,
|
|
UpdateCronRequest,
|
|
DeleteCronsRequest,
|
|
CronResponse,
|
|
GetCronsRequest,
|
|
CronsResponse,
|
|
GetCronByIdRequest,
|
|
EnableCronsRequest,
|
|
DisableCronsRequest,
|
|
RunCronsRequest,
|
|
} from '../protos/api';
|
|
import { NotificationInfo } from '../data/notify';
|
|
|
|
Container.set('logger', LoggerInstance);
|
|
|
|
export const getEnvs = async (
|
|
call: ServerUnaryCall<GetEnvsRequest, EnvsResponse>,
|
|
callback: sendUnaryData<EnvsResponse>,
|
|
) => {
|
|
try {
|
|
const envService = Container.get(EnvService);
|
|
const data = await envService.envs(call.request.searchValue);
|
|
callback(null, {
|
|
code: 200,
|
|
data: data.map((x) => ({ ...x, remarks: x.remarks || '' })),
|
|
});
|
|
} catch (e: any) {
|
|
callback(null, {
|
|
code: 500,
|
|
data: [],
|
|
message: e.message,
|
|
});
|
|
}
|
|
};
|
|
|
|
export const createEnv = async (
|
|
call: ServerUnaryCall<CreateEnvRequest, EnvsResponse>,
|
|
callback: sendUnaryData<EnvsResponse>,
|
|
) => {
|
|
try {
|
|
const envService = Container.get(EnvService);
|
|
const data = await envService.create(call.request.envs);
|
|
callback(null, { code: 200, data });
|
|
} catch (e: any) {
|
|
callback(e);
|
|
}
|
|
};
|
|
|
|
export const updateEnv = async (
|
|
call: ServerUnaryCall<UpdateEnvRequest, EnvResponse>,
|
|
callback: sendUnaryData<EnvResponse>,
|
|
) => {
|
|
try {
|
|
if (!call.request.env?.id) {
|
|
return callback(null, {
|
|
code: 400,
|
|
data: undefined,
|
|
message: 'id parameter is required',
|
|
});
|
|
}
|
|
|
|
const envService = Container.get(EnvService);
|
|
const data = await envService.update(
|
|
pick(call.request.env, ['id', 'name', 'value', 'remarks']) as EnvItem,
|
|
);
|
|
callback(null, { code: 200, data });
|
|
} catch (e: any) {
|
|
callback(e);
|
|
}
|
|
};
|
|
|
|
export const deleteEnvs = async (
|
|
call: ServerUnaryCall<DeleteEnvsRequest, Response>,
|
|
callback: sendUnaryData<Response>,
|
|
) => {
|
|
try {
|
|
if (!call.request.ids || call.request.ids.length === 0) {
|
|
return callback(null, {
|
|
code: 400,
|
|
message: 'ids parameter is required',
|
|
});
|
|
}
|
|
|
|
const envService = Container.get(EnvService);
|
|
await envService.remove(call.request.ids);
|
|
callback(null, { code: 200 });
|
|
} catch (e: any) {
|
|
callback(e);
|
|
}
|
|
};
|
|
|
|
export const moveEnv = async (
|
|
call: ServerUnaryCall<MoveEnvRequest, EnvResponse>,
|
|
callback: sendUnaryData<EnvResponse>,
|
|
) => {
|
|
try {
|
|
if (!call.request.id) {
|
|
return callback(null, {
|
|
code: 400,
|
|
data: undefined,
|
|
message: 'id parameter is required',
|
|
});
|
|
}
|
|
|
|
const envService = Container.get(EnvService);
|
|
const data = await envService.move(call.request.id, {
|
|
fromIndex: call.request.fromIndex,
|
|
toIndex: call.request.toIndex,
|
|
});
|
|
callback(null, { code: 200, data });
|
|
} catch (e: any) {
|
|
callback(e);
|
|
}
|
|
};
|
|
|
|
export const disableEnvs = async (
|
|
call: ServerUnaryCall<DisableEnvsRequest, Response>,
|
|
callback: sendUnaryData<Response>,
|
|
) => {
|
|
try {
|
|
if (!call.request.ids || call.request.ids.length === 0) {
|
|
return callback(null, {
|
|
code: 400,
|
|
message: 'ids parameter is required',
|
|
});
|
|
}
|
|
|
|
const envService = Container.get(EnvService);
|
|
await envService.disabled(call.request.ids);
|
|
callback(null, { code: 200 });
|
|
} catch (e: any) {
|
|
callback(e);
|
|
}
|
|
};
|
|
|
|
export const enableEnvs = async (
|
|
call: ServerUnaryCall<EnableEnvsRequest, Response>,
|
|
callback: sendUnaryData<Response>,
|
|
) => {
|
|
try {
|
|
if (!call.request.ids || call.request.ids.length === 0) {
|
|
return callback(null, {
|
|
code: 400,
|
|
message: 'ids parameter is required',
|
|
});
|
|
}
|
|
|
|
const envService = Container.get(EnvService);
|
|
await envService.enabled(call.request.ids);
|
|
callback(null, { code: 200 });
|
|
} catch (e: any) {
|
|
callback(e);
|
|
}
|
|
};
|
|
|
|
export const updateEnvNames = async (
|
|
call: ServerUnaryCall<UpdateEnvNamesRequest, Response>,
|
|
callback: sendUnaryData<Response>,
|
|
) => {
|
|
try {
|
|
if (!call.request.ids || call.request.ids.length === 0) {
|
|
return callback(null, {
|
|
code: 400,
|
|
message: 'ids parameter is required',
|
|
});
|
|
}
|
|
|
|
const envService = Container.get(EnvService);
|
|
await envService.updateNames({
|
|
ids: call.request.ids,
|
|
name: call.request.name,
|
|
});
|
|
callback(null, { code: 200 });
|
|
} catch (e: any) {
|
|
callback(e);
|
|
}
|
|
};
|
|
|
|
export const getEnvById = async (
|
|
call: ServerUnaryCall<GetEnvByIdRequest, EnvResponse>,
|
|
callback: sendUnaryData<EnvResponse>,
|
|
) => {
|
|
try {
|
|
if (!call.request.id) {
|
|
return callback(null, {
|
|
code: 400,
|
|
data: undefined,
|
|
message: 'id parameter is required',
|
|
});
|
|
}
|
|
|
|
const envService = Container.get(EnvService);
|
|
const data = await envService.getDb({ id: call.request.id });
|
|
callback(null, {
|
|
code: 200,
|
|
data: { ...data, remarks: data.remarks || '' },
|
|
});
|
|
} catch (e: any) {
|
|
callback(e);
|
|
}
|
|
};
|
|
|
|
export const systemNotify = async (
|
|
call: ServerUnaryCall<SystemNotifyRequest, Response>,
|
|
callback: sendUnaryData<Response>,
|
|
) => {
|
|
try {
|
|
const systemService = Container.get(SystemService);
|
|
const data = await systemService.notify({
|
|
title: call.request.title,
|
|
content: call.request.content,
|
|
notificationInfo: call.request.notificationInfo as unknown as NotificationInfo,
|
|
});
|
|
callback(null, data);
|
|
} catch (e: any) {
|
|
callback(e);
|
|
}
|
|
};
|
|
|
|
const normalizeCronData = (data: CronItem | null): CronItem | undefined => {
|
|
if (!data) return undefined;
|
|
return {
|
|
...data,
|
|
sub_id: data.sub_id ?? undefined,
|
|
extra_schedules: data.extra_schedules ?? undefined,
|
|
pid: data.pid ?? undefined,
|
|
task_before: data.task_before ?? undefined,
|
|
task_after: data.task_after ?? undefined,
|
|
};
|
|
};
|
|
|
|
export const getCronDetail = async (
|
|
call: ServerUnaryCall<CronDetailRequest, CronDetailResponse>,
|
|
callback: sendUnaryData<CronDetailResponse>,
|
|
) => {
|
|
try {
|
|
if (!call.request.log_path) {
|
|
return callback(null, {
|
|
code: 400,
|
|
data: undefined,
|
|
message: 'log_path is required',
|
|
});
|
|
}
|
|
const cronService = Container.get(CronService);
|
|
const data = (await cronService.find({
|
|
log_path: call.request.log_path,
|
|
})) as CronItem;
|
|
callback(null, { code: 200, data: normalizeCronData(data) });
|
|
} catch (e: any) {
|
|
callback(e);
|
|
}
|
|
};
|
|
|
|
export const createCron = async (
|
|
call: ServerUnaryCall<CreateCronRequest, CronResponse>,
|
|
callback: sendUnaryData<CronResponse>,
|
|
) => {
|
|
try {
|
|
const cronService = Container.get(CronService);
|
|
const data = (await cronService.create(call.request)) as CronItem;
|
|
callback(null, { code: 200, data: normalizeCronData(data) });
|
|
} catch (e: any) {
|
|
callback(e);
|
|
}
|
|
};
|
|
|
|
export const updateCron = async (
|
|
call: ServerUnaryCall<UpdateCronRequest, CronResponse>,
|
|
callback: sendUnaryData<CronResponse>,
|
|
) => {
|
|
try {
|
|
const cronService = Container.get(CronService);
|
|
const { id, ...fields } = call.request;
|
|
|
|
const updateRequest = {
|
|
id,
|
|
...Object.entries(fields).reduce((acc: any, [key, value]) => {
|
|
if (value !== undefined) {
|
|
acc[key] = value;
|
|
}
|
|
return acc;
|
|
}, {}),
|
|
} as UpdateCronRequest;
|
|
|
|
const data = (await cronService.update(updateRequest)) as CronItem;
|
|
callback(null, { code: 200, data: normalizeCronData(data) });
|
|
} catch (e: any) {
|
|
callback(e);
|
|
}
|
|
};
|
|
|
|
export const deleteCrons = async (
|
|
call: ServerUnaryCall<DeleteCronsRequest, Response>,
|
|
callback: sendUnaryData<Response>,
|
|
) => {
|
|
try {
|
|
const cronService = Container.get(CronService);
|
|
await cronService.remove(call.request.ids);
|
|
callback(null, { code: 200 });
|
|
} catch (e: any) {
|
|
callback(e);
|
|
}
|
|
};
|
|
|
|
export const getCrons = async (
|
|
call: ServerUnaryCall<GetCronsRequest, CronsResponse>,
|
|
callback: sendUnaryData<CronsResponse>,
|
|
) => {
|
|
try {
|
|
const cronService = Container.get(CronService);
|
|
const result = await cronService.crontabs({
|
|
searchValue: call.request.searchValue || '',
|
|
page: '0',
|
|
size: '0',
|
|
sorter: '',
|
|
filters: '',
|
|
queryString: '',
|
|
});
|
|
const data = result.data.map((x) => normalizeCronData(x as CronItem));
|
|
callback(null, {
|
|
code: 200,
|
|
data: data.filter((x): x is CronItem => x !== undefined),
|
|
});
|
|
} catch (e: any) {
|
|
callback(null, {
|
|
code: 500,
|
|
data: [],
|
|
message: e.message,
|
|
});
|
|
}
|
|
};
|
|
|
|
export const getCronById = async (
|
|
call: ServerUnaryCall<GetCronByIdRequest, CronResponse>,
|
|
callback: sendUnaryData<CronResponse>,
|
|
) => {
|
|
try {
|
|
if (!call.request.id) {
|
|
return callback(null, {
|
|
code: 400,
|
|
data: undefined,
|
|
message: 'id parameter is required',
|
|
});
|
|
}
|
|
|
|
const cronService = Container.get(CronService);
|
|
const data = (await cronService.getDb({ id: call.request.id })) as CronItem;
|
|
callback(null, { code: 200, data: normalizeCronData(data) });
|
|
} catch (e: any) {
|
|
callback(null, {
|
|
code: 404,
|
|
data: undefined,
|
|
message: e.message,
|
|
});
|
|
}
|
|
};
|
|
|
|
export const enableCrons = async (
|
|
call: ServerUnaryCall<EnableCronsRequest, Response>,
|
|
callback: sendUnaryData<Response>,
|
|
) => {
|
|
try {
|
|
if (!call.request.ids || call.request.ids.length === 0) {
|
|
return callback(null, {
|
|
code: 400,
|
|
message: 'ids parameter is required',
|
|
});
|
|
}
|
|
|
|
const cronService = Container.get(CronService);
|
|
await cronService.enabled(call.request.ids);
|
|
callback(null, { code: 200 });
|
|
} catch (e: any) {
|
|
callback(e);
|
|
}
|
|
};
|
|
|
|
export const disableCrons = async (
|
|
call: ServerUnaryCall<DisableCronsRequest, Response>,
|
|
callback: sendUnaryData<Response>,
|
|
) => {
|
|
try {
|
|
if (!call.request.ids || call.request.ids.length === 0) {
|
|
return callback(null, {
|
|
code: 400,
|
|
message: 'ids parameter is required',
|
|
});
|
|
}
|
|
|
|
const cronService = Container.get(CronService);
|
|
await cronService.disabled(call.request.ids);
|
|
callback(null, { code: 200 });
|
|
} catch (e: any) {
|
|
callback(e);
|
|
}
|
|
};
|
|
|
|
export const runCrons = async (
|
|
call: ServerUnaryCall<RunCronsRequest, Response>,
|
|
callback: sendUnaryData<Response>,
|
|
) => {
|
|
try {
|
|
if (!call.request.ids || call.request.ids.length === 0) {
|
|
return callback(null, {
|
|
code: 400,
|
|
message: 'ids parameter is required',
|
|
});
|
|
}
|
|
|
|
const cronService = Container.get(CronService);
|
|
await cronService.run(call.request.ids);
|
|
callback(null, { code: 200 });
|
|
} catch (e: any) {
|
|
callback(e);
|
|
}
|
|
};
|