Merge remote-tracking branch 'origin/feature/refactor' into feature/refactor

This commit is contained in:
MoeSnowyFox
2025-08-13 23:38:42 +08:00
354 changed files with 1447 additions and 227 deletions

View File

@@ -1,6 +1,7 @@
import * as https from 'https'
import * as fs from 'fs'
import { BrowserWindow } from 'electron'
import * as http from 'http'
let mainWindow: BrowserWindow | null = null
@@ -8,51 +9,55 @@ export function setMainWindow(window: BrowserWindow) {
mainWindow = window
}
// 下载文件的通用函数
export function downloadFile(url: string, outputPath: string): Promise<void> {
return new Promise((resolve, reject) => {
console.log(`开始下载文件: ${url}`)
console.log(`保存路径: ${outputPath}`)
const file = fs.createWriteStream(outputPath)
https.get(url, (response) => {
const totalSize = parseInt(response.headers['content-length'] || '0', 10)
let downloadedSize = 0
// 创建HTTP客户端兼容https和http
const client = url.startsWith('https') ? https : http
console.log(`文件大小: ${totalSize} bytes`)
response.pipe(file)
client
.get(url, response => {
const totalSize = parseInt(response.headers['content-length'] || '0', 10)
let downloadedSize = 0
response.on('data', (chunk) => {
downloadedSize += chunk.length
const progress = Math.round((downloadedSize / totalSize) * 100)
console.log(`下载进度: ${progress}% (${downloadedSize}/${totalSize})`)
if (mainWindow) {
mainWindow.webContents.send('download-progress', {
progress,
status: 'downloading',
message: `下载中... ${progress}%`
})
}
console.log(`文件大小: ${totalSize} bytes`)
response.pipe(file)
response.on('data', chunk => {
downloadedSize += chunk.length
const progress = totalSize ? Math.round((downloadedSize / totalSize) * 100) : 0
console.log(`下载进度: ${progress}% (${downloadedSize}/${totalSize})`)
if (mainWindow) {
mainWindow.webContents.send('download-progress', {
progress,
status: 'downloading',
message: `下载中... ${progress}%`,
})
}
})
file.on('finish', () => {
file.close()
console.log(`文件下载完成: ${outputPath}`)
resolve()
})
file.on('error', err => {
console.error(`文件写入错误: ${err.message}`)
fs.unlink(outputPath, () => {}) // 删除不完整的文件
reject(err)
})
})
file.on('finish', () => {
file.close()
console.log(`文件下载完成: ${outputPath}`)
resolve()
})
file.on('error', (err) => {
console.error(`文件写入错误: ${err.message}`)
fs.unlink(outputPath, () => {}) // 删除不完整的文件
.on('error', err => {
console.error(`下载错误: ${err.message}`)
reject(err)
})
}).on('error', (err) => {
console.error(`下载错误: ${err.message}`)
reject(err)
})
})
}
}

View File

@@ -11,7 +11,7 @@ export function setMainWindow(window: BrowserWindow) {
mainWindow = window
}
const gitDownloadUrl = 'https://alist-automaa.fearr.xyz/d/AUTO_MAA/git.zip'
const gitDownloadUrl = 'http://221.236.27.82:10197/d/AUTO_MAA/git.zip'
// 递归复制目录,包括文件和隐藏文件
function copyDirSync(src: string, dest: string) {

View File

@@ -64,7 +64,7 @@ async function installPip(pythonPath: string, appRoot: string): Promise<void> {
console.log('pip未安装开始安装...')
const getPipPath = path.join(pythonPath, 'get-pip.py')
const getPipUrl = 'https://alist-automaa.fearr.xyz/d/AUTO_MAA/get-pip.py'
const getPipUrl = 'http://221.236.27.82:10197/d/AUTO_MAA/get-pip.py'
console.log(`Python可执行文件路径: ${pythonExe}`)
console.log(`get-pip.py下载URL: ${getPipUrl}`)
@@ -203,7 +203,7 @@ export async function downloadPython(appRoot: string, mirror = 'ustc'): Promise<
// Python 3.12.0嵌入式版本应该大约30MB如果小于5MB可能是无效文件
if (stats.size < 5 * 1024 * 1024) { // 5MB
fs.unlinkSync(zipPath) // 删除无效文件
throw new Error(`Python下载文件大小异常: ${stats.size} bytes (${(stats.size / 1024).toFixed(2)} KB),可能是镜像站返回的错误页面或无效文件`)
throw new Error(`Python下载文件大小异常: ${stats.size} bytes (${(stats.size / 1024).toFixed(2)} KB),可能是镜像站返回的错误页面或无效文件。请选择一个其他可用镜像源进行下载!`)
}
if (mainWindow) {

View File

@@ -10,6 +10,7 @@ export type { OpenAPIConfig } from './core/OpenAPI';
export type { ComboBoxItem } from './models/ComboBoxItem';
export type { ComboBoxOut } from './models/ComboBoxOut';
export type { DispatchIn } from './models/DispatchIn';
export { GetStageIn } from './models/GetStageIn';
export type { GlobalConfig } from './models/GlobalConfig';
export type { GlobalConfig_Function } from './models/GlobalConfig_Function';
export type { GlobalConfig_Notify } from './models/GlobalConfig_Notify';

100
frontend/src/api/mirrors.ts Normal file
View File

@@ -0,0 +1,100 @@
/**
* 镜像源 API 接口
* 用于从后端获取最新的镜像源配置
*/
import { OpenAPI } from '@/api'
import type { MirrorConfig } from '@/config/mirrors'
export interface MirrorApiResponse {
git?: MirrorConfig[]
python?: MirrorConfig[]
pip?: MirrorConfig[]
apiEndpoints?: {
local?: string
production?: string
proxy?: string
}
downloadLinks?: {
[category: string]: {
[key: string]: string
}
}
}
/**
* 获取镜像源配置
*/
export async function fetchMirrorConfig(): Promise<MirrorApiResponse> {
try {
const response = await fetch(`${OpenAPI.BASE}/api/mirrors`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
})
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}
return await response.json()
} catch (error) {
console.warn('获取镜像源配置失败,使用默认配置:', error)
throw error
}
}
/**
* 测试镜像源连通性
*/
export async function testMirrorConnectivity(url: string, timeout: number = 5000): Promise<{
success: boolean
speed: number
error?: string
}> {
try {
const startTime = Date.now()
const controller = new AbortController()
const timeoutId = setTimeout(() => controller.abort(), timeout)
const response = await fetch(url, {
method: 'HEAD',
signal: controller.signal,
cache: 'no-cache',
mode: 'no-cors' // 避免 CORS 问题
})
clearTimeout(timeoutId)
const speed = Date.now() - startTime
return {
success: true,
speed
}
} catch (error) {
return {
success: false,
speed: 9999,
error: error instanceof Error ? error.message : String(error)
}
}
}
/**
* 批量测试镜像源
*/
export async function batchTestMirrors(mirrors: MirrorConfig[]): Promise<MirrorConfig[]> {
const promises = mirrors.map(async (mirror) => {
const result = await testMirrorConnectivity(mirror.url)
return {
...mirror,
speed: result.speed
}
})
const results = await Promise.all(promises)
// 按速度排序
return results.sort((a, b) => (a.speed || 9999) - (b.speed || 9999))
}

View File

@@ -10,6 +10,6 @@ export type ComboBoxItem = {
/**
* 实际值
*/
value: string;
value: (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 GetStageIn = {
/**
* 选择的日期类型, Today为当天, ALL为包含当天未开放关卡在内的所有项
*/
type: GetStageIn.type;
};
export namespace GetStageIn {
/**
* 选择的日期类型, Today为当天, ALL为包含当天未开放关卡在内的所有项
*/
export enum type {
TODAY = 'Today',
ALL = 'ALL',
MONDAY = 'Monday',
TUESDAY = 'Tuesday',
WEDNESDAY = 'Wednesday',
THURSDAY = 'Thursday',
FRIDAY = 'Friday',
SATURDAY = 'Saturday',
SUNDAY = 'Sunday',
}
}

View File

@@ -18,6 +18,6 @@ export type TaskCreateOut = {
/**
* 新创建的任务ID
*/
taskId: string;
websocketId: string;
};

View File

@@ -4,6 +4,7 @@
/* eslint-disable */
import type { ComboBoxOut } from '../models/ComboBoxOut';
import type { DispatchIn } from '../models/DispatchIn';
import type { GetStageIn } from '../models/GetStageIn';
import type { InfoOut } from '../models/InfoOut';
import type { OutBase } from '../models/OutBase';
import type { PlanCreateIn } from '../models/PlanCreateIn';
@@ -49,14 +50,22 @@ import { OpenAPI } from '../core/OpenAPI';
import { request as __request } from '../core/request';
export class Service {
/**
* 获取关卡号信息
* @returns InfoOut Successful Response
* 获取关卡号下拉框信息
* @param requestBody
* @returns ComboBoxOut Successful Response
* @throws ApiError
*/
public static getStageInfoApiInfoStagePost(): CancelablePromise<InfoOut> {
public static getStageComboxApiInfoComboxStagePost(
requestBody: GetStageIn,
): CancelablePromise<ComboBoxOut> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/info/stage',
url: '/api/info/combox/stage',
body: requestBody,
mediaType: 'application/json',
errors: {
422: `Validation Error`,
},
});
}
/**
@@ -70,6 +79,17 @@ export class Service {
url: '/api/info/combox/script',
});
}
/**
* 获取可选任务下拉框信息
* @returns ComboBoxOut Successful Response
* @throws ApiError
*/
public static getTaskComboxApiInfoComboxTaskPost(): CancelablePromise<ComboBoxOut> {
return __request(OpenAPI, {
method: 'POST',
url: '/api/info/combox/task',
});
}
/**
* 获取通知信息
* @returns InfoOut Successful Response

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Some files were not shown because too many files have changed in this diff Show More