添加加项接口

This commit is contained in:
xianyi
2025-12-30 17:54:06 +08:00
parent 59b5cc5b31
commit 586ce25bdc
3 changed files with 114 additions and 24 deletions

View File

@@ -28,6 +28,8 @@ import type {
CustomerDetailEditResponse, CustomerDetailEditResponse,
InputPhysicalExamAddItem, InputPhysicalExamAddItem,
PhysicalExamAddItemListResponse, PhysicalExamAddItemListResponse,
InputAddItemCustomerInfo,
AddItemCustomerInfoResponse,
InputPhysicalExamAddOrder, InputPhysicalExamAddOrder,
PhysicalExamQrcodeCreateResponse, PhysicalExamQrcodeCreateResponse,
InputOrderPaymentInfo, InputOrderPaymentInfo,
@@ -220,6 +222,18 @@ export const searchPhysicalExamAddItem = (
).then(res => res.data); ).then(res => res.data);
}; };
/**
* 获取体检加项客户信息
*/
export const getAddItemCustomerInfo = (
data: InputAddItemCustomerInfo
): Promise<AddItemCustomerInfoResponse> => {
return request.post<AddItemCustomerInfoResponse>(
`${MEDICAL_EXAM_BASE_PATH}/add-item-customer-info`,
data
).then(res => res.data);
};
/** /**
* Native-生成扫码支付二维码 * Native-生成扫码支付二维码
*/ */

View File

@@ -444,11 +444,11 @@ export interface OutputCustomerDetailEdit {
export type CustomerDetailEditResponse = CommonActionResult<OutputCustomerDetailEdit>; export type CustomerDetailEditResponse = CommonActionResult<OutputCustomerDetailEdit>;
/** /**
* 体检加项列表信息入参 * 体检加项列表信息入参(搜索体检加项)
*/ */
export interface InputPhysicalExamAddItem { export interface InputPhysicalExamAddItem {
/** 体检ID */ /** 折扣率 */
physical_exam_id: number; discount_ratio: number;
/** 项目名称(默认空值,传入项目名称过滤数据) */ /** 项目名称(默认空值,传入项目名称过滤数据) */
item_name?: string | null; item_name?: string | null;
} }
@@ -463,12 +463,16 @@ export interface PoAddItemCustomerInfo {
exam_no?: string | null; exam_no?: string | null;
/** 体检ID */ /** 体检ID */
physical_exam_id?: number | null; physical_exam_id?: number | null;
/** 渠道ID */
scrm_account_id?: string | null;
/** 渠道名称 */ /** 渠道名称 */
scrm_account_name?: string | null; scrm_account_name?: string | null;
/** 是否VIP1是0否 */ /** 是否VIP1是0否 */
is_vip?: number | null; is_vip?: number | null;
/** 是否VIP名称1是0否 */ /** 是否VIP名称1是0否 */
is_vip_name?: string | null; is_vip_name?: string | null;
/** 联系电话 */
phone?: string | null;
} }
/** /**
@@ -494,19 +498,68 @@ export interface PoPhysicalExamAddItem {
} }
/** /**
* 体检加项列表信息出参 * 体检加项列表信息出参(每一项加项信息)
*/ */
export interface OutputPhysicalExamAddItem { export interface OutputPhysicalExamAddItem {
/** 客户基本信息 */ /** 项目ID */
customerInfo?: PoAddItemCustomerInfo | null; item_id?: number | null;
/** 体检加项列表 */ /** 项目名称 */
addItemList?: PoPhysicalExamAddItem[] | null; item_name?: string | null;
/** 实收金额 */
actual_received_amount?: number | null;
/** 原价 */
original_price?: number | null;
/** 折扣率含折扣单位如8.0折) */
discount_rate?: string | null;
/** 折扣比例 */
discount_ratio?: number | null;
/** 次数 */
times?: number | null;
/** 组合项目代码 */
combination_item_code?: number | null;
} }
/** /**
* 体检加项列表信息响应 * 体检加项列表信息响应
*/ */
export type PhysicalExamAddItemListResponse = CommonActionResult<OutputPhysicalExamAddItem>; export type PhysicalExamAddItemListResponse = CommonActionResult<OutputPhysicalExamAddItem[]>;
/**
* 获取体检加项客户信息入参
*/
export interface InputAddItemCustomerInfo {
/** 体检ID */
physical_exam_id: number;
}
/**
* 体检渠道加项折扣比例信息列表出参
*/
export interface OutputTijianChannelDiscountInfo {
/** 渠道ID */
channel_id?: string | null;
/** 渠道名称 */
channel_name?: string | null;
/** 折扣比例 */
discount_rate?: number | null;
/** 折扣名称 */
discount_name?: string | null;
}
/**
* 加项客户信息出参
*/
export interface OutputAddItemCustomerInfo {
/** 客户基本信息 */
customerInfo?: PoAddItemCustomerInfo | null;
/** 渠道折扣信息列表 */
listChannelDiscount?: OutputTijianChannelDiscountInfo[] | null;
}
/**
* 获取体检加项客户信息响应
*/
export type AddItemCustomerInfoResponse = CommonActionResult<OutputAddItemCustomerInfo>;
/** /**
* 体检加项支付记录入参(生成扫码支付二维码) * 体检加项支付记录入参(生成扫码支付二维码)

View File

@@ -1,7 +1,7 @@
import { useEffect, useMemo, useState, useRef } from 'react'; import { useEffect, useMemo, useState, useRef } from 'react';
import type { ExamClient } from '../../data/mockData'; import type { ExamClient } from '../../data/mockData';
import { searchPhysicalExamAddItem } from '../../api'; import { searchPhysicalExamAddItem, getAddItemCustomerInfo } from '../../api';
import { Button, Input } from '../ui'; import { Button, Input } from '../ui';
interface AddonTag { interface AddonTag {
@@ -31,6 +31,29 @@ export const ExamAddonPanel = ({ client }: ExamAddonPanelProps) => {
const debounceTimerRef = useRef<number | null>(null); const debounceTimerRef = useRef<number | null>(null);
const [addonLoading, setAddonLoading] = useState(false); const [addonLoading, setAddonLoading] = useState(false);
const [addonError, setAddonError] = useState<string | null>(null); const [addonError, setAddonError] = useState<string | null>(null);
const [discountRatio, setDiscountRatio] = useState<number>(1);
// 获取体检加项客户信息(用于拿到渠道折扣等信息)
useEffect(() => {
const physical_exam_id = Number(client.id);
if (!physical_exam_id) return;
const fetchCustomerInfo = async () => {
try {
const res = await getAddItemCustomerInfo({ physical_exam_id });
if (res.Status === 200 && res.Data?.listChannelDiscount && res.Data.listChannelDiscount.length > 0) {
const rate = res.Data.listChannelDiscount[0]?.discount_rate;
if (typeof rate === 'number' && rate > 0) {
setDiscountRatio(rate);
}
}
} catch (err) {
console.error('获取加项客户信息失败', err);
}
};
fetchCustomerInfo();
}, [client.id]);
// 防抖:当输入值变化时,延迟 0.5 秒后更新 debouncedAddonSearch用于 API 调用) // 防抖:当输入值变化时,延迟 0.5 秒后更新 debouncedAddonSearch用于 API 调用)
useEffect(() => { useEffect(() => {
@@ -51,28 +74,28 @@ export const ExamAddonPanel = ({ client }: ExamAddonPanelProps) => {
// 拉取加项列表 // 拉取加项列表
useEffect(() => { useEffect(() => {
const physical_exam_id = Number(client.id);
if (!physical_exam_id) {
setAddonError('缺少体检ID');
return;
}
const fetchList = async () => { const fetchList = async () => {
setAddonLoading(true); setAddonLoading(true);
setAddonError(null); setAddonError(null);
try { try {
const res = await searchPhysicalExamAddItem({ const res = await searchPhysicalExamAddItem({
physical_exam_id, discount_ratio: discountRatio || 1,
item_name: debouncedAddonSearch.trim() || null, item_name: debouncedAddonSearch.trim() || null,
}); });
if (res.Status === 200 && res.Data?.addItemList) { if (res.Status === 200 && Array.isArray(res.Data)) {
const list: AddonItem[] = res.Data.addItemList.map((item) => ({ const list: AddonItem[] = res.Data.map((item) => ({
id: item.item_id ? String(item.item_id) : `addon_${item.item_name}`, id: item.item_id ? String(item.item_id) : `addon_${item.item_name}`,
name: item.item_name || '', name: item.item_name || '',
originalPrice: item.original_price !== undefined ? Number(item.original_price).toFixed(2) : '0.00', originalPrice:
currentPrice: item.actual_received_amount !== undefined item.original_price !== undefined && item.original_price !== null
? Number(item.original_price).toFixed(2)
: '0.00',
currentPrice:
item.actual_received_amount !== undefined && item.actual_received_amount !== null
? Number(item.actual_received_amount).toFixed(2) ? Number(item.actual_received_amount).toFixed(2)
: (item.original_price !== undefined ? Number(item.original_price).toFixed(2) : '0.00'), : item.original_price !== undefined && item.original_price !== null
? Number(item.original_price).toFixed(2)
: '0.00',
tags: [], tags: [],
paid: false, paid: false,
})); }));
@@ -90,7 +113,7 @@ export const ExamAddonPanel = ({ client }: ExamAddonPanelProps) => {
} }
}; };
fetchList(); fetchList();
}, [debouncedAddonSearch, client.id]); }, [debouncedAddonSearch, discountRatio]);
const allAddons = useMemo(() => addonList, [addonList]); const allAddons = useMemo(() => addonList, [addonList]);