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

@@ -170,7 +170,12 @@ function getGitMirrorUrl(mirrorKey: string): string {
const mirrors = {
github: '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
}

View File

@@ -52,9 +52,14 @@ defineProps<{
const gitMirrors = ref<Mirror[]>([
{ 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 testingGitSpeed = ref(false)

View File

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

View File

@@ -1,101 +1,101 @@
<template>
<div class="header">
<a-typography-title>{{ greeting }}</a-typography-title>
</div>
<div class="header">
<a-typography-title>主人早上好喵~</a-typography-title>
</div>
<div class="content">
<!-- 当期活动关卡 -->
<a-card title="当期活动关卡" class="activity-card" :loading="loading">
<template #extra>
<a-button type="text" @click="refreshActivity" :loading="loading">
<template #icon>
<ReloadOutlined />
</template>
刷新
</a-button>
</template>
<div v-if="error" class="error-message">
<a-alert
:message="error"
type="error"
show-icon
closable
@close="error = ''"
/>
</div>
<!-- 活动信息展示 -->
<div v-if="currentActivity && !loading" class="activity-info">
<div class="activity-header">
<div class="activity-left">
<div class="activity-name">
<span class="activity-title">{{ currentActivity.StageName }}</span>
<a-tag color="blue" class="activity-tip">{{ currentActivity.Tip }}</a-tag>
</div>
<div class="activity-end-time">
<ClockCircleOutlined class="time-icon" />
<span class="time-label">结束时间</span>
<span class="time-value">{{ formatTime(currentActivity.UtcExpireTime, currentActivity.TimeZone) }}</span>
</div>
<div class="content">
<!-- 当期活动关卡 -->
<a-card title="当期活动关卡" class="activity-card" :loading="loading">
<template #extra>
<a-button type="text" @click="refreshActivity" :loading="loading">
<template #icon>
<ReloadOutlined />
</template>
刷新
</a-button>
</template>
<div v-if="error" class="error-message">
<a-alert :message="error" type="error" show-icon closable @close="error = ''" />
</div>
<!-- 活动信息展示 -->
<div v-if="currentActivity && !loading" class="activity-info">
<div class="activity-header">
<div class="activity-left">
<div class="activity-name">
<span class="activity-title">{{ currentActivity.StageName }}</span>
<a-tag color="blue" class="activity-tip">{{ currentActivity.Tip }}</a-tag>
</div>
<div class="activity-right">
<a-statistic-countdown
title="当期活动剩余时间"
:value="getCountdownValue(currentActivity.UtcExpireTime)"
format="D 天 H 时 m 分"
:value-style="getCountdownStyle(currentActivity.UtcExpireTime)"
@finish="onCountdownFinish"
<div class="activity-end-time">
<ClockCircleOutlined class="time-icon" />
<span class="time-label">结束时间</span>
<span class="time-value">{{
formatTime(currentActivity.UtcExpireTime, currentActivity.TimeZone)
}}</span>
</div>
</div>
<div class="activity-right">
<a-statistic-countdown
title="当期活动剩余时间"
:value="getCountdownValue(currentActivity.UtcExpireTime)"
format="D 天 H 时 m 分"
:value-style="getCountdownStyle(currentActivity.UtcExpireTime)"
@finish="onCountdownFinish"
/>
</div>
</div>
</div>
<div v-if="activityData?.length" class="activity-list">
<div v-for="item in activityData" :key="item.Value" class="activity-item">
<div class="stage-info">
<div class="stage-name">{{ item.Display }}</div>
<!-- <div class="stage-value">{{ item.Value }}</div>-->
</div>
<div class="drop-info">
<div class="drop-image">
<img
:src="
item.DropName.startsWith('DESC:')
? getMaterialImage('固源岩')
: getMaterialImage(item.DropName)
"
:alt="item.DropName.startsWith('DESC:') ? '固源岩' : item.DropName"
@error="handleImageError"
/>
</div>
</div>
</div>
<div v-if="activityData?.length" class="activity-list">
<div
v-for="item in activityData"
:key="item.Value"
class="activity-item"
>
<div class="stage-info">
<div class="stage-name">{{ item.Display }}</div>
<!-- <div class="stage-value">{{ item.Value }}</div>-->
</div>
<div class="drop-info">
<div class="drop-image">
<img
:src="item.DropName.startsWith('DESC:') ? getMaterialImage('固源岩') : getMaterialImage(item.DropName)"
:alt="item.DropName.startsWith('DESC:') ? '固源岩' : item.DropName"
@error="handleImageError"
/>
</div>
<div class="drop-details">
<div class="drop-name">
{{ item.DropName.startsWith('DESC:') ? item.DropName.substring(5) : item.DropName }}
</div>
<!-- <div v-if="item.Drop && !item.DropName.startsWith('DESC:')" class="drop-id">-->
<!-- ID: {{ item.Drop }}-->
<!-- </div>-->
<div class="drop-details">
<div class="drop-name">
{{ item.DropName.startsWith('DESC:') ? item.DropName.substring(5) : item.DropName }}
</div>
<!-- <div v-if="item.Drop && !item.DropName.startsWith('DESC:')" class="drop-id">-->
<!-- ID: {{ item.Drop }}-->
<!-- </div>-->
</div>
</div>
</div>
<div v-else-if="!loading" class="empty-state">
<a-empty description="暂无活动关卡数据" />
</div>
</a-card>
</div>
</div>
<div v-else-if="!loading" class="empty-state">
<a-empty description="暂无活动关卡数据" />
</div>
</a-card>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, computed } from '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'
interface ActivityInfo {
@@ -134,7 +134,7 @@ const formatTime = (timeString: string, timeZone: number) => {
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit'
minute: '2-digit',
})
} catch {
return timeString
@@ -157,25 +157,25 @@ const getCountdownStyle = (expireTime: string) => {
const now = new Date()
const remaining = expire.getTime() - now.getTime()
const twoDaysInMs = 2 * 24 * 60 * 60 * 1000
if (remaining <= twoDaysInMs) {
return {
color: '#ff4d4f',
fontWeight: 'bold',
fontSize: '18px'
fontSize: '18px',
}
}
return {
color: 'var(--ant-color-text)',
fontWeight: '600',
fontSize: '20px'
fontSize: '20px',
}
} catch {
return {
color: 'var(--ant-color-text)',
fontWeight: '600',
fontSize: '20px'
fontSize: '20px',
}
}
}
@@ -203,10 +203,10 @@ const handleImageError = (event: Event) => {
const fetchActivityData = async () => {
loading.value = true
error.value = ''
try {
const response = await Service.addOverviewApiInfoGetOverviewPost()
if (response.code === 200 && response.data?.ALL) {
activityData.value = response.data.ALL
} else {
@@ -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(() => {
fetchActivityData()
})
</script>
<style scoped>
.header {
margin-bottom: 24px;
}
@@ -245,8 +259,6 @@ onMounted(() => {
font-weight: 600;
}
.activity-card {
margin-bottom: 24px;
}
@@ -458,15 +470,15 @@ onMounted(() => {
.page-container {
padding: 16px;
}
.activity-list {
grid-template-columns: 1fr;
}
.activity-item {
padding: 12px;
}
.drop-image {
width: 40px;
height: 40px;