From 564c80d63a8520cc9d510c4224e787e1a82d5a93 Mon Sep 17 00:00:00 2001 From: xianyi Date: Tue, 16 Dec 2025 17:17:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9A=82=E6=97=B6=E4=BC=98=E5=8C=96=E4=BD=93?= =?UTF-8?q?=E6=A3=80=E5=8A=A0=E9=A1=B9=E9=9D=A2=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/exam/ExamAddonPanel.tsx | 81 +++++++++++++++++--------- src/components/exam/ExamModal.tsx | 2 +- 2 files changed, 54 insertions(+), 29 deletions(-) diff --git a/src/components/exam/ExamAddonPanel.tsx b/src/components/exam/ExamAddonPanel.tsx index e8340b1..9414e7d 100644 --- a/src/components/exam/ExamAddonPanel.tsx +++ b/src/components/exam/ExamAddonPanel.tsx @@ -1,6 +1,6 @@ -import { useState } from 'react'; +import { useEffect, useMemo, useState } from 'react'; -import type { ExamClient } from '../../data/mockData'; +import { searchPhysicalExamAddItem } from '../../api'; import { Button, Input } from '../ui'; interface AddonTag { @@ -15,40 +15,56 @@ interface AddonItem { tags?: AddonTag[]; originalPrice?: string; currentPrice?: string; - price?: number; // 兼容 addonOptions 结构 } -export const ExamAddonPanel = ({ client }: { client: ExamClient }) => { - // 从 client 获取加项选项数据 - const addonOptions = (client['addonOptions' as keyof ExamClient] as AddonItem[] | undefined) || []; - const addonSummary = (client['addonSummary' as keyof ExamClient] as AddonItem[] | undefined) || []; +export const ExamAddonPanel = () => { + const [addonList, setAddonList] = useState([]); + const [addonSearch, setAddonSearch] = useState(''); + const [addonLoading, setAddonLoading] = useState(false); + const [addonError, setAddonError] = useState(null); - // 合并数据,优先使用 addonOptions,如果没有则使用 addonSummary - const allAddons: AddonItem[] = addonOptions.length > 0 - ? addonOptions.map(item => ({ - id: item.id || `addon_${item.name}`, - name: item.name, - paid: item.paid || false, - tags: item.tags || [], - originalPrice: item.originalPrice || (item.price ? item.price.toFixed(2) : '0.00'), - currentPrice: item.currentPrice || (item.price ? item.price.toFixed(2) : '0.00'), - })) - : addonSummary; + // 拉取加项列表 + useEffect(() => { + const fetchList = async () => { + setAddonLoading(true); + setAddonError(null); + try { + const res = await searchPhysicalExamAddItem({ item_name: addonSearch.trim() }); + if (res.Status === 200 && Array.isArray(res.Data)) { + const list: AddonItem[] = res.Data.map((item) => ({ + id: item.item_id ? String(item.item_id) : `addon_${item.item_name}`, + name: item.item_name || '', + originalPrice: item.original_price !== undefined ? Number(item.original_price).toFixed(2) : '0.00', + currentPrice: item.actual_received_amount !== undefined + ? Number(item.actual_received_amount).toFixed(2) + : (item.original_price !== undefined ? Number(item.original_price).toFixed(2) : '0.00'), + tags: [], + paid: false, + })); + setAddonList(list); + } else { + setAddonError(res.Message || '获取加项列表失败'); + setAddonList([]); + } + } catch (err) { + console.error('获取加项列表失败', err); + setAddonError('获取加项列表失败,请稍后重试'); + setAddonList([]); + } finally { + setAddonLoading(false); + } + }; + fetchList(); + }, [addonSearch]); - const [selectedIds, setSelectedIds] = useState>( - new Set(allAddons.filter(item => item.paid).map(item => item.id || item.name)) - ); + const allAddons = useMemo(() => addonList, [addonList]); + + const [selectedIds, setSelectedIds] = useState>(new Set()); const maxSelect = 15; const selectedCount = selectedIds.size; - const [addonSearch, setAddonSearch] = useState(''); - - const filteredAddons = addonSearch.trim() - ? allAddons.filter(item => - item.name.toLowerCase().includes(addonSearch.toLowerCase()) - ) - : allAddons; + const filteredAddons = allAddons; const toggleSelect = (id: string) => { if (selectedIds.has(id)) { @@ -125,6 +141,15 @@ export const ExamAddonPanel = ({ client }: { client: ExamClient }) => { {/* 加项网格 */}
+ {addonError && ( +
{addonError}
+ )} + {addonLoading && ( +
加载中...
+ )} + {!addonLoading && !addonError && filteredAddons.length === 0 && ( +
暂无数据
+ )} {filteredAddons.map((item) => { const id = item.id || item.name; const isSelected = selectedIds.has(id); diff --git a/src/components/exam/ExamModal.tsx b/src/components/exam/ExamModal.tsx index b707f52..d38a87d 100644 --- a/src/components/exam/ExamModal.tsx +++ b/src/components/exam/ExamModal.tsx @@ -153,7 +153,7 @@ export const ExamModal = ({ client, tab, onTabChange, onClose }: ExamModalProps) /> )} {tab === 'sign' && } - {tab === 'addon' && } + {tab === 'addon' && } {tab === 'print' && } {tab === 'delivery' && }