c5413644f9
Add group expense tracking (ledger) and public asset inventory (asset) features. Ledger supports income/expense recording with monthly summary. Asset tracks group equipment with free-form holder transfer. Both are independent pages accessible from GroupView navigation. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
112 lines
2.6 KiB
TypeScript
112 lines
2.6 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
import { ref } from 'vue'
|
|
import type { Asset } from '@/types'
|
|
import {
|
|
listAssets,
|
|
createAsset,
|
|
updateAsset,
|
|
transferAsset,
|
|
deleteAsset,
|
|
subscribeAssets
|
|
} from '@/api/assets'
|
|
import type { CreateAssetData, UpdateAssetData } from '@/api/assets'
|
|
|
|
export const useAssetStore = defineStore('asset', () => {
|
|
const assets = ref<Asset[]>([])
|
|
const loading = ref(false)
|
|
let unsubFn: (() => Promise<void> | void) | null = null
|
|
|
|
async function loadAssets(groupId: string) {
|
|
try {
|
|
loading.value = true
|
|
assets.value = await listAssets(groupId)
|
|
} catch (error) {
|
|
console.error('加载资产列表失败:', error)
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function addAsset(data: CreateAssetData) {
|
|
try {
|
|
loading.value = true
|
|
await createAsset(data)
|
|
await loadAssets(data.group)
|
|
} catch (error) {
|
|
console.error('创建资产失败:', error)
|
|
throw error
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function editAsset(assetId: string, data: UpdateAssetData, image?: File) {
|
|
try {
|
|
loading.value = true
|
|
await updateAsset(assetId, data, image)
|
|
// 找到当前资产的 groupId 以刷新列表
|
|
const asset = assets.value.find(a => a.id === assetId)
|
|
if (asset) {
|
|
await loadAssets(asset.group)
|
|
}
|
|
} catch (error) {
|
|
console.error('更新资产失败:', error)
|
|
throw error
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function transfer(assetId: string, userId: string) {
|
|
try {
|
|
await transferAsset(assetId, userId)
|
|
const asset = assets.value.find(a => a.id === assetId)
|
|
if (asset) {
|
|
await loadAssets(asset.group)
|
|
}
|
|
} catch (error) {
|
|
console.error('转移资产失败:', error)
|
|
throw error
|
|
}
|
|
}
|
|
|
|
async function removeAsset(assetId: string) {
|
|
try {
|
|
await deleteAsset(assetId)
|
|
const asset = assets.value.find(a => a.id === assetId)
|
|
assets.value = assets.value.filter(a => a.id !== assetId)
|
|
// 返回 groupId 以便调用方需要时使用
|
|
return asset?.group
|
|
} catch (error) {
|
|
console.error('删除资产失败:', error)
|
|
throw error
|
|
}
|
|
}
|
|
|
|
async function startSubscription(groupId: string) {
|
|
stopSubscription()
|
|
unsubFn = await subscribeAssets(groupId, () => {
|
|
loadAssets(groupId)
|
|
})
|
|
}
|
|
|
|
function stopSubscription() {
|
|
if (unsubFn) {
|
|
unsubFn()
|
|
unsubFn = null
|
|
}
|
|
}
|
|
|
|
return {
|
|
assets,
|
|
loading,
|
|
loadAssets,
|
|
addAsset,
|
|
editAsset,
|
|
transfer,
|
|
removeAsset,
|
|
startSubscription,
|
|
stopSubscription
|
|
}
|
|
})
|