ERPTurbo_Client/packages/app-client/src/pages/purchase/enter/create.tsx
shenyifei 6b51d6b1e3 refactor(purchase): 优化采购模块代码逻辑与UI组件
- 统一使用非空断言操作符处理costItemId比较
- 在Step1Form中添加useImperativeHandle暴露表单验证方法
- 替换按钮图标组件为Icon增强视觉一致性
- 为输入框添加清空功能图标提升用户体验
- 调整商品单位默认值从"件"改为"kg"
- 在MelonFarmer模块初始化时添加packageUsage配置
- 修正selected属性赋值逻辑确保布尔值正确性
- 简化OrderOption模块保存逻辑移除冗余try-catch
- 重构OrderPackage模块减少依赖优化性能
- 引入全局loading状态改善异步操作反馈
- 重新设计纸箱类型启用逻辑支持动态配置
- 移除大量冗余状态管理与事件处理函数
- 优化useEffect依赖数组避免不必要的重复执行
- 整体简化组件结构提高可维护性
2025-12-10 13:33:54 +08:00

487 lines
14 KiB
TypeScript

import hocAuth from "@/hocs/auth";
import { CommonComponent } from "@/types/typings";
import { View } from "@tarojs/components";
import { purchase } from "@/constant";
import { useEffect, useRef, useState } from "react";
import {
Icon,
MelonFarmer,
MelonFarmerRef,
OrderCost,
OrderCostItem,
OrderCostItemRef,
OrderCostRef,
OrderOption,
OrderOptionRef,
OrderPackage,
OrderPackageRef,
OrderVehicle,
OrderVehicleRef,
SupplierList,
TicketUpload,
Weigh,
WeighRef,
} from "@/components";
import { business } from "@/services";
import { buildUrl, generateShortId, SupplierWeightCalculator } from "@/utils";
import Taro from "@tarojs/taro";
import { Button } from "@nutui/nutui-react-taro";
const defaultSupplierList: Partial<BusinessAPI.OrderSupplier>[] = [
{
orderSupplierId: generateShortId(),
supplierId: "",
name: "瓜农1",
idCard: "",
bankCard: "",
phone: "",
selected: true,
wechatQr: "",
isLast: undefined,
// 空磅是否包含纸箱
isPaper: undefined,
// 空磅重量
emptyWeight: undefined,
// 总磅重量
totalWeight: undefined,
// 采购单价
purchasePrice: undefined,
// 空磅照片
emptyWeightImg: "",
// 总磅照片
totalWeightImg: "",
orderPackageList: [],
packageUsage: [
{
boxType: "USED",
isUsed: 0,
},
{
boxType: "EXTRA_USED",
isUsed: 0,
},
{
boxType: "EXTRA",
isUsed: 0,
},
{
boxType: "REMAIN",
isUsed: 0,
},
{
boxType: "OWN",
isUsed: 0,
},
],
},
];
export default hocAuth(function Page(props: CommonComponent) {
const { router, userRoleVO, setLoading } = props;
const orderId = router.params.orderId as string;
const defaultStep = router.params.step as number;
const defaultActive = router.params.active as number;
const defaultSupplierId = router.params.supplierId as string;
const defaultOrderSupplierId = router.params.orderSupplierId as string;
const orderOptionRef = useRef<OrderOptionRef>(null);
const vehicleRef = useRef<OrderVehicleRef>(null);
// 创建MelonFarmer组件的ref数组
const melonFarmerRefs = useRef<MelonFarmerRef[]>([]);
// 创建Weigh组件的ref数组
const weighRefs = useRef<WeighRef[]>([]);
// 创建OrderCost组件的ref
const orderCostRef = useRef<OrderCostRef>(null);
// 创建OrderCostItem组件的ref
const orderCostItemRef = useRef<OrderCostItemRef>(null);
// 创建OrderPackage组件的ref
const orderPackageRefs = useRef<OrderPackageRef[]>([]);
const [purchaseOrder, setPurchaseOrder] =
useState<BusinessAPI.PurchaseOrderVO>();
const [step, setStep] = useState<any>();
useEffect(() => {
if (orderId) {
setLoading(true);
business.purchaseOrder
.showPurchaseOrder({
purchaseOrderShowQry: {
orderId: orderId,
},
})
.then(({ data: { data: purchaseOrder, success } }) => {
if (success && purchaseOrder) {
// 如果订单状态不是草稿,则跳转到预览页面
if (
purchaseOrder.state !== "DRAFT" &&
userRoleVO.slug === "origin-entry"
) {
Taro.redirectTo({
url: buildUrl("/pages/purchase/enter/preview", {
orderId: purchaseOrder.orderId,
}),
});
return;
}
setPurchaseOrder(purchaseOrder);
const orderSupplierList1 = purchaseOrder.orderSupplierList as any;
if (defaultOrderSupplierId) {
const index = orderSupplierList1.findIndex(
(item: any) => item.orderSupplierId === defaultOrderSupplierId,
);
orderSupplierList1[index].selected = true;
} else {
orderSupplierList1[0].selected = true;
}
console.log("defaultStep", defaultStep);
let active: number;
if (defaultActive) {
active = defaultActive;
} else if (defaultStep) {
active = defaultStep;
} else {
active = purchaseOrder.active || 1;
if (active < 1 || active > purchase.steps.length - 1) {
active = 1;
}
}
console.log("active", active);
setPurchaseOrder({
...purchaseOrder,
active,
orderSupplierList: orderSupplierList1,
});
}
})
.catch((err) => {
console.error("获取采购订单失败:", err);
})
.finally(() => {
setLoading(false);
});
} else {
setPurchaseOrder({
...purchaseOrder!,
active: 1,
orderSupplierList: defaultSupplierList as any,
});
}
}, [orderId]);
useEffect(() => {
setStep(purchase.steps[purchaseOrder?.active! - 1]);
}, [purchaseOrder?.active]);
// useEffect(() => {
// if (defaultStep) {
// setPurchaseOrder((prev) => ({
// ...prev!,
// active: defaultStep + 1,
// }));
// }
// }, [defaultStep]);
const setOrderSupplierList = (
orderSupplierList: BusinessAPI.OrderSupplier[],
) => {
setPurchaseOrder((prev) => ({
...prev!,
orderSupplierList,
}));
};
useEffect(() => {
if (defaultSupplierId) {
setLoading(true);
business.supplier
.showSupplier({
supplierShowQry: {
supplierId: defaultSupplierId,
},
})
.then(({ data: { data: supplierVO } }) => {
if (supplierVO) {
setOrderSupplierList([
{
orderSupplierId: generateShortId(),
...supplierVO,
selected: true,
} as any,
]);
}
})
.finally(() => {
setLoading(false);
});
}
}, [defaultSupplierId]);
if (step === undefined) {
return;
}
return (
<>
<View className={"sticky top-0 z-11"}>
{step.value < purchase.steps.length && (
<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.replace("{}", purchase.steps.length - 1)}
</View>
</View>
)}
{step.value >= 2 && step.value <= 5 && (
<SupplierList
value={purchaseOrder as any}
onChange={(purchaseOrder: BusinessAPI.PurchaseOrderVO) => {
setPurchaseOrder(purchaseOrder);
}}
melonFarmerRefs={melonFarmerRefs}
weighRefs={weighRefs}
orderPackageRefs={orderPackageRefs}
/>
)}
</View>
<View className={"flex-1 bg-[#D1D5DB]"}>
{/* 车辆信息 */}
{step.value === 1 && (
<OrderVehicle
value={purchaseOrder as any}
onChange={(purchaseOrder: BusinessAPI.PurchaseOrderVO) => {
setPurchaseOrder((prev) => {
return {
...prev!,
...purchaseOrder,
};
});
}}
ref={vehicleRef}
/>
)}
{/* 瓜农信息 */}
{purchaseOrder?.orderSupplierList?.map(
(item: BusinessAPI.OrderSupplier, index) => {
if (!item.selected) {
return;
}
if (step.value === 2) {
// 确保ref数组足够长
while (melonFarmerRefs.current.length <= index) {
melonFarmerRefs.current.push({
validate: () => true, // 默认验证方法
} as MelonFarmerRef);
}
return (
<MelonFarmer
index={index}
key={item.orderSupplierId}
value={purchaseOrder as any}
onChange={(purchaseOrder: BusinessAPI.PurchaseOrderVO) => {
setPurchaseOrder((prev) => {
return {
...prev!,
...purchaseOrder,
orderSupplierList: new SupplierWeightCalculator(
purchaseOrder?.orderSupplierList,
).calculate(),
};
});
}}
ref={(ref) => {
if (ref) {
melonFarmerRefs.current[index] = ref;
}
}}
/>
);
}
// 称重信息
if (step.value === 3) {
// 确保ref数组足够长
while (weighRefs.current.length <= index) {
weighRefs.current.push({
validate: () => true, // 默认验证方法
} as WeighRef);
}
return (
<Weigh
index={index}
key={item.orderSupplierId}
value={purchaseOrder as any}
onChange={(purchaseOrder: BusinessAPI.PurchaseOrderVO) => {
setPurchaseOrder((prev) => {
return {
...prev!,
...purchaseOrder,
orderSupplierList: new SupplierWeightCalculator(
purchaseOrder?.orderSupplierList,
).calculate(),
};
});
}}
ref={(ref) => {
if (ref) {
weighRefs.current[index] = ref;
}
}}
/>
);
}
// 包装信息
if (step.value === 4) {
// 确保ref数组足够长
while (orderPackageRefs.current.length <= index) {
orderPackageRefs.current.push({
validate: () => true, // 默认验证方法
} as OrderPackageRef);
}
return (
<OrderPackage
index={index}
key={item.orderSupplierId}
value={purchaseOrder as any}
onChange={(purchaseOrder: BusinessAPI.PurchaseOrderVO) => {
setPurchaseOrder((prev) => {
return {
...prev!,
...purchaseOrder,
orderSupplierList: new SupplierWeightCalculator(
purchaseOrder?.orderSupplierList,
).calculate(),
};
});
}}
ref={(ref) => {
if (ref) {
orderPackageRefs.current[index] = ref;
}
}}
/>
);
}
// 票证上传
if (step.value === 5) {
return (
<TicketUpload
index={index}
key={item.orderSupplierId}
value={purchaseOrder as any}
onChange={(purchaseOrder: BusinessAPI.PurchaseOrderVO) => {
setPurchaseOrder((prev) => {
return {
...prev!,
...purchaseOrder,
};
});
}}
/>
);
}
},
)}
{/* 人工和辅料信息 */}
{step.value === 6 && (
<OrderCostItem
ref={orderCostItemRef}
value={purchaseOrder as any}
onChange={(purchaseOrder: BusinessAPI.PurchaseOrderVO) => {
setPurchaseOrder((prev) => {
return {
...prev!,
foreman: purchaseOrder.foreman,
orderCostItemList: purchaseOrder.orderCostItemList,
};
});
}}
/>
)}
{/* 费用 */}
{step.value === 6 && (
<OrderCost
value={purchaseOrder as any}
onChange={(purchaseOrder: BusinessAPI.PurchaseOrderVO) => {
setPurchaseOrder((prev) => {
return {
...prev!,
orderCostList: purchaseOrder.orderCostList,
};
});
}}
ref={orderCostRef}
/>
)}
{(step.value === 6 || step.value === 5) &&
!purchaseOrder?.orderSupplierList[
purchaseOrder?.orderSupplierList.length - 1
]?.isLast && (
<View className="flex flex-1 flex-col gap-2.5 bg-[#D1D5DB] p-2.5 pt-2.5">
<View className={"flex flex-1 flex-col gap-2.5"}>
<View className="text-sm font-bold"></View>
<Button
icon={<Icon name={"plus"} size={20} />}
type={"primary"}
size={"xlarge"}
fill={"outline"}
block
className="border-primary text-primary flex w-full items-center justify-center !border-4 !bg-white"
onClick={() => {
orderOptionRef.current?.onAdd();
}}
>
<View></View>
</Button>
</View>
</View>
)}
</View>
{/* 按钮操作 */}
<OrderOption
ref={orderOptionRef}
value={purchaseOrder as any}
onChange={(purchaseOrderVO: BusinessAPI.PurchaseOrderVO) =>
setPurchaseOrder((prev) => {
return {
...prev!,
...purchaseOrderVO,
};
})
}
vehicleRef={vehicleRef}
melonFarmerRefs={melonFarmerRefs}
weighRefs={weighRefs}
orderPackageRefs={orderPackageRefs}
orderCostRef={orderCostRef}
orderCostItemRef={orderCostItemRef}
/>
</>
);
});