- 移除 PageList 组件中对全局 loading 状态的依赖 - 简化 EmptyBoxModule 组件逻辑,使用 PackageList 组件替代原有复杂实现 - 移除冗余的状态管理和弹窗渲染逻辑 - 优化 OrderCost 组件样式和费用项匹配逻辑 - 修复成本项 ID 匹配问题,确保数据正确关联 - 添加边框样式增强视觉效果 - 移除调试日志和无用代码 - 简化组件间数据传递方式
491 lines
16 KiB
TypeScript
491 lines
16 KiB
TypeScript
import { View } from "@tarojs/components";
|
||
import { Button, Toast } from "@nutui/nutui-react-taro";
|
||
import { forwardRef, useEffect, useImperativeHandle, useState } from "react";
|
||
import { business } from "@/services";
|
||
import { BoxBrand, BoxProduct, BoxSpec } from "@/types/typings";
|
||
import { generateShortId } from "@/utils";
|
||
import { PackageList } from "@/components";
|
||
import { globalStore } from "@/store/global-store";
|
||
|
||
// 定义ref暴露的方法接口
|
||
export interface OrderPackageRef {
|
||
validate: () => boolean;
|
||
}
|
||
|
||
interface IOrderPackageProps {
|
||
index: number;
|
||
value: BusinessAPI.PurchaseOrderVO;
|
||
onChange: (purchaseOrderVO: BusinessAPI.PurchaseOrderVO) => void;
|
||
}
|
||
|
||
export default forwardRef<OrderPackageRef, IOrderPackageProps>(
|
||
function OrderPackage(props, ref) {
|
||
const { value, onChange, index } = props;
|
||
|
||
const { setLoading } = globalStore((state: any) => state);
|
||
const { orderSupplierList } = value;
|
||
const supplierVO = orderSupplierList[index];
|
||
const orderPackageList =
|
||
supplierVO.orderPackageList as BusinessAPI.OrderPackage[];
|
||
|
||
useEffect(() => {
|
||
// 初始化数据
|
||
|
||
// 确定当前供应商需要检查哪些纸箱类型
|
||
const initializePackageTypeEnabled = () => {
|
||
const usageMap = (supplierVO.packageUsage || []).reduce(
|
||
(acc, item) => {
|
||
if (item.boxType) {
|
||
acc[item.boxType] = item.isUsed || 0;
|
||
}
|
||
return acc;
|
||
},
|
||
{} as Record<string, number>,
|
||
);
|
||
|
||
if (supplierVO.isPaper && supplierVO.isLast) {
|
||
setPackageTypeEnabled({
|
||
EXTRA: 0,
|
||
EXTRA_USED: usageMap["EXTRA_USED"] || 0,
|
||
REMAIN: usageMap["REMAIN"] || 0,
|
||
});
|
||
} else if (supplierVO.isPaper && !supplierVO.isLast) {
|
||
setPackageTypeEnabled({
|
||
EXTRA: usageMap["EXTRA"] || 0,
|
||
EXTRA_USED: 0,
|
||
REMAIN: 0,
|
||
});
|
||
} else if (!supplierVO.isPaper) {
|
||
setPackageTypeEnabled({
|
||
EXTRA: 0,
|
||
EXTRA_USED: 0,
|
||
REMAIN: 0,
|
||
});
|
||
}
|
||
};
|
||
|
||
initializePackageTypeEnabled();
|
||
}, []);
|
||
|
||
const setOrderPackageList = (
|
||
orderPackageList: BusinessAPI.OrderPackage[],
|
||
) => {
|
||
onChange?.({
|
||
...value,
|
||
orderSupplierList: orderSupplierList.map((item, index1) => {
|
||
if (index1 === index) {
|
||
return {
|
||
...item,
|
||
orderPackageList,
|
||
};
|
||
}
|
||
return item;
|
||
}),
|
||
});
|
||
};
|
||
|
||
// 将校验方法暴露给父组件
|
||
useImperativeHandle(ref, () => ({
|
||
validate,
|
||
}));
|
||
|
||
// 校验函数
|
||
const validate = () => {
|
||
// 根据当前供应商确定需要检查的纸箱类型
|
||
let requiredTypes: string[] = [];
|
||
|
||
// 确定当前供应商需要检查哪些纸箱类型
|
||
if (supplierVO.isPaper && supplierVO.isLast) {
|
||
// 空磅包含纸箱 + 最后一个瓜农
|
||
requiredTypes = ["EXTRA_USED", "REMAIN"];
|
||
} else if (supplierVO.isPaper && !supplierVO.isLast) {
|
||
requiredTypes = ["EXTRA"];
|
||
}
|
||
|
||
console.log("requiredTypes", requiredTypes);
|
||
if (requiredTypes.length > 0) {
|
||
// 检查所需选项是否都已做出选择(不是1就是2,不能是0)
|
||
const allRequiredAnswered = requiredTypes.every(
|
||
(type) =>
|
||
packageTypeEnabled[type] === 1 || packageTypeEnabled[type] === 2,
|
||
);
|
||
|
||
if (!allRequiredAnswered || requiredTypes.length === 0) {
|
||
Toast.show("toast", {
|
||
icon: "fail",
|
||
title: "提示",
|
||
content: "请回答相关的纸箱使用情况问题",
|
||
});
|
||
return false;
|
||
}
|
||
}
|
||
|
||
requiredTypes.push("USED");
|
||
|
||
// 检查所有启用的纸箱类型是否都填写了信息
|
||
const enabledTypes = Object.entries(packageTypeEnabled)
|
||
.filter(
|
||
([type, enabled]) => requiredTypes.includes(type) && enabled === 1,
|
||
)
|
||
.map(([type, _]) => type);
|
||
|
||
// 检查每个启用的类型是否有对应的纸箱数据
|
||
for (const type of enabledTypes) {
|
||
const hasPackagesOfType = orderPackageList.some(
|
||
(item) => item.boxType === type,
|
||
);
|
||
|
||
if (!hasPackagesOfType) {
|
||
const typeLabels = {
|
||
USED: "记录装车用的纸箱",
|
||
EXTRA_USED: "记录用的额外运输纸箱",
|
||
EXTRA: "记录额外运输来的所有纸箱",
|
||
REMAIN: "记录车上没用完的纸箱",
|
||
};
|
||
|
||
Toast.show("toast", {
|
||
icon: "fail",
|
||
title: "提示",
|
||
content: `已选择使用${typeLabels[type]},请添加对应的纸箱信息`,
|
||
});
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
};
|
||
|
||
// 纸箱品牌数据
|
||
const [boxBrandList, setBoxBrandList] = useState<BoxBrand[]>();
|
||
|
||
const initBoxBrandList = async () => {
|
||
setLoading(true);
|
||
const { data } = await business.boxBrand.listBoxBrand({
|
||
boxBrandListQry: {
|
||
status: true,
|
||
withProduct: true,
|
||
},
|
||
});
|
||
|
||
const boxBrandList =
|
||
data.data
|
||
?.filter(
|
||
(boxBrand) =>
|
||
boxBrand.status &&
|
||
boxBrand.boxProductVOList &&
|
||
boxBrand.boxProductVOList.length > 0,
|
||
)
|
||
.map((boxBrand) => {
|
||
// 将产品按规格分类
|
||
const boxSpecList: BoxSpec[] =
|
||
boxBrand.boxSpecVOList?.map((item) => {
|
||
return {
|
||
id: generateShortId(),
|
||
boxSpecId: item.specId,
|
||
boxSpecName: item.name,
|
||
boxProductList: [],
|
||
};
|
||
}) || [];
|
||
const boxProductList = boxBrand.boxProductVOList?.map(
|
||
(boxProductVO) => {
|
||
const boxProduct: BoxProduct = {
|
||
id: generateShortId(),
|
||
boxProductId: boxProductVO.productId,
|
||
boxProductName: boxProductVO.name,
|
||
boxProductWeight: boxProductVO.weight,
|
||
boxSpecId: boxProductVO.specId,
|
||
boxSpecName: boxProductVO.specName,
|
||
boxCostPrice: boxProductVO.costPrice,
|
||
boxSalePrice: boxProductVO.salePrice,
|
||
boxBrandId: boxBrand.brandId,
|
||
boxBrandName: boxBrand.name,
|
||
boxCount: 0,
|
||
};
|
||
|
||
return boxProduct;
|
||
},
|
||
);
|
||
|
||
return {
|
||
id: generateShortId(),
|
||
boxBrandId: boxBrand.brandId,
|
||
boxBrandName: boxBrand.name,
|
||
boxBrandImage: boxBrand.image,
|
||
boxBrandType: boxBrand.type,
|
||
boxSpecList:
|
||
boxSpecList
|
||
.map((boxSpec) => {
|
||
return {
|
||
id: generateShortId(),
|
||
boxSpecId: boxSpec.boxSpecId,
|
||
boxSpecName: boxSpec.boxSpecName,
|
||
boxProductList:
|
||
boxProductList?.filter(
|
||
(boxProduct) =>
|
||
boxProduct.boxSpecId === boxSpec.boxSpecId,
|
||
) || [],
|
||
};
|
||
})
|
||
.filter(
|
||
(boxSpec) =>
|
||
boxSpec.boxProductList &&
|
||
boxSpec.boxProductList.length > 0,
|
||
) || [],
|
||
};
|
||
}) || [];
|
||
|
||
setBoxBrandList(boxBrandList as any);
|
||
setLoading(false);
|
||
};
|
||
|
||
useEffect(() => {
|
||
initBoxBrandList().then();
|
||
}, []);
|
||
|
||
// 新增状态:跟踪每种纸箱类型的启用状态
|
||
// 0: 未选, 1: 选择是, 2: 选择否
|
||
const [packageTypeEnabled, setPackageTypeEnabled] = useState({
|
||
EXTRA_USED: 0,
|
||
EXTRA: 0,
|
||
REMAIN: 0,
|
||
});
|
||
|
||
console.log("packageTypeEnabled", packageTypeEnabled);
|
||
|
||
useEffect(() => {
|
||
if (packageTypeEnabled) {
|
||
onChange?.({
|
||
...value,
|
||
orderSupplierList: orderSupplierList.map((item, index1) => {
|
||
if (index1 === index) {
|
||
return {
|
||
...item,
|
||
packageUsage: [
|
||
...(Object.entries(
|
||
packageTypeEnabled || {
|
||
EXTRA_USED: 0,
|
||
EXTRA: 0,
|
||
REMAIN: 0,
|
||
},
|
||
).map(
|
||
([boxType, isUsed]: [
|
||
BusinessAPI.OrderPackage["boxType"],
|
||
number,
|
||
]) => {
|
||
return {
|
||
boxType: boxType,
|
||
isUsed: isUsed,
|
||
};
|
||
},
|
||
) || []),
|
||
],
|
||
};
|
||
}
|
||
return item;
|
||
}),
|
||
});
|
||
}
|
||
}, [packageTypeEnabled]);
|
||
|
||
return (
|
||
<View className="flex flex-1 flex-col gap-2.5 p-2.5">
|
||
{/* 替换原来的Tab导航为问答式选择 */}
|
||
<View className="border-primary rounded-lg border-4 bg-white p-2.5 shadow-sm">
|
||
<View className="flex flex-col gap-2.5">
|
||
<View className="text-base font-bold">
|
||
{supplierVO.name}装车的纸箱使用情况
|
||
</View>
|
||
|
||
<PackageList
|
||
boxType={"USED"}
|
||
orderPackageList={orderPackageList}
|
||
setOrderPackageList={setOrderPackageList}
|
||
boxBrandList={boxBrandList}
|
||
/>
|
||
</View>
|
||
</View>
|
||
|
||
{/* 根据供应商属性显示不同的问题 */}
|
||
{supplierVO.isPaper && supplierVO.isLast && (
|
||
<>
|
||
<View className="border-primary rounded-lg border-4 bg-white p-2.5 shadow-sm">
|
||
<View className="flex flex-col gap-2.5">
|
||
{/* 空车带来的纸箱用完了吗? */}
|
||
<View className="flex items-center justify-between">
|
||
<View className="text-sm">空车带来的纸箱用完了吗?</View>
|
||
<View className="flex flex-shrink-0 gap-2">
|
||
<Button
|
||
size="small"
|
||
type={
|
||
packageTypeEnabled.REMAIN === 2 ? "primary" : "default"
|
||
}
|
||
onClick={() => {
|
||
setPackageTypeEnabled({
|
||
...packageTypeEnabled,
|
||
REMAIN: 2,
|
||
});
|
||
// 如果关闭,也需要清除相关数据
|
||
if (packageTypeEnabled.REMAIN === 1) {
|
||
setOrderPackageList(
|
||
orderPackageList.filter(
|
||
(item) => item.boxType !== "REMAIN",
|
||
),
|
||
);
|
||
}
|
||
}}
|
||
>
|
||
用完了
|
||
</Button>
|
||
<Button
|
||
size="small"
|
||
type={
|
||
packageTypeEnabled.REMAIN === 1 ? "primary" : "default"
|
||
}
|
||
onClick={() => {
|
||
setPackageTypeEnabled({
|
||
...packageTypeEnabled,
|
||
REMAIN: 1,
|
||
});
|
||
}}
|
||
>
|
||
没用完
|
||
</Button>
|
||
</View>
|
||
</View>
|
||
|
||
{packageTypeEnabled.REMAIN === 1 && (
|
||
<PackageList
|
||
boxType={"REMAIN"}
|
||
orderPackageList={orderPackageList}
|
||
setOrderPackageList={setOrderPackageList}
|
||
boxBrandList={boxBrandList}
|
||
/>
|
||
)}
|
||
</View>
|
||
</View>
|
||
|
||
<View className="border-primary rounded-lg border-4 bg-white p-2.5 shadow-sm">
|
||
<View className="flex flex-col gap-2.5">
|
||
{/* 用额外运输纸箱的了吗? */}
|
||
<View className="flex items-center justify-between">
|
||
<View className="text-sm">用额外运输纸箱的了吗?</View>
|
||
<View className="flex flex-shrink-0 gap-2">
|
||
<Button
|
||
size="small"
|
||
type={
|
||
packageTypeEnabled.EXTRA_USED === 1
|
||
? "primary"
|
||
: "default"
|
||
}
|
||
onClick={() => {
|
||
setPackageTypeEnabled({
|
||
...packageTypeEnabled,
|
||
EXTRA_USED: 1,
|
||
});
|
||
}}
|
||
>
|
||
用了
|
||
</Button>
|
||
<Button
|
||
size="small"
|
||
type={
|
||
packageTypeEnabled.EXTRA_USED === 2
|
||
? "primary"
|
||
: "default"
|
||
}
|
||
onClick={() => {
|
||
setPackageTypeEnabled({
|
||
...packageTypeEnabled,
|
||
EXTRA_USED: 2,
|
||
});
|
||
// 如果关闭,也需要清除相关数据
|
||
if (packageTypeEnabled.EXTRA_USED === 1) {
|
||
setOrderPackageList(
|
||
orderPackageList.filter(
|
||
(item) => item.boxType !== "EXTRA_USED",
|
||
),
|
||
);
|
||
}
|
||
}}
|
||
>
|
||
没用
|
||
</Button>
|
||
</View>
|
||
</View>
|
||
|
||
{packageTypeEnabled.EXTRA_USED === 1 && (
|
||
<PackageList
|
||
boxType={"EXTRA_USED"}
|
||
orderPackageList={orderPackageList}
|
||
setOrderPackageList={setOrderPackageList}
|
||
boxBrandList={boxBrandList}
|
||
/>
|
||
)}
|
||
</View>
|
||
</View>
|
||
</>
|
||
)}
|
||
|
||
{supplierVO.isPaper && !supplierVO.isLast && (
|
||
/* 非最后一个瓜农 */
|
||
<View className="border-primary rounded-lg border-4 bg-white p-2.5 shadow-sm">
|
||
<View className="flex flex-col gap-2.5">
|
||
{/* 有额外运输纸箱过来吗? */}
|
||
<View className="flex items-center justify-between">
|
||
<View className="text-sm">有额外运输纸箱过来吗?</View>
|
||
<View className="flex flex-shrink-0 gap-2">
|
||
<Button
|
||
size="small"
|
||
type={
|
||
packageTypeEnabled.EXTRA === 1 ? "primary" : "default"
|
||
}
|
||
onClick={() => {
|
||
setPackageTypeEnabled({
|
||
...packageTypeEnabled,
|
||
EXTRA: 1,
|
||
});
|
||
}}
|
||
>
|
||
有
|
||
</Button>
|
||
<Button
|
||
size="small"
|
||
type={
|
||
packageTypeEnabled.EXTRA === 2 ? "primary" : "default"
|
||
}
|
||
onClick={() => {
|
||
setPackageTypeEnabled({
|
||
...packageTypeEnabled,
|
||
EXTRA: 2,
|
||
});
|
||
// 如果关闭,也需要清除相关数据
|
||
if (packageTypeEnabled.EXTRA === 1) {
|
||
setOrderPackageList(
|
||
orderPackageList.filter(
|
||
(item) => item.boxType !== "EXTRA",
|
||
),
|
||
);
|
||
}
|
||
}}
|
||
>
|
||
没有
|
||
</Button>
|
||
</View>
|
||
</View>
|
||
|
||
{packageTypeEnabled.EXTRA === 1 && (
|
||
<PackageList
|
||
boxType={"EXTRA"}
|
||
orderPackageList={orderPackageList}
|
||
setOrderPackageList={setOrderPackageList}
|
||
boxBrandList={boxBrandList}
|
||
/>
|
||
)}
|
||
</View>
|
||
</View>
|
||
)}
|
||
</View>
|
||
);
|
||
},
|
||
);
|