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>
This commit is contained in:
22
apps/web/lib/api.ts
Normal file
22
apps/web/lib/api.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
const API_BASE = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3001/api/v1';
|
||||
|
||||
async function request<T>(path: string, options?: RequestInit): Promise<T> {
|
||||
const res = await fetch(`${API_BASE}${path}`, {
|
||||
headers: { 'Content-Type': 'application/json', ...options?.headers },
|
||||
...options,
|
||||
});
|
||||
if (!res.ok) {
|
||||
const error = await res.json().catch(() => ({}));
|
||||
throw new Error(error.message || `请求失败: ${res.status}`);
|
||||
}
|
||||
return res.json();
|
||||
}
|
||||
|
||||
export const api = {
|
||||
get: <T>(path: string) => request<T>(path),
|
||||
post: <T>(path: string, data: unknown) =>
|
||||
request<T>(path, { method: 'POST', body: JSON.stringify(data) }),
|
||||
patch: <T>(path: string, data: unknown) =>
|
||||
request<T>(path, { method: 'PATCH', body: JSON.stringify(data) }),
|
||||
delete: <T>(path: string) => request<T>(path, { method: 'DELETE' }),
|
||||
};
|
||||
25
apps/web/lib/constants.ts
Normal file
25
apps/web/lib/constants.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { RequirementStatus } from '@ftb/shared';
|
||||
|
||||
export const REQUIREMENT_STATUS_LABEL: Record<RequirementStatus, string> = {
|
||||
[RequirementStatus.DRAFT]: '草稿',
|
||||
[RequirementStatus.REVIEWING]: '评审中',
|
||||
[RequirementStatus.APPROVED]: '已通过',
|
||||
[RequirementStatus.REJECTED]: '已拒绝',
|
||||
[RequirementStatus.DELIVERED]: '已交付',
|
||||
};
|
||||
|
||||
export const REQUIREMENT_STATUS_COLOR: Record<RequirementStatus, string> = {
|
||||
[RequirementStatus.DRAFT]: 'bg-gray-100 text-gray-700',
|
||||
[RequirementStatus.REVIEWING]: 'bg-blue-100 text-blue-700',
|
||||
[RequirementStatus.APPROVED]: 'bg-green-100 text-green-700',
|
||||
[RequirementStatus.REJECTED]: 'bg-red-100 text-red-700',
|
||||
[RequirementStatus.DELIVERED]: 'bg-purple-100 text-purple-700',
|
||||
};
|
||||
|
||||
export const PRIORITY_LABEL: Record<number, string> = {
|
||||
0: '无',
|
||||
1: '低',
|
||||
2: '中',
|
||||
3: '高',
|
||||
4: '紧急',
|
||||
};
|
||||
Reference in New Issue
Block a user