feat: 完善项目架构并增强分析页面功能
- 新增项目文档和 Docker 配置 - 添加 README.md 和 TODO.md 项目文档 - 为各服务添加 Dockerfile 和 docker-compose 配置 - 重构后端架构 - 新增 adapter 层(HTTP/Python 适配器) - 新增 repository 层(数据访问抽象) - 新增 router 模块统一管理路由 - 新增账单处理 handler - 扩展前端 UI 组件库 - 新增 Calendar、DateRangePicker、Drawer、Popover 等组件 - 集成 shadcn-svelte 组件库 - 增强分析页面功能 - 添加时间范围筛选器(支持本月默认值) - 修复 DateRangePicker 默认值显示问题 - 优化数据获取和展示逻辑 - 完善分析器服务 - 新增 FastAPI 服务接口 - 改进账单清理器实现
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { uploadBill, type UploadResponse } from '$lib/api';
|
||||
import { uploadBill, type UploadResponse, type BillType } from '$lib/api';
|
||||
import * as Card from '$lib/components/ui/card';
|
||||
import { Button } from '$lib/components/ui/button';
|
||||
import { Badge } from '$lib/components/ui/badge';
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
let isDragOver = $state(false);
|
||||
let selectedFile: File | null = $state(null);
|
||||
let selectedType: BillType = $state('alipay');
|
||||
let isUploading = $state(false);
|
||||
let uploadResult: UploadResponse | null = $state(null);
|
||||
let errorMessage = $state('');
|
||||
@@ -86,6 +87,14 @@
|
||||
selectedFile = file;
|
||||
errorMessage = '';
|
||||
uploadResult = null;
|
||||
|
||||
// 根据文件名自动识别账单类型
|
||||
const fileName = file.name.toLowerCase();
|
||||
if (fileName.includes('支付宝') || fileName.includes('alipay')) {
|
||||
selectedType = 'alipay';
|
||||
} else if (fileName.includes('微信') || fileName.includes('wechat')) {
|
||||
selectedType = 'wechat';
|
||||
}
|
||||
}
|
||||
|
||||
function clearFile() {
|
||||
@@ -101,7 +110,7 @@
|
||||
errorMessage = '';
|
||||
|
||||
try {
|
||||
const result = await uploadBill(selectedFile);
|
||||
const result = await uploadBill(selectedFile, selectedType);
|
||||
if (result.result) {
|
||||
uploadResult = result;
|
||||
} else {
|
||||
@@ -135,7 +144,7 @@
|
||||
<!-- 统计卡片 -->
|
||||
<div class="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
|
||||
{#each stats as stat}
|
||||
<Card.Root>
|
||||
<Card.Root class="transition-all duration-200 hover:shadow-lg hover:-translate-y-1 cursor-default">
|
||||
<Card.Header class="flex flex-row items-center justify-between space-y-0 pb-2">
|
||||
<Card.Title class="text-sm font-medium">{stat.title}</Card.Title>
|
||||
{#if stat.trend === 'up'}
|
||||
@@ -226,6 +235,27 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- 账单类型选择 -->
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="text-sm font-medium">账单类型:</span>
|
||||
<div class="flex gap-2">
|
||||
<Button
|
||||
variant={selectedType === 'alipay' ? 'default' : 'outline'}
|
||||
size="sm"
|
||||
onclick={() => selectedType = 'alipay'}
|
||||
>
|
||||
支付宝
|
||||
</Button>
|
||||
<Button
|
||||
variant={selectedType === 'wechat' ? 'default' : 'outline'}
|
||||
size="sm"
|
||||
onclick={() => selectedType = 'wechat'}
|
||||
>
|
||||
微信
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 上传按钮 -->
|
||||
<Button
|
||||
class="w-full"
|
||||
@@ -256,7 +286,7 @@
|
||||
<CheckCircle class="h-5 w-5 text-green-600 dark:text-green-400" />
|
||||
<div>
|
||||
<p class="font-medium text-green-800 dark:text-green-200">处理成功</p>
|
||||
<p class="text-sm text-green-600 dark:text-green-400">账单已分析完成</p>
|
||||
<p class="text-sm text-green-600 dark:text-green-400">{uploadResult.message}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -267,6 +297,14 @@
|
||||
{uploadResult.data?.bill_type === 'alipay' ? '支付宝' : '微信'}
|
||||
</Badge>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-sm text-muted-foreground">原始记录数</span>
|
||||
<span class="text-sm font-medium">{uploadResult.data?.raw_count ?? 0} 条</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-sm text-muted-foreground">清洗后记录数</span>
|
||||
<span class="text-sm font-medium">{uploadResult.data?.cleaned_count ?? 0} 条</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-sm text-muted-foreground">输出文件</span>
|
||||
<span class="text-sm font-medium">{uploadResult.data?.file_name}</span>
|
||||
@@ -275,7 +313,7 @@
|
||||
|
||||
<div class="flex gap-3 pt-2">
|
||||
<a
|
||||
href={`http://localhost:8080${uploadResult.data?.file_url}`}
|
||||
href={uploadResult.data?.file_url || '#'}
|
||||
download
|
||||
class="flex-1"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user