feat: 允许http下载&添加了多个镜像源

- 在 AutoMode 组件中添加了多个 gh-proxy 镜像选项
- 在 BackendStep 组件中增加了新的镜像选择项
- 修改了 downloadService 中的下载逻辑,支持 http 和 https
- 更新了 gitService 和 pythonService 中的下载 URL
- 在 Home 组件中添加了动态问候语
This commit is contained in:
2025-08-13 20:00:28 +08:00
parent 9aeda23ade
commit 95126a85d8
7 changed files with 182 additions and 155 deletions

View File

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

View File

@@ -11,7 +11,7 @@ export function setMainWindow(window: BrowserWindow) {
mainWindow = window 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) { function copyDirSync(src: string, dest: string) {

View File

@@ -64,7 +64,7 @@ async function installPip(pythonPath: string, appRoot: string): Promise<void> {
console.log('pip未安装开始安装...') console.log('pip未安装开始安装...')
const getPipPath = path.join(pythonPath, 'get-pip.py') 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(`Python可执行文件路径: ${pythonExe}`)
console.log(`get-pip.py下载URL: ${getPipUrl}`) console.log(`get-pip.py下载URL: ${getPipUrl}`)

View File

@@ -170,7 +170,12 @@ function getGitMirrorUrl(mirrorKey: string): string {
const mirrors = { const mirrors = {
github: 'https://github.com/DLmaster361/AUTO_MAA.git', github: 'https://github.com/DLmaster361/AUTO_MAA.git',
ghfast: 'https://ghfast.top/https://github.com/DLmaster361/AUTO_MAA.git', ghfast: 'https://ghfast.top/https://github.com/DLmaster361/AUTO_MAA.git',
ghproxy_cloudflare: 'https://gh-proxy.com/https://github.com/DLmaster361/AUTO_MAA.git.git',
ghproxy_hongkong: 'https://hk.gh-proxy.com/https://github.com/DLmaster361/AUTO_MAA.git.git',
ghproxy_fastly: 'https://cdn.gh-proxy.com/https://github.com/DLmaster361/AUTO_MAA.git.git',
ghproxy_edgeone: 'https://edgeone.gh-proxy.com/https://github.com/DLmaster361/AUTO_MAA.git.git'
} }
return mirrors[mirrorKey as keyof typeof mirrors] || mirrors.github return mirrors[mirrorKey as keyof typeof mirrors] || mirrors.github
} }

View File

@@ -52,9 +52,14 @@ defineProps<{
const gitMirrors = ref<Mirror[]>([ const gitMirrors = ref<Mirror[]>([
{ key: 'github', name: 'GitHub 官方', url: 'https://github.com/DLmaster361/AUTO_MAA.git', speed: null }, { key: 'github', name: 'GitHub 官方', url: 'https://github.com/DLmaster361/AUTO_MAA.git', speed: null },
{ key: 'ghfast', name: 'ghfast 镜像', url: 'https://ghfast.top/https://github.com/DLmaster361/AUTO_MAA.git', speed: null } { key: 'ghfast', name: 'ghfast 镜像', url: 'https://ghfast.top/https://github.com/DLmaster361/AUTO_MAA.git', speed: null },
{ key: 'ghproxy_cloudflare', name: 'gh-proxy Cloudflare 全球加速', url: 'https://gh-proxy.com/https://github.com/DLmaster361/AUTO_MAA.git.git', speed: null },
{ key: 'ghproxy_hongkong', name: 'gh-proxy 香港节点(大陆优化)', url: 'https://hk.gh-proxy.com/https://github.com/DLmaster361/AUTO_MAA.git.git', speed: null },
{ key: 'ghproxy_fastly', name: 'gh-proxy Fastly CDN', url: 'https://cdn.gh-proxy.com/https://github.com/DLmaster361/AUTO_MAA.git.git', speed: null },
{ key: 'ghproxy_edgeone', name: 'gh-proxy EdgeOne 全球加速', url: 'https://edgeone.gh-proxy.com/https://github.com/DLmaster361/AUTO_MAA.git.git', speed: null }
]) ])
const selectedGitMirror = ref('github') const selectedGitMirror = ref('github')
const testingGitSpeed = ref(false) const testingGitSpeed = ref(false)

View File

@@ -90,23 +90,23 @@ const router = createRouter({
}) })
// // 添加路由守卫,确保在生产环境中也能正确进入初始化页面 // 添加路由守卫,确保在生产环境中也能正确进入初始化页面
// router.beforeEach(async (to, from, next) => { router.beforeEach(async (to, from, next) => {
// console.log('路由守卫:', { to: to.path, from: from.path }) console.log('路由守卫:', { to: to.path, from: from.path })
//
// // 如果访问的不是初始化页面,且没有初始化标记,则重定向到初始化页面 // 如果访问的不是初始化页面,且没有初始化标记,则重定向到初始化页面
// if (to.path !== '/initialization') { if (to.path !== '/initialization') {
// const initialized = await isAppInitialized() const initialized = await isAppInitialized()
// console.log('检查初始化状态:', initialized) console.log('检查初始化状态:', initialized)
//
// if (!initialized) { if (!initialized) {
// console.log('应用未初始化,重定向到初始化页面') console.log('应用未初始化,重定向到初始化页面')
// next('/initialization') next('/initialization')
// return return
// } }
// } }
//
// next() next()
// }) })
export default router export default router

View File

@@ -1,7 +1,6 @@
<template> <template>
<div class="header"> <div class="header">
<a-typography-title>主人早上好喵~</a-typography-title> <a-typography-title>{{ greeting }}</a-typography-title>
</div> </div>
<div class="content"> <div class="content">
@@ -17,13 +16,7 @@
</template> </template>
<div v-if="error" class="error-message"> <div v-if="error" class="error-message">
<a-alert <a-alert :message="error" type="error" show-icon closable @close="error = ''" />
:message="error"
type="error"
show-icon
closable
@close="error = ''"
/>
</div> </div>
<!-- 活动信息展示 --> <!-- 活动信息展示 -->
@@ -37,7 +30,9 @@
<div class="activity-end-time"> <div class="activity-end-time">
<ClockCircleOutlined class="time-icon" /> <ClockCircleOutlined class="time-icon" />
<span class="time-label">结束时间</span> <span class="time-label">结束时间</span>
<span class="time-value">{{ formatTime(currentActivity.UtcExpireTime, currentActivity.TimeZone) }}</span> <span class="time-value">{{
formatTime(currentActivity.UtcExpireTime, currentActivity.TimeZone)
}}</span>
</div> </div>
</div> </div>
@@ -54,11 +49,7 @@
</div> </div>
<div v-if="activityData?.length" class="activity-list"> <div v-if="activityData?.length" class="activity-list">
<div <div v-for="item in activityData" :key="item.Value" class="activity-item">
v-for="item in activityData"
:key="item.Value"
class="activity-item"
>
<div class="stage-info"> <div class="stage-info">
<div class="stage-name">{{ item.Display }}</div> <div class="stage-name">{{ item.Display }}</div>
<!-- <div class="stage-value">{{ item.Value }}</div>--> <!-- <div class="stage-value">{{ item.Value }}</div>-->
@@ -67,7 +58,11 @@
<div class="drop-info"> <div class="drop-info">
<div class="drop-image"> <div class="drop-image">
<img <img
:src="item.DropName.startsWith('DESC:') ? getMaterialImage('固源岩') : getMaterialImage(item.DropName)" :src="
item.DropName.startsWith('DESC:')
? getMaterialImage('固源岩')
: getMaterialImage(item.DropName)
"
:alt="item.DropName.startsWith('DESC:') ? '固源岩' : item.DropName" :alt="item.DropName.startsWith('DESC:') ? '固源岩' : item.DropName"
@error="handleImageError" @error="handleImageError"
/> />
@@ -95,7 +90,12 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, computed } from 'vue' import { ref, onMounted, computed } from 'vue'
import { message } from 'ant-design-vue' import { message } from 'ant-design-vue'
import { ReloadOutlined, InfoCircleOutlined, CalendarOutlined, ClockCircleOutlined } from '@ant-design/icons-vue' import {
ReloadOutlined,
InfoCircleOutlined,
CalendarOutlined,
ClockCircleOutlined,
} from '@ant-design/icons-vue'
import { Service } from '@/api' import { Service } from '@/api'
interface ActivityInfo { interface ActivityInfo {
@@ -134,7 +134,7 @@ const formatTime = (timeString: string, timeZone: number) => {
month: '2-digit', month: '2-digit',
day: '2-digit', day: '2-digit',
hour: '2-digit', hour: '2-digit',
minute: '2-digit' minute: '2-digit',
}) })
} catch { } catch {
return timeString return timeString
@@ -162,20 +162,20 @@ const getCountdownStyle = (expireTime: string) => {
return { return {
color: '#ff4d4f', color: '#ff4d4f',
fontWeight: 'bold', fontWeight: 'bold',
fontSize: '18px' fontSize: '18px',
} }
} }
return { return {
color: 'var(--ant-color-text)', color: 'var(--ant-color-text)',
fontWeight: '600', fontWeight: '600',
fontSize: '20px' fontSize: '20px',
} }
} catch { } catch {
return { return {
color: 'var(--ant-color-text)', color: 'var(--ant-color-text)',
fontWeight: '600', fontWeight: '600',
fontSize: '20px' fontSize: '20px',
} }
} }
} }
@@ -227,13 +227,27 @@ const refreshActivity = async () => {
} }
} }
const greeting = computed(() => {
const hour = new Date().getHours()
if (hour >= 5 && hour < 11) {
return '主人早上好喵~'
} else if (hour >= 11 && hour < 14) {
return '主人中午好喵~'
} else if (hour >= 14 && hour < 18) {
return '主人下午好喵~'
} else if (hour >= 18 && hour < 23) {
return '主人晚上好喵~'
} else {
return '主人夜深了喵~早点休息喵~'
}
})
onMounted(() => { onMounted(() => {
fetchActivityData() fetchActivityData()
}) })
</script> </script>
<style scoped> <style scoped>
.header { .header {
margin-bottom: 24px; margin-bottom: 24px;
} }
@@ -245,8 +259,6 @@ onMounted(() => {
font-weight: 600; font-weight: 600;
} }
.activity-card { .activity-card {
margin-bottom: 24px; margin-bottom: 24px;
} }