feat(pre-planting): Admin Web 预种计划 Service 层
[2026-02-17] Admin Web 预种管理 API 服务 + React Query Hooks 新增文件: - endpoints.ts: PRE_PLANTING 端点组(config/toggle/orders/positions/merges/stats) - prePlantingService.ts: 预种管理服务(开关配置、订单/持仓/合并查询、统计汇总) - 完整 TypeScript 类型定义(Config, Stats, Order, Position, Merge) - 分页列表请求/响应类型 - usePrePlanting.ts: React Query hooks - Query key factory(层级化参数化) - usePrePlantingConfig/Stats/Orders/Positions/Merges - useTogglePrePlantingConfig(mutation + 自动刷新) - hooks/index.ts: 导出新 hooks 所有端点走 admin-service 的 PrePlantingAdminModule 与现有认种管理完全独立 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
03f5c4af28
commit
63ae7662a4
|
|
@ -5,3 +5,5 @@ export * from './useUsers';
|
|||
export * from './useUserDetailPage';
|
||||
export * from './useAuthorizations';
|
||||
export * from './useSystemWithdrawal';
|
||||
// [2026-02-17] 预种计划管理
|
||||
export * from './usePrePlanting';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,107 @@
|
|||
/**
|
||||
* [2026-02-17] 预种计划管理 React Query Hooks
|
||||
*
|
||||
* 为 admin-web 预种管理页面提供数据获取 hooks。
|
||||
* 遵循项目的 React Query 模式:
|
||||
* - Query key factory(层级化、参数化)
|
||||
* - 每个查询对应一个 hook
|
||||
* - useMutation 用于开关切换等写操作
|
||||
*
|
||||
* === 使用方式 ===
|
||||
* import { usePrePlantingConfig, usePrePlantingStats, ... } from '@/hooks';
|
||||
*/
|
||||
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import {
|
||||
prePlantingService,
|
||||
type PrePlantingListParams,
|
||||
} from '@/services/prePlantingService';
|
||||
|
||||
// ============================================
|
||||
// Query Key Factory
|
||||
// ============================================
|
||||
|
||||
export const prePlantingKeys = {
|
||||
all: ['pre-planting'] as const,
|
||||
config: () => [...prePlantingKeys.all, 'config'] as const,
|
||||
stats: () => [...prePlantingKeys.all, 'stats'] as const,
|
||||
orders: (params: PrePlantingListParams) =>
|
||||
[...prePlantingKeys.all, 'orders', params] as const,
|
||||
positions: (params: PrePlantingListParams) =>
|
||||
[...prePlantingKeys.all, 'positions', params] as const,
|
||||
merges: (params: PrePlantingListParams) =>
|
||||
[...prePlantingKeys.all, 'merges', params] as const,
|
||||
};
|
||||
|
||||
// ============================================
|
||||
// Query Hooks
|
||||
// ============================================
|
||||
|
||||
/** 获取预种开关配置 */
|
||||
export function usePrePlantingConfig() {
|
||||
return useQuery({
|
||||
queryKey: prePlantingKeys.config(),
|
||||
queryFn: () => prePlantingService.getConfig(),
|
||||
staleTime: 30 * 1000,
|
||||
gcTime: 5 * 60 * 1000,
|
||||
});
|
||||
}
|
||||
|
||||
/** 获取预种统计汇总 */
|
||||
export function usePrePlantingStats() {
|
||||
return useQuery({
|
||||
queryKey: prePlantingKeys.stats(),
|
||||
queryFn: () => prePlantingService.getStats(),
|
||||
staleTime: 30 * 1000,
|
||||
gcTime: 5 * 60 * 1000,
|
||||
});
|
||||
}
|
||||
|
||||
/** 获取预种订单列表 */
|
||||
export function usePrePlantingOrders(params: PrePlantingListParams = {}) {
|
||||
return useQuery({
|
||||
queryKey: prePlantingKeys.orders(params),
|
||||
queryFn: () => prePlantingService.getOrders(params),
|
||||
staleTime: 30 * 1000,
|
||||
gcTime: 5 * 60 * 1000,
|
||||
});
|
||||
}
|
||||
|
||||
/** 获取预种持仓列表 */
|
||||
export function usePrePlantingPositions(params: PrePlantingListParams = {}) {
|
||||
return useQuery({
|
||||
queryKey: prePlantingKeys.positions(params),
|
||||
queryFn: () => prePlantingService.getPositions(params),
|
||||
staleTime: 30 * 1000,
|
||||
gcTime: 5 * 60 * 1000,
|
||||
});
|
||||
}
|
||||
|
||||
/** 获取合并记录列表 */
|
||||
export function usePrePlantingMerges(params: PrePlantingListParams = {}) {
|
||||
return useQuery({
|
||||
queryKey: prePlantingKeys.merges(params),
|
||||
queryFn: () => prePlantingService.getMerges(params),
|
||||
staleTime: 30 * 1000,
|
||||
gcTime: 5 * 60 * 1000,
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Mutation Hooks
|
||||
// ============================================
|
||||
|
||||
/** 切换预种开关 */
|
||||
export function useTogglePrePlantingConfig() {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: (isActive: boolean) =>
|
||||
prePlantingService.toggleConfig(isActive),
|
||||
onSuccess: () => {
|
||||
// 开关切换后刷新配置和统计
|
||||
queryClient.invalidateQueries({ queryKey: prePlantingKeys.config() });
|
||||
queryClient.invalidateQueries({ queryKey: prePlantingKeys.stats() });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
@ -288,4 +288,20 @@ export const API_ENDPOINTS = {
|
|||
// 批量下载任务状态
|
||||
BATCH_DOWNLOAD_STATUS: (taskNo: string) => `/v1/admin/contracts/batch-download/${taskNo}`,
|
||||
},
|
||||
// [2026-02-17] 新增:预种计划管理 (admin-service / PrePlantingAdminModule)
|
||||
// 3171 USDT/份预种,累计 5 份合成 1 棵树
|
||||
// 开关管理 + 预种订单/持仓/合并记录查询
|
||||
PRE_PLANTING: {
|
||||
// 预种开关配置
|
||||
CONFIG: '/v1/admin/pre-planting/config',
|
||||
TOGGLE: '/v1/admin/pre-planting/config/toggle',
|
||||
// 预种订单列表(管理员视角,可按用户/状态过滤)
|
||||
ORDERS: '/v1/admin/pre-planting/orders',
|
||||
// 预种持仓列表(管理员视角)
|
||||
POSITIONS: '/v1/admin/pre-planting/positions',
|
||||
// 合并记录列表(管理员视角)
|
||||
MERGES: '/v1/admin/pre-planting/merges',
|
||||
// 预种统计汇总(总份数、总金额、合并树数等)
|
||||
STATS: '/v1/admin/pre-planting/stats',
|
||||
},
|
||||
} as const;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,163 @@
|
|||
/**
|
||||
* [2026-02-17] 预种计划管理服务
|
||||
*
|
||||
* 管理员端的预种计划 API 调用服务。
|
||||
* 提供预种开关管理、订单/持仓/合并记录查询、统计汇总等功能。
|
||||
*
|
||||
* === API 端点 ===
|
||||
* 所有端点走 admin-service 的 PrePlantingAdminModule:
|
||||
* - GET /v1/admin/pre-planting/config 获取预种开关配置
|
||||
* - PUT /v1/admin/pre-planting/config/toggle 切换预种开关
|
||||
* - GET /v1/admin/pre-planting/orders 预种订单列表
|
||||
* - GET /v1/admin/pre-planting/positions 预种持仓列表
|
||||
* - GET /v1/admin/pre-planting/merges 合并记录列表
|
||||
* - GET /v1/admin/pre-planting/stats 统计汇总
|
||||
*
|
||||
* === 与现有服务的关系 ===
|
||||
* 完全独立于现有认种管理。不涉及 planting_orders 或 CONTRACTS 等现有端点。
|
||||
*/
|
||||
|
||||
import apiClient from '@/infrastructure/api/client';
|
||||
import { API_ENDPOINTS } from '@/infrastructure/api/endpoints';
|
||||
|
||||
// ============================================
|
||||
// 类型定义
|
||||
// ============================================
|
||||
|
||||
/** 预种开关配置 */
|
||||
export interface PrePlantingConfig {
|
||||
isActive: boolean;
|
||||
activatedAt: string | null;
|
||||
updatedAt: string;
|
||||
updatedBy: string | null;
|
||||
}
|
||||
|
||||
/** 预种统计汇总 */
|
||||
export interface PrePlantingStats {
|
||||
totalOrders: number; // 总订单数
|
||||
totalPortions: number; // 总份数
|
||||
totalAmount: number; // 总金额(USDT)
|
||||
totalMerges: number; // 合并次数
|
||||
totalTreesMerged: number; // 合成树数
|
||||
totalUsers: number; // 参与用户数
|
||||
pendingContracts: number; // 待签约合并数
|
||||
}
|
||||
|
||||
/** 预种订单(管理员视角) */
|
||||
export interface PrePlantingAdminOrder {
|
||||
id: string;
|
||||
orderNo: string;
|
||||
userId: string;
|
||||
accountSequence: string;
|
||||
portionCount: number;
|
||||
pricePerPortion: number;
|
||||
totalAmount: number;
|
||||
provinceCode: string;
|
||||
cityCode: string;
|
||||
status: 'CREATED' | 'PAID' | 'MERGED';
|
||||
mergedToMergeId: string | null;
|
||||
createdAt: string;
|
||||
paidAt: string | null;
|
||||
mergedAt: string | null;
|
||||
}
|
||||
|
||||
/** 预种持仓(管理员视角) */
|
||||
export interface PrePlantingAdminPosition {
|
||||
id: string;
|
||||
userId: string;
|
||||
accountSequence: string;
|
||||
totalPortions: number;
|
||||
availablePortions: number;
|
||||
mergedPortions: number;
|
||||
totalTreesMerged: number;
|
||||
provinceCode: string | null;
|
||||
cityCode: string | null;
|
||||
firstPurchaseAt: string | null;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
/** 预种合并记录(管理员视角) */
|
||||
export interface PrePlantingAdminMerge {
|
||||
id: string;
|
||||
mergeNo: string;
|
||||
userId: string;
|
||||
accountSequence: string;
|
||||
sourceOrderNos: string[];
|
||||
treeCount: number;
|
||||
contractStatus: 'PENDING' | 'SIGNED' | 'EXPIRED';
|
||||
contractSignedAt: string | null;
|
||||
miningEnabledAt: string | null;
|
||||
selectedProvince: string | null;
|
||||
selectedCity: string | null;
|
||||
mergedAt: string;
|
||||
}
|
||||
|
||||
/** 分页列表请求参数 */
|
||||
export interface PrePlantingListParams {
|
||||
page?: number;
|
||||
pageSize?: number;
|
||||
status?: string;
|
||||
accountSequence?: string;
|
||||
keyword?: string;
|
||||
}
|
||||
|
||||
/** 分页列表响应 */
|
||||
export interface PaginatedResponse<T> {
|
||||
items: T[];
|
||||
total: number;
|
||||
page: number;
|
||||
pageSize: number;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 预种计划管理服务
|
||||
// ============================================
|
||||
|
||||
export const prePlantingService = {
|
||||
/**
|
||||
* 获取预种开关配置
|
||||
*/
|
||||
async getConfig(): Promise<PrePlantingConfig> {
|
||||
return apiClient.get(API_ENDPOINTS.PRE_PLANTING.CONFIG);
|
||||
},
|
||||
|
||||
/**
|
||||
* 切换预种开关(开启/关闭)
|
||||
*
|
||||
* 开关仅控制"能否发起新购买",不影响已完成的业务流程。
|
||||
* 关闭后已有未凑满份额的用户仍可继续购买至 5 的倍数。
|
||||
*/
|
||||
async toggleConfig(isActive: boolean): Promise<PrePlantingConfig> {
|
||||
return apiClient.put(API_ENDPOINTS.PRE_PLANTING.TOGGLE, { isActive });
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取预种统计汇总
|
||||
*/
|
||||
async getStats(): Promise<PrePlantingStats> {
|
||||
return apiClient.get(API_ENDPOINTS.PRE_PLANTING.STATS);
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取预种订单列表(管理员视角)
|
||||
*/
|
||||
async getOrders(params: PrePlantingListParams = {}): Promise<PaginatedResponse<PrePlantingAdminOrder>> {
|
||||
return apiClient.get(API_ENDPOINTS.PRE_PLANTING.ORDERS, { params });
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取预种持仓列表(管理员视角)
|
||||
*/
|
||||
async getPositions(params: PrePlantingListParams = {}): Promise<PaginatedResponse<PrePlantingAdminPosition>> {
|
||||
return apiClient.get(API_ENDPOINTS.PRE_PLANTING.POSITIONS, { params });
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取合并记录列表(管理员视角)
|
||||
*/
|
||||
async getMerges(params: PrePlantingListParams = {}): Promise<PaginatedResponse<PrePlantingAdminMerge>> {
|
||||
return apiClient.get(API_ENDPOINTS.PRE_PLANTING.MERGES, { params });
|
||||
},
|
||||
};
|
||||
|
||||
export default prePlantingService;
|
||||
Loading…
Reference in New Issue