Files
ftb-project-management/apps/web/stores/useRequirementStore.ts
Script Generator e261c3d0b8 feat(product): 实现产品需求管理模块(后端 + 前端)
后端:Product Module(CRUD)、Requirement Module(CRUD + 状态机流转)、PrismaService
前端:产品列表页、产品详情页(含需求池 Tab)、Zustand Store、API 封装

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-08 11:06:16 +08:00

67 lines
2.4 KiB
TypeScript

'use client';
import { create } from 'zustand';
import { Requirement, RequirementStatus } from '@ftb/shared';
import { api } from '@/lib/api';
interface RequirementWithCreator extends Requirement {
creator?: { id: string; name: string };
}
interface RequirementState {
requirements: RequirementWithCreator[];
loading: boolean;
error: string | null;
statusFilter: RequirementStatus | null;
fetchRequirements: (productId: string, status?: RequirementStatus) => Promise<void>;
createRequirement: (productId: string, data: { title: string; description?: string; priority?: number; creatorId: string }) => Promise<void>;
updateRequirement: (productId: string, id: string, data: { title?: string; description?: string; priority?: number }) => Promise<void>;
updateStatus: (productId: string, id: string, status: RequirementStatus) => Promise<void>;
deleteRequirement: (productId: string, id: string) => Promise<void>;
setStatusFilter: (status: RequirementStatus | null) => void;
}
export const useRequirementStore = create<RequirementState>((set, get) => ({
requirements: [],
loading: false,
error: null,
statusFilter: null,
fetchRequirements: async (productId, status) => {
set({ loading: true, error: null });
try {
const query = status ? `?status=${status}` : '';
const requirements = await api.get<RequirementWithCreator[]>(
`/products/${productId}/requirements${query}`,
);
set({ requirements, loading: false });
} catch (e: any) {
set({ error: e.message, loading: false });
}
},
createRequirement: async (productId, data) => {
await api.post(`/products/${productId}/requirements`, data);
await get().fetchRequirements(productId, get().statusFilter || undefined);
},
updateRequirement: async (productId, id, data) => {
await api.patch(`/products/${productId}/requirements/${id}`, data);
await get().fetchRequirements(productId, get().statusFilter || undefined);
},
updateStatus: async (productId, id, status) => {
await api.patch(`/products/${productId}/requirements/${id}/status`, { status });
await get().fetchRequirements(productId, get().statusFilter || undefined);
},
deleteRequirement: async (productId, id) => {
await api.delete(`/products/${productId}/requirements/${id}`);
set({ requirements: get().requirements.filter((r) => r.id !== id) });
},
setStatusFilter: (status) => {
set({ statusFilter: status });
},
}));