项目迁移
Some checks failed
CI/CD / Code Check (push) Has been cancelled
CI/CD / Build Windows (push) Has been cancelled

This commit is contained in:
2026-03-14 21:11:59 +08:00
commit 4654f36202
153 changed files with 55923 additions and 0 deletions

View File

@@ -0,0 +1,258 @@
<script lang="ts" setup>
import { open } from "@tauri-apps/plugin-shell";
import { ref, onMounted, computed } from "vue";
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
interface Sponsor {
id: string;
name: string;
imageUrl: string;
type: string;
url: string;
}
interface VersionInfo {
version: string;
buildTime: string;
author: string;
}
const sponsors = ref<Sponsor[]>([]);
const currentVersion = ref<string>(t('common.loading'));
const buildTime = ref<string>('');
const author = ref<string>('');
async function getVersionFromJson(): Promise<VersionInfo> {
try {
const response = await fetch('/version.json');
if (!response.ok) {
throw new Error(t('about.version_file_read_failed'));
}
return await response.json();
} catch (error) {
console.error('读取 version.json 失败:', error);
return {
version: '1.0.0',
buildTime: 'Unknown',
author: 'Tianpao'
};
}
}
async function getCurrentVersion() {
const versionInfo = await getVersionFromJson();
currentVersion.value = versionInfo.version;
buildTime.value = versionInfo.buildTime;
author.value = versionInfo.author;
}
const SPONSORS_JSON_URL = "https://bk.xcclyc.cn/upzzs.json";
async function fetchSponsors() {
try {
const response = await fetch(SPONSORS_JSON_URL);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
sponsors.value = data;
} catch (error) {
console.error("Failed to fetch sponsors:", error);
sponsors.value = [
{
id: "elfidc",
name: "亿讯云",
imageUrl: "./elfidc.svg",
type: t('about.sponsor_type_gold'),
url: "https://www.elfidc.com"
}
];
}
}
const thanksList = computed(() => {
return [
{
id: "user",
name: "天跑",
avatar: "./tianpao.jpg",
contribution: t('about.contribution_author'),
bilibiliUrl: "https://space.bilibili.com/1728953419"
},
{
id: "dev2",
name: "XCC",
avatar: "./xcc.jpg",
contribution: t('about.contribution_dev2'),
bilibiliUrl: "https://space.bilibili.com/3546586967706135"
},
{
id: "mirror",
name: "bangbang93",
avatar: "./bb93.jpg",
contribution: t('about.contribution_bangbang93')
},{
id: "mirror",
name: "z0z0r4",
avatar: "./z0z0r4.jpg",
contribution: t('about.contribution_z0z0r4')
}
];
});
async function contant(sponsor: Sponsor){
try {
await open(sponsor.url)
} catch (error) {
console.error("Failed to open sponsor URL:", error)
window.open(sponsor.url, '_blank')
}
}
async function openBilibili(url: string) {
try {
await open(url);
} catch (error) {
console.error("Failed to open Bilibili URL:", error)
window.open(url, '_blank')
}
}
onMounted(() => {
fetchSponsors();
getCurrentVersion();
});
</script>
<template>
<div class="tw:h-full tw:w-full tw:p-8 tw:bg-gradient-to-br tw:from-slate-50 tw:via-blue-50 tw:to-indigo-50 tw:overflow-auto">
<div class="tw:w-full tw:max-w-5xl tw:mx-auto tw:flex tw:flex-col tw:gap-8">
<div class="tw:text-center tw:animate-fade-in">
<h1 class="tw:text-3xl tw:font-bold tw:bg-gradient-to-r tw:from-emerald-500 tw:via-cyan-500 tw:to-blue-500 tw:bg-clip-text tw:text-transparent tw:mb-3">
{{ t('about.title') }}
</h1>
<p class="tw:text-gray-500 tw:text-lg">{{ t('about.subtitle') }}</p>
</div>
<div class="tw:bg-white tw:rounded-2xl tw:shadow-lg tw:p-8 tw:animate-fade-in-up">
<h2 class="tw:text-xl tw:font-bold tw:text-gray-800 tw:text-center tw:mb-6 tw:flex tw:items-center tw:justify-center tw:gap-3">
<span class="tw:text-2xl"></span>
<span>{{ t('about.about_software') }}</span>
</h2>
<div class="tw:flex tw:flex-col tw:items-center tw:gap-6">
<div class="tw:flex tw:flex-col tw:items-center tw:gap-3">
<div class="tw:flex tw:items-center tw:gap-3">
<span class="tw:text-gray-600 tw:text-base">{{ t('about.current_version') }}</span>
<span class="tw:text-2xl tw:font-bold tw:bg-gradient-to-r tw:from-emerald-500 tw:to-cyan-500 tw:bg-clip-text tw:text-transparent">
{{ currentVersion }}
</span>
</div>
</div>
<div class="tw:flex tw:flex-col tw:items-center tw:gap-2 tw:text-gray-500 tw:text-sm">
<div class="tw:flex tw:items-center tw:gap-2">
<span>{{ t('about.build_time') }}</span>
<span class="tw:font-medium">{{ buildTime }}</span>
</div>
<div class="tw:flex tw:items-center tw:gap-2">
<span>{{ t('about.author') }}</span>
<span class="tw:font-medium">{{ author }}</span>
</div>
</div>
</div>
</div>
<div class="tw:bg-white tw:rounded-2xl tw:shadow-lg tw:p-8 tw:animate-fade-in-up">
<h2 class="tw:text-xl tw:font-bold tw:text-gray-800 tw:text-center tw:mb-8 tw:flex tw:items-center tw:justify-center tw:gap-3">
<span class="tw:text-2xl"></span>
<span>{{ t('about.development_team') }}</span>
</h2>
<div class="tw:grid tw:grid-cols-2 md:tw:grid-cols-3 lg:tw:grid-cols-5 tw:gap-6 tw:justify-items-center">
<div
v-for="item in thanksList"
:key="item.id"
class="tw:flex tw:flex-col tw:items-center tw:w-36 tw:p-5 tw:bg-gradient-to-br tw:from-white tw:to-gray-50 tw:rounded-2xl tw:shadow-sm tw:transition-all duration-300 hover:shadow-xl hover:-translate-y-2 tw:border tw:border-gray-100 tw:group"
>
<div class="tw:w-20 tw:h-20 tw:bg-gradient-to-br tw:from-emerald-100 tw:to-cyan-100 tw:rounded-full tw:overflow-hidden tw:flex tw:items-center tw:justify-center tw:mb-4 tw:ring-2 tw:ring-emerald-200 tw:ring-offset-2 tw:group-hover:tw:ring-emerald-400 tw:transition-all duration-300">
<img class="tw:w-full tw:h-full tw:object-cover" :src="item.avatar" :alt="item.name">
</div>
<h3 class="tw:text-sm tw:font-bold tw:text-gray-800 tw:group-hover:tw:text-emerald-600 tw:transition-colors">{{ item.name }}</h3>
<p class="tw:text-xs tw:text-gray-500 tw:mt-2">{{ item.contribution }}</p>
<a-button
v-if="item.bilibiliUrl"
type="link"
size="small"
class="tw:text-xs tw:mt-3 tw:px-3 tw:py-1 tw:rounded-full tw:bg-gradient-to-r tw:from-pink-100 tw:to-pink-200 tw:text-pink-600 tw:hover:tw:from-pink-200 tw:hover:tw:to-pink-300 tw:transition-all"
@click="openBilibili(item.bilibiliUrl)"
>
B站
</a-button>
</div>
</div>
</div>
<div class="tw:tw:py-6">
<div class="tw:w-full tw:h-px tw:bg-gradient-to-r tw:from-transparent tw:via-gray-300 tw:to-transparent"></div>
</div>
<div class="tw:bg-white tw:rounded-2xl tw:shadow-lg tw:p-8 tw:animate-fade-in-up tw:delay-100">
<h1 class="tw:text-xl tw:text-center tw:font-bold tw:bg-gradient-to-r tw:from-amber-500 tw:to-orange-500 tw:bg-clip-text tw:text-transparent tw:mb-8 tw:flex tw:items-center tw:justify-center tw:gap-3">
<span class="tw:text-2xl">💎</span>
<span>{{ t('about.sponsor') }}</span>
</h1>
<div class="tw:flex tw:flex-wrap tw:justify-center tw:gap-6">
<div
v-for="sponsor in sponsors"
:key="sponsor.id"
class="tw:flex tw:flex-col tw:items-center tw:w-44 tw:p-5 tw:bg-gradient-to-br tw:from-amber-50 tw:to-orange-50 tw:rounded-2xl tw:shadow-md tw:cursor-pointer tw:hover:shadow-2xl tw:hover:-translate-y-2 tw:transition-all duration-300 tw:group tw:border tw:border-amber-100"
@click="contant(sponsor)"
>
<div class="tw:w-24 tw:h-24 tw:flex tw:items-center tw:justify-center tw:bg-gradient-to-br tw:from-white tw:to-amber-100 tw:rounded-2xl tw:p-3 tw:mb-4 tw:group-hover:tw:scale-110 tw:transition-transform duration-300">
<img class="tw:max-w-full tw:max-h-full tw:object-contain" :src="sponsor.imageUrl" :alt="sponsor.name">
</div>
<h2 class="tw:text-base tw:font-bold tw:text-gray-800 tw:group-hover:tw:text-amber-600 tw:transition-colors">{{ sponsor.name }}</h2>
<span class="tw:text-xs tw:text-amber-600 tw:bg-amber-100 tw:px-3 tw:py-1 tw:rounded-full tw:mt-3 tw:font-medium">
{{ sponsor.type }}
</span>
</div>
</div>
</div>
</div>
</div>
</template>
<style scoped>
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.tw-animate-fade-in {
animation: fadeIn 0.6s ease-out;
}
.tw-animate-fade-in-up {
animation: fadeInUp 0.6s ease-out;
}
.delay-100 {
animation-delay: 0.1s;
}
</style>