- 统一处理 purchaseOrderVO.orderDealer 可能为空的情况,避免运行时错误 - 修复多个组件中颜色样式结尾多余的分号导致的渲染异常 - 调整 OrderCost 组件中 selected 状态的判断逻辑,确保 count 大于 0 才选中 - 优化 PurchasePreview 组件中空箱使用明细的条件渲染,仅在有数据时显示 - 完善成本校验逻辑,在没有启用的"我方"费用项时标记为有效 - 修正 WorkerAdvanceSection 中费用类型的初始值设置错误 - 更新市场报价计算逻辑,根据是否包含包装费标志位决定计算方式 - 加强 SupplierWeightCalculator 中数值计算的空值防护,防止 NaN问题 - 移除冗余的控制台日志输出,清理调试代码- 调整部分组件结构和类名,提升代码可读性和一致性
1041 lines
32 KiB
TypeScript
1041 lines
32 KiB
TypeScript
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<OrderVehicleRef>(null);
|
||
// 创建MelonFarmer组件的ref数组
|
||
const melonFarmerRefs = useRef<MelonFarmerRef[]>([]);
|
||
// 创建Weigh组件的ref数组
|
||
const weighRefs = useRef<WeighRef[]>([]);
|
||
// 创建OrderCost组件的ref
|
||
const orderCostRef = useRef<OrderCostRef>(null);
|
||
// 创建OrderPackage组件的ref
|
||
const orderPackageRefs = useRef<OrderPackageRef[]>([]);
|
||
|
||
const [purchaseOrder, setPurchaseOrder] =
|
||
useState<BusinessAPI.PurchaseOrderCreateCmd>();
|
||
|
||
console.log("purchaseOrder", purchaseOrder);
|
||
|
||
const [step, setStep] = useState<any>();
|
||
|
||
const [active, setActive] = useState<number>(1);
|
||
const [orderVehicle, setOrderVehicle] =
|
||
useState<BusinessAPI.PurchaseOrderCreateCmd["orderVehicle"]>();
|
||
const [orderDealer, setOrderDealer] =
|
||
useState<BusinessAPI.PurchaseOrderCreateCmd["orderDealer"]>();
|
||
const [orderSupplierList, setOrderSupplierList] =
|
||
useState<SupplierVO[]>(defaultSupplierList);
|
||
const [orderCostList, setOrderCostList] = useState<CostItem[]>([]);
|
||
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 (
|
||
<>
|
||
<View className={"sticky top-0 z-11"}>
|
||
{step.value !== 7 && (
|
||
<View className="h-12 bg-white p-2.5 shadow-sm">
|
||
<View className="step-indicator flex h-2 rounded-full bg-gray-200">
|
||
<View
|
||
className="bg-primary rounded-full"
|
||
style={`width: ${(100 / purchase.steps.length) * step.value}%`}
|
||
></View>
|
||
</View>
|
||
<View className="mt-1 text-sm font-bold text-[#000000]">
|
||
{step.title}
|
||
</View>
|
||
</View>
|
||
)}
|
||
|
||
{(step.value === 2 ||
|
||
step.value === 3 ||
|
||
step.value === 4 ||
|
||
step.value === 5) && (
|
||
<SupplierList
|
||
value={orderSupplierList}
|
||
onSelect={(supplierVO: SupplierVO) => {
|
||
// 获取当前选中的供应商
|
||
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;
|
||
}),
|
||
);
|
||
}}
|
||
/>
|
||
)}
|
||
</View>
|
||
|
||
<View className={"flex-1 bg-[#D1D5DB]"}>
|
||
{/* 车辆信息 */}
|
||
{step.value === 1 && (
|
||
<OrderVehicle
|
||
ref={vehicleRef}
|
||
orderVehicle={orderVehicle!}
|
||
setOrderVehicle={(orderVehicle) => {
|
||
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 (
|
||
<MelonFarmer
|
||
setLoading={setLoading}
|
||
supplierCount={orderSupplierList.length}
|
||
key={item.orderSupplierId}
|
||
ref={(ref) => {
|
||
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 (
|
||
<Weigh
|
||
changePaper={(isPaper) => {
|
||
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 (
|
||
<OrderPackage
|
||
key={item.orderSupplierId}
|
||
ref={(ref) => {
|
||
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 (
|
||
<TicketUpload
|
||
key={item.orderSupplierId}
|
||
value={item}
|
||
onChange={(supplierVO: SupplierVO) => {
|
||
orderSupplierList[index] = { ...item, ...supplierVO };
|
||
setOrderSupplierList([...orderSupplierList]);
|
||
}}
|
||
/>
|
||
);
|
||
}
|
||
})}
|
||
|
||
{/* 人工和辅料信息 */}
|
||
{step.value === 6 && (
|
||
<OrderCost
|
||
supplierVO={orderSupplierList[orderSupplierList.length - 1]}
|
||
onAdd={() => {
|
||
saveSupplierInfo();
|
||
setActive(2);
|
||
onAdd();
|
||
}}
|
||
ref={orderCostRef}
|
||
value={orderCostList}
|
||
onChange={(costItemList: CostItem[]) => {
|
||
// 修改标识将在useEffect中自动更新
|
||
setOrderCostList(costItemList);
|
||
}}
|
||
emptyBoxList={orderPackageList}
|
||
onEmptyBoxChange={(emptyBoxList: BusinessAPI.OrderPackage[]) => {
|
||
setOrderPackageList(emptyBoxList);
|
||
}}
|
||
costItemVOList={costItemVOList}
|
||
/>
|
||
)}
|
||
</View>
|
||
|
||
{/* 按钮操作 */}
|
||
<View className={"sticky bottom-0 z-10 bg-white"}>
|
||
<View className="flex justify-between gap-2 border-t border-gray-200 p-2.5">
|
||
{active > 1 && active <= 6 && (
|
||
<View className={"flex-1"}>
|
||
<Button
|
||
block
|
||
type={"default"}
|
||
size={"xlarge"}
|
||
className="flex-1 bg-gray-200 text-gray-700"
|
||
onClick={() => {
|
||
if (active > 1) {
|
||
setActive(active - 1);
|
||
}
|
||
}}
|
||
>
|
||
上一步
|
||
</Button>
|
||
</View>
|
||
)}
|
||
|
||
{active >= 1 && active <= 6 && (
|
||
<View className={"flex-1"}>
|
||
<Button
|
||
block
|
||
type={"default"}
|
||
size={"xlarge"}
|
||
className="flex-1 bg-gray-200 text-gray-700"
|
||
onClick={async () => {
|
||
await saveDraft();
|
||
}}
|
||
>
|
||
暂存
|
||
</Button>
|
||
</View>
|
||
)}
|
||
|
||
{active < 6 && (
|
||
<View className={"flex-1"}>
|
||
<Button
|
||
block
|
||
type={"primary"}
|
||
size={"xlarge"}
|
||
className="bg-primary flex-1 text-white"
|
||
onClick={async () => {
|
||
setLoading(true);
|
||
// 在第一步(车辆信息)时进行校验
|
||
if (active === 1) {
|
||
if (vehicleRef.current?.validate()) {
|
||
const success = await saveVehicleAndDealerInfo();
|
||
if (success) {
|
||
setActive(active + 1);
|
||
}
|
||
}
|
||
}
|
||
// 在第二步(瓜农信息)时进行校验
|
||
else if (active === 2) {
|
||
// 获取当前选中的供应商
|
||
const selectedIndex = orderSupplierList.findIndex(
|
||
(supplier) => supplier.selected,
|
||
);
|
||
if (
|
||
selectedIndex !== -1 &&
|
||
melonFarmerRefs.current[selectedIndex]?.validate()
|
||
) {
|
||
const success = await saveSupplierInfo();
|
||
if (success) {
|
||
setActive(active + 1);
|
||
}
|
||
}
|
||
}
|
||
// 在第三步(称重信息)时进行校验
|
||
else if (active === 3) {
|
||
// 获取当前选中的供应商
|
||
const selectedIndex = orderSupplierList.findIndex(
|
||
(supplier) => supplier.selected,
|
||
);
|
||
if (
|
||
selectedIndex !== -1 &&
|
||
weighRefs.current[selectedIndex]?.validate()
|
||
) {
|
||
const success = await saveSupplierInfo();
|
||
if (success) {
|
||
setActive(active + 1);
|
||
}
|
||
}
|
||
} // 在第四步(包装信息)时进行校验
|
||
else if (active === 4) {
|
||
// 获取当前选中的供应商
|
||
const selectedIndex = orderSupplierList.findIndex(
|
||
(supplier) => supplier.selected,
|
||
);
|
||
if (
|
||
selectedIndex !== -1 &&
|
||
orderPackageRefs.current[selectedIndex]?.validate()
|
||
) {
|
||
const success = await saveSupplierInfo();
|
||
if (success) {
|
||
setActive(active + 1);
|
||
}
|
||
}
|
||
} // 在第五步(票证上传)时进行校验
|
||
else if (active === 5) {
|
||
const success = await saveSupplierInfo();
|
||
if (success) {
|
||
setActive(active + 1);
|
||
}
|
||
} else {
|
||
setActive(active + 1);
|
||
}
|
||
setLoading(false);
|
||
}}
|
||
>
|
||
下一步
|
||
</Button>
|
||
</View>
|
||
)}
|
||
{active === 6 && (
|
||
<>
|
||
<View className={"flex-1"}>
|
||
<Button
|
||
block
|
||
type={"primary"}
|
||
size={"xlarge"}
|
||
className="btn-large bg-primary ml-2 flex-1 text-white"
|
||
onClick={async () => {
|
||
setLoading(true);
|
||
// 第六步(人工辅料)时进行校验
|
||
if (orderCostRef.current?.validate()) {
|
||
await onFinish();
|
||
}
|
||
setLoading(false);
|
||
}}
|
||
>
|
||
预览
|
||
</Button>
|
||
</View>
|
||
</>
|
||
)}
|
||
</View>
|
||
<SafeArea position={"bottom"} />
|
||
</View>
|
||
|
||
<Tour
|
||
className="nut-custom-tour nut-customword-tour hidden"
|
||
visible={showTour}
|
||
onClose={closeTour}
|
||
list={steps}
|
||
type="step"
|
||
location="bottom-right"
|
||
/>
|
||
</>
|
||
);
|
||
});
|