style:格式化代码

This commit is contained in:
2025-08-15 14:21:16 +08:00
parent 9f849608db
commit a738f102a6
40 changed files with 1144 additions and 922 deletions

View File

@@ -18,7 +18,6 @@ export function downloadFile(url: string, outputPath: string): Promise<void> {
// 创建HTTP客户端兼容https和http
const client = url.startsWith('https') ? https : http
client
.get(url, response => {
const totalSize = parseInt(response.headers['content-length'] || '0', 10)

View File

@@ -4,9 +4,7 @@ import { app } from 'electron'
// 获取应用根目录
export function getAppRoot(): string {
return process.env.NODE_ENV === 'development'
? process.cwd()
: path.dirname(app.getPath('exe'))
return process.env.NODE_ENV === 'development' ? process.cwd() : path.dirname(app.getPath('exe'))
}
// 检查环境
@@ -20,16 +18,17 @@ export function checkEnvironment(appRoot: string) {
const pythonExists = fs.existsSync(pythonPath)
const gitExists = fs.existsSync(gitPath)
const backendExists = fs.existsSync(backendPath)
// 检查依赖是否已安装简单检查是否存在site-packages目录
const sitePackagesPath = path.join(pythonPath, 'Lib', 'site-packages')
const dependenciesInstalled = fs.existsSync(sitePackagesPath) && fs.readdirSync(sitePackagesPath).length > 10
const dependenciesInstalled =
fs.existsSync(sitePackagesPath) && fs.readdirSync(sitePackagesPath).length > 10
return {
pythonExists,
gitExists,
backendExists,
dependenciesInstalled,
isInitialized: pythonExists && gitExists && backendExists && dependenciesInstalled
isInitialized: pythonExists && gitExists && backendExists && dependenciesInstalled,
}
}
}

View File

@@ -31,7 +31,6 @@ function copyDirSync(src: string, dest: string) {
}
}
// 获取Git环境变量配置
function getGitEnvironment(appRoot: string) {
const gitDir = path.join(appRoot, 'environment', 'git')
@@ -249,11 +248,26 @@ export async function cloneBackend(
})
}
await new Promise<void>((resolve, reject) => {
const proc = spawn(gitPath, ['clone', '--progress', '--verbose','--single-branch','--depth','1','--branch', 'feature/refactor-backend', repoUrl, tmpDir], {
stdio: 'pipe',
env: gitEnv,
cwd: appRoot,
})
const proc = spawn(
gitPath,
[
'clone',
'--progress',
'--verbose',
'--single-branch',
'--depth',
'1',
'--branch',
'feature/refactor-backend',
repoUrl,
tmpDir,
],
{
stdio: 'pipe',
env: gitEnv,
cwd: appRoot,
}
)
proc.stdout?.on('data', d => console.log('git clone:', d.toString()))
proc.stderr?.on('data', d => console.log('git clone err:', d.toString()))
proc.on('close', code =>

View File

@@ -16,8 +16,9 @@ const pythonMirrorUrls = {
official: 'https://www.python.org/ftp/python/3.12.0/python-3.12.0-embed-amd64.zip',
tsinghua: 'https://mirrors.tuna.tsinghua.edu.cn/python/3.12.0/python-3.12.0-embed-amd64.zip',
ustc: 'https://mirrors.ustc.edu.cn/python/3.12.0/python-3.12.0-embed-amd64.zip',
huawei: 'https://mirrors.huaweicloud.com/repository/toolkit/python/3.12.0/python-3.12.0-embed-amd64.zip',
aliyun: 'https://mirrors.aliyun.com/python-release/windows/python-3.12.0-embed-amd64.zip'
huawei:
'https://mirrors.huaweicloud.com/repository/toolkit/python/3.12.0/python-3.12.0-embed-amd64.zip',
aliyun: 'https://mirrors.aliyun.com/python-release/windows/python-3.12.0-embed-amd64.zip',
}
// 检查pip是否已安装
@@ -25,20 +26,20 @@ function isPipInstalled(pythonPath: string): boolean {
const scriptsPath = path.join(pythonPath, 'Scripts')
const pipExePath = path.join(scriptsPath, 'pip.exe')
const pip3ExePath = path.join(scriptsPath, 'pip3.exe')
console.log(`检查pip安装状态:`)
console.log(`Scripts目录: ${scriptsPath}`)
console.log(`pip.exe路径: ${pipExePath}`)
console.log(`pip3.exe路径: ${pip3ExePath}`)
const scriptsExists = fs.existsSync(scriptsPath)
const pipExists = fs.existsSync(pipExePath)
const pip3Exists = fs.existsSync(pip3ExePath)
console.log(`Scripts目录存在: ${scriptsExists}`)
console.log(`pip.exe存在: ${pipExists}`)
console.log(`pip3.exe存在: ${pip3Exists}`)
return scriptsExists && (pipExists || pip3Exists)
}
@@ -62,7 +63,7 @@ async function installPip(pythonPath: string, appRoot: string): Promise<void> {
}
console.log('pip未安装开始安装...')
const getPipPath = path.join(pythonPath, 'get-pip.py')
const getPipUrl = 'http://221.236.27.82:10197/d/AUTO_MAA/get-pip.py'
@@ -75,12 +76,13 @@ async function installPip(pythonPath: string, appRoot: string): Promise<void> {
try {
await downloadFile(getPipUrl, getPipPath)
console.log('get-pip.py下载完成')
// 检查下载的文件大小
const stats = fs.statSync(getPipPath)
console.log(`get-pip.py文件大小: ${stats.size} bytes`)
if (stats.size < 10000) { // 如果文件小于10KB可能是无效文件
if (stats.size < 10000) {
// 如果文件小于10KB可能是无效文件
throw new Error(`get-pip.py文件大小异常: ${stats.size} bytes可能下载失败`)
}
} catch (error) {
@@ -94,20 +96,20 @@ async function installPip(pythonPath: string, appRoot: string): Promise<void> {
const process = spawn(pythonExe, [getPipPath], {
cwd: pythonPath,
stdio: 'pipe'
stdio: 'pipe',
})
process.stdout?.on('data', (data) => {
process.stdout?.on('data', data => {
const output = data.toString()
console.log('pip安装输出:', output)
})
process.stderr?.on('data', (data) => {
process.stderr?.on('data', data => {
const errorOutput = data.toString()
console.log('pip安装错误输出:', errorOutput)
})
process.on('close', (code) => {
process.on('close', code => {
console.log(`pip安装完成退出码: ${code}`)
if (code === 0) {
console.log('pip安装成功')
@@ -117,7 +119,7 @@ async function installPip(pythonPath: string, appRoot: string): Promise<void> {
}
})
process.on('error', (error) => {
process.on('error', error => {
console.error('pip安装进程错误:', error)
reject(error)
})
@@ -128,20 +130,20 @@ async function installPip(pythonPath: string, appRoot: string): Promise<void> {
await new Promise<void>((resolve, reject) => {
const verifyProcess = spawn(pythonExe, ['-m', 'pip', '--version'], {
cwd: pythonPath,
stdio: 'pipe'
stdio: 'pipe',
})
verifyProcess.stdout?.on('data', (data) => {
verifyProcess.stdout?.on('data', data => {
const output = data.toString()
console.log('pip版本信息:', output)
})
verifyProcess.stderr?.on('data', (data) => {
verifyProcess.stderr?.on('data', data => {
const errorOutput = data.toString()
console.log('pip版本检查错误:', errorOutput)
})
verifyProcess.on('close', (code) => {
verifyProcess.on('close', code => {
if (code === 0) {
console.log('pip验证成功')
resolve()
@@ -150,7 +152,7 @@ async function installPip(pythonPath: string, appRoot: string): Promise<void> {
}
})
verifyProcess.on('error', (error) => {
verifyProcess.on('error', error => {
console.error('pip验证进程错误:', error)
reject(error)
})
@@ -171,11 +173,14 @@ async function installPip(pythonPath: string, appRoot: string): Promise<void> {
}
// 下载Python
export async function downloadPython(appRoot: string, mirror = 'ustc'): Promise<{ success: boolean; error?: string }> {
export async function downloadPython(
appRoot: string,
mirror = 'ustc'
): Promise<{ success: boolean; error?: string }> {
try {
const environmentPath = path.join(appRoot, 'environment')
const pythonPath = path.join(environmentPath, 'python')
// 确保environment目录存在
if (!fs.existsSync(environmentPath)) {
fs.mkdirSync(environmentPath, { recursive: true })
@@ -186,24 +191,30 @@ export async function downloadPython(appRoot: string, mirror = 'ustc'): Promise<
type: 'python',
progress: 0,
status: 'downloading',
message: '开始下载Python...'
message: '开始下载Python...',
})
}
// 根据选择的镜像源获取下载链接
const pythonUrl = pythonMirrorUrls[mirror as keyof typeof pythonMirrorUrls] || pythonMirrorUrls.ustc
const pythonUrl =
pythonMirrorUrls[mirror as keyof typeof pythonMirrorUrls] || pythonMirrorUrls.ustc
const zipPath = path.join(environmentPath, 'python.zip')
await downloadFile(pythonUrl, zipPath)
// 检查下载的Python文件大小
const stats = fs.statSync(zipPath)
console.log(`Python压缩包大小: ${stats.size} bytes (${(stats.size / 1024 / 1024).toFixed(2)} MB)`)
console.log(
`Python压缩包大小: ${stats.size} bytes (${(stats.size / 1024 / 1024).toFixed(2)} MB)`
)
// Python 3.12.0嵌入式版本应该大约30MB如果小于5MB可能是无效文件
if (stats.size < 5 * 1024 * 1024) { // 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) {
@@ -211,19 +222,19 @@ export async function downloadPython(appRoot: string, mirror = 'ustc'): Promise<
type: 'python',
progress: 100,
status: 'extracting',
message: '正在解压Python...'
message: '正在解压Python...',
})
}
// 解压Python到指定目录
console.log(`开始解压Python到: ${pythonPath}`)
// 确保Python目录存在
if (!fs.existsSync(pythonPath)) {
fs.mkdirSync(pythonPath, { recursive: true })
console.log(`创建Python目录: ${pythonPath}`)
}
const zip = new AdmZip(zipPath)
zip.extractAllTo(pythonPath, true)
console.log(`Python解压完成到: ${pythonPath}`)
@@ -241,14 +252,13 @@ export async function downloadPython(appRoot: string, mirror = 'ustc'): Promise<
console.log('已启用 site-packages 支持')
}
// 安装pip
if (mainWindow) {
mainWindow.webContents.send('download-progress', {
type: 'python',
progress: 80,
status: 'installing',
message: '正在安装pip...'
message: '正在安装pip...',
})
}
@@ -259,7 +269,7 @@ export async function downloadPython(appRoot: string, mirror = 'ustc'): Promise<
type: 'python',
progress: 100,
status: 'completed',
message: 'Python和pip安装完成'
message: 'Python和pip安装完成',
})
}
@@ -271,7 +281,7 @@ export async function downloadPython(appRoot: string, mirror = 'ustc'): Promise<
type: 'python',
progress: 0,
status: 'error',
message: `Python下载失败: ${errorMessage}`
message: `Python下载失败: ${errorMessage}`,
})
}
return { success: false, error: errorMessage }
@@ -284,11 +294,17 @@ const pipMirrorUrls = {
tsinghua: 'https://pypi.tuna.tsinghua.edu.cn/simple/',
ustc: 'https://pypi.mirrors.ustc.edu.cn/simple/',
aliyun: 'https://mirrors.aliyun.com/pypi/simple/',
douban: 'https://pypi.douban.com/simple/'
douban: 'https://pypi.douban.com/simple/',
}
// 安装Python依赖
export async function installDependencies(appRoot: string, mirror = 'tsinghua'): Promise<{ success: boolean; error?: string }> {
export async function installDependencies(
appRoot: string,
mirror = 'tsinghua'
): Promise<{
success: boolean
error?: string
}> {
try {
const pythonPath = path.join(appRoot, 'environment', 'python', 'python.exe')
const backendPath = path.join(appRoot)
@@ -307,17 +323,18 @@ export async function installDependencies(appRoot: string, mirror = 'tsinghua'):
type: 'dependencies',
progress: 0,
status: 'downloading',
message: '正在安装Python依赖包...'
message: '正在安装Python依赖包...',
})
}
// 获取pip镜像源URL
const pipMirrorUrl = pipMirrorUrls[mirror as keyof typeof pipMirrorUrls] || pipMirrorUrls.tsinghua
const pipMirrorUrl =
pipMirrorUrls[mirror as keyof typeof pipMirrorUrls] || pipMirrorUrls.tsinghua
// 使用Scripts文件夹中的pip.exe
const pythonDir = path.join(appRoot, 'environment', 'python')
const pipExePath = path.join(pythonDir, 'Scripts', 'pip.exe')
console.log(`开始安装Python依赖`)
console.log(`Python目录: ${pythonDir}`)
console.log(`pip.exe路径: ${pipExePath}`)
@@ -331,17 +348,24 @@ export async function installDependencies(appRoot: string, mirror = 'tsinghua'):
// 安装依赖 - 直接使用pip.exe而不是python -m pip
await new Promise<void>((resolve, reject) => {
const process = spawn(pipExePath, [
'install',
'-r', requirementsPath,
'-i', pipMirrorUrl,
'--trusted-host', new URL(pipMirrorUrl).hostname
], {
cwd: backendPath,
stdio: 'pipe'
})
const process = spawn(
pipExePath,
[
'install',
'-r',
requirementsPath,
'-i',
pipMirrorUrl,
'--trusted-host',
new URL(pipMirrorUrl).hostname,
],
{
cwd: backendPath,
stdio: 'pipe',
}
)
process.stdout?.on('data', (data) => {
process.stdout?.on('data', data => {
const output = data.toString()
console.log('Pip output:', output)
@@ -350,17 +374,17 @@ export async function installDependencies(appRoot: string, mirror = 'tsinghua'):
type: 'dependencies',
progress: 50,
status: 'downloading',
message: '正在安装依赖包...'
message: '正在安装依赖包...',
})
}
})
process.stderr?.on('data', (data) => {
process.stderr?.on('data', data => {
const errorOutput = data.toString()
console.error('Pip error:', errorOutput)
})
process.on('close', (code) => {
process.on('close', code => {
console.log(`pip安装完成退出码: ${code}`)
if (code === 0) {
resolve()
@@ -369,7 +393,7 @@ export async function installDependencies(appRoot: string, mirror = 'tsinghua'):
}
})
process.on('error', (error) => {
process.on('error', error => {
console.error('pip进程错误:', error)
reject(error)
})
@@ -380,7 +404,7 @@ export async function installDependencies(appRoot: string, mirror = 'tsinghua'):
type: 'dependencies',
progress: 100,
status: 'completed',
message: 'Python依赖安装完成'
message: 'Python依赖安装完成',
})
}
@@ -392,7 +416,7 @@ export async function installDependencies(appRoot: string, mirror = 'tsinghua'):
type: 'dependencies',
progress: 0,
status: 'error',
message: `依赖安装失败: ${errorMessage}`
message: `依赖安装失败: ${errorMessage}`,
})
}
return { success: false, error: errorMessage }
@@ -400,10 +424,12 @@ export async function installDependencies(appRoot: string, mirror = 'tsinghua'):
}
// 导出pip安装函数
export async function installPipPackage(appRoot: string): Promise<{ success: boolean; error?: string }> {
export async function installPipPackage(
appRoot: string
): Promise<{ success: boolean; error?: string }> {
try {
const pythonPath = path.join(appRoot, 'environment', 'python')
if (!fs.existsSync(pythonPath)) {
throw new Error('Python环境不存在请先安装Python')
}
@@ -413,7 +439,7 @@ export async function installPipPackage(appRoot: string): Promise<{ success: boo
type: 'pip',
progress: 0,
status: 'installing',
message: '正在安装pip...'
message: '正在安装pip...',
})
}
@@ -424,7 +450,7 @@ export async function installPipPackage(appRoot: string): Promise<{ success: boo
type: 'pip',
progress: 100,
status: 'completed',
message: 'pip安装完成'
message: 'pip安装完成',
})
}
@@ -436,7 +462,7 @@ export async function installPipPackage(appRoot: string): Promise<{ success: boo
type: 'pip',
progress: 0,
status: 'error',
message: `pip安装失败: ${errorMessage}`
message: `pip安装失败: ${errorMessage}`,
})
}
return { success: false, error: errorMessage }
@@ -448,7 +474,7 @@ export async function startBackend(appRoot: string): Promise<{ success: boolean;
try {
const pythonPath = path.join(appRoot, 'environment', 'python', 'python.exe')
const backendPath = path.join(appRoot)
const mainPyPath = path.join(backendPath,'main.py')
const mainPyPath = path.join(backendPath, 'main.py')
// 检查文件是否存在
if (!fs.existsSync(pythonPath)) {
@@ -466,22 +492,20 @@ export async function startBackend(appRoot: string): Promise<{ success: boolean;
stdio: 'pipe',
env: {
...process.env,
PYTHONIOENCODING: 'utf-8' // 设置Python输出编码为UTF-8
}
PYTHONIOENCODING: 'utf-8', // 设置Python输出编码为UTF-8
},
})
// 等待后端启动
await new Promise<void>((resolve, reject) => {
const timeout = setTimeout(() => {
reject(new Error('后端启动超时'))
}, 30000) // 30秒超时
backendProcess.stdout?.on('data', (data) => {
backendProcess.stdout?.on('data', data => {
const output = data.toString()
console.log('Backend output:', output)
// 检查是否包含启动成功的标志
if (output.includes('Uvicorn running') || output.includes('8000')) {
clearTimeout(timeout)
@@ -490,7 +514,7 @@ export async function startBackend(appRoot: string): Promise<{ success: boolean;
})
// ✅ 重要:也要监听 stderr
backendProcess.stderr?.on('data', (data) => {
backendProcess.stderr?.on('data', data => {
const output = data.toString()
console.error('Backend error:', output) // 保留原有日志
@@ -501,11 +525,11 @@ export async function startBackend(appRoot: string): Promise<{ success: boolean;
}
})
backendProcess.stderr?.on('data', (data) => {
backendProcess.stderr?.on('data', data => {
console.error('Backend error:', data.toString())
})
backendProcess.on('error', (error) => {
backendProcess.on('error', error => {
clearTimeout(timeout)
reject(error)
})
@@ -515,4 +539,4 @@ export async function startBackend(appRoot: string): Promise<{ success: boolean;
} catch (error) {
return { success: false, error: error instanceof Error ? error.message : String(error) }
}
}
}