import hocAuth from "@/hocs/auth"; import { CommonComponent, CostItem, SupplierVO } from "@/types/typings"; import { View } from "@tarojs/components"; import { Button, Dialog, SafeArea, Toast, Tour, TourList, } from "@nutui/nutui-react-taro"; import { purchase } from "@/constant"; import { useEffect, useRef, useState } from "react"; import { MelonFarmer, MelonFarmerRef, OrderCost, OrderCostRef, OrderPackage, OrderPackageRef, OrderVehicle, OrderVehicleRef, SupplierList, TicketUpload, Weigh, WeighRef, } from "@/components"; import { business } from "@/services"; import { generateShortId } from "@/utils/generateShortId"; import Taro from "@tarojs/taro"; import buildUrl from "@/utils/buildUrl"; import { SupplierWeightCalculator } from "@/utils/SupplierWeightCalculator"; import { PurchaseOrderCalculator } from "@/utils/PurchaseOrderCalculator"; const defaultSupplierList: SupplierVO[] = [ { orderSupplierId: generateShortId(), supplierId: "", name: "瓜农1", idCard: "", bankCard: "", phone: "", selected: true, wechatQr: "", isLast: undefined, // 空磅是否包含纸箱 isPaper: undefined, // 空磅重量 emptyWeight: undefined, // 总磅重量 totalWeight: undefined, // 采购单价 purchasePrice: undefined, // 空磅照片 emptyWeightImg: "", // 总磅照片 totalWeightImg: "", orderPackageList: [], }, ]; export default hocAuth(function Page(props: CommonComponent) { const { router, role, setLoading } = props; const [orderId, setOrderId] = useState( router.params.orderId as BusinessAPI.PurchaseOrderShowQry["orderId"], ); const defaultStep = router.params.step as number; const defaultSupplierId = router.params.supplierId as string; const [showTour, setShowTour] = useState(true); const closeTour = () => { setShowTour(false); }; const steps: TourList[] = [ { content: "粘贴识别", target: "target1", popoverOffset: [0, 12], arrowOffset: 0, }, { content: "选择经销商", target: "target2", location: "bottom-left", }, ]; const vehicleRef = useRef(null); // 创建MelonFarmer组件的ref数组 const melonFarmerRefs = useRef([]); // 创建Weigh组件的ref数组 const weighRefs = useRef([]); // 创建OrderCost组件的ref const orderCostRef = useRef(null); // 创建OrderPackage组件的ref const orderPackageRefs = useRef([]); const [purchaseOrder, setPurchaseOrder] = useState(); console.log("purchaseOrder", purchaseOrder); const [step, setStep] = useState(); const [active, setActive] = useState(1); const [orderVehicle, setOrderVehicle] = useState(); const [orderDealer, setOrderDealer] = useState(); const [orderSupplierList, setOrderSupplierList] = useState(defaultSupplierList); const [orderCostList, setOrderCostList] = useState([]); const [orderPackageList, setOrderPackageList] = useState< BusinessAPI.OrderPackage[] >([]); // 费用项目列表 const [costItemVOList, setCostItemVOList] = useState< BusinessAPI.CostItemVO[] >([]); // 获取费用项目列表 useEffect(() => { const fetchCostItems = async () => { try { const { data } = await business.costItem.listCostItem({ costItemListQry: { status: true, showInEntry: true, }, }); setCostItemVOList(data.data || []); } catch (error) { console.error("获取费用项目列表失败:", error); } }; fetchCostItems(); }, []); useEffect(() => { if (orderId) { setLoading(true); business.purchaseOrder .showPurchaseOrder({ purchaseOrderShowQry: { orderId: orderId, }, }) .then(({ data: { data: purchaseOrder, success } }) => { if (success && purchaseOrder) { // 如果订单状态不是草稿,则跳转到预览页面 if (purchaseOrder.state !== "DRAFT" && role === "origin-entry") { Taro.redirectTo({ url: buildUrl("/pages/purchase/purchaser/preview", { orderId: purchaseOrder.orderId, }), }); return; } setPurchaseOrder(purchaseOrder); setOrderVehicle(purchaseOrder.orderVehicle); const orderSupplierList1 = purchaseOrder.orderSupplierList as any; if (defaultSupplierId) { const index = orderSupplierList1.findIndex( (item: any) => item.supplierId === defaultSupplierId, ); orderSupplierList1[index].selected = true; setOrderSupplierList(orderSupplierList1); } else { orderSupplierList1[0].selected = true; setOrderSupplierList(orderSupplierList1); } if (defaultStep) { setActive(Number(defaultStep)); } else { const active = purchaseOrder.active || 1; if (active < 1 || active > 6) { setActive(1); } else { setActive(active); } } const orderCostList1 = purchaseOrder.orderCostList.map( (item: CostItem) => ({ ...item, // 设置默认选中, selected: item.count > 0, }), ) as any; setOrderCostList(orderCostList1); setOrderPackageList(purchaseOrder.orderPackageList); } }) .catch((err) => { console.error("获取采购订单失败:", err); }) .finally(() => { setLoading(false); }); } }, []); useEffect(() => { if (active) { setStep(purchase.steps.find((item) => item.value === active)); // 同步更新purchaseOrder中的active值 setPurchaseOrder((prev) => ({ ...prev!, active })); } }, [active]); useEffect(() => { if (orderSupplierList) { const supplierWeightCalculator = new SupplierWeightCalculator( orderSupplierList as any, ); setPurchaseOrder((prev) => ({ ...prev!, orderSupplierList: supplierWeightCalculator.calculate(), })); } }, [orderSupplierList]); useEffect(() => { setPurchaseOrder((prev) => ({ ...prev!, orderVehicle: orderVehicle as BusinessAPI.OrderVehicle, })); }, [orderVehicle]); useEffect(() => { setPurchaseOrder((prev) => ({ ...prev!, orderDealer: orderDealer as BusinessAPI.OrderDealer, })); }, [orderDealer]); useEffect(() => { setPurchaseOrder((prev) => ({ ...prev!, orderCostList: orderCostList || [], })); }, [orderCostList]); useEffect(() => { setPurchaseOrder((prev) => ({ ...prev!, orderPackageList: orderPackageList || [], })); }, [orderPackageList]); if (step === undefined) { return; } const onAdd = () => { // 获取当前选中的供应商 const selectedIndex = orderSupplierList.findIndex( (supplier) => supplier.selected, ); if (active === 2 && !melonFarmerRefs.current[selectedIndex]?.validate()) { return; } // 在第三步(称重信息)时进行校验 else if (active === 3 && !weighRefs.current[selectedIndex]?.validate()) { return; } // 在第四步(包装信息)时进行校验 else if ( active === 4 && !orderPackageRefs.current[selectedIndex]?.validate() ) { return; } setOrderSupplierList([ ...orderSupplierList.map((supplierVO: SupplierVO) => { supplierVO.selected = false; return supplierVO; }), { orderSupplierId: generateShortId(), supplierId: "", name: "瓜农" + (orderSupplierList.length + 1), idCard: "", bankCard: "", phone: "", selected: true, isPaper: orderSupplierList[selectedIndex].isPaper, orderPackageList: [], }, ]); }; // 车辆信息和经销商信息的保存 const saveVehicleAndDealerInfo = async () => { if (!purchaseOrder) { Toast.show("toast", { icon: "warn", title: "提示", content: "保存失败", }); return false; } try { let tempOrderId = orderId; if (tempOrderId) { const { data } = await business.purchaseOrder.savePurchaseOrderStep1({ orderId: tempOrderId, active: active, orderVehicle: purchaseOrder.orderVehicle, orderDealer: purchaseOrder.orderDealer, orderCostList: purchaseOrder.orderCostList, }); if (data.success) { return true; } else { Toast.show("toast", { icon: "warn", title: "提示", content: data?.errMessage || "保存失败", }); return false; } } else { const { data } = await business.purchaseOrder.savePurchaseOrderStep1({ active: active, orderVehicle: purchaseOrder.orderVehicle, orderDealer: purchaseOrder.orderDealer, orderCostList: purchaseOrder.orderCostList, }); if (data.success) { setOrderId(data.data?.orderId); return true; } else { Toast.show("toast", { icon: "warn", title: "提示", content: data?.errMessage || "保存失败", }); return false; } } } catch (error) { Toast.show("toast", { icon: "fail", title: "提示", content: "保存失败", }); console.error("保存车辆和经销商信息失败:", error); return false; } }; // 供应商信息的保存(基础信息,称重信息,包材信息) const saveSupplierInfo = async () => { if (!purchaseOrder || !orderId) { Toast.show("toast", { icon: "warn", title: "提示", content: "保存失败", }); return false; } try { const { data } = await business.purchaseOrder.savePurchaseOrderStep2({ orderId: orderId, active: active, orderSupplierList: purchaseOrder.orderSupplierList, orderCostList: purchaseOrder.orderCostList, }); if (data.success) { return true; } else { Toast.show("toast", { icon: "warn", title: "提示", content: data?.errMessage || "保存失败", }); return false; } } catch (error) { Toast.show("toast", { icon: "fail", title: "提示", content: "保存失败", }); console.error("保存供应商信息失败:", error); return false; } }; // 人工和辅料等保存 const saveCostInfo = async () => { if (!purchaseOrder || !orderId) { Toast.show("toast", { icon: "warn", title: "提示", content: "保存失败", }); return false; } try { const { data } = await business.purchaseOrder.savePurchaseOrderStep3({ orderId: orderId, active: active + 1, orderCostList: purchaseOrder.orderCostList.filter( (item: CostItem) => item.selected, ), orderPackageList: purchaseOrder.orderPackageList, }); if (data.success) { return true; } else { Toast.show("toast", { icon: "warn", title: "提示", content: data?.errMessage || "保存失败", }); return false; } } catch (error) { Toast.show("toast", { icon: "fail", title: "提示", content: "保存失败", }); console.error("保存人工和辅料信息失败:", error); return false; } }; const onFinish = async () => { Dialog.open("dialog", { title: "预览确认", content: "即将保存并预览当前采购订单,确定要继续吗?", confirmText: "确认预览", cancelText: "取消", onConfirm: async () => { // 只保存第六步的人工和辅料信息 const costSuccess = await saveCostInfo(); if (!costSuccess) { Dialog.close("dialog"); return; } Toast.show("toast", { icon: "success", title: "提示", content: "保存成功,正在跳转预览...", }); // 跳转到预览页面 Taro.redirectTo({ url: buildUrl("/pages/purchase/purchaser/preview", { orderId: orderId, }), }); Dialog.close("dialog"); }, onCancel: () => { Dialog.close("dialog"); }, }); }; async function saveDraft() { Dialog.open("dialog", { title: "暂存确认", content: "确定要暂存当前采购订单吗?", confirmText: "确认暂存", cancelText: "取消", onConfirm: async () => { // 按步骤调用保存接口进行暂存 let success = true; // 保存第一步车辆和经销商信息 if (active == 1) { success = await saveVehicleAndDealerInfo(); } // 保存第二到第五步的供应商信息 if (success && active >= 2 && active <= 5) { success = await saveSupplierInfo(); } // 保存第六步的人工和辅料信息 if (success && active === 6) { success = await saveCostInfo(); } Dialog.close("dialog"); if (success) { Toast.show("toast", { icon: "success", title: "提示", content: "当前采购订单已暂存成功", }); Taro.redirectTo({ url: "/pages/purchase/purchaser/history", }); } }, onCancel: () => { Dialog.close("dialog"); }, }); } return ( <> {step.value !== 7 && ( {step.title} )} {(step.value === 2 || step.value === 3 || step.value === 4 || step.value === 5) && ( { // 获取当前选中的供应商 const selectedIndex = orderSupplierList.findIndex( (supplier) => supplier.selected, ); if ( active === 2 && !melonFarmerRefs.current[selectedIndex]?.validate() ) { return; } // 在第三步(称重信息)时进行校验 else if ( active === 3 && !weighRefs.current[selectedIndex]?.validate() ) { return; } // 在第四步(包装信息)时进行校验 else if ( active === 4 && !orderPackageRefs.current[selectedIndex]?.validate() ) { return; } setOrderSupplierList( orderSupplierList.map((item: any) => { item.selected = item.orderSupplierId === supplierVO.orderSupplierId; return item; }), ); }} /> )} {/* 车辆信息 */} {step.value === 1 && ( { setOrderVehicle(orderVehicle); }} orderDealer={orderDealer!} setOrderDealer={(orderDealer) => { setOrderDealer(orderDealer); }} orderCostList={orderCostList} setOrderCostList={(costItemList: CostItem[]) => { setOrderCostList(costItemList); }} costItemVOList={costItemVOList} /> )} {/* 瓜农信息 */} {orderSupplierList.map((item: SupplierVO, index) => { if (!item.selected) { return; } if (step.value === 2) { // 确保ref数组足够长 while (melonFarmerRefs.current.length <= index) { melonFarmerRefs.current.push({ validate: () => true, // 默认验证方法 } as MelonFarmerRef); } // 获取已选择的供应商ID列表(排除当前项) const selectedSupplierIds = orderSupplierList .filter((supplier, idx) => idx !== index && supplier.supplierId) .map((supplier) => supplier.supplierId!); // 获取已选择的供应商ID列表(排除当前项) const selectedSupplierNames = orderSupplierList .filter((supplier, idx) => idx !== index && supplier.supplierId) .map((supplier) => supplier.name!); return ( { if (ref) { melonFarmerRefs.current[index] = ref; } }} value={item} onRemove={(supplierVO: SupplierVO) => { if (orderSupplierList.length <= 1) { setOrderSupplierList([ { orderSupplierId: generateShortId(), supplierId: "", name: "瓜农1", idCard: "", bankCard: "", phone: "", selected: true, orderPackageList: [], }, ]); return; } let temp = orderSupplierList.filter( (item: SupplierVO) => item.orderSupplierId !== supplierVO.orderSupplierId, ); temp[0].selected = true; setOrderSupplierList(temp); }} onChange={(supplierVO: SupplierVO) => { orderSupplierList[index] = { ...item, ...supplierVO }; setOrderSupplierList([...orderSupplierList]); console.log("supplierVO", supplierVO); }} isLast={index === orderSupplierList.length - 1} selectedSupplierIds={selectedSupplierIds} selectedSupplierNames={selectedSupplierNames} /> ); } // 称重信息 if (step.value === 3) { // 确保ref数组足够长 while (weighRefs.current.length <= index) { weighRefs.current.push({ validate: () => true, // 默认验证方法 } as WeighRef); } return ( { setOrderSupplierList([ ...orderSupplierList.map((item: SupplierVO) => { item.isPaper = isPaper; return item; }), ]); }} changeProduct={(productVO: BusinessAPI.ProductVO) => { setOrderSupplierList([ ...orderSupplierList.map((item: SupplierVO) => { item.productId = productVO.productId; item.productName = productVO.name; return item; }), ]); setOrderCostList((prev) => { const costItemVOList = productVO.costItemVOList; console.log("prev", prev); // 将 orderCostList 中 不存在与 costItemVOList 的项 删除,剩余项保留 const orderCostList = prev?.filter((item) => { return ( (item.costType === "WORKER_ADVANCE" || item.costType === "PRODUCTION_ADVANCE" || item.costType === "PACKAGING_MATERIALS") && costItemVOList?.find( (costItemVO) => costItemVO.itemId === item.itemId, ) ); }); // 添加 costItemVOList 中 不存在与 orderCostList 的项 costItemVOList?.forEach((item) => { if ( !orderCostList?.find( (costItemVO) => costItemVO.itemId === item.itemId, ) ) { orderCostList?.push({ orderCostId: generateShortId(), orderId: purchaseOrder?.orderId, itemId: item.itemId, name: item.name, price: item.price, unit: item.unit, count: 0, payerType: "US" as any, principal: "", costType: item.costType, requireQuantityAndPrice: item.requireQuantityAndPrice, selected: true, }); } }); return [ ...(prev?.filter((item) => { return ( item.costType !== "WORKER_ADVANCE" && item.costType !== "PRODUCTION_ADVANCE" && item.costType !== "PACKAGING_MATERIALS" ); }) || []), ...(orderCostList || []), ]; }); }} isFirst={index === 0} key={item.orderSupplierId} ref={(ref) => { if (ref) { weighRefs.current[index] = ref; } }} value={item} onChange={(supplierVO: SupplierVO) => { orderSupplierList[index] = { ...item, ...supplierVO }; setOrderSupplierList([...orderSupplierList]); }} /> ); } // 包装信息 if (step.value === 4) { // 确保ref数组足够长 while (orderPackageRefs.current.length <= index) { orderPackageRefs.current.push({ validate: () => true, // 默认验证方法 } as OrderPackageRef); } return ( { if (ref) { orderPackageRefs.current[index] = ref; } }} value={item} onChange={(supplierVO: SupplierVO) => { orderSupplierList[index] = { ...item, ...supplierVO }; setOrderSupplierList([...orderSupplierList]); setOrderCostList((prev) => { console.log("prev", prev); // 检查是否已存在纸箱费项目 const hasBoxFee = prev?.some( (item) => item.name === "纸箱费" && item.costType === "FIXED_COST", ); const boxCostItem = costItemVOList.find( (item) => item.name === "纸箱费" && item.costType === "FIXED_COST", ); const calculator = new PurchaseOrderCalculator( purchaseOrder as any, ); // 如果不存在空箱费项目,则添加 if (!hasBoxFee) { const boxFeeItem: CostItem = { orderCostId: generateShortId(), itemId: boxCostItem?.itemId || "", name: "纸箱费", price: calculator.getBoxSale(), unit: "项", selected: true, count: 1, payerType: "US", principal: "", costType: "FIXED_COST", requireQuantityAndPrice: false, }; return [...prev, boxFeeItem]; } else { // 如果已存在空箱费项目,更新其数量 return prev.map((item) => { if ( item.name === "纸箱费" && item.costType === "FIXED_COST" ) { return { ...item, price: calculator.getBoxSale(), count: 1, }; } return item; }); } }); }} /> ); } // 票证上传 if (step.value === 5) { return ( { orderSupplierList[index] = { ...item, ...supplierVO }; setOrderSupplierList([...orderSupplierList]); }} /> ); } })} {/* 人工和辅料信息 */} {step.value === 6 && ( { saveSupplierInfo(); setActive(2); onAdd(); }} ref={orderCostRef} value={orderCostList} onChange={(costItemList: CostItem[]) => { // 修改标识将在useEffect中自动更新 setOrderCostList(costItemList); }} emptyBoxList={orderPackageList} onEmptyBoxChange={(emptyBoxList: BusinessAPI.OrderPackage[]) => { setOrderPackageList(emptyBoxList); }} costItemVOList={costItemVOList} /> )} {/* 按钮操作 */} {active > 1 && active <= 6 && ( )} {active >= 1 && active <= 6 && ( )} {active < 6 && ( )} {active === 6 && ( <> )} ); });