e4b730c8db
- Ledger store: add stopSubscription() to properly clean up realtime subscriptions, matching asset store pattern - LedgerList: call stopSubscription on unmount - Assets migration: restrict image upload to image/* mime types (C3 updateRule is a known tradeoff — PocketBase lacks field-level permissions, frontend enforces edit restrictions instead) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
109 lines
2.6 KiB
TypeScript
109 lines
2.6 KiB
TypeScript
// src/stores/ledger.ts
|
|
import { defineStore } from 'pinia'
|
|
import { ref } from 'vue'
|
|
import type { Ledger } from '@/types'
|
|
import {
|
|
listLedgers,
|
|
createLedger,
|
|
updateLedger,
|
|
deleteLedger,
|
|
getLedgerSummary,
|
|
subscribeLedgers
|
|
} from '@/api/ledgers'
|
|
|
|
export const useLedgerStore = defineStore('ledger', () => {
|
|
const ledgers = ref<Ledger[]>([])
|
|
const loading = ref(false)
|
|
const summary = ref({ totalIncome: 0, totalExpense: 0, balance: 0 })
|
|
const currentMonth = ref(new Date().toISOString().slice(0, 7))
|
|
let unsubFn: (() => Promise<void> | void) | null = null
|
|
|
|
// 加载账目列表和汇总
|
|
async function loadLedgers(groupId: string, month?: string) {
|
|
try {
|
|
loading.value = true
|
|
const filterMonth = month || currentMonth.value
|
|
const [listResult, summaryResult] = await Promise.all([
|
|
listLedgers(groupId, { month: filterMonth }),
|
|
getLedgerSummary(groupId, filterMonth)
|
|
])
|
|
ledgers.value = listResult.items
|
|
summary.value = summaryResult
|
|
if (month) currentMonth.value = month
|
|
} catch (error) {
|
|
console.error('加载账目列表失败:', error)
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
// 只加载汇总
|
|
async function loadSummary(groupId: string, month?: string) {
|
|
try {
|
|
const filterMonth = month || currentMonth.value
|
|
summary.value = await getLedgerSummary(groupId, filterMonth)
|
|
} catch (error) {
|
|
console.error('加载账目汇总失败:', error)
|
|
}
|
|
}
|
|
|
|
// 新增账目
|
|
async function addLedger(data: Parameters<typeof createLedger>[0]) {
|
|
try {
|
|
await createLedger(data)
|
|
} catch (error) {
|
|
console.error('新增账目失败:', error)
|
|
throw error
|
|
}
|
|
}
|
|
|
|
// 编辑账目
|
|
async function editLedger(ledgerId: string, data: Parameters<typeof updateLedger>[1]) {
|
|
try {
|
|
await updateLedger(ledgerId, data)
|
|
} catch (error) {
|
|
console.error('编辑账目失败:', error)
|
|
throw error
|
|
}
|
|
}
|
|
|
|
// 删除账目
|
|
async function removeLedger(ledgerId: string) {
|
|
try {
|
|
await deleteLedger(ledgerId)
|
|
} catch (error) {
|
|
console.error('删除账目失败:', error)
|
|
throw error
|
|
}
|
|
}
|
|
|
|
// 订阅实时更新
|
|
async function startSubscription(groupId: string) {
|
|
stopSubscription()
|
|
unsubFn = await subscribeLedgers(groupId, () => {
|
|
loadLedgers(groupId)
|
|
})
|
|
}
|
|
|
|
function stopSubscription() {
|
|
if (unsubFn) {
|
|
unsubFn()
|
|
unsubFn = null
|
|
}
|
|
}
|
|
|
|
return {
|
|
ledgers,
|
|
loading,
|
|
summary,
|
|
currentMonth,
|
|
loadLedgers,
|
|
loadSummary,
|
|
addLedger,
|
|
editLedger,
|
|
removeLedger,
|
|
startSubscription,
|
|
stopSubscription
|
|
}
|
|
})
|