feat(api): 添加 OpenAPI 客户端支持

- 新增 ApiError、ApiRequestOptions、ApiResult、CancelablePromise 等核心类
- 添加多种模型类型定义,如 PlanCreateIn、QueueGetOut、ScriptCreateOut 等
- 实现请求发送、错误处理、数据解析等核心功能
- 配置 axios 客户端并集成到请求流程中
- 优化路由配置,添加用户相关路由
- 更新脚本编辑界面文案,使用更通用的描述
This commit is contained in:
2025-08-05 20:04:00 +08:00
parent c116efd6f4
commit d68e423768
59 changed files with 3274 additions and 1217 deletions

View File

@@ -51,6 +51,7 @@
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-prettier": "^5.5.3",
"eslint-plugin-vue": "^10.4.0",
"openapi-typescript-codegen": "^0.29.0",
"prettier": "^3.6.2",
"typescript": "^5.9.2",
"vite": "^7.0.4",

View File

@@ -0,0 +1,25 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { ApiRequestOptions } from './ApiRequestOptions.ts';
import type { ApiResult } from './ApiResult.ts';
export class ApiError extends Error {
public readonly url: string;
public readonly status: number;
public readonly statusText: string;
public readonly body: any;
public readonly request: ApiRequestOptions;
constructor(request: ApiRequestOptions, response: ApiResult, message: string) {
super(message);
this.name = 'ApiError';
this.url = response.url;
this.status = response.status;
this.statusText = response.statusText;
this.body = response.body;
this.request = request;
}
}

View File

@@ -0,0 +1,17 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type ApiRequestOptions = {
readonly method: 'GET' | 'PUT' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'PATCH';
readonly url: string;
readonly path?: Record<string, any>;
readonly cookies?: Record<string, any>;
readonly headers?: Record<string, any>;
readonly query?: Record<string, any>;
readonly formData?: Record<string, any>;
readonly body?: any;
readonly mediaType?: string;
readonly responseHeader?: string;
readonly errors?: Record<number, string>;
};

View File

@@ -0,0 +1,11 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type ApiResult = {
readonly url: string;
readonly ok: boolean;
readonly status: number;
readonly statusText: string;
readonly body: any;
};

View File

@@ -0,0 +1,131 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export class CancelError extends Error {
constructor(message: string) {
super(message);
this.name = 'CancelError';
}
public get isCancelled(): boolean {
return true;
}
}
export interface OnCancel {
readonly isResolved: boolean;
readonly isRejected: boolean;
readonly isCancelled: boolean;
(cancelHandler: () => void): void;
}
export class CancelablePromise<T> implements Promise<T> {
#isResolved: boolean;
#isRejected: boolean;
#isCancelled: boolean;
readonly #cancelHandlers: (() => void)[];
readonly #promise: Promise<T>;
#resolve?: (value: T | PromiseLike<T>) => void;
#reject?: (reason?: any) => void;
constructor(
executor: (
resolve: (value: T | PromiseLike<T>) => void,
reject: (reason?: any) => void,
onCancel: OnCancel
) => void
) {
this.#isResolved = false;
this.#isRejected = false;
this.#isCancelled = false;
this.#cancelHandlers = [];
this.#promise = new Promise<T>((resolve, reject) => {
this.#resolve = resolve;
this.#reject = reject;
const onResolve = (value: T | PromiseLike<T>): void => {
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
return;
}
this.#isResolved = true;
if (this.#resolve) this.#resolve(value);
};
const onReject = (reason?: any): void => {
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
return;
}
this.#isRejected = true;
if (this.#reject) this.#reject(reason);
};
const onCancel = (cancelHandler: () => void): void => {
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
return;
}
this.#cancelHandlers.push(cancelHandler);
};
Object.defineProperty(onCancel, 'isResolved', {
get: (): boolean => this.#isResolved,
});
Object.defineProperty(onCancel, 'isRejected', {
get: (): boolean => this.#isRejected,
});
Object.defineProperty(onCancel, 'isCancelled', {
get: (): boolean => this.#isCancelled,
});
return executor(onResolve, onReject, onCancel as OnCancel);
});
}
get [Symbol.toStringTag]() {
return "Cancellable Promise";
}
public then<TResult1 = T, TResult2 = never>(
onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,
onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
): Promise<TResult1 | TResult2> {
return this.#promise.then(onFulfilled, onRejected);
}
public catch<TResult = never>(
onRejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null
): Promise<T | TResult> {
return this.#promise.catch(onRejected);
}
public finally(onFinally?: (() => void) | null): Promise<T> {
return this.#promise.finally(onFinally);
}
public cancel(): void {
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
return;
}
this.#isCancelled = true;
if (this.#cancelHandlers.length) {
try {
for (const cancelHandler of this.#cancelHandlers) {
cancelHandler();
}
} catch (error) {
console.warn('Cancellation threw an error', error);
return;
}
}
this.#cancelHandlers.length = 0;
if (this.#reject) this.#reject(new CancelError('Request aborted'));
}
public get isCancelled(): boolean {
return this.#isCancelled;
}
}

View File

@@ -0,0 +1,32 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { ApiRequestOptions } from './ApiRequestOptions.ts';
type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
type Headers = Record<string, string>;
export type OpenAPIConfig = {
BASE: string;
VERSION: string;
WITH_CREDENTIALS: boolean;
CREDENTIALS: 'include' | 'omit' | 'same-origin';
TOKEN?: string | Resolver<string> | undefined;
USERNAME?: string | Resolver<string> | undefined;
PASSWORD?: string | Resolver<string> | undefined;
HEADERS?: Headers | Resolver<Headers> | undefined;
ENCODE_PATH?: ((path: string) => string) | undefined;
};
export const OpenAPI: OpenAPIConfig = {
BASE: '',
VERSION: '1.0.0',
WITH_CREDENTIALS: false,
CREDENTIALS: 'include',
TOKEN: undefined,
USERNAME: undefined,
PASSWORD: undefined,
HEADERS: undefined,
ENCODE_PATH: undefined,
};

View File

@@ -0,0 +1,323 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import axios from 'axios';
import type { AxiosError, AxiosRequestConfig, AxiosResponse, AxiosInstance } from 'axios';
import FormData from 'form-data';
import { ApiError } from './ApiError.ts';
import type { ApiRequestOptions } from './ApiRequestOptions.ts';
import type { ApiResult } from './ApiResult.ts';
import { CancelablePromise } from './CancelablePromise.ts';
import type { OnCancel } from './CancelablePromise.ts';
import type { OpenAPIConfig } from './OpenAPI.ts';
export const isDefined = <T>(value: T | null | undefined): value is Exclude<T, null | undefined> => {
return value !== undefined && value !== null;
};
export const isString = (value: any): value is string => {
return typeof value === 'string';
};
export const isStringWithValue = (value: any): value is string => {
return isString(value) && value !== '';
};
export const isBlob = (value: any): value is Blob => {
return (
typeof value === 'object' &&
typeof value.type === 'string' &&
typeof value.stream === 'function' &&
typeof value.arrayBuffer === 'function' &&
typeof value.constructor === 'function' &&
typeof value.constructor.name === 'string' &&
/^(Blob|File)$/.test(value.constructor.name) &&
/^(Blob|File)$/.test(value[Symbol.toStringTag])
);
};
export const isFormData = (value: any): value is FormData => {
return value instanceof FormData;
};
export const isSuccess = (status: number): boolean => {
return status >= 200 && status < 300;
};
export const base64 = (str: string): string => {
try {
return btoa(str);
} catch (err) {
// @ts-ignore
return Buffer.from(str).toString('base64');
}
};
export const getQueryString = (params: Record<string, any>): string => {
const qs: string[] = [];
const append = (key: string, value: any) => {
qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
};
const process = (key: string, value: any) => {
if (isDefined(value)) {
if (Array.isArray(value)) {
value.forEach(v => {
process(key, v);
});
} else if (typeof value === 'object') {
Object.entries(value).forEach(([k, v]) => {
process(`${key}[${k}]`, v);
});
} else {
append(key, value);
}
}
};
Object.entries(params).forEach(([key, value]) => {
process(key, value);
});
if (qs.length > 0) {
return `?${qs.join('&')}`;
}
return '';
};
const getUrl = (config: OpenAPIConfig, options: ApiRequestOptions): string => {
const encoder = config.ENCODE_PATH || encodeURI;
const path = options.url
.replace('{api-version}', config.VERSION)
.replace(/{(.*?)}/g, (substring: string, group: string) => {
if (options.path?.hasOwnProperty(group)) {
return encoder(String(options.path[group]));
}
return substring;
});
const url = `${config.BASE}${path}`;
if (options.query) {
return `${url}${getQueryString(options.query)}`;
}
return url;
};
export const getFormData = (options: ApiRequestOptions): FormData | undefined => {
if (options.formData) {
const formData = new FormData();
const process = (key: string, value: any) => {
if (isString(value) || isBlob(value)) {
formData.append(key, value);
} else {
formData.append(key, JSON.stringify(value));
}
};
Object.entries(options.formData)
.filter(([_, value]) => isDefined(value))
.forEach(([key, value]) => {
if (Array.isArray(value)) {
value.forEach(v => process(key, v));
} else {
process(key, value);
}
});
return formData;
}
return undefined;
};
type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
export const resolve = async <T>(options: ApiRequestOptions, resolver?: T | Resolver<T>): Promise<T | undefined> => {
if (typeof resolver === 'function') {
return (resolver as Resolver<T>)(options);
}
return resolver;
};
export const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions, formData?: FormData): Promise<Record<string, string>> => {
const [token, username, password, additionalHeaders] = await Promise.all([
resolve(options, config.TOKEN),
resolve(options, config.USERNAME),
resolve(options, config.PASSWORD),
resolve(options, config.HEADERS),
]);
const formHeaders = typeof formData?.getHeaders === 'function' && formData?.getHeaders() || {}
const headers = Object.entries({
Accept: 'application/json',
...additionalHeaders,
...options.headers,
...formHeaders,
})
.filter(([_, value]) => isDefined(value))
.reduce((headers, [key, value]) => ({
...headers,
[key]: String(value),
}), {} as Record<string, string>);
if (isStringWithValue(token)) {
headers['Authorization'] = `Bearer ${token}`;
}
if (isStringWithValue(username) && isStringWithValue(password)) {
const credentials = base64(`${username}:${password}`);
headers['Authorization'] = `Basic ${credentials}`;
}
if (options.body !== undefined) {
if (options.mediaType) {
headers['Content-Type'] = options.mediaType;
} else if (isBlob(options.body)) {
headers['Content-Type'] = options.body.type || 'application/octet-stream';
} else if (isString(options.body)) {
headers['Content-Type'] = 'text/plain';
} else if (!isFormData(options.body)) {
headers['Content-Type'] = 'application/json';
}
}
return headers;
};
export const getRequestBody = (options: ApiRequestOptions): any => {
if (options.body) {
return options.body;
}
return undefined;
};
export const sendRequest = async <T>(
config: OpenAPIConfig,
options: ApiRequestOptions,
url: string,
body: any,
formData: FormData | undefined,
headers: Record<string, string>,
onCancel: OnCancel,
axiosClient: AxiosInstance
): Promise<AxiosResponse<T>> => {
const source = axios.CancelToken.source();
const requestConfig: AxiosRequestConfig = {
url,
headers,
data: body ?? formData,
method: options.method,
withCredentials: config.WITH_CREDENTIALS,
withXSRFToken: config.CREDENTIALS === 'include' ? config.WITH_CREDENTIALS : false,
cancelToken: source.token,
};
onCancel(() => source.cancel('The user aborted a request.'));
try {
return await axiosClient.request(requestConfig);
} catch (error) {
const axiosError = error as AxiosError<T>;
if (axiosError.response) {
return axiosError.response;
}
throw error;
}
};
export const getResponseHeader = (response: AxiosResponse<any>, responseHeader?: string): string | undefined => {
if (responseHeader) {
const content = response.headers[responseHeader];
if (isString(content)) {
return content;
}
}
return undefined;
};
export const getResponseBody = (response: AxiosResponse<any>): any => {
if (response.status !== 204) {
return response.data;
}
return undefined;
};
export const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => {
const errors: Record<number, string> = {
400: 'Bad Request',
401: 'Unauthorized',
403: 'Forbidden',
404: 'Not Found',
500: 'Internal Server Error',
502: 'Bad Gateway',
503: 'Service Unavailable',
...options.errors,
}
const error = errors[result.status];
if (error) {
throw new ApiError(options, result, error);
}
if (!result.ok) {
const errorStatus = result.status ?? 'unknown';
const errorStatusText = result.statusText ?? 'unknown';
const errorBody = (() => {
try {
return JSON.stringify(result.body, null, 2);
} catch (e) {
return undefined;
}
})();
throw new ApiError(options, result,
`Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody}`
);
}
};
/**
* Request method
* @param config The OpenAPI configuration object
* @param options The request options from the service
* @param axiosClient The axios client instance to use
* @returns CancelablePromise<T>
* @throws ApiError
*/
export const request = <T>(config: OpenAPIConfig, options: ApiRequestOptions, axiosClient: AxiosInstance = axios): CancelablePromise<T> => {
return new CancelablePromise(async (resolve, reject, onCancel) => {
try {
const url = getUrl(config, options);
const formData = getFormData(options);
const body = getRequestBody(options);
const headers = await getHeaders(config, options, formData);
if (!onCancel.isCancelled) {
const response = await sendRequest<T>(config, options, url, body, formData, headers, onCancel, axiosClient);
const responseBody = getResponseBody(response);
const responseHeader = getResponseHeader(response, options.responseHeader);
const result: ApiResult = {
url,
ok: isSuccess(response.status),
status: response.status,
statusText: response.statusText,
body: responseHeader ?? responseBody,
};
catchErrorCodes(options, result);
resolve(result.body);
}
} catch (error) {
reject(error);
}
});
};

51
frontend/src/api/index.ts Normal file
View File

@@ -0,0 +1,51 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export { ApiError } from './core/ApiError.ts';
export { CancelablePromise, CancelError } from './core/CancelablePromise.ts';
export { OpenAPI } from './core/OpenAPI.ts';
export type { OpenAPIConfig } from './core/OpenAPI.ts';
export type { HTTPValidationError } from './models/HTTPValidationError.ts';
export type { InfoOut } from './models/InfoOut.ts';
export type { OutBase } from './models/OutBase.ts';
export type { PlanCreateIn } from './models/PlanCreateIn.ts';
export type { PlanCreateOut } from './models/PlanCreateOut.ts';
export type { PlanDeleteIn } from './models/PlanDeleteIn.ts';
export type { PlanGetIn } from './models/PlanGetIn.ts';
export type { PlanGetOut } from './models/PlanGetOut.ts';
export type { PlanReorderIn } from './models/PlanReorderIn.ts';
export type { PlanUpdateIn } from './models/PlanUpdateIn.ts';
export type { QueueCreateOut } from './models/QueueCreateOut.ts';
export type { QueueDeleteIn } from './models/QueueDeleteIn.ts';
export type { QueueGetIn } from './models/QueueGetIn.ts';
export type { QueueGetOut } from './models/QueueGetOut.ts';
export type { QueueItemCreateOut } from './models/QueueItemCreateOut.ts';
export type { QueueItemDeleteIn } from './models/QueueItemDeleteIn.ts';
export type { QueueItemReorderIn } from './models/QueueItemReorderIn.ts';
export type { QueueItemUpdateIn } from './models/QueueItemUpdateIn.ts';
export type { QueueReorderIn } from './models/QueueReorderIn.ts';
export type { QueueSetInBase } from './models/QueueSetInBase.ts';
export type { QueueUpdateIn } from './models/QueueUpdateIn.ts';
export { ScriptCreateIn } from './models/ScriptCreateIn.ts';
export type { ScriptCreateOut } from './models/ScriptCreateOut.ts';
export type { ScriptDeleteIn } from './models/ScriptDeleteIn.ts';
export type { ScriptGetIn } from './models/ScriptGetIn.ts';
export type { ScriptGetOut } from './models/ScriptGetOut.ts';
export type { ScriptReorderIn } from './models/ScriptReorderIn.ts';
export type { ScriptUpdateIn } from './models/ScriptUpdateIn.ts';
export type { SettingGetOut } from './models/SettingGetOut.ts';
export type { SettingUpdateIn } from './models/SettingUpdateIn.ts';
export type { TimeSetCreateOut } from './models/TimeSetCreateOut.ts';
export type { TimeSetDeleteIn } from './models/TimeSetDeleteIn.ts';
export type { TimeSetReorderIn } from './models/TimeSetReorderIn.ts';
export type { TimeSetUpdateIn } from './models/TimeSetUpdateIn.ts';
export type { UserCreateOut } from './models/UserCreateOut.ts';
export type { UserDeleteIn } from './models/UserDeleteIn.ts';
export type { UserInBase } from './models/UserInBase.ts';
export type { UserReorderIn } from './models/UserReorderIn.ts';
export type { UserUpdateIn } from './models/UserUpdateIn.ts';
export type { ValidationError } from './models/ValidationError.ts';
export { Service } from './services/Service.ts';

View File

@@ -0,0 +1,9 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { ValidationError } from './ValidationError.ts';
export type HTTPValidationError = {
detail?: Array<ValidationError>;
};

View File

@@ -0,0 +1,23 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type InfoOut = {
/**
* 状态码
*/
code?: number;
/**
* 操作状态
*/
status?: string;
/**
* 操作消息
*/
message?: string;
/**
* 收到的服务器数据
*/
data: Record<string, any>;
};

View File

@@ -0,0 +1,19 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type OutBase = {
/**
* 状态码
*/
code?: number;
/**
* 操作状态
*/
status?: string;
/**
* 操作消息
*/
message?: string;
};

View File

@@ -0,0 +1,8 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type PlanCreateIn = {
type: string;
};

View File

@@ -0,0 +1,27 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type PlanCreateOut = {
/**
* 状态码
*/
code?: number;
/**
* 操作状态
*/
status?: string;
/**
* 操作消息
*/
message?: string;
/**
* 新创建的计划ID
*/
planId: string;
/**
* 计划配置数据
*/
data: Record<string, any>;
};

View File

@@ -0,0 +1,11 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type PlanDeleteIn = {
/**
* 计划ID
*/
planId: string;
};

View File

@@ -0,0 +1,11 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type PlanGetIn = {
/**
* 计划ID仅在模式为Single时需要
*/
planId?: (string | null);
};

View File

@@ -0,0 +1,27 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type PlanGetOut = {
/**
* 状态码
*/
code?: number;
/**
* 操作状态
*/
status?: string;
/**
* 操作消息
*/
message?: string;
/**
* 计划索引列表
*/
index: Array<Record<string, string>>;
/**
* 计划列表或单个计划数据
*/
data: Record<string, any>;
};

View File

@@ -0,0 +1,11 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type PlanReorderIn = {
/**
* 计划ID列表按新顺序排列
*/
indexList: Array<string>;
};

View File

@@ -0,0 +1,15 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type PlanUpdateIn = {
/**
* 计划ID
*/
planId: string;
/**
* 计划更新数据
*/
data: Record<string, Record<string, any>>;
};

View File

@@ -0,0 +1,27 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type QueueCreateOut = {
/**
* 状态码
*/
code?: number;
/**
* 操作状态
*/
status?: string;
/**
* 操作消息
*/
message?: string;
/**
* 新创建的队列ID
*/
queueId: string;
/**
* 队列配置数据
*/
data: Record<string, any>;
};

View File

@@ -0,0 +1,11 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type QueueDeleteIn = {
/**
* 队列ID
*/
queueId: string;
};

View File

@@ -0,0 +1,11 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type QueueGetIn = {
/**
* 队列ID仅在模式为Single时需要
*/
queueId?: (string | null);
};

View File

@@ -0,0 +1,27 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type QueueGetOut = {
/**
* 状态码
*/
code?: number;
/**
* 操作状态
*/
status?: string;
/**
* 操作消息
*/
message?: string;
/**
* 队列索引列表
*/
index: Array<Record<string, string>>;
/**
* 队列列表或单个队列数据
*/
data: Record<string, any>;
};

View File

@@ -0,0 +1,27 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type QueueItemCreateOut = {
/**
* 状态码
*/
code?: number;
/**
* 操作状态
*/
status?: string;
/**
* 操作消息
*/
message?: string;
/**
* 新创建的队列项ID
*/
queueItemId: string;
/**
* 队列项配置数据
*/
data: Record<string, any>;
};

View File

@@ -0,0 +1,15 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type QueueItemDeleteIn = {
/**
* 所属队列ID
*/
queueId: string;
/**
* 队列项ID
*/
queueItemId: string;
};

View File

@@ -0,0 +1,15 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type QueueItemReorderIn = {
/**
* 所属队列ID
*/
queueId: string;
/**
* 队列项ID列表按新顺序排列
*/
indexList: Array<string>;
};

View File

@@ -0,0 +1,19 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type QueueItemUpdateIn = {
/**
* 所属队列ID
*/
queueId: string;
/**
* 队列项ID
*/
queueItemId: string;
/**
* 队列项更新数据
*/
data: Record<string, Record<string, any>>;
};

View File

@@ -0,0 +1,11 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type QueueReorderIn = {
/**
* 调度队列ID列表按新顺序排列
*/
indexList: Array<string>;
};

View File

@@ -0,0 +1,11 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type QueueSetInBase = {
/**
* 所属队列ID
*/
queueId: string;
};

View File

@@ -0,0 +1,15 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type QueueUpdateIn = {
/**
* 队列ID
*/
queueId: string;
/**
* 队列更新数据
*/
data: Record<string, Record<string, any>>;
};

View File

@@ -0,0 +1,14 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type ScriptCreateIn = {
type: ScriptCreateIn.type;
};
export namespace ScriptCreateIn {
export enum type {
MAA = 'MAA',
GENERAL = 'General',
}
}

View File

@@ -0,0 +1,27 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type ScriptCreateOut = {
/**
* 状态码
*/
code?: number;
/**
* 操作状态
*/
status?: string;
/**
* 操作消息
*/
message?: string;
/**
* 新创建的脚本ID
*/
scriptId: string;
/**
* 脚本配置数据
*/
data: Record<string, any>;
};

View File

@@ -0,0 +1,11 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type ScriptDeleteIn = {
/**
* 脚本ID
*/
scriptId: string;
};

View File

@@ -0,0 +1,11 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type ScriptGetIn = {
/**
* 脚本ID仅在模式为Single时需要
*/
scriptId?: (string | null);
};

View File

@@ -0,0 +1,27 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type ScriptGetOut = {
/**
* 状态码
*/
code?: number;
/**
* 操作状态
*/
status?: string;
/**
* 操作消息
*/
message?: string;
/**
* 脚本索引列表
*/
index: Array<Record<string, string>>;
/**
* 脚本列表或单个脚本数据
*/
data: Record<string, any>;
};

View File

@@ -0,0 +1,11 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type ScriptReorderIn = {
/**
* 脚本ID列表按新顺序排列
*/
indexList: Array<string>;
};

View File

@@ -0,0 +1,15 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type ScriptUpdateIn = {
/**
* 脚本ID
*/
scriptId: string;
/**
* 脚本更新数据
*/
data: Record<string, Record<string, any>>;
};

View File

@@ -0,0 +1,23 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type SettingGetOut = {
/**
* 状态码
*/
code?: number;
/**
* 操作状态
*/
status?: string;
/**
* 操作消息
*/
message?: string;
/**
* 全局设置数据
*/
data: Record<string, Record<string, any>>;
};

View File

@@ -0,0 +1,11 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type SettingUpdateIn = {
/**
* 全局设置更新数据
*/
data: Record<string, Record<string, any>>;
};

View File

@@ -0,0 +1,27 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type TimeSetCreateOut = {
/**
* 状态码
*/
code?: number;
/**
* 操作状态
*/
status?: string;
/**
* 操作消息
*/
message?: string;
/**
* 新创建的时间设置ID
*/
timeSetId: string;
/**
* 时间设置配置数据
*/
data: Record<string, any>;
};

View File

@@ -0,0 +1,15 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type TimeSetDeleteIn = {
/**
* 所属队列ID
*/
queueId: string;
/**
* 时间设置ID
*/
timeSetId: string;
};

View File

@@ -0,0 +1,15 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type TimeSetReorderIn = {
/**
* 所属队列ID
*/
queueId: string;
/**
* 时间设置ID列表按新顺序排列
*/
indexList: Array<string>;
};

View File

@@ -0,0 +1,19 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type TimeSetUpdateIn = {
/**
* 所属队列ID
*/
queueId: string;
/**
* 时间设置ID
*/
timeSetId: string;
/**
* 时间设置更新数据
*/
data: Record<string, Record<string, any>>;
};

View File

@@ -0,0 +1,27 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type UserCreateOut = {
/**
* 状态码
*/
code?: number;
/**
* 操作状态
*/
status?: string;
/**
* 操作消息
*/
message?: string;
/**
* 新创建的用户ID
*/
userId: string;
/**
* 用户配置数据
*/
data: Record<string, any>;
};

View File

@@ -0,0 +1,15 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type UserDeleteIn = {
/**
* 所属脚本ID
*/
scriptId: string;
/**
* 用户ID
*/
userId: string;
};

View File

@@ -0,0 +1,11 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type UserInBase = {
/**
* 所属脚本ID
*/
scriptId: string;
};

View File

@@ -0,0 +1,15 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type UserReorderIn = {
/**
* 所属脚本ID
*/
scriptId: string;
/**
* 用户ID列表按新顺序排列
*/
indexList: Array<string>;
};

View File

@@ -0,0 +1,19 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type UserUpdateIn = {
/**
* 所属脚本ID
*/
scriptId: string;
/**
* 用户ID
*/
userId: string;
/**
* 用户更新数据
*/
data: Record<string, Record<string, any>>;
};

View File

@@ -0,0 +1,10 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type ValidationError = {
loc: Array<(string | number)>;
msg: string;
type: string;
};

View File

@@ -0,0 +1,617 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { InfoOut } from '../models/InfoOut.ts';
import type { OutBase } from '../models/OutBase.ts';
import type { PlanCreateIn } from '../models/PlanCreateIn.ts';
import type { PlanCreateOut } from '../models/PlanCreateOut.ts';
import type { PlanDeleteIn } from '../models/PlanDeleteIn.ts';
import type { PlanGetIn } from '../models/PlanGetIn.ts';
import type { PlanGetOut } from '../models/PlanGetOut.ts';
import type { PlanReorderIn } from '../models/PlanReorderIn.ts';
import type { PlanUpdateIn } from '../models/PlanUpdateIn.ts';
import type { QueueCreateOut } from '../models/QueueCreateOut.ts';
import type { QueueDeleteIn } from '../models/QueueDeleteIn.ts';
import type { QueueGetIn } from '../models/QueueGetIn.ts';
import type { QueueGetOut } from '../models/QueueGetOut.ts';
import type { QueueItemCreateOut } from '../models/QueueItemCreateOut.ts';
import type { QueueItemDeleteIn } from '../models/QueueItemDeleteIn.ts';
import type { QueueItemReorderIn } from '../models/QueueItemReorderIn.ts';
import type { QueueItemUpdateIn } from '../models/QueueItemUpdateIn.ts';
import type { QueueReorderIn } from '../models/QueueReorderIn.ts';
import type { QueueSetInBase } from '../models/QueueSetInBase.ts';
import type { QueueUpdateIn } from '../models/QueueUpdateIn.ts';
import type { ScriptCreateIn } from '../models/ScriptCreateIn.ts';
import type { ScriptCreateOut } from '../models/ScriptCreateOut.ts';
import type { ScriptDeleteIn } from '../models/ScriptDeleteIn.ts';
import type { ScriptGetIn } from '../models/ScriptGetIn.ts';
import type { ScriptGetOut } from '../models/ScriptGetOut.ts';
import type { ScriptReorderIn } from '../models/ScriptReorderIn.ts';
import type { ScriptUpdateIn } from '../models/ScriptUpdateIn.ts';
import type { SettingGetOut } from '../models/SettingGetOut.ts';
import type { SettingUpdateIn } from '../models/SettingUpdateIn.ts';
import type { TimeSetCreateOut } from '../models/TimeSetCreateOut.ts';
import type { TimeSetDeleteIn } from '../models/TimeSetDeleteIn.ts';
import type { TimeSetReorderIn } from '../models/TimeSetReorderIn.ts';
import type { TimeSetUpdateIn } from '../models/TimeSetUpdateIn.ts';
import type { UserCreateOut } from '../models/UserCreateOut.ts';
import type { UserDeleteIn } from '../models/UserDeleteIn.ts';
import type { UserInBase } from '../models/UserInBase.ts';
import type { UserReorderIn } from '../models/UserReorderIn.ts';
import type { UserUpdateIn } from '../models/UserUpdateIn.ts';
import type { CancelablePromise } from '../core/CancelablePromise.ts';
import { OpenAPI } from '../core/OpenAPI.ts';
import { request as __request } from '../core/request.ts';
export class Service {
/**
* 获取关卡号信息
* @returns InfoOut Successful Response
* @throws ApiError
*/
public static getStageInfoApiInfoStagePost(): CancelablePromise<InfoOut> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/info/stage',
});
}
/**
* 获取通知信息
* @returns InfoOut Successful Response
* @throws ApiError
*/
public static getNoticeInfoApiInfoNoticePost(): CancelablePromise<InfoOut> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/info/notice',
});
}
/**
* 获取可下载应用信息
* @returns InfoOut Successful Response
* @throws ApiError
*/
public static getAppsInfoApiInfoAppsInfoPost(): CancelablePromise<InfoOut> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/info/apps_info',
});
}
/**
* 添加脚本
* @param requestBody
* @returns ScriptCreateOut Successful Response
* @throws ApiError
*/
public static addScriptApiScriptsAddPost(
requestBody: ScriptCreateIn,
): CancelablePromise<ScriptCreateOut> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/scripts/add',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 查询脚本配置信息
* @param requestBody
* @returns ScriptGetOut Successful Response
* @throws ApiError
*/
public static getScriptsApiScriptsGetPost(
requestBody: ScriptGetIn,
): CancelablePromise<ScriptGetOut> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/scripts/get',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 更新脚本配置信息
* @param requestBody
* @returns OutBase Successful Response
* @throws ApiError
*/
public static updateScriptApiScriptsUpdatePost(
requestBody: ScriptUpdateIn,
): CancelablePromise<OutBase> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/scripts/update',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 删除脚本
* @param requestBody
* @returns OutBase Successful Response
* @throws ApiError
*/
public static deleteScriptApiScriptsDeletePost(
requestBody: ScriptDeleteIn,
): CancelablePromise<OutBase> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/scripts/delete',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 重新排序脚本
* @param requestBody
* @returns OutBase Successful Response
* @throws ApiError
*/
public static reorderScriptApiScriptsOrderPost(
requestBody: ScriptReorderIn,
): CancelablePromise<OutBase> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/scripts/order',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 添加用户
* @param requestBody
* @returns UserCreateOut Successful Response
* @throws ApiError
*/
public static addUserApiScriptsUserAddPost(
requestBody: UserInBase,
): CancelablePromise<UserCreateOut> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/scripts/user/add',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 更新用户配置信息
* @param requestBody
* @returns OutBase Successful Response
* @throws ApiError
*/
public static updateUserApiScriptsUserUpdatePost(
requestBody: UserUpdateIn,
): CancelablePromise<OutBase> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/scripts/user/update',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 删除用户
* @param requestBody
* @returns OutBase Successful Response
* @throws ApiError
*/
public static deleteUserApiScriptsUserDeletePost(
requestBody: UserDeleteIn,
): CancelablePromise<OutBase> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/scripts/user/delete',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 重新排序用户
* @param requestBody
* @returns OutBase Successful Response
* @throws ApiError
*/
public static reorderUserApiScriptsUserOrderPost(
requestBody: UserReorderIn,
): CancelablePromise<OutBase> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/scripts/user/order',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 添加计划表
* @param requestBody
* @returns PlanCreateOut Successful Response
* @throws ApiError
*/
public static addPlanApiPlanAddPost(
requestBody: PlanCreateIn,
): CancelablePromise<PlanCreateOut> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/plan/add',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 查询计划表配置信息
* @param requestBody
* @returns PlanGetOut Successful Response
* @throws ApiError
*/
public static getPlanApiPlanGetPost(
requestBody: PlanGetIn,
): CancelablePromise<PlanGetOut> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/plan/get',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 更新计划表配置信息
* @param requestBody
* @returns OutBase Successful Response
* @throws ApiError
*/
public static updatePlanApiPlanUpdatePost(
requestBody: PlanUpdateIn,
): CancelablePromise<OutBase> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/plan/update',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 删除计划表
* @param requestBody
* @returns OutBase Successful Response
* @throws ApiError
*/
public static deletePlanApiPlanDeletePost(
requestBody: PlanDeleteIn,
): CancelablePromise<OutBase> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/plan/delete',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 重新排序计划表
* @param requestBody
* @returns OutBase Successful Response
* @throws ApiError
*/
public static reorderPlanApiPlanOrderPost(
requestBody: PlanReorderIn,
): CancelablePromise<OutBase> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/plan/order',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 添加调度队列
* @returns QueueCreateOut Successful Response
* @throws ApiError
*/
public static addQueueApiQueueAddPost(): CancelablePromise<QueueCreateOut> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/queue/add',
});
}
/**
* 查询调度队列配置信息
* @param requestBody
* @returns QueueGetOut Successful Response
* @throws ApiError
*/
public static getQueuesApiQueueGetPost(
requestBody: QueueGetIn,
): CancelablePromise<QueueGetOut> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/queue/get',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 更新调度队列配置信息
* @param requestBody
* @returns OutBase Successful Response
* @throws ApiError
*/
public static updateQueueApiQueueUpdatePost(
requestBody: QueueUpdateIn,
): CancelablePromise<OutBase> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/queue/update',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 删除调度队列
* @param requestBody
* @returns OutBase Successful Response
* @throws ApiError
*/
public static deleteQueueApiQueueDeletePost(
requestBody: QueueDeleteIn,
): CancelablePromise<OutBase> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/queue/delete',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 重新排序
* @param requestBody
* @returns OutBase Successful Response
* @throws ApiError
*/
public static reorderQueueApiQueueOrderPost(
requestBody: QueueReorderIn,
): CancelablePromise<OutBase> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/queue/order',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 添加定时项
* @param requestBody
* @returns TimeSetCreateOut Successful Response
* @throws ApiError
*/
public static addTimeSetApiQueueTimeAddPost(
requestBody: QueueSetInBase,
): CancelablePromise<TimeSetCreateOut> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/queue/time/add',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 更新定时项
* @param requestBody
* @returns OutBase Successful Response
* @throws ApiError
*/
public static updateTimeSetApiQueueTimeUpdatePost(
requestBody: TimeSetUpdateIn,
): CancelablePromise<OutBase> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/queue/time/update',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 删除定时项
* @param requestBody
* @returns OutBase Successful Response
* @throws ApiError
*/
public static deleteTimeSetApiQueueTimeDeletePost(
requestBody: TimeSetDeleteIn,
): CancelablePromise<OutBase> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/queue/time/delete',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 重新排序时间设置
* @param requestBody
* @returns OutBase Successful Response
* @throws ApiError
*/
public static reorderTimeSetApiQueueTimeOrderPost(
requestBody: TimeSetReorderIn,
): CancelablePromise<OutBase> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/queue/time/order',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 添加队列项
* @param requestBody
* @returns QueueItemCreateOut Successful Response
* @throws ApiError
*/
public static addItemApiQueueItemAddPost(
requestBody: QueueSetInBase,
): CancelablePromise<QueueItemCreateOut> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/queue/item/add',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 更新队列项
* @param requestBody
* @returns OutBase Successful Response
* @throws ApiError
*/
public static updateItemApiQueueItemUpdatePost(
requestBody: QueueItemUpdateIn,
): CancelablePromise<OutBase> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/queue/item/update',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 删除队列项
* @param requestBody
* @returns OutBase Successful Response
* @throws ApiError
*/
public static deleteItemApiQueueItemDeletePost(
requestBody: QueueItemDeleteIn,
): CancelablePromise<OutBase> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/queue/item/delete',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 重新排序队列项
* @param requestBody
* @returns OutBase Successful Response
* @throws ApiError
*/
public static reorderItemApiQueueItemOrderPost(
requestBody: QueueItemReorderIn,
): CancelablePromise<OutBase> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/queue/item/order',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
* 查询配置
* 查询配置
* @returns SettingGetOut Successful Response
* @throws ApiError
*/
public static getScriptsApiSettingGetPost(): CancelablePromise<SettingGetOut> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/setting/get',
});
}
/**
* 更新配置
* 更新配置
* @param requestBody
* @returns OutBase Successful Response
* @throws ApiError
*/
public static updateScriptApiSettingUpdatePost(
requestBody: SettingUpdateIn,
): CancelablePromise<OutBase> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/setting/update',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
}

View File

@@ -83,7 +83,13 @@
row-key="id"
class="user-table"
>
<template #bodyCell="{ column, record: user }">
<template v-if="column.key === 'server'">
<div class="server-cell">
<a-tag color="green">{{ user.Info.Server === 'Official' ? '官服' : 'B服' }}</a-tag>
</div>
</template>
<template v-if="column.key === 'status'">
<div class="status-cell">
<PlayCircleOutlined v-if="user.Info.Status" class="status-icon active" />
@@ -96,26 +102,22 @@
<template v-if="column.key === 'lastRun'">
<div class="last-run-cell">
<div class="run-item">
<span class="run-label">剿灭:</span>
<span class="run-date">{{ user.Data.LastAnnihilationDate }}</span>
</div>
<div class="run-item">
<span class="run-label">代理:</span>
<span class="run-date">{{ user.Data.LastProxyDate }}</span>
<div v-if="!user.Data.LastAnnihilationDate && !user.Data.LastProxyDate" class="no-run-text">
尚未运行
</div>
<template v-else>
<div class="run-item" v-if="user.Data.LastAnnihilationDate">
<span class="run-label">剿灭:</span>
<span class="run-date">{{ user.Data.LastAnnihilationDate }}</span>
</div>
<div class="run-item" v-if="user.Data.LastProxyDate">
<span class="run-label">代理:</span>
<span class="run-date">{{ user.Data.LastProxyDate }}</span>
</div>
</template>
</div>
</template>
<template v-if="column.key === 'tasks'">
<a-space wrap class="task-tags">
<a-tag v-if="user.Task.IfBase" color="blue" class="task-tag">基建</a-tag>
<a-tag v-if="user.Task.IfCombat" color="green" class="task-tag">作战</a-tag>
<a-tag v-if="user.Task.IfMall" color="orange" class="task-tag">商店</a-tag>
<a-tag v-if="user.Task.IfMission" color="purple" class="task-tag">任务</a-tag>
<a-tag v-if="user.Task.IfRecruiting" color="cyan" class="task-tag">招募</a-tag>
</a-space>
</template>
<template v-if="column.key === 'userAction'">
<a-space size="small">
@@ -160,7 +162,7 @@
<script setup lang="ts">
import { computed } from 'vue'
import type { TableColumnsType } from 'ant-design-vue'
import type { Script, User } from '@/types/script'
import type { Script, User } from '../types/script'
import {
DeleteOutlined,
EditOutlined,
@@ -195,13 +197,13 @@ const columns: TableColumnsType = [
key: 'name',
width: 300,
},
// {
// title: '用户数量',
// dataIndex: 'userCount',
// key: 'userCount',
// width: 120,
// align: 'center',
// },
{
title: '用户数量',
dataIndex: 'userCount',
key: 'userCount',
width: 120,
align: 'center',
},
// {
// title: '创建时间',
// dataIndex: 'createTime',
@@ -246,16 +248,11 @@ const userColumns: TableColumnsType = [
key: 'lastRun',
width: 200,
},
{
title: '启用任务',
key: 'tasks',
width: 300,
},
{
title: '备注',
dataIndex: ['Info', 'Notes'],
key: 'notes',
width: 150,
width: 250,
},
{
title: '操作',
@@ -267,7 +264,7 @@ const userColumns: TableColumnsType = [
const expandableConfig = computed(() => ({
expandedRowRender: true,
rowExpandable: (record: Script) => record.users.length > 0,
rowExpandable: (record: Script) => record.users && record.users.length > 0,
}))
const handleEdit = (script: Script) => {
@@ -481,6 +478,14 @@ const handleDeleteUser = (user: User) => {
font-family: 'Consolas', 'Monaco', monospace;
}
.no-run-text {
color: var(--ant-color-text-tertiary);
font-size: 12px;
font-style: italic;
text-align: center;
padding: 8px 0;
}
/* 任务标签 */
.task-tags {
max-width: 300px;

View File

@@ -1,51 +1,35 @@
import { ref } from 'vue'
import { message } from 'ant-design-vue'
import type {
ScriptType,
AddScriptResponse,
MAAScriptConfig,
GeneralScriptConfig,
GetScriptsResponse,
ScriptDetail,
ScriptIndexItem,
DeleteScriptResponse,
UpdateScriptResponse
} from '../types/script.ts'
const API_BASE_URL = 'http://localhost:8000/api'
import { Service, ScriptCreateIn } from '@/api'
import type { ScriptDetail, ScriptType } from '@/types/script'
export function useScriptApi() {
const loading = ref(false)
const error = ref<string | null>(null)
// 添加脚本
const addScript = async (type: ScriptType): Promise<AddScriptResponse | null> => {
const addScript = async (type: ScriptType) => {
loading.value = true
error.value = null
try {
const response = await fetch(`${API_BASE_URL}/add/scripts`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ type }),
})
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
const requestData: ScriptCreateIn = {
type: type === 'MAA' ? ScriptCreateIn.type.MAA : ScriptCreateIn.type.GENERAL
}
const data: AddScriptResponse = await response.json()
const response = await Service.addScriptApiScriptsAddPost(requestData)
// 检查API响应的code字段
if (data.code !== 200) {
const errorMsg = data.message || '添加脚本失败'
if (response.code !== 200) {
const errorMsg = response.message || '添加脚本失败'
message.error(errorMsg)
throw new Error(errorMsg)
}
return data
return {
scriptId: response.scriptId,
message: response.message || '脚本添加成功',
data: response.data
}
} catch (err) {
const errorMsg = err instanceof Error ? err.message : '添加脚本失败'
error.value = errorMsg
@@ -58,51 +42,35 @@ export function useScriptApi() {
}
}
// 获取所有脚本
// 获取脚本列表
const getScripts = async (): Promise<ScriptDetail[]> => {
loading.value = true
error.value = null
try {
const response = await fetch(`${API_BASE_URL}/scripts/get`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({}), // 传空对象获取全部脚本
})
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
const response = await Service.getScriptsApiScriptsGetPost({})
if (response.code !== 200) {
const errorMsg = response.message || '获取脚本列表失败'
message.error(errorMsg)
throw new Error(errorMsg)
}
const apiResponse: GetScriptsResponse = await response.json()
// 将API响应转换为ScriptDetail数组
const scriptDetails: ScriptDetail[] = response.index.map(indexItem => ({
uid: indexItem.uid,
type: indexItem.type === 'MaaConfig' ? 'MAA' : 'General',
name: response.data[indexItem.uid]?.Info?.Name || `${indexItem.type}脚本`,
config: response.data[indexItem.uid],
}))
// 转换API响应为前端需要的格式
const scripts: ScriptDetail[] = apiResponse.index.map((item: ScriptIndexItem) => {
const config = apiResponse.data[item.uid]
const scriptType: ScriptType = item.type === 'MaaConfig' ? 'MAA' : 'General'
// 从配置中获取脚本名称
let name = ''
if (scriptType === 'MAA') {
name = (config as MAAScriptConfig).Info.Name || '未命名MAA脚本'
} else {
name = (config as GeneralScriptConfig).Info.Name || '未命名General脚本'
}
return {
uid: item.uid,
type: scriptType,
name,
config,
createTime: new Date().toLocaleString() // 暂时使用当前时间后续可从API获取
}
})
return scripts
return scriptDetails
} catch (err) {
error.value = err instanceof Error ? err.message : '获取脚本列表失败'
const errorMsg = err instanceof Error ? err.message : '获取脚本列表失败'
error.value = errorMsg
if (!err.message?.includes('HTTP error')) {
message.error(errorMsg)
}
return []
} finally {
loading.value = false
@@ -115,93 +83,37 @@ export function useScriptApi() {
error.value = null
try {
const response = await fetch(`${API_BASE_URL}/scripts/get`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ scriptId }), // 传scriptId获取单个脚本
})
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}
const apiResponse: GetScriptsResponse = await response.json()
// 检查是否有数据返回
if (apiResponse.index.length === 0) {
throw new Error('脚本不存在')
}
const item = apiResponse.index[0]
const config = apiResponse.data[item.uid]
const scriptType: ScriptType = item.type === 'MaaConfig' ? 'MAA' : 'General'
// 从配置中获取脚本名称
let name = ''
if (scriptType === 'MAA') {
name = (config as MAAScriptConfig).Info.Name || '未命名MAA脚本'
} else {
name = (config as GeneralScriptConfig).Info.Name || '未命名General脚本'
}
return {
uid: item.uid,
type: scriptType,
name,
config,
createTime: new Date().toLocaleString() // 暂时使用当前时间后续可从API获取
}
} catch (err) {
error.value = err instanceof Error ? err.message : '获取脚本详情失败'
return null
} finally {
loading.value = false
}
}
// 更新脚本
const updateScript = async (scriptId: string, data: MAAScriptConfig | GeneralScriptConfig): Promise<boolean> => {
loading.value = true
error.value = null
try {
// 创建数据副本并移除 SubConfigsInfo 字段
const { SubConfigsInfo, ...dataToSend } = data
const response = await fetch(`${API_BASE_URL}/scripts/update`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ scriptId, data: dataToSend }),
})
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}
const apiResponse: UpdateScriptResponse = await response.json()
const response = await Service.getScriptsApiScriptsGetPost({ scriptId })
// 根据code判断是否成功非200就是不成功
if (apiResponse.code !== 200) {
const errorMsg = apiResponse.message || '更新脚本失败'
if (response.code !== 200) {
const errorMsg = response.message || '获取脚本详情失败'
message.error(errorMsg)
throw new Error(errorMsg)
}
return true
// 检查是否有数据返回
if (response.index.length === 0) {
throw new Error('脚本不存在')
}
const item = response.index[0]
const config = response.data[item.uid]
const scriptType: ScriptType = item.type === 'MaaConfig' ? 'MAA' : 'General'
return {
uid: item.uid,
type: scriptType,
name: config?.Info?.Name || `${item.type}脚本`,
config,
createTime: new Date().toLocaleString()
}
} catch (err) {
const errorMsg = err instanceof Error ? err.message : '更新脚本失败'
const errorMsg = err instanceof Error ? err.message : '获取脚本详情失败'
error.value = errorMsg
// 如果错误不是来自API响应即没有显示过message.error则显示错误消息
if (err instanceof Error && !err.message.includes('HTTP error')) {
// API响应错误已经在上面显示了这里只处理其他错误
} else {
if (!err.message?.includes('HTTP error')) {
message.error(errorMsg)
}
return false
return null
} finally {
loading.value = false
}
@@ -213,28 +125,55 @@ export function useScriptApi() {
error.value = null
try {
const response = await fetch(`${API_BASE_URL}/scripts/delete`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ scriptId }),
})
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}
const apiResponse: DeleteScriptResponse = await response.json()
const response = await Service.deleteScriptApiScriptsDeletePost({ scriptId })
// 根据code判断是否成功非200就是不成功
if (apiResponse.code !== 200) {
throw new Error(apiResponse.message || '删除脚本失败')
if (response.code !== 200) {
const errorMsg = response.message || '删除脚本失败'
message.error(errorMsg)
throw new Error(errorMsg)
}
return true
} catch (err) {
error.value = err instanceof Error ? err.message : '删除脚本失败'
const errorMsg = err instanceof Error ? err.message : '删除脚本失败'
error.value = errorMsg
if (!err.message?.includes('HTTP error')) {
message.error(errorMsg)
}
return false
} finally {
loading.value = false
}
}
// 更新脚本
const updateScript = async (scriptId: string, data: any): Promise<boolean> => {
loading.value = true
error.value = null
try {
// 创建数据副本并移除 SubConfigsInfo 字段
const { SubConfigsInfo, ...dataToSend } = data
const response = await Service.updateScriptApiScriptsUpdatePost({
scriptId,
data: dataToSend
})
if (response.code !== 200) {
const errorMsg = response.message || '更新脚本失败'
message.error(errorMsg)
throw new Error(errorMsg)
}
message.success(response.message || '脚本更新成功')
return true
} catch (err) {
const errorMsg = err instanceof Error ? err.message : '更新脚本失败'
error.value = errorMsg
if (!err.message?.includes('HTTP error')) {
message.error(errorMsg)
}
return false
} finally {
loading.value = false
@@ -247,7 +186,7 @@ export function useScriptApi() {
addScript,
getScripts,
getScript,
updateScript,
deleteScript,
updateScript,
}
}

View File

@@ -1,8 +1,7 @@
import { ref } from 'vue'
import { message } from 'ant-design-vue'
import type { SettingsData, GetSettingsResponse, UpdateSettingsResponse } from '../types/settings.ts'
const API_BASE_URL = 'http://localhost:8000/api'
import { Service } from '@/api'
import type { SettingsData } from '@/types/script'
export function useSettingsApi() {
const loading = ref(false)
@@ -14,28 +13,16 @@ export function useSettingsApi() {
error.value = null
try {
const response = await fetch(`${API_BASE_URL}/setting/get`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({}), // 空请求体
})
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}
const apiResponse: GetSettingsResponse = await response.json()
const response = await Service.getScriptsApiSettingGetPost()
// 根据code判断是否成功非200就是不成功
if (apiResponse.code !== 200) {
const errorMsg = apiResponse.message || '获取设置失败'
if (response.code !== 200) {
const errorMsg = response.message || '获取设置失败'
message.error(errorMsg)
throw new Error(errorMsg)
}
return apiResponse.data
return response.data as SettingsData
} catch (err) {
const errorMsg = err instanceof Error ? err.message : '获取设置失败'
error.value = errorMsg
@@ -54,30 +41,18 @@ export function useSettingsApi() {
error.value = null
try {
const response = await fetch(`${API_BASE_URL}/setting/update`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
data: settings,
}),
const response = await Service.updateScriptApiSettingUpdatePost({
data: settings
})
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}
const apiResponse: UpdateSettingsResponse = await response.json()
// 根据code判断是否成功非200就是不成功
if (apiResponse.code !== 200) {
const errorMsg = apiResponse.message || '设置修改失败'
if (response.code !== 200) {
const errorMsg = response.message || '设置修改失败'
message.error(errorMsg)
throw new Error(errorMsg)
}
// message.success(apiResponse.message || '设置修改成功')
message.success(response.message || '设置修改成功')
return true
} catch (err) {
const errorMsg = err instanceof Error ? err.message : '设置修改失败'
@@ -97,4 +72,4 @@ export function useSettingsApi() {
getSettings,
updateSettings,
}
}
}

View File

@@ -1,8 +1,12 @@
import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index.ts'
import { OpenAPI } from '@/api'
import Antd from 'ant-design-vue'
import 'ant-design-vue/dist/reset.css'
// 配置API基础URL
OpenAPI.BASE = 'http://localhost:8000'
createApp(App).use(Antd).use(router).mount('#app')

View File

@@ -24,6 +24,18 @@ const routes: RouteRecordRaw[] = [
component: () => import('../views/ScriptEdit.vue'),
meta: { title: '编辑脚本' },
},
{
path: '/scripts/:scriptId/users/add',
name: 'UserAdd',
component: () => import('../views/UserEdit.vue'),
meta: { title: '添加用户' },
},
{
path: '/scripts/:scriptId/users/:userId/edit',
name: 'UserEdit',
component: () => import('../views/UserEdit.vue'),
meta: { title: '编辑用户' },
},
{
path: '/plans',
name: 'Plans',
@@ -54,12 +66,6 @@ const routes: RouteRecordRaw[] = [
component: () => import('../views/Settings.vue'),
meta: { title: '设置' },
},
{
path: '/test',
name: 'Test',
component: () => import('../views/TestScript.vue'),
meta: { title: '测试' },
},
]
const router = createRouter({

View File

@@ -23,7 +23,7 @@ export interface MAAScriptConfig {
}
}
// General脚本配置
// 通用脚本配置
export interface GeneralScriptConfig {
Game: {
Arguments: string

View File

@@ -281,7 +281,7 @@
</div>
</template>
<!-- General脚本配置 -->
<!-- 通用脚本配置 -->
<template v-if="formData.type === 'General'">
<!-- 基础配置 -->
<div class="form-section">
@@ -931,12 +931,12 @@ const loadScript = async () => {
}
} else {
const config = scriptData.config as GeneralScriptConfig
formData.name = config.Info.Name || '新建General脚本'
formData.name = config.Info.Name || '新建通用脚本'
Object.assign(generalConfig, config)
// 如果名称为空,设置默认名称
if (!generalConfig.Info.Name) {
generalConfig.Info.Name = '新建General脚本'
formData.name = '新建General脚本'
generalConfig.Info.Name = '新建通用脚本'
formData.name = '新建通用脚本'
}
}
} else {
@@ -1119,7 +1119,7 @@ const selectLogPath = async () => {
}
const getCardTitle = () => {
return formData.type === 'MAA' ? 'MAA脚本配置' : 'General脚本配置'
return formData.type === 'MAA' ? 'MAA脚本配置' : '通用脚本配置'
}
</script>

View File

@@ -59,7 +59,7 @@
<img src="@/assets/AUTO_MAA.png" alt="AUTO MAA" class="type-logo" />
</div>
<div class="type-info">
<div class="type-title">General脚本</div>
<div class="type-title">通用脚本</div>
<div class="type-description">通用自动化脚本支持自定义游戏和脚本配置</div>
</div>
</div>
@@ -77,9 +77,11 @@ import { PlusOutlined, ReloadOutlined } from '@ant-design/icons-vue'
import ScriptTable from '@/components/ScriptTable.vue'
import type { Script, ScriptType, User } from '@/types/script'
import { useScriptApi } from '@/composables/useScriptApi'
import { useUserApi } from '@/composables/useUserApi'
const router = useRouter()
const { addScript, deleteScript, getScripts, loading } = useScriptApi()
const { addUser, updateUser, deleteUser, loading: userLoading } = useUserApi()
const scripts = ref<Script[]>([])
const typeSelectVisible = ref(false)
@@ -95,14 +97,105 @@ const loadScripts = async () => {
const scriptDetails = await getScripts()
// 将 ScriptDetail 转换为 Script 格式(为了兼容现有的表格组件)
scripts.value = scriptDetails.map(detail => ({
id: detail.uid,
type: detail.type,
name: detail.name,
config: detail.config,
users: [], // 暂时为空后续可以从其他API获取用户数据
createTime: detail.createTime || new Date().toLocaleString(),
}))
scripts.value = scriptDetails.map(detail => {
// 从配置中提取用户数据
const users: User[] = []
// 检查配置中是否有用户数据
if (detail.config && typeof detail.config === 'object') {
const config = detail.config as any
// 检查 SubConfigsInfo.UserData.instances
if (
config.SubConfigsInfo?.UserData?.instances &&
Array.isArray(config.SubConfigsInfo.UserData.instances)
) {
config.SubConfigsInfo.UserData.instances.forEach((instance: any, index: number) => {
if (instance && typeof instance === 'object' && instance.uid) {
// 从用户数据中获取实际的用户信息
const userData = config.SubConfigsInfo.UserData[instance.uid]
if (userData) {
// 创建用户对象,使用真实的用户数据
const user: User = {
id: instance.uid, // 使用真实的用户ID
name: userData.Info?.Name || `用户${index + 1}`,
Info: {
Name: userData.Info?.Name || `用户${index + 1}`,
Id: userData.Info?.Id || '',
Password: userData.Info?.Password || '',
Server: userData.Info?.Server || '官服',
MedicineNumb: userData.Info?.MedicineNumb || 0,
RemainedDay: userData.Info?.RemainedDay || 0,
SeriesNumb: userData.Info?.SeriesNumb || '',
Notes: userData.Info?.Notes || '',
Status: userData.Info?.Status !== undefined ? userData.Info.Status : true,
Mode: userData.Info?.Mode || 'MAA',
InfrastMode: userData.Info?.InfrastMode || '默认',
Routine: userData.Info?.Routine !== undefined ? userData.Info.Routine : true,
Annihilation: userData.Info?.Annihilation || '当期',
Stage: userData.Info?.Stage || '1-7',
StageMode: userData.Info?.StageMode || '刷完即停',
Stage_1: userData.Info?.Stage_1 || '',
Stage_2: userData.Info?.Stage_2 || '',
Stage_3: userData.Info?.Stage_3 || '',
Stage_Remain: userData.Info?.Stage_Remain || '',
IfSkland: userData.Info?.IfSkland || false,
SklandToken: userData.Info?.SklandToken || '',
},
Task: {
IfBase: userData.Task?.IfBase !== undefined ? userData.Task.IfBase : true,
IfCombat: userData.Task?.IfCombat !== undefined ? userData.Task.IfCombat : true,
IfMall: userData.Task?.IfMall !== undefined ? userData.Task.IfMall : true,
IfMission:
userData.Task?.IfMission !== undefined ? userData.Task.IfMission : true,
IfRecruiting:
userData.Task?.IfRecruiting !== undefined ? userData.Task.IfRecruiting : true,
IfReclamation: userData.Task?.IfReclamation || false,
IfAutoRoguelike: userData.Task?.IfAutoRoguelike || false,
IfWakeUp: userData.Task?.IfWakeUp || false,
},
Notify: {
Enabled: userData.Notify?.Enabled || false,
ToAddress: userData.Notify?.ToAddress || '',
IfSendMail: userData.Notify?.IfSendMail || false,
IfSendSixStar: userData.Notify?.IfSendSixStar || false,
IfSendStatistic: userData.Notify?.IfSendStatistic || false,
IfServerChan: userData.Notify?.IfServerChan || false,
IfCompanyWebHookBot: userData.Notify?.IfCompanyWebHookBot || false,
ServerChanKey: userData.Notify?.ServerChanKey || '',
ServerChanChannel: userData.Notify?.ServerChanChannel || '',
ServerChanTag: userData.Notify?.ServerChanTag || '',
CompanyWebHookBotUrl: userData.Notify?.CompanyWebHookBotUrl || '',
},
Data: {
CustomInfrastPlanIndex: userData.Data?.CustomInfrastPlanIndex || '',
IfPassCheck: userData.Data?.IfPassCheck || false,
LastAnnihilationDate: userData.Data?.LastAnnihilationDate || '',
LastProxyDate: userData.Data?.LastProxyDate || '',
LastSklandDate: userData.Data?.LastSklandDate || '',
ProxyTimes: userData.Data?.ProxyTimes || 0,
},
QFluentWidgets: {
ThemeColor: userData.QFluentWidgets?.ThemeColor || 'blue',
ThemeMode: userData.QFluentWidgets?.ThemeMode || 'system',
},
}
users.push(user)
}
}
})
}
}
return {
id: detail.uid,
type: detail.type,
name: detail.name,
config: detail.config,
users,
createTime: detail.createTime || new Date().toLocaleString(),
}
})
} catch (error) {
console.error('加载脚本列表失败:', error)
message.error('加载脚本列表失败')
@@ -154,18 +247,38 @@ const handleDeleteScript = async (script: Script) => {
}
const handleAddUser = (script: Script) => {
// TODO: 实现添加用户功能
message.info('添加用户功能待实现')
// 跳转到添加用户页面
router.push(`/scripts/${script.id}/users/add`)
}
const handleEditUser = (user: User) => {
// TODO: 实现编辑用户功能
message.info('编辑用户功能待实现')
// 从用户数据中找到对应的脚本
const script = scripts.value.find(s => s.users.some(u => u.id === user.id))
if (script) {
// 跳转到编辑用户页面
router.push(`/scripts/${script.id}/users/${user.id}/edit`)
} else {
message.error('找不到对应的脚本')
}
}
const handleDeleteUser = (user: User) => {
// TODO: 实现删除用户功能
message.info('删除用户功能待实现')
const handleDeleteUser = async (user: User) => {
// 从用户数据中找到对应的脚本
const script = scripts.value.find(s => s.users.some(u => u.id === user.id))
if (!script) {
message.error('找不到对应的脚本')
return
}
const result = await deleteUser(script.id, user.id)
if (result) {
// 删除成功后,从本地数据中移除用户
const userIndex = script.users.findIndex(u => u.id === user.id)
if (userIndex > -1) {
script.users.splice(userIndex, 1)
}
message.success('用户删除成功')
}
}
const handleRefresh = () => {

View File

@@ -1,90 +0,0 @@
<template>
<div style="padding: 20px;">
<h2>脚本API测试</h2>
<a-space>
<a-button type="primary" @click="testAddMAA" :loading="loading">
测试添加MAA脚本
</a-button>
<a-button type="primary" @click="testAddGeneral" :loading="loading">
测试添加General脚本
</a-button>
<a-button @click="goToScripts">
前往脚本管理页面
</a-button>
</a-space>
<div v-if="result" style="margin-top: 20px;">
<h3>API响应结果</h3>
<pre>{{ JSON.stringify(result, null, 2) }}</pre>
<a-space style="margin-top: 10px;">
<a-button type="primary" @click="goToEdit">
前往编辑页面
</a-button>
</a-space>
</div>
<div v-if="error" style="margin-top: 20px; color: red;">
<h3>错误信息</h3>
<p>{{ error }}</p>
</div>
<div style="margin-top: 30px;">
<h3>测试说明</h3>
<ul>
<li>点击"测试添加MAA脚本""测试添加General脚本"来测试API调用</li>
<li>成功后会显示API返回的数据包含scriptId和配置信息</li>
<li>点击"前往编辑页面"可以跳转到编辑页面查看配置</li>
<li>或者直接前往脚本管理页面测试完整流程</li>
</ul>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { useScriptApi } from '@/composables/useScriptApi'
const router = useRouter()
const { addScript, loading, error } = useScriptApi()
const result = ref<any>(null)
const lastScriptType = ref<'MAA' | 'General'>('MAA')
const testAddMAA = async () => {
result.value = null
lastScriptType.value = 'MAA'
const response = await addScript('MAA')
if (response) {
result.value = response
}
}
const testAddGeneral = async () => {
result.value = null
lastScriptType.value = 'General'
const response = await addScript('General')
if (response) {
result.value = response
}
}
const goToEdit = () => {
if (result.value) {
router.push({
path: `/scripts/${result.value.scriptId}/edit`,
state: {
scriptData: {
id: result.value.scriptId,
type: lastScriptType.value,
config: result.value.data
}
}
})
}
}
const goToScripts = () => {
router.push('/scripts')
}
</script>

File diff suppressed because it is too large Load Diff