This commit is contained in:
@@ -0,0 +1,203 @@
|
||||
<template>
|
||||
<PageHeader title="关于项目" description="查看 Havline 版本、源开源项目和技术信息">
|
||||
<template #actions>
|
||||
<n-button :loading="refreshing" @click="refreshVersion">
|
||||
<template #icon><n-icon :component="RefreshOutline" /></template>
|
||||
刷新版本信息
|
||||
</n-button>
|
||||
</template>
|
||||
</PageHeader>
|
||||
|
||||
<div class="stats-row">
|
||||
<StatCard label="当前版本" :value="`v${version}`" sub="来自 /api/version" tone="brand">
|
||||
<template #icon><n-icon :component="CloudOutline" /></template>
|
||||
</StatCard>
|
||||
<StatCard label="源项目" :value="GITHUB_REPO" sub="上游开源项目地址" tone="blue" value-small>
|
||||
<template #icon><n-icon :component="LogoGithub" /></template>
|
||||
</StatCard>
|
||||
<StatCard label="开源协议" value="GPL-3.0" sub="GNU General Public License" tone="green">
|
||||
<template #icon><n-icon :component="DocumentTextOutline" /></template>
|
||||
</StatCard>
|
||||
<StatCard label="运行状态" value="正常" sub="Havline 服务运行中" tone="teal">
|
||||
<template #icon><n-icon :component="CheckmarkCircleOutline" /></template>
|
||||
</StatCard>
|
||||
</div>
|
||||
|
||||
<HavlineCard title="项目信息" subtitle="当前版本、项目定位和最近检查时间">
|
||||
<div class="about-grid">
|
||||
<div class="about-item">
|
||||
<label>项目名称</label>
|
||||
<strong>Havline</strong>
|
||||
</div>
|
||||
<div class="about-item">
|
||||
<label>项目定位</label>
|
||||
<span>面向 NAS 的轻量公网访问管理工具</span>
|
||||
</div>
|
||||
<div class="about-item">
|
||||
<label>当前版本</label>
|
||||
<span class="mono">v{{ version }}</span>
|
||||
</div>
|
||||
<div class="about-item">
|
||||
<label>最近检查</label>
|
||||
<span>{{ checkedAt || '刚刚' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="about-links">
|
||||
<a :href="GITHUB_REPO_URL" target="_blank" rel="noopener noreferrer">
|
||||
<n-icon :component="LogoGithub" />
|
||||
源项目:{{ GITHUB_REPO }}
|
||||
</a>
|
||||
<a :href="GPL_URL" target="_blank" rel="noopener noreferrer">
|
||||
<n-icon :component="DocumentTextOutline" />
|
||||
查看 GPL-3.0 协议
|
||||
</a>
|
||||
</div>
|
||||
</HavlineCard>
|
||||
|
||||
<HavlineCard title="源项目与开源说明" subtitle="Havline 的源项目地址保持不变">
|
||||
<div class="about-copy">
|
||||
<p>
|
||||
Havline 的源开源项目为
|
||||
<a :href="GITHUB_REPO_URL" target="_blank" rel="noopener noreferrer">{{ GITHUB_REPO }}</a>。
|
||||
该地址用于查阅上游代码、提交记录和 Release 信息。
|
||||
</p>
|
||||
<p>
|
||||
本项目继续采用
|
||||
<a :href="GPL_URL" target="_blank" rel="noopener noreferrer">GPL-3.0</a>
|
||||
开源。品牌名称调整不会改变原项目及其衍生版本的许可证义务。
|
||||
</p>
|
||||
</div>
|
||||
</HavlineCard>
|
||||
|
||||
<HavlineCard title="技术栈" subtitle="Havline 当前使用的主要技术组件">
|
||||
<div class="about-stack">
|
||||
<span v-for="item in stack" :key="item">{{ item }}</span>
|
||||
</div>
|
||||
</HavlineCard>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { NButton, NIcon, useMessage } from 'naive-ui'
|
||||
import {
|
||||
CheckmarkCircleOutline,
|
||||
CloudOutline,
|
||||
DocumentTextOutline,
|
||||
LogoGithub,
|
||||
RefreshOutline,
|
||||
} from '@vicons/ionicons5'
|
||||
import { api } from '../api/client'
|
||||
import HavlineCard from '../components/HavlineCard.vue'
|
||||
import PageHeader from '../components/PageHeader.vue'
|
||||
import StatCard from '../components/StatCard.vue'
|
||||
import { GITHUB_REPO, GITHUB_REPO_URL } from '../constants/app'
|
||||
import { formatDate } from '../utils/format'
|
||||
|
||||
const GPL_URL = 'https://www.gnu.org/licenses/gpl-3.0.html'
|
||||
const message = useMessage()
|
||||
const version = ref(__APP_VERSION__)
|
||||
const checkedAt = ref('')
|
||||
const refreshing = ref(false)
|
||||
const stack = [
|
||||
'Go 1.23',
|
||||
'Vue 3',
|
||||
'TypeScript',
|
||||
'Vite',
|
||||
'Naive UI',
|
||||
'ECharts',
|
||||
'SQLite',
|
||||
'Nginx',
|
||||
'FRP',
|
||||
'Cloudflare Tunnel',
|
||||
]
|
||||
|
||||
async function refreshVersion() {
|
||||
refreshing.value = true
|
||||
try {
|
||||
const result = await api.getVersion()
|
||||
version.value = result.version || version.value
|
||||
checkedAt.value = formatDate(new Date().toISOString())
|
||||
} catch (error) {
|
||||
message.error(error instanceof Error ? error.message : '读取版本失败')
|
||||
} finally {
|
||||
refreshing.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
void refreshVersion()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.about-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||
gap: var(--havline-space-4);
|
||||
}
|
||||
|
||||
.about-item {
|
||||
min-width: 0;
|
||||
padding: var(--havline-space-4);
|
||||
border: 1px solid var(--havline-border);
|
||||
border-radius: var(--havline-radius-sm);
|
||||
background: var(--havline-bg);
|
||||
}
|
||||
|
||||
.about-item label {
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
color: var(--havline-text-muted);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.about-item strong,
|
||||
.about-item span {
|
||||
color: var(--havline-text);
|
||||
}
|
||||
|
||||
.about-links,
|
||||
.about-stack {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--havline-space-3);
|
||||
margin-top: var(--havline-space-4);
|
||||
}
|
||||
|
||||
.about-links a {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 10px;
|
||||
color: var(--havline-brand-text);
|
||||
border: 1px solid var(--havline-border);
|
||||
border-radius: var(--havline-radius-sm);
|
||||
background: var(--havline-surface);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.about-copy {
|
||||
display: grid;
|
||||
gap: var(--havline-space-3);
|
||||
color: var(--havline-text-secondary);
|
||||
}
|
||||
|
||||
.about-copy p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.about-copy a {
|
||||
color: var(--havline-brand-text);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.about-stack span {
|
||||
padding: 6px 10px;
|
||||
color: var(--havline-text-secondary);
|
||||
border: 1px solid var(--havline-border);
|
||||
border-radius: 999px;
|
||||
background: var(--havline-bg);
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user