- C2: ColorPicker and EditModal reusable components extracted - C2: tag-manage and category-manage pages use EditModal (remove ~120 dup lines) - C3: Upload logic extracted to server/src/utils/upload.ts - C4: /recurring/sync wrapped in DB transaction - C7: Backup download uses API_BASE (no hardcoded URLs) - C9: getAvatarUrl() utility function, used in 5 files - C1: getCurrentMonth() documented as aligned with server date.ts
53 lines
1.8 KiB
TypeScript
53 lines
1.8 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
import { ref, computed } from 'vue'
|
|
import * as api from '@/api/user'
|
|
import { getAvatarUrl } from '@/utils/avatar'
|
|
|
|
export const useUserStore = defineStore('user', () => {
|
|
const userInfo = ref<api.UserInfo | null>(null)
|
|
|
|
const nickname = computed(() => {
|
|
return userInfo.value?.nickname || uni.getStorageSync('xc:nickname') || '小菜'
|
|
})
|
|
|
|
const slogan = computed(() => {
|
|
return userInfo.value?.slogan
|
|
})
|
|
|
|
const avatarUrl = computed(() => {
|
|
const filename = userInfo.value?.avatar_url || uni.getStorageSync('xc:avatar_url') || ''
|
|
return getAvatarUrl(filename)
|
|
})
|
|
|
|
async function fetchUserInfo() {
|
|
userInfo.value = await api.getUserInfo()
|
|
if (userInfo.value) {
|
|
uni.setStorageSync('xc:nickname', userInfo.value.nickname)
|
|
uni.setStorageSync('xc:avatar_url', userInfo.value.avatar_url)
|
|
uni.setStorageSync('xc:role', userInfo.value.role)
|
|
}
|
|
}
|
|
|
|
async function updateProfile(data: { nickname?: string; slogan?: string }) {
|
|
const nickname = data.nickname ?? userInfo.value?.nickname ?? ''
|
|
const slogan = data.slogan ?? userInfo.value?.slogan ?? ''
|
|
await api.updateNickname(nickname, slogan)
|
|
if (userInfo.value) {
|
|
if (data.nickname !== undefined) userInfo.value.nickname = data.nickname
|
|
if (data.slogan !== undefined) userInfo.value.slogan = data.slogan
|
|
}
|
|
if (data.nickname !== undefined) {
|
|
uni.setStorageSync('xc:nickname', data.nickname)
|
|
}
|
|
}
|
|
|
|
async function uploadAvatar(filePath: string) {
|
|
const result = await api.uploadAvatar(filePath)
|
|
if (userInfo.value) userInfo.value.avatar_url = result.avatar_url
|
|
uni.setStorageSync('xc:avatar_url', result.avatar_url)
|
|
return avatarUrl.value
|
|
}
|
|
|
|
return { userInfo, nickname, slogan, avatarUrl, fetchUserInfo, updateProfile, uploadAvatar }
|
|
})
|