feat: 在 web 页面显示版本号和更新日志

This commit is contained in:
CHE LIANG ZHAO
2026-01-26 16:06:06 +08:00
parent f537b53ebd
commit 61d26fc971
2 changed files with 148 additions and 1 deletions

View File

@@ -0,0 +1,120 @@
<script lang="ts">
import * as Drawer from '$lib/components/ui/drawer';
import { Button } from '$lib/components/ui/button';
import X from '@lucide/svelte/icons/x';
import Calendar from '@lucide/svelte/icons/calendar';
import Tag from '@lucide/svelte/icons/tag';
let { open = $bindable(false) } = $props();
// Changelog 内容(从 CHANGELOG.md 解析或硬编码)
const changelog = [
{
version: '1.3.0',
date: '2026-01-26',
changes: {
新增: [
'京东账单支持 - 支持京东白条账单上传和清洗',
'自动识别京东账单类型(交易流水 ZIP',
'解析京东白条账单 CSV 格式(含还款日期信息)',
'京东专属分类映射配置',
'支持京东外卖、京东平台商户等商户识别',
'上传页面和账单列表页面添加"京东"选项'
],
优化: [
'京东订单智能去重 - 上传京东账单时自动软删除其他来源中的京东订单',
'分类推断复核等级优化 - 京东账单引入 LOW 复核等级',
'京东平台商户关键词扩展'
],
技术改进: [
'新增京东账单清理器',
'新增京东专属配置',
'后端新增软删除接口',
'新增单元测试11 个测试用例)'
]
}
},
{
version: '1.2.1',
date: '2026-01-23',
changes: {
优化: [
'智能复核快捷确认 - 在复核列表每行添加快捷确认按钮',
'无需打开详情页面即可确认分类正确',
'自动更新统计数据',
'提升复核效率,支持快速批量确认'
],
文档: ['AGENTS.md 更新 - 精简为 150 行,专为 AI 编程助手设计']
}
},
{
version: '1.2.0',
date: '2026-01-25',
changes: {
新增: [
'账单删除功能 - 支持在账单详情抽屉中删除账单(软删除)',
'删除按钮带二次确认,防止误操作',
'已删除的账单在所有查询中自动过滤'
],
技术改进: [
'后端 MongoDB 查询方法添加软删除过滤',
'新增 DELETE /api/bills/:id 接口'
]
}
}
];
</script>
<Drawer.Root bind:open>
<Drawer.Content class="max-h-[90vh]">
<Drawer.Header class="border-b">
<div class="flex items-center justify-between">
<Drawer.Title class="text-xl font-semibold">版本更新日志</Drawer.Title>
<Button variant="ghost" size="icon" onclick={() => (open = false)}>
<X class="size-4" />
</Button>
</div>
</Drawer.Header>
<div class="h-[calc(90vh-8rem)] overflow-y-auto p-6">
<div class="space-y-8">
{#each changelog as release}
<div class="space-y-3">
<!-- 版本号和日期 -->
<div class="flex items-center gap-3">
<div class="flex items-center gap-2">
<Tag class="size-5 text-primary" />
<h3 class="text-lg font-semibold">v{release.version}</h3>
</div>
<div class="flex items-center gap-1.5 text-sm text-muted-foreground">
<Calendar class="size-4" />
<span>{release.date}</span>
</div>
</div>
<!-- 变更内容 -->
<div class="space-y-4 pl-7 border-l-2 border-muted">
{#each Object.entries(release.changes) as [category, items]}
<div class="space-y-2">
<h4 class="text-sm font-semibold text-primary">{category}</h4>
<ul class="space-y-1.5 text-sm text-muted-foreground">
{#each items as item}
<li class="flex gap-2 leading-relaxed">
<span class="text-primary mt-1.5"></span>
<span>{item}</span>
</li>
{/each}
</ul>
</div>
{/each}
</div>
</div>
{/each}
</div>
</div>
<Drawer.Footer class="border-t">
<Button variant="outline" onclick={() => (open = false)} class="w-full">关闭</Button>
</Drawer.Footer>
</Drawer.Content>
</Drawer.Root>

View File

@@ -10,6 +10,7 @@
import * as DropdownMenu from '$lib/components/ui/dropdown-menu'; import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
import * as Avatar from '$lib/components/ui/avatar'; import * as Avatar from '$lib/components/ui/avatar';
import { Separator } from '$lib/components/ui/separator'; import { Separator } from '$lib/components/ui/separator';
import ChangelogDrawer from '$lib/components/ChangelogDrawer.svelte';
// Icons // Icons
import Upload from '@lucide/svelte/icons/upload'; import Upload from '@lucide/svelte/icons/upload';
@@ -24,6 +25,10 @@
import User from '@lucide/svelte/icons/user'; import User from '@lucide/svelte/icons/user';
import Bell from '@lucide/svelte/icons/bell'; import Bell from '@lucide/svelte/icons/bell';
import Sparkles from '@lucide/svelte/icons/sparkles'; import Sparkles from '@lucide/svelte/icons/sparkles';
import Info from '@lucide/svelte/icons/info';
// 从 package.json 导入版本号
import pkg from '../../package.json';
// Theme // Theme
import { import {
@@ -42,6 +47,7 @@
let checkingHealth = $state(true); let checkingHealth = $state(true);
let isAuthenticated = $state(false); let isAuthenticated = $state(false);
let currentUser = $state<AuthUser | null>(null); let currentUser = $state<AuthUser | null>(null);
let changelogOpen = $state(false);
// 订阅认证状态 // 订阅认证状态
$effect(() => { $effect(() => {
@@ -228,9 +234,27 @@
</Sidebar.Group> </Sidebar.Group>
</Sidebar.Content> </Sidebar.Content>
<!-- Footer: 用户信息 --> <!-- Footer: 用户信息 + 版本号 -->
<Sidebar.Footer> <Sidebar.Footer>
<Sidebar.Menu> <Sidebar.Menu>
<!-- 版本号 -->
<Sidebar.MenuItem>
<Sidebar.MenuButton>
{#snippet child({ props })}
<button
{...props}
onclick={() => changelogOpen = true}
class="w-full"
title="查看更新日志"
>
<Info class="size-4" />
<span class="text-xs">v{pkg.version}</span>
</button>
{/snippet}
</Sidebar.MenuButton>
</Sidebar.MenuItem>
<!-- 用户信息 -->
<Sidebar.MenuItem> <Sidebar.MenuItem>
<DropdownMenu.Root> <DropdownMenu.Root>
<DropdownMenu.Trigger> <DropdownMenu.Trigger>
@@ -344,4 +368,7 @@
</main> </main>
</Sidebar.Inset> </Sidebar.Inset>
</Sidebar.Provider> </Sidebar.Provider>
<!-- Changelog 抽屉 -->
<ChangelogDrawer bind:open={changelogOpen} />
{/if} {/if}