feat: 小菜记账 v1.0 - 完整功能实现
核心功能: - 记账CRUD(支出/收入/分类/备注/日期) - 统计分析(概览/分类占比/每日趋势) - 预算管理(按月设置/进度条/超支提醒) - 数据导出CSV 安全与认证: - HMAC-SHA256签名token认证 - 用户数据隔离 - 输入验证与错误处理 - CORS配置 前端优化: - 骨架屏加载 - 账单按日期分组 - 预算页面重构(快捷预设+Numpad) - SvgIcon组件(H5+微信双端适配) - 下拉刷新 后端优化: - 共享日期工具函数 - 数据库连接池优化 - 健康检查端点 - 优雅关闭处理 技术栈: - 前端:Uni-app (Vue 3 + Pinia) - 后端:Node.js + Express + MySQL
This commit is contained in:
95
client/src/components/TransactionItem/TransactionItem.vue
Normal file
95
client/src/components/TransactionItem/TransactionItem.vue
Normal file
@@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<view class="tx-item" @tap="$emit('tap', item)" @longpress="$emit('longpress', item)">
|
||||
<view class="icon-wrap" :style="{ background: item.category_color + '20' }">
|
||||
<text class="icon-text" :style="{ color: item.category_color }">{{ item.category_name?.[0] || '?' }}</text>
|
||||
</view>
|
||||
<view class="info">
|
||||
<text class="name">{{ item.note || item.category_name || '未分类' }}</text>
|
||||
<text class="meta">{{ item.category_name || '未分类' }}{{ hideDate ? '' : ' · ' + formatDate(item.date) }}</text>
|
||||
</view>
|
||||
<text class="amount" :class="item.type">{{ item.type === 'expense' ? '-' : '+' }}{{ formatAmount(item.amount) }}</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { formatAmount, formatDate } from '@/utils/format'
|
||||
|
||||
withDefaults(defineProps<{
|
||||
item: {
|
||||
id: number
|
||||
amount: number
|
||||
type: 'expense' | 'income'
|
||||
note?: string
|
||||
date: string
|
||||
category_name?: string
|
||||
category_icon?: string
|
||||
category_color?: string
|
||||
}
|
||||
hideDate?: boolean
|
||||
}>(), { hideDate: false })
|
||||
|
||||
defineEmits(['tap', 'longpress'])
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tx-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 28rpx 0;
|
||||
gap: 24rpx;
|
||||
border-radius: 20rpx;
|
||||
transition: background 0.15s;
|
||||
|
||||
&:active {
|
||||
background: #FFF0E6;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-wrap {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 24rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.icon-text {
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
color: #2D1B1B;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.meta {
|
||||
font-size: 24rpx;
|
||||
color: #8B7E7E;
|
||||
display: block;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
|
||||
.amount {
|
||||
font-family: 'Fredoka', sans-serif;
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
font-variant-numeric: tabular-nums;
|
||||
white-space: nowrap;
|
||||
|
||||
&.expense { color: #2D1B1B; }
|
||||
&.income { color: #7BC67E; }
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user