refactor: API 请求整合与 Bug 修复
前端重构: - 新增 api/ 目录统一管理所有 API 请求 - 所有 stores 和 pages 改为使用 api 模块 - 修复日期格式化函数,支持 Date 对象和 ISO 字符串 - 修复 TransactionItem 使用 CategoryIcon 组件 - 优化 ChartWrapper 区分 H5 和小程序环境 后端修复: - 修复 auth 中间件 PUBLIC_PATHS 缺少 demo-login - 修复备份工具命令注入漏洞,改用 execFile - 修复 stats 路由 type 参数验证 - 优化分类排序为批量 SQL 更新 - 合并迁移和删除为数据库事务原子操作 - 修复交易和统计日期返回格式 - 新增自动备份功能(启动时备份)
This commit is contained in:
17
client/src/api/auth.ts
Normal file
17
client/src/api/auth.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { request } from '@/utils/request'
|
||||
|
||||
/** 登录响应 */
|
||||
export interface LoginResult {
|
||||
token: string
|
||||
userId: number
|
||||
}
|
||||
|
||||
/** H5 演示登录 */
|
||||
export function demoLogin() {
|
||||
return request<LoginResult>({ url: '/auth/demo-login', method: 'POST' })
|
||||
}
|
||||
|
||||
/** 微信登录 */
|
||||
export function wxLogin(code: string) {
|
||||
return request<LoginResult>({ url: '/auth/login', method: 'POST', data: { code } })
|
||||
}
|
||||
18
client/src/api/budget.ts
Normal file
18
client/src/api/budget.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { request } from '@/utils/request'
|
||||
|
||||
/** 预算 */
|
||||
export interface Budget {
|
||||
id: number
|
||||
amount: number
|
||||
month: string
|
||||
}
|
||||
|
||||
/** 获取预算 */
|
||||
export function getBudget(month?: string) {
|
||||
return request<Budget | null>({ url: '/budget', data: month ? { month } : {} })
|
||||
}
|
||||
|
||||
/** 设置预算 */
|
||||
export function setBudget(amount: number, month: string) {
|
||||
return request<{ id: number }>({ url: '/budget', method: 'POST', data: { amount, month } })
|
||||
}
|
||||
52
client/src/api/category.ts
Normal file
52
client/src/api/category.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { request } from '@/utils/request'
|
||||
|
||||
/** 分类 */
|
||||
export interface Category {
|
||||
id: number
|
||||
name: string
|
||||
icon: string
|
||||
color: string
|
||||
type: 'expense' | 'income'
|
||||
sort_order: number
|
||||
is_custom: number
|
||||
}
|
||||
|
||||
/** 获取分类列表 */
|
||||
export function getCategories() {
|
||||
return request<Category[]>({ url: '/categories' })
|
||||
}
|
||||
|
||||
/** 创建分类 */
|
||||
export function createCategory(data: {
|
||||
name: string
|
||||
icon: string
|
||||
color: string
|
||||
type: 'expense' | 'income'
|
||||
}) {
|
||||
return request<{ id: number }>({ url: '/categories', method: 'POST', data })
|
||||
}
|
||||
|
||||
/** 更新分类 */
|
||||
export function updateCategory(id: number, data: { name: string; color: string }) {
|
||||
return request({ url: `/categories/${id}`, method: 'PUT', data })
|
||||
}
|
||||
|
||||
/** 删除分类 */
|
||||
export function deleteCategory(id: number) {
|
||||
return request({ url: `/categories/${id}`, method: 'DELETE' })
|
||||
}
|
||||
|
||||
/** 获取分类关联的交易数量 */
|
||||
export function getCategoryTransactionCount(id: number) {
|
||||
return request<{ count: number }>({ url: `/categories/${id}/transaction-count` })
|
||||
}
|
||||
|
||||
/** 迁移分类关联的交易并删除分类 */
|
||||
export function migrateCategory(fromId: number, targetId: number) {
|
||||
return request({ url: `/categories/${fromId}/migrate`, method: 'POST', data: { targetId } })
|
||||
}
|
||||
|
||||
/** 更新分类排序 */
|
||||
export function sortCategories(ids: number[]) {
|
||||
return request({ url: '/categories/sort', method: 'PUT', data: { ids } })
|
||||
}
|
||||
5
client/src/api/index.ts
Normal file
5
client/src/api/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export * from './auth'
|
||||
export * from './transaction'
|
||||
export * from './category'
|
||||
export * from './budget'
|
||||
export * from './stats'
|
||||
40
client/src/api/stats.ts
Normal file
40
client/src/api/stats.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { request } from '@/utils/request'
|
||||
|
||||
/** 概览数据 */
|
||||
export interface Overview {
|
||||
expense: number
|
||||
income: number
|
||||
count: number
|
||||
daily: number
|
||||
}
|
||||
|
||||
/** 分类统计 */
|
||||
export interface CategoryStat {
|
||||
id: number
|
||||
name: string
|
||||
icon: string
|
||||
color: string
|
||||
amount: number
|
||||
count: number
|
||||
}
|
||||
|
||||
/** 趋势数据点 */
|
||||
export interface TrendPoint {
|
||||
date: string
|
||||
amount: number
|
||||
}
|
||||
|
||||
/** 获取概览数据 */
|
||||
export function getOverview(params?: { month?: string; startDate?: string; endDate?: string }) {
|
||||
return request<Overview>({ url: '/stats/overview', data: params })
|
||||
}
|
||||
|
||||
/** 获取分类统计 */
|
||||
export function getCategoryStats(month?: string, type: string = 'expense') {
|
||||
return request<CategoryStat[]>({ url: '/stats/category', data: { month, type } })
|
||||
}
|
||||
|
||||
/** 获取趋势数据 */
|
||||
export function getTrend(month?: string, type: string = 'expense') {
|
||||
return request<TrendPoint[]>({ url: '/stats/trend', data: { month, type } })
|
||||
}
|
||||
69
client/src/api/transaction.ts
Normal file
69
client/src/api/transaction.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { request } from '@/utils/request'
|
||||
|
||||
/** 交易记录 */
|
||||
export interface Transaction {
|
||||
id: number
|
||||
amount: number
|
||||
type: 'expense' | 'income'
|
||||
category_id: number
|
||||
note?: string
|
||||
date: string
|
||||
category_name?: string
|
||||
category_icon?: string
|
||||
category_color?: string
|
||||
}
|
||||
|
||||
/** 交易列表响应 */
|
||||
export interface TransactionList {
|
||||
list: Transaction[]
|
||||
total: number
|
||||
page: number
|
||||
pageSize: number
|
||||
}
|
||||
|
||||
/** 获取交易列表参数 */
|
||||
export interface TransactionParams {
|
||||
page: number
|
||||
pageSize?: number
|
||||
type?: string
|
||||
startDate?: string
|
||||
endDate?: string
|
||||
sortBy?: string
|
||||
}
|
||||
|
||||
/** 获取交易列表 */
|
||||
export function getTransactions(params: TransactionParams) {
|
||||
return request<TransactionList>({ url: '/transactions', data: params })
|
||||
}
|
||||
|
||||
/** 获取单条交易记录 */
|
||||
export function getTransaction(id: number) {
|
||||
return request<Transaction>({ url: `/transactions/${id}` })
|
||||
}
|
||||
|
||||
/** 创建交易记录 */
|
||||
export function createTransaction(data: {
|
||||
amount: number
|
||||
type: 'expense' | 'income'
|
||||
category_id?: number
|
||||
note?: string
|
||||
date: string
|
||||
}) {
|
||||
return request<{ id: number }>({ url: '/transactions', method: 'POST', data })
|
||||
}
|
||||
|
||||
/** 更新交易记录 */
|
||||
export function updateTransaction(id: number, data: {
|
||||
amount: number
|
||||
type: 'expense' | 'income'
|
||||
category_id?: number
|
||||
note?: string
|
||||
date: string
|
||||
}) {
|
||||
return request({ url: `/transactions/${id}`, method: 'PUT', data })
|
||||
}
|
||||
|
||||
/** 删除交易记录 */
|
||||
export function deleteTransaction(id: number) {
|
||||
return request({ url: `/transactions/${id}`, method: 'DELETE' })
|
||||
}
|
||||
Reference in New Issue
Block a user