调整结构
This commit is contained in:
142
frontend/src/stores/userStore.ts
Normal file
142
frontend/src/stores/userStore.ts
Normal file
@@ -0,0 +1,142 @@
|
||||
import { create } from 'zustand'
|
||||
|
||||
import { userApi } from '../http/userApi'
|
||||
import type { UserQuery, UserRequest } from '../interfaces/user/api'
|
||||
import type { Role, Status, User, UserSummary } from '../interfaces/user/model'
|
||||
import { errorMessage } from '../utils/user'
|
||||
|
||||
interface UserStore {
|
||||
users: User[]
|
||||
total: number
|
||||
summary: UserSummary
|
||||
search: string
|
||||
roleFilter: Role | ''
|
||||
statusFilter: Status | ''
|
||||
selectedIds: Set<number>
|
||||
isLoading: boolean
|
||||
isSaving: boolean
|
||||
isBulkUpdating: boolean
|
||||
error: string
|
||||
setSearch: (search: string) => void
|
||||
setRoleFilter: (role: Role | '') => void
|
||||
setStatusFilter: (status: Status | '') => void
|
||||
clearFilters: () => void
|
||||
loadUsers: () => Promise<void>
|
||||
loadSummary: () => Promise<void>
|
||||
createUser: (payload: UserRequest) => Promise<boolean>
|
||||
updateUser: (id: number, payload: UserRequest) => Promise<boolean>
|
||||
deleteUser: (id: number) => Promise<boolean>
|
||||
updateSelectedStatus: (status: Status) => Promise<boolean>
|
||||
toggleSelected: (id: number) => void
|
||||
toggleAll: () => void
|
||||
clearError: () => void
|
||||
}
|
||||
|
||||
const emptySummary: UserSummary = { total: 0, active: 0, inactive: 0, admins: 0 }
|
||||
|
||||
function queryFromState(state: UserStore): UserQuery {
|
||||
return {
|
||||
keyword: state.search,
|
||||
role: state.roleFilter,
|
||||
status: state.statusFilter,
|
||||
page: 1,
|
||||
pageSize: 50,
|
||||
}
|
||||
}
|
||||
|
||||
export const useUserStore = create<UserStore>((set, get) => ({
|
||||
users: [],
|
||||
total: 0,
|
||||
summary: emptySummary,
|
||||
search: '',
|
||||
roleFilter: '',
|
||||
statusFilter: '',
|
||||
selectedIds: new Set<number>(),
|
||||
isLoading: true,
|
||||
isSaving: false,
|
||||
isBulkUpdating: false,
|
||||
error: '',
|
||||
setSearch: (search) => set({ search }),
|
||||
setRoleFilter: (roleFilter) => set({ roleFilter }),
|
||||
setStatusFilter: (statusFilter) => set({ statusFilter }),
|
||||
clearFilters: () => set({ search: '', roleFilter: '', statusFilter: '' }),
|
||||
loadUsers: async () => {
|
||||
set({ isLoading: true, error: '' })
|
||||
try {
|
||||
const data = await userApi.list(queryFromState(get()))
|
||||
set({ users: data.items, total: data.total, selectedIds: new Set<number>() })
|
||||
} catch (error) {
|
||||
set({ error: errorMessage(error, '无法加载用户列表') })
|
||||
} finally {
|
||||
set({ isLoading: false })
|
||||
}
|
||||
},
|
||||
loadSummary: async () => {
|
||||
try {
|
||||
const summary = await userApi.summary()
|
||||
set({ summary })
|
||||
} catch (error) {
|
||||
set({ error: errorMessage(error, '无法加载用户概览') })
|
||||
}
|
||||
},
|
||||
createUser: async (payload) => {
|
||||
set({ isSaving: true, error: '' })
|
||||
try {
|
||||
await userApi.create(payload)
|
||||
return true
|
||||
} catch (error) {
|
||||
set({ error: errorMessage(error, '保存失败,请检查输入') })
|
||||
return false
|
||||
} finally {
|
||||
set({ isSaving: false })
|
||||
}
|
||||
},
|
||||
updateUser: async (id, payload) => {
|
||||
set({ isSaving: true, error: '' })
|
||||
try {
|
||||
await userApi.update(id, payload)
|
||||
return true
|
||||
} catch (error) {
|
||||
set({ error: errorMessage(error, '保存失败,请检查输入') })
|
||||
return false
|
||||
} finally {
|
||||
set({ isSaving: false })
|
||||
}
|
||||
},
|
||||
deleteUser: async (id) => {
|
||||
set({ error: '' })
|
||||
try {
|
||||
await userApi.remove(id)
|
||||
return true
|
||||
} catch (error) {
|
||||
set({ error: errorMessage(error, '删除失败,请稍后重试') })
|
||||
return false
|
||||
}
|
||||
},
|
||||
updateSelectedStatus: async (status) => {
|
||||
const ids = [...get().selectedIds]
|
||||
if (ids.length === 0) return false
|
||||
set({ isBulkUpdating: true, error: '' })
|
||||
try {
|
||||
await userApi.updateStatuses({ ids, status })
|
||||
return true
|
||||
} catch (error) {
|
||||
set({ error: errorMessage(error, '批量更新失败,请稍后重试') })
|
||||
return false
|
||||
} finally {
|
||||
set({ isBulkUpdating: false })
|
||||
}
|
||||
},
|
||||
toggleSelected: (id) => set((state) => {
|
||||
const selectedIds = new Set(state.selectedIds)
|
||||
if (selectedIds.has(id)) selectedIds.delete(id)
|
||||
else selectedIds.add(id)
|
||||
return { selectedIds }
|
||||
}),
|
||||
toggleAll: () => set((state) => ({
|
||||
selectedIds: state.users.length > 0 && state.selectedIds.size === state.users.length
|
||||
? new Set<number>()
|
||||
: new Set(state.users.map((user) => user.id)),
|
||||
})),
|
||||
clearError: () => set({ error: '' }),
|
||||
}))
|
||||
Reference in New Issue
Block a user