feat: 完成任务1 - 建立项目版本管理和基础架构
任务1.1 初始化 Git 版本控制 - 建立 Git 仓库并连接到阿里云服务器 - 创建 .gitignore 和项目文档 - 建立 master/develop 分支管理策略 任务1.2 搭建前端项目基础架构 - 创建 Vue.js 3 + TypeScript 项目 - 集成 Tailwind CSS 和温暖现代主义设计系统 - 实现基础 UI 组件库(BaseButton, BaseCard, BaseInput) - 建立路由结构和页面组件 - 配置 Vite 构建工具 任务1.3 配置 Capacitor 和本地存储 - 集成 Capacitor.js 并生成 Android 项目 - 配置 SQLite 数据库和数据模型 - 实现完整的数据库服务层 - 创建 Pinia 状态管理 store - 建立本地数据 CRUD 操作基础 技术栈:Vue 3 + TypeScript + Tailwind CSS + Capacitor + SQLite
This commit is contained in:
174
frontend/src/stores/database.ts
Normal file
174
frontend/src/stores/database.ts
Normal file
@@ -0,0 +1,174 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
import { databaseService, type Transaction, type Category, type Account } from '@/services/database'
|
||||
|
||||
export const useDatabaseStore = defineStore('database', () => {
|
||||
const isInitialized = ref(false)
|
||||
const isLoading = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
|
||||
// 数据状态
|
||||
const transactions = ref<Transaction[]>([])
|
||||
const categories = ref<Category[]>([])
|
||||
const accounts = ref<Account[]>([])
|
||||
|
||||
// 初始化数据库
|
||||
async function initialize() {
|
||||
if (isInitialized.value) return
|
||||
|
||||
isLoading.value = true
|
||||
error.value = null
|
||||
|
||||
try {
|
||||
await databaseService.initialize()
|
||||
await loadInitialData()
|
||||
isInitialized.value = true
|
||||
console.log('Database store initialized successfully')
|
||||
} catch (err) {
|
||||
error.value = err instanceof Error ? err.message : 'Database initialization failed'
|
||||
console.error('Database store initialization failed:', err)
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 加载初始数据
|
||||
async function loadInitialData() {
|
||||
try {
|
||||
const [transactionsData, categoriesData, accountsData] = await Promise.all([
|
||||
databaseService.getTransactions(20, 0),
|
||||
databaseService.getCategories(),
|
||||
databaseService.getAccounts()
|
||||
])
|
||||
|
||||
transactions.value = transactionsData
|
||||
categories.value = categoriesData
|
||||
accounts.value = accountsData
|
||||
} catch (err) {
|
||||
console.error('Failed to load initial data:', err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
// 交易操作
|
||||
async function addTransaction(transaction: Omit<Transaction, 'id'>) {
|
||||
try {
|
||||
const id = await databaseService.createTransaction(transaction)
|
||||
const newTransaction = { ...transaction, id }
|
||||
transactions.value.unshift(newTransaction)
|
||||
return id
|
||||
} catch (err) {
|
||||
console.error('Failed to add transaction:', err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
async function updateTransaction(id: number, updates: Partial<Transaction>) {
|
||||
try {
|
||||
await databaseService.updateTransaction(id, updates)
|
||||
const index = transactions.value.findIndex(t => t.id === id)
|
||||
if (index !== -1) {
|
||||
transactions.value[index] = { ...transactions.value[index], ...updates }
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to update transaction:', err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteTransaction(id: number) {
|
||||
try {
|
||||
await databaseService.deleteTransaction(id)
|
||||
const index = transactions.value.findIndex(t => t.id === id)
|
||||
if (index !== -1) {
|
||||
transactions.value.splice(index, 1)
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to delete transaction:', err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
// 分类操作
|
||||
async function addCategory(category: Omit<Category, 'id'>) {
|
||||
try {
|
||||
const id = await databaseService.createCategory(category)
|
||||
const newCategory = { ...category, id }
|
||||
categories.value.push(newCategory)
|
||||
return id
|
||||
} catch (err) {
|
||||
console.error('Failed to add category:', err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
// 账户操作
|
||||
async function addAccount(account: Omit<Account, 'id'>) {
|
||||
try {
|
||||
const id = await databaseService.createAccount(account)
|
||||
const newAccount = { ...account, id }
|
||||
accounts.value.push(newAccount)
|
||||
return id
|
||||
} catch (err) {
|
||||
console.error('Failed to add account:', err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
// 获取默认分类和账户
|
||||
function getDefaultCategory(type: 'income' | 'expense'): Category | undefined {
|
||||
return categories.value.find(c => c.is_default && (c.type === type || c.type === 'both'))
|
||||
}
|
||||
|
||||
function getDefaultAccount(): Account | undefined {
|
||||
return accounts.value.find(a => a.is_default)
|
||||
}
|
||||
|
||||
// 搜索和筛选
|
||||
function searchTransactions(query: string): Transaction[] {
|
||||
if (!query.trim()) return transactions.value
|
||||
|
||||
const lowerQuery = query.toLowerCase()
|
||||
return transactions.value.filter(t =>
|
||||
t.merchant.toLowerCase().includes(lowerQuery) ||
|
||||
(t.description && t.description.toLowerCase().includes(lowerQuery))
|
||||
)
|
||||
}
|
||||
|
||||
function filterTransactionsByCategory(categoryId: number): Transaction[] {
|
||||
return transactions.value.filter(t => t.category_id === categoryId)
|
||||
}
|
||||
|
||||
function filterTransactionsByAccount(accountId: number): Transaction[] {
|
||||
return transactions.value.filter(t => t.account_id === accountId)
|
||||
}
|
||||
|
||||
function filterTransactionsByDateRange(startDate: string, endDate: string): Transaction[] {
|
||||
return transactions.value.filter(t => t.date >= startDate && t.date <= endDate)
|
||||
}
|
||||
|
||||
return {
|
||||
// 状态
|
||||
isInitialized,
|
||||
isLoading,
|
||||
error,
|
||||
transactions,
|
||||
categories,
|
||||
accounts,
|
||||
|
||||
// 方法
|
||||
initialize,
|
||||
loadInitialData,
|
||||
addTransaction,
|
||||
updateTransaction,
|
||||
deleteTransaction,
|
||||
addCategory,
|
||||
addAccount,
|
||||
getDefaultCategory,
|
||||
getDefaultAccount,
|
||||
searchTransactions,
|
||||
filterTransactionsByCategory,
|
||||
filterTransactionsByAccount,
|
||||
filterTransactionsByDateRange
|
||||
}
|
||||
})
|
Reference in New Issue
Block a user