feat(health): 日常监测后端 + 积分商城 PC 管理页面 (Chunk 3 V2 迭代)
后端 - 日常监测: - 新增 daily_monitoring 表 (血压/体重/血糖/出入量/备注) - Entity/DTO/Service/Handler 完整 CRUD - 唯一约束 (patient_id, record_date) 防重复上报 前端 - 积分商城管理 (3 页面): - PointsRuleList: 积分规则增删改 + 启用禁用 - PointsProductList: 商品管理 + 库存 + 类型筛选 - PointsOrderList: 订单列表 + 扫码核销 - API 模块 points.ts 对接 6 个管理端接口 - 侧边栏新增积分规则/商品管理/订单管理入口
This commit is contained in:
131
apps/web/src/api/health/points.ts
Normal file
131
apps/web/src/api/health/points.ts
Normal file
@@ -0,0 +1,131 @@
|
||||
import client from '../client';
|
||||
import type { PaginatedResponse } from '../types';
|
||||
|
||||
// --- Types ---
|
||||
|
||||
export interface PointsRule {
|
||||
id: string;
|
||||
event_type: string;
|
||||
name: string;
|
||||
description: string | null;
|
||||
points_value: number;
|
||||
daily_cap: number;
|
||||
streak_7d_bonus: number;
|
||||
streak_14d_bonus: number;
|
||||
streak_30d_bonus: number;
|
||||
is_active: boolean;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
version: number;
|
||||
}
|
||||
|
||||
export interface CreatePointsRuleReq {
|
||||
event_type: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
points_value: number;
|
||||
daily_cap?: number;
|
||||
streak_7d_bonus?: number;
|
||||
streak_14d_bonus?: number;
|
||||
streak_30d_bonus?: number;
|
||||
}
|
||||
|
||||
export interface PointsProduct {
|
||||
id: string;
|
||||
name: string;
|
||||
product_type: string; // physical / service / privilege
|
||||
points_cost: number;
|
||||
stock: number;
|
||||
image_url: string | null;
|
||||
description: string | null;
|
||||
is_active: boolean;
|
||||
sort_order: number;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
version: number;
|
||||
}
|
||||
|
||||
export interface CreatePointsProductReq {
|
||||
name: string;
|
||||
product_type: string;
|
||||
points_cost: number;
|
||||
stock: number;
|
||||
description?: string;
|
||||
image_url?: string;
|
||||
sort_order?: number;
|
||||
}
|
||||
|
||||
export interface PointsOrder {
|
||||
id: string;
|
||||
patient_id: string;
|
||||
product_id: string;
|
||||
points_cost: number;
|
||||
status: string; // pending / verified / cancelled / expired
|
||||
qr_code: string;
|
||||
verified_by: string | null;
|
||||
verified_at: string | null;
|
||||
expires_at: string | null;
|
||||
notes: string | null;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
version: number;
|
||||
}
|
||||
|
||||
export interface VerifyOrderReq {
|
||||
qr_code: string;
|
||||
}
|
||||
|
||||
// --- API ---
|
||||
|
||||
export const pointsApi = {
|
||||
// Rules
|
||||
listRules: async () => {
|
||||
const { data } = await client.get<{
|
||||
success: boolean;
|
||||
data: PointsRule[];
|
||||
}>('/health/admin/points/rules');
|
||||
return data.data;
|
||||
},
|
||||
|
||||
createRule: async (req: CreatePointsRuleReq) => {
|
||||
const { data } = await client.post<{
|
||||
success: boolean;
|
||||
data: PointsRule;
|
||||
}>('/health/admin/points/rules', req);
|
||||
return data.data;
|
||||
},
|
||||
|
||||
// Products
|
||||
listProducts: async (params?: Record<string, unknown>) => {
|
||||
const { data } = await client.get<{
|
||||
success: boolean;
|
||||
data: PaginatedResponse<PointsProduct>;
|
||||
}>('/health/points/products', { params });
|
||||
return data.data;
|
||||
},
|
||||
|
||||
createProduct: async (req: CreatePointsProductReq) => {
|
||||
const { data } = await client.post<{
|
||||
success: boolean;
|
||||
data: PointsProduct;
|
||||
}>('/health/admin/points/products', req);
|
||||
return data.data;
|
||||
},
|
||||
|
||||
// Orders
|
||||
listOrders: async (params?: Record<string, unknown>) => {
|
||||
const { data } = await client.get<{
|
||||
success: boolean;
|
||||
data: PaginatedResponse<PointsOrder>;
|
||||
}>('/health/admin/points/orders', { params });
|
||||
return data.data;
|
||||
},
|
||||
|
||||
verifyOrder: async (req: VerifyOrderReq) => {
|
||||
const { data } = await client.post<{
|
||||
success: boolean;
|
||||
data: PointsOrder;
|
||||
}>('/health/points/verify', req);
|
||||
return data.data;
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user