import { ScrollView, View } from "@tarojs/components"; import { Button, Input, Picker, Popup, SafeArea, } from "@nutui/nutui-react-taro"; import { useEffect, useState } from "react"; import { Icon } from "@/components"; import { formatCurrency, validatePrice } from "@/utils/format"; import { generateShortId } from "@/utils/generateShortId"; export default function PackagingCostSection(props: { purchaseOrderVO: BusinessAPI.PurchaseOrderVO; costItemVOList: BusinessAPI.CostItemVO[]; onChange?: (purchaseOrderVO: BusinessAPI.PurchaseOrderVO) => void; readOnly?: boolean; }) { const { purchaseOrderVO, onChange, readOnly, costItemVOList } = props; // 弹窗相关状态 const [visiblePopup, setVisiblePopup] = useState<{ [key: string]: boolean }>( {}, ); // 新增包装费弹窗状态 const [showAddCostPopup, setShowAddCostPopup] = useState(false); // 新增包装费表单数据 const [newCostData, setNewCostData] = useState({ costType: "FIXED_COST", // 费用类型 itemId: "", // 费用项目ID name: "", // 费用名称 quantity: 0, // 数量(人数) unit: "", // 单位 unitPrice: "", // 单价 amount: "", // 金额 payerType: "US", // 费用承担方,默认我方 principal: "", // 工头姓名 requireQuantityAndPrice: false, }); // Picker可见状态 const [pickerVisible, setPickerVisible] = useState({ costType: false, // 费用类型Picker costItem: false, // 费用项目Picker fixedCost: false, // 固定费用Picker }); // 编辑值的状态 const [editValues, setEditValues] = useState<{ [key: string]: { count: number; price: number; name?: string; principal?: string; payerType?: "US" | "OTHER"; }; }>({}); // 临时编辑值的状态(用于在保存前暂存编辑的值) const [tempEditValues, setTempEditValues] = useState<{ [key: string]: { count: number; price: number; name?: string; principal?: string; payerType?: "US" | "OTHER"; }; }>({}); // 初始化编辑值 const initEditValues = ( itemId: string, count: number, price: number, name?: string, principal?: string, payerType?: "US" | "OTHER", ) => { if (!editValues[itemId]) { setEditValues((prev) => ({ ...prev, [itemId]: { count, price, name, principal, payerType }, })); } // 同时初始化临时编辑值 if (!tempEditValues[itemId]) { setTempEditValues((prev) => ({ ...prev, [itemId]: { count, price, name, principal, payerType }, })); } }; // 费用类型选项 const costTypeOptions = [ { label: "固定费用", value: "FIXED_COST" }, { label: "其他费用", value: "OTHER_COST" }, ]; // 固定费用 const fixedCosts = purchaseOrderVO.orderCostList?.filter( (item) => item.costType === "FIXED_COST", ) || []; // 其他费用 const otherCosts = purchaseOrderVO.orderCostList?.filter( (item) => item.costType === "OTHER_COST", ) || []; // 检查是否存在计提费,如果不存在则添加一个默认的计提费 useEffect(() => { if (onChange) { // 检查是否已存在计提费 const accrualFeeItem = costItemVOList.find( (item) => item.name === "计提费" && item.costType === "FIXED_COST", ); const hasAccrualFee = fixedCosts.some((item) => item.name === "计提费"); if (!hasAccrualFee && accrualFeeItem) { // 创建默认计提费 const defaultAccrualFee: BusinessAPI.OrderCost = { itemId: accrualFeeItem.itemId, orderCostId: generateShortId(), name: "计提费", costType: "FIXED_COST", price: 0, count: 1, unit: "项", payerType: "US", requireQuantityAndPrice: false, }; // 更新purchaseOrderVO,添加默认计提费 const updatedOrderCostList = [ ...(purchaseOrderVO.orderCostList || []), defaultAccrualFee, ]; const newPurchaseOrderVO = { ...purchaseOrderVO, orderCostList: updatedOrderCostList, }; onChange(newPurchaseOrderVO as any); } } }, [purchaseOrderVO.orderCostList, onChange, fixedCosts]); // 当editValues发生变化时,更新purchaseOrderVO useEffect(() => { // 只有当onChange存在时才更新 if (onChange) { // 获取现有的orderCostList const existingOrderCostList = purchaseOrderVO.orderCostList || []; // 更新已有的成本项 const updatedOrderCostList = existingOrderCostList.map((item) => { if (editValues[item.orderCostId]) { return { ...item, price: editValues[item.orderCostId].price !== undefined ? editValues[item.orderCostId].price : item.price, count: editValues[item.orderCostId].count !== undefined ? editValues[item.orderCostId].count : item.count, name: editValues[item.orderCostId].name !== undefined ? editValues[item.orderCostId].name : item.name, principal: editValues[item.orderCostId].principal !== undefined ? editValues[item.orderCostId].principal : item.principal, payerType: editValues[item.orderCostId].payerType !== undefined ? editValues[item.orderCostId].payerType : item.payerType, }; } // 未修改的成本项保持原样 return item; }); // 创建新的purchaseOrderVO对象 const newPurchaseOrderVO = { ...purchaseOrderVO, orderCostList: updatedOrderCostList, }; // 调用onChange回调 onChange(newPurchaseOrderVO as any); } }, [editValues]); return ( <> {/* 固定费用 */} {fixedCosts.map((item, index) => { // 初始化编辑值 initEditValues(item.orderCostId, item.count, item.price); return ( setVisiblePopup((prev) => ({ ...prev, [item.orderCostId]: true, })) } > {index + 1}-{item.name} {formatCurrency( Number( (editValues[item.orderCostId]?.price || item.price) * (editValues[item.orderCostId]?.count || item.count), ), )} {!readOnly && ( )} ); })} {/* 其他费用 */} {otherCosts.map((item, index) => { // 初始化编辑值 initEditValues( item.orderCostId, item.count, item.price, item.name, item.principal, ); return ( setVisiblePopup((prev) => ({ ...prev, [item.orderCostId]: true, })) } > {fixedCosts.length + index + 1}- {editValues[item.orderCostId]?.name || item.name} {formatCurrency( Number( (editValues[item.orderCostId]?.price || item.price) * (editValues[item.orderCostId]?.count || item.count), ), )} {!readOnly && ( )} ); })} {!readOnly && ( )} {/* 新增其他费用*/} setShowAddCostPopup(false)} onOverlayClick={() => setShowAddCostPopup(false)} lockScroll > {/* 费用类型选择 */} 费用类型 {costTypeOptions.map((option) => ( { setNewCostData((prev) => ({ ...prev, costType: option.value, itemId: "", name: "", // 费用名称 quantity: 0, // 数量 unit: "", // 单位 unitPrice: "", // 单价 amount: "", // 金额 requireQuantityAndPrice: false, })); }} > {option.label} ))} {/* 固定费用子类型 */} {newCostData.costType === "FIXED_COST" && ( <> 固定费用类型 setPickerVisible((prev) => ({ ...prev, fixedCost: true })) } > item.costType === newCostData.costType) .filter((item) => { // 检查该项目是否已经被选择 return !fixedCosts.some( (hc) => hc.itemId === item.itemId, ); }) .map((item) => ({ label: item.name, value: item.itemId, })), ]} onConfirm={(_, values) => { const selectedValue = values[0] as string; const selectedItem = costItemVOList.find( (item) => item.itemId === selectedValue, ); if (selectedItem) { setNewCostData((prev) => ({ ...prev, itemId: selectedValue, name: selectedItem.name, payerType: "US", quantity: selectedItem.requireQuantityAndPrice ? 0 : 1, unit: selectedItem.requireQuantityAndPrice ? selectedItem.unit : "元", // 单位 unitPrice: "", // 单价 amount: "", // 金额 principal: "", // 工头姓名 requireQuantityAndPrice: selectedItem.requireQuantityAndPrice, })); } setPickerVisible((prev) => ({ ...prev, fixedCost: false })); }} onCancel={() => setPickerVisible((prev) => ({ ...prev, fixedCost: false })) } onClose={() => setPickerVisible((prev) => ({ ...prev, fixedCost: false })) } /> )} {/* 其他费用名称输入 */} {newCostData.costType === "OTHER_COST" && ( <> 费用名称 { setNewCostData((prev) => ({ ...prev, name: value, })); }} /> 收款人姓名 { setNewCostData((prev) => ({ ...prev, payee: value, })); }} /> )} {/* 金额输入(固定费用和其他费用)*/} {((newCostData.costType === "FIXED_COST" && newCostData.name) || newCostData.costType === "OTHER_COST") && ( <> 金额 { const numValue = validatePrice(value); if (numValue !== undefined) { setNewCostData((prev) => ({ ...prev, amount: numValue as any, })); } }} /> )} {/* 固定费用编辑弹窗 */} {fixedCosts.map((item) => ( setVisiblePopup((prev) => ({ ...prev, [item.orderCostId]: false })) } onOverlayClick={() => setVisiblePopup((prev) => ({ ...prev, [item.orderCostId]: false })) } lockScroll > 金额 { const numValue = validatePrice(value); if (numValue !== undefined) { setTempEditValues((prev) => ({ ...prev, [item.orderCostId]: { ...prev[item.orderCostId], price: numValue as number, count: 1, }, })); } }} /> ))} {/* 其他费用编辑弹窗 */} {otherCosts.map((item) => ( setVisiblePopup((prev) => ({ ...prev, [item.orderCostId]: false })) } onOverlayClick={() => setVisiblePopup((prev) => ({ ...prev, [item.orderCostId]: false })) } lockScroll > 费用名称 { setTempEditValues((prev) => ({ ...prev, [item.orderCostId]: { ...prev[item.orderCostId], name: value, }, })); }} /> 收款人姓名 { setTempEditValues((prev) => ({ ...prev, [item.orderCostId]: { ...prev[item.orderCostId], principal: value, }, })); }} /> 金额 { const numValue = validatePrice(value); if (numValue !== undefined) { setTempEditValues((prev) => ({ ...prev, [item.orderCostId]: { ...prev[item.orderCostId], price: numValue as number, count: 1, }, })); } }} /> ))} ); }