feat(purchase): 添加拼车选择功能并优化UI细节
- 在MelonFarmer组件中新增supplierCount属性用于判断是否显示拼车选项 - 修改"是否为最后一个瓜农"为"是否要拼车"的逻辑与文案 - 更新多个图标引用,包括新增address-book图标 - 调整输入框样式,增加图标前缀提升用户体验 - 优化称重信息页面的提示文字,使其更清晰易懂 - 增加OrderPackage相关类型定义及转换工具函数 - 更新页面审核和创建流程中的样式与交互逻辑 - 升级iconfont字体文件版本,支持新图标 - 修复部分组件样式问题,如SupplierList底部间距等
This commit is contained in:
parent
fb7951e2f3
commit
1ac1564ec2
@ -3,6 +3,7 @@ import classNames from "classnames";
|
||||
import React from "react";
|
||||
|
||||
export type IconNames =
|
||||
| "address-book"
|
||||
| "pen-to-square"
|
||||
| "location-dot"
|
||||
| "clock"
|
||||
|
||||
@ -25,11 +25,12 @@ interface IMelonFarmerProps {
|
||||
onRemove: (supplierVO: SupplierVO) => void;
|
||||
onAdd: () => void;
|
||||
isLast: boolean; // 添加一个属性来标识是否是最后一个瓜农
|
||||
supplierCount: number;
|
||||
}
|
||||
|
||||
export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
||||
function MelonFarmer(props, ref) {
|
||||
const { value, onChange, onRemove, onAdd, isLast } = props;
|
||||
const { value, onChange, onRemove, onAdd, isLast, supplierCount } = props;
|
||||
|
||||
const [supplierVO, setSupplierVO] = useState<SupplierVO>();
|
||||
console.log("supplierVO", supplierVO);
|
||||
@ -94,7 +95,7 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
||||
);
|
||||
const [isLastFarmerError, setIsLastFarmerError] = useState<{
|
||||
[key: string]: boolean;
|
||||
}>({}); // 添加是否为最后一个瓜农的错误状态
|
||||
}>({}); // 添加是否要拼车的错误状态
|
||||
|
||||
// 校验姓名函数
|
||||
const validateName = (name: string) => {
|
||||
@ -136,9 +137,10 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
||||
return phoneRegex.test(phone);
|
||||
};
|
||||
|
||||
// 校验是否为最后一个瓜农函数
|
||||
// 校验是否要拼车函数
|
||||
// 校验是否要拼车函数
|
||||
const validateIsLastFarmer = (isLast?: boolean) => {
|
||||
// 必须选择是或否
|
||||
// 必须选择要不要
|
||||
return isLast !== undefined;
|
||||
};
|
||||
|
||||
@ -151,7 +153,7 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
||||
const isIdCardValid = validateIdCard(supplierVO.idCard || "");
|
||||
const isBankCardValid = validateBankCard(supplierVO.bankCard || "");
|
||||
const isPhoneValid = validatePhone(supplierVO.phone || "");
|
||||
const isLastFarmerValid = validateIsLastFarmer(supplierVO?.isLast); // 校验是否为最后一个瓜农
|
||||
const isLastFarmerValid = validateIsLastFarmer(supplierVO?.isLast); // 校验是否需要拼车
|
||||
|
||||
// 更新错误状态
|
||||
setNameError((prev) => ({
|
||||
@ -384,7 +386,13 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
||||
}
|
||||
|
||||
return (
|
||||
<View className="flex flex-1 flex-col gap-2.5 p-2.5">
|
||||
<View
|
||||
className="flex flex-1 flex-col gap-2.5 p-2.5"
|
||||
style={{
|
||||
//@ts-ignore
|
||||
"--nutui-input-padding": 0,
|
||||
}}
|
||||
>
|
||||
{/* 功能提醒 */}
|
||||
<View className="flex items-center rounded-lg border border-blue-200 bg-blue-50 p-2.5">
|
||||
<Icon
|
||||
@ -398,6 +406,61 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 只有最后一个瓜农才显示是否为最后一个瓜农的选项和添加按钮 */}
|
||||
{isLast && (
|
||||
<View className="rounded-lg bg-white p-2.5 shadow-sm">
|
||||
<View className="flex items-center justify-between">
|
||||
{supplierCount > 1 ? (
|
||||
<View className="text-sm">这车货还要继续拼车吗?</View>
|
||||
) : (
|
||||
<View className="text-sm">这车货要拼车吗?</View>
|
||||
)}
|
||||
|
||||
<View className="text-neutral-darkest text-sm font-medium">
|
||||
<Radio.Group
|
||||
direction="horizontal"
|
||||
value={
|
||||
supplierVO.isLast === true
|
||||
? "true"
|
||||
: supplierVO.isLast === false
|
||||
? "false"
|
||||
: undefined
|
||||
}
|
||||
onChange={(value) => {
|
||||
// 清除错误状态
|
||||
setIsLastFarmerError((prev) => ({
|
||||
...prev,
|
||||
[supplierVO.orderSupplierId]: false,
|
||||
}));
|
||||
|
||||
// 根据用户选择设置是否为最后一个瓜农
|
||||
const isLastValue =
|
||||
value === "true"
|
||||
? true
|
||||
: value === "false"
|
||||
? false
|
||||
: undefined;
|
||||
setSupplierVO({
|
||||
...supplierVO,
|
||||
isLast: isLastValue,
|
||||
});
|
||||
|
||||
setIsLastFarmer(isLastValue!);
|
||||
}}
|
||||
>
|
||||
<Radio value="false">要</Radio>
|
||||
<Radio value="true">不要</Radio>
|
||||
</Radio.Group>
|
||||
</View>
|
||||
</View>
|
||||
{isLastFarmerError[supplierVO.orderSupplierId] && (
|
||||
<View className="mt-1 text-xs text-red-500">
|
||||
请选择本车货要不要拼车
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* 快捷工具 */}
|
||||
<View className="flex gap-2">
|
||||
<View className={"flex-1"}>
|
||||
@ -477,15 +540,22 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
||||
</View>
|
||||
</View>
|
||||
<View className="mb-2.5">
|
||||
<View className="mb-1 flex flex-row">
|
||||
<View className="mb-1 flex flex-row justify-between">
|
||||
<View className={"block text-sm font-normal text-[#000000]"}>
|
||||
姓名
|
||||
</View>
|
||||
<SupplierPicker
|
||||
trigger={
|
||||
<View className="flex items-center">
|
||||
<Icon
|
||||
name="address-book"
|
||||
size={16}
|
||||
color="var(--color-primary)"
|
||||
/>
|
||||
<Text className={"text-primary ml-1 text-sm font-bold"}>
|
||||
点我选瓜农
|
||||
</Text>
|
||||
</View>
|
||||
}
|
||||
onFinish={(supplierVO1) => {
|
||||
setSupplierVO({
|
||||
@ -516,6 +586,7 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
||||
<View
|
||||
className={`flex h-10 w-full items-center rounded-md ${nameError[supplierVO.orderSupplierId] ? "border-4 border-red-500" : "border-4 border-gray-300"}`}
|
||||
>
|
||||
<Icon name="user" size={16} color="#999" className="mx-2" />
|
||||
<Input
|
||||
type="text"
|
||||
placeholder="请输入姓名"
|
||||
@ -527,6 +598,7 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
||||
supplierVO.orderSupplierId,
|
||||
)
|
||||
}
|
||||
className="flex-1"
|
||||
/>
|
||||
</View>
|
||||
{nameError[supplierVO.orderSupplierId] && (
|
||||
@ -540,6 +612,7 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
||||
<View
|
||||
className={`flex h-10 w-full items-center rounded-md ${idCardError[supplierVO.orderSupplierId] ? "border-4 border-red-500" : "border-4 border-gray-300"}`}
|
||||
>
|
||||
<Icon name="id-card" size={16} color="#999" className="mx-2" />
|
||||
<Input
|
||||
type="text"
|
||||
placeholder="请输入身份证号"
|
||||
@ -551,6 +624,7 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
||||
supplierVO.orderSupplierId,
|
||||
)
|
||||
}
|
||||
className="flex-1"
|
||||
/>
|
||||
</View>
|
||||
{idCardError[supplierVO.orderSupplierId] && (
|
||||
@ -566,6 +640,12 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
||||
<View
|
||||
className={`flex h-10 w-full items-center rounded-md ${bankCardError[supplierVO.orderSupplierId] ? "border-4 border-red-500" : "border-4 border-gray-300"}`}
|
||||
>
|
||||
<Icon
|
||||
name="credit-card"
|
||||
size={16}
|
||||
color="#999"
|
||||
className="mx-2"
|
||||
/>
|
||||
<Input
|
||||
type="text"
|
||||
placeholder="请输入银行卡号"
|
||||
@ -577,6 +657,7 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
||||
supplierVO.orderSupplierId,
|
||||
)
|
||||
}
|
||||
className="flex-1"
|
||||
/>
|
||||
</View>
|
||||
{bankCardError[supplierVO.orderSupplierId] && (
|
||||
@ -592,6 +673,7 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
||||
<View
|
||||
className={`flex h-10 w-full items-center rounded-md ${phoneError[supplierVO.orderSupplierId] ? "border-4 border-red-500" : "border-4 border-gray-300"}`}
|
||||
>
|
||||
<Icon name="phone" size={16} color="#999" className="mx-2" />
|
||||
<Input
|
||||
type="tel"
|
||||
placeholder="请输入手机号码"
|
||||
@ -603,6 +685,7 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
||||
supplierVO.orderSupplierId,
|
||||
)
|
||||
}
|
||||
className="flex-1"
|
||||
/>
|
||||
</View>
|
||||
{phoneError[supplierVO.orderSupplierId] && (
|
||||
@ -639,56 +722,6 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 只有最后一个瓜农才显示是否为最后一个瓜农的选项和添加按钮 */}
|
||||
{isLast && (
|
||||
<View className="rounded-lg bg-white p-2.5 shadow-sm">
|
||||
<View className="flex items-center justify-between">
|
||||
<View className="text-sm">是否为最后一个瓜农</View>
|
||||
<View className="text-neutral-darkest text-sm font-medium">
|
||||
<Radio.Group
|
||||
direction="horizontal"
|
||||
value={
|
||||
supplierVO.isLast === true
|
||||
? "true"
|
||||
: supplierVO.isLast === false
|
||||
? "false"
|
||||
: undefined
|
||||
}
|
||||
onChange={(value) => {
|
||||
// 清除错误状态
|
||||
setIsLastFarmerError((prev) => ({
|
||||
...prev,
|
||||
[supplierVO.orderSupplierId]: false,
|
||||
}));
|
||||
|
||||
// 根据用户选择设置是否为最后一个瓜农
|
||||
const isLastValue =
|
||||
value === "true"
|
||||
? true
|
||||
: value === "false"
|
||||
? false
|
||||
: undefined;
|
||||
setSupplierVO({
|
||||
...supplierVO,
|
||||
isLast: isLastValue,
|
||||
});
|
||||
|
||||
setIsLastFarmer(isLastValue!);
|
||||
}}
|
||||
>
|
||||
<Radio value="true">是</Radio>
|
||||
<Radio value="false">否</Radio>
|
||||
</Radio.Group>
|
||||
</View>
|
||||
</View>
|
||||
{isLastFarmerError[supplierVO.orderSupplierId] && (
|
||||
<View className="mt-1 text-xs text-red-500">
|
||||
请选择是否为最后一个瓜农
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* 只有当用户选择"否"时才显示添加按钮 */}
|
||||
{isLast && !isLastFarmer && isLastFarmer !== null && (
|
||||
<Button
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -19,7 +19,7 @@ export default function SupplierList(props: ISupplierListProps) {
|
||||
console.log("value", value);
|
||||
|
||||
return (
|
||||
<View className={"sticky top-12 z-10 bg-[#D1D5DB] p-2.5"}>
|
||||
<View className={"sticky top-12 z-10 bg-[#D1D5DB] p-2.5 pb-0"}>
|
||||
<ScrollView className={"rounded-xl bg-white shadow-sm"} scrollX>
|
||||
<View className="flex flex-row">
|
||||
{value.map((supplierVO: SupplierVO) => (
|
||||
|
||||
@ -265,18 +265,8 @@ export default forwardRef<WeighRef, IWeightProps>(function Weigh(props, ref) {
|
||||
return (
|
||||
<View className="flex flex-1 flex-col gap-2.5 p-2.5">
|
||||
<View className="border-primary rounded-lg border-4 bg-white p-2.5 shadow-sm">
|
||||
<View className="text-primary mb-2.5 text-base font-bold">
|
||||
{supplierVO.name}的称重信息
|
||||
</View>
|
||||
|
||||
<View className="mb-2.5">
|
||||
<View className="mb-2.5">
|
||||
<View
|
||||
className={
|
||||
"flex flex-row items-center justify-between rounded-lg bg-gray-50 p-2.5"
|
||||
}
|
||||
>
|
||||
<View className="text-sm">空磅包含空纸箱</View>
|
||||
<View className={"flex items-center justify-between gap-2.5"}>
|
||||
<View className="text-sm">空车来的时候带纸箱了吗?</View>
|
||||
<View className="text-neutral-darkest text-sm font-medium">
|
||||
<Radio.Group
|
||||
direction="horizontal"
|
||||
@ -307,18 +297,24 @@ export default forwardRef<WeighRef, IWeightProps>(function Weigh(props, ref) {
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Radio value="true">是</Radio>
|
||||
<Radio value="false">否</Radio>
|
||||
<Radio value="true">带了</Radio>
|
||||
<Radio value="false">没带</Radio>
|
||||
</Radio.Group>
|
||||
</View>
|
||||
</View>
|
||||
{isPaperError[supplierVO.orderSupplierId] && (
|
||||
<View className="mt-1 text-xs text-red-500">
|
||||
请选择空磅是否包含空纸箱
|
||||
请选择车来的时候有没有带纸箱
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
|
||||
<View className="border-primary rounded-lg border-4 bg-white p-2.5 shadow-sm">
|
||||
<View className="text-primary mb-2.5 text-base font-bold">
|
||||
{supplierVO.name}的称重信息
|
||||
</View>
|
||||
|
||||
<View className="mb-2.5">
|
||||
<View className="mb-2.5 flex gap-2.5">
|
||||
<View className="flex-1 rounded-lg bg-blue-50 p-2.5">
|
||||
<View className="mb-2.5 flex items-center">
|
||||
|
||||
@ -37,7 +37,7 @@ export default function SupplierPicker(props: ISupplierPickerProps) {
|
||||
};
|
||||
|
||||
return (
|
||||
<View className={"flex-1"}>
|
||||
<View>
|
||||
<View
|
||||
onClick={(event) => {
|
||||
setVisible(true);
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 5042354 */
|
||||
src: url('//at.alicdn.com/t/c/font_5042354_lmz58v86a1h.woff2?t=1761549950025') format('woff2'),
|
||||
url('//at.alicdn.com/t/c/font_5042354_lmz58v86a1h.woff?t=1761549950025') format('woff'),
|
||||
url('//at.alicdn.com/t/c/font_5042354_lmz58v86a1h.ttf?t=1761549950025') format('truetype');
|
||||
src: url('//at.alicdn.com/t/c/font_5042354_wqti51yo9xk.woff2?t=1762227792781') format('woff2'),
|
||||
url('//at.alicdn.com/t/c/font_5042354_wqti51yo9xk.woff?t=1762227792781') format('woff'),
|
||||
url('//at.alicdn.com/t/c/font_5042354_wqti51yo9xk.ttf?t=1762227792781') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
@ -13,6 +13,10 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-address-book:before {
|
||||
content: "\e623";
|
||||
}
|
||||
|
||||
.icon-pen-to-square:before {
|
||||
content: "\e630";
|
||||
}
|
||||
|
||||
@ -70,67 +70,67 @@ const sectionList = {
|
||||
const sectionConfig = {
|
||||
supplierInfo: {
|
||||
title: "销售方信息",
|
||||
containerClass: "border-l-4 border-l-blue-500",
|
||||
containerClass: "border-l-8 border-l-blue-500",
|
||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||
},
|
||||
dealerInfo: {
|
||||
title: "下游经销商信息",
|
||||
containerClass: "border-l-4 border-l-green-500",
|
||||
containerClass: "border-l-8 border-l-green-500",
|
||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||
},
|
||||
basicInfo: {
|
||||
title: "基础信息",
|
||||
containerClass: "border-l-4 border-l-yellow-500",
|
||||
containerClass: "border-l-8 border-l-yellow-500",
|
||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||
},
|
||||
farmerInfo: {
|
||||
title: "瓜农信息",
|
||||
containerClass: "border-l-4 border-l-purple-500",
|
||||
containerClass: "border-l-8 border-l-purple-500",
|
||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||
},
|
||||
purchaseCostInfo: {
|
||||
title: "采购成本",
|
||||
containerClass: "border-l-4 border-l-red-500",
|
||||
containerClass: "border-l-8 border-l-red-500",
|
||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||
},
|
||||
packageInfo: {
|
||||
title: "包装纸箱费",
|
||||
containerClass: "border-l-4 border-l-indigo-500",
|
||||
containerClass: "border-l-8 border-l-indigo-500",
|
||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||
},
|
||||
emptyBoxInfo: {
|
||||
title: "空箱费用",
|
||||
containerClass: "border-l-4 border-l-pink-500",
|
||||
containerClass: "border-l-8 border-l-pink-500",
|
||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||
},
|
||||
laborInfo: {
|
||||
title: "用工信息",
|
||||
containerClass: "border-l-4 border-l-teal-500",
|
||||
containerClass: "border-l-8 border-l-teal-500",
|
||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||
},
|
||||
packagingCost: {
|
||||
title: "包装费",
|
||||
containerClass: "border-l-4 border-l-orange-500",
|
||||
containerClass: "border-l-8 border-l-orange-500",
|
||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||
},
|
||||
costSummary: {
|
||||
title: "成本合计",
|
||||
containerClass: "border-l-4 border-l-cyan-500",
|
||||
containerClass: "border-l-8 border-l-cyan-500",
|
||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||
},
|
||||
marketPrice: {
|
||||
title: "市场报价",
|
||||
containerClass: "border-l-4 border-l-lime-500",
|
||||
containerClass: "border-l-8 border-l-lime-500",
|
||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||
},
|
||||
rebateCalc: {
|
||||
title: "返点计算",
|
||||
containerClass: "border-l-4 border-l-amber-500",
|
||||
containerClass: "border-l-8 border-l-amber-500",
|
||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||
},
|
||||
profitCalc: {
|
||||
title: "利润计算",
|
||||
containerClass: "border-l-4 border-l-emerald-500",
|
||||
containerClass: "border-l-8 border-l-emerald-500",
|
||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||
},
|
||||
};
|
||||
|
||||
@ -22,6 +22,7 @@ import { business } from "@/services";
|
||||
import { generateShortId } from "@/utils/generateShortId";
|
||||
import Taro from "@tarojs/taro";
|
||||
import buildUrl from "@/utils/buildUrl";
|
||||
import { OrderPackageRef } from "@/components/purchase/OrderPackage";
|
||||
|
||||
const defaultSupplierList: SupplierVO[] = [
|
||||
{
|
||||
@ -62,8 +63,10 @@ export default hocAuth(function Page(props: CommonComponent) {
|
||||
const melonFarmerRefs = useRef<MelonFarmerRef[]>([]);
|
||||
// 创建Weigh组件的ref数组
|
||||
const weighRefs = useRef<WeighRef[]>([]);
|
||||
// 创建Artificial组件的ref
|
||||
const artificialRef = useRef<OrderCostRef>(null);
|
||||
// 创建OrderCost组件的ref
|
||||
const orderCostRef = useRef<OrderCostRef>(null);
|
||||
// 创建OrderPackage组件的ref
|
||||
const orderPackageRefs = useRef<OrderPackageRef[]>([]);
|
||||
|
||||
const [purchaseOrder, setPurchaseOrder] =
|
||||
useState<BusinessAPI.PurchaseOrderCreateCmd>();
|
||||
@ -355,6 +358,7 @@ export default hocAuth(function Page(props: CommonComponent) {
|
||||
|
||||
return (
|
||||
<MelonFarmer
|
||||
supplierCount={orderSupplierList.length}
|
||||
key={item.orderSupplierId}
|
||||
ref={(ref) => {
|
||||
if (ref) {
|
||||
@ -442,9 +446,21 @@ export default hocAuth(function Page(props: CommonComponent) {
|
||||
|
||||
// 包装信息
|
||||
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 };
|
||||
@ -472,7 +488,7 @@ export default hocAuth(function Page(props: CommonComponent) {
|
||||
{/* 人工和辅料信息 */}
|
||||
{step.value === 6 && (
|
||||
<OrderCost
|
||||
ref={artificialRef}
|
||||
ref={orderCostRef}
|
||||
value={orderCostList}
|
||||
onChange={(costItemList: CostItem[]) =>
|
||||
setOrderCostList(costItemList)
|
||||
@ -553,6 +569,18 @@ export default hocAuth(function Page(props: CommonComponent) {
|
||||
) {
|
||||
setActive(active + 1);
|
||||
}
|
||||
} // 在第四步(包装信息)时进行校验
|
||||
else if (active === 4) {
|
||||
// 获取当前选中的供应商
|
||||
const selectedIndex = orderSupplierList.findIndex(
|
||||
(supplier) => supplier.selected,
|
||||
);
|
||||
if (
|
||||
selectedIndex !== -1 &&
|
||||
orderPackageRefs.current[selectedIndex]?.validate()
|
||||
) {
|
||||
setActive(active + 1);
|
||||
}
|
||||
} else {
|
||||
setActive(active + 1);
|
||||
}
|
||||
@ -572,7 +600,7 @@ export default hocAuth(function Page(props: CommonComponent) {
|
||||
className="btn-large bg-primary ml-2 flex-1 text-white"
|
||||
onClick={async () => {
|
||||
// 第六步(人工辅料)时进行校验
|
||||
if (artificialRef.current?.validate()) {
|
||||
if (orderCostRef.current?.validate()) {
|
||||
await onFinish(true);
|
||||
}
|
||||
}}
|
||||
|
||||
@ -2165,6 +2165,7 @@ declare namespace BusinessAPI {
|
||||
boxBrandId: string;
|
||||
/** 箱子品牌名称 */
|
||||
boxBrandName: string;
|
||||
boxBrandImage: string;
|
||||
/** 箱子分类ID */
|
||||
boxCategoryId: string;
|
||||
/** 箱子产品ID */
|
||||
@ -2180,7 +2181,7 @@ declare namespace BusinessAPI {
|
||||
/** 销售单价(元/个) */
|
||||
boxSalePrice?: number;
|
||||
/** 箱子类型:1_本次使用;2_额外运输;3_已使用额外运输;4_车上剩余; */
|
||||
boxType: "USED" | "EXTRA" | "EXTRA_USED" | "REMAIN";
|
||||
boxType: "USED" | "EXTRA" | "EXTRA_USED" | "REMAIN" | "OWN" | "DEFAULT";
|
||||
};
|
||||
|
||||
type OrderRebate = {
|
||||
|
||||
@ -32,14 +32,18 @@ export interface BoxBrand {
|
||||
id: string;
|
||||
boxBrandId: string;
|
||||
boxBrandName: string;
|
||||
boxBrandImage: string | undefined;
|
||||
boxBrandImage: string;
|
||||
boxType: "USED" | "EXTRA" | "EXTRA_USED" | "REMAIN" | "OWN" | "DEFAULT";
|
||||
boxCategoryList: BoxCategory[];
|
||||
}
|
||||
|
||||
export interface BoxProduct {
|
||||
id: string;
|
||||
boxBrandId: string;
|
||||
boxBrandName: string;
|
||||
boxProductId: string;
|
||||
boxProductName: string;
|
||||
boxCount: number;
|
||||
boxProductWeight: number;
|
||||
boxCategoryId: "FOUR_GRAIN" | "TWO_GRAIN";
|
||||
boxCostPrice: number;
|
||||
|
||||
112
packages/app-client/src/utils/orderPackage.ts
Normal file
112
packages/app-client/src/utils/orderPackage.ts
Normal file
@ -0,0 +1,112 @@
|
||||
// 将BoxBrand转换为OrderPackage数组
|
||||
import { BoxBrand, BoxCategory, BoxProduct } from "@/types/typings";
|
||||
import { generateShortId } from "@/utils/generateShortId";
|
||||
|
||||
// 添加一个辅助函数用于分组
|
||||
const groupBy = <T,>(
|
||||
array: T[],
|
||||
keyFn: (item: T) => string,
|
||||
): Record<string, T[]> => {
|
||||
return array.reduce(
|
||||
(groups, item) => {
|
||||
const key = keyFn(item);
|
||||
if (!groups[key]) {
|
||||
groups[key] = [];
|
||||
}
|
||||
groups[key].push(item);
|
||||
return groups;
|
||||
},
|
||||
{} as Record<string, T[]>,
|
||||
);
|
||||
};
|
||||
|
||||
export const convertBoxBrandToOrderPackages = (
|
||||
boxBrand: BoxBrand,
|
||||
boxType: BusinessAPI.OrderPackage["boxType"] = "USED"
|
||||
): BusinessAPI.OrderPackage[] => {
|
||||
const orderPackages: BusinessAPI.OrderPackage[] = [];
|
||||
|
||||
boxBrand.boxCategoryList?.forEach((category) => {
|
||||
category.boxProductList.forEach((product) => {
|
||||
orderPackages.push({
|
||||
orderPackageId: product.id,
|
||||
boxBrandId: product.boxBrandId,
|
||||
boxBrandName: product.boxBrandName,
|
||||
boxBrandImage: boxBrand.boxBrandImage,
|
||||
boxCategoryId: product.boxCategoryId,
|
||||
boxProductId: product.boxProductId,
|
||||
boxProductName: product.boxProductName,
|
||||
boxProductWeight: product.boxProductWeight,
|
||||
boxCount: product.boxCount || 0,
|
||||
boxCostPrice: product.boxCostPrice,
|
||||
boxSalePrice: product.boxSalePrice,
|
||||
boxType: boxType,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return orderPackages;
|
||||
};
|
||||
|
||||
// 将OrderPackage数组转换为BoxBrand数组
|
||||
export const convertOrderPackagesToBoxBrands = (
|
||||
orderPackages: BusinessAPI.OrderPackage[]
|
||||
): BoxBrand[] => {
|
||||
// 按品牌ID分组
|
||||
const packagesByBrand = groupBy(
|
||||
orderPackages,
|
||||
(pkg) => pkg.boxBrandId
|
||||
);
|
||||
|
||||
// 转换为BoxBrand数组
|
||||
return Object.entries(packagesByBrand).map(([brandId, packages]) => {
|
||||
const firstPackage = packages[0];
|
||||
|
||||
// 按分类ID分组
|
||||
const packagesByCategory = groupBy(
|
||||
packages,
|
||||
(pkg) => pkg.boxCategoryId
|
||||
);
|
||||
|
||||
// 创建BoxCategory数组
|
||||
const boxCategories: BoxCategory[] = Object.entries(packagesByCategory).map(
|
||||
([categoryId, categoryPackages]) => {
|
||||
const firstCategoryPackage = categoryPackages[0];
|
||||
|
||||
// 创建BoxProduct数组
|
||||
const boxProducts: BoxProduct[] = categoryPackages.map((pkg) => ({
|
||||
id: pkg.orderPackageId || generateShortId(),
|
||||
boxBrandId: pkg.boxBrandId,
|
||||
boxBrandName: pkg.boxBrandName,
|
||||
boxProductId: pkg.boxProductId,
|
||||
boxProductName: pkg.boxProductName,
|
||||
boxProductWeight: pkg.boxProductWeight,
|
||||
boxCategoryId: pkg.boxCategoryId,
|
||||
boxCostPrice: pkg.boxCostPrice,
|
||||
boxSalePrice: pkg.boxSalePrice,
|
||||
boxCount: pkg.boxCount,
|
||||
} as BoxProduct));
|
||||
|
||||
return {
|
||||
id: generateShortId(),
|
||||
boxCategoryId: categoryId as "FOUR_GRAIN" | "TWO_GRAIN",
|
||||
boxCategoryName: firstCategoryPackage.boxCategoryId === "FOUR_GRAIN"
|
||||
? "4粒装"
|
||||
: firstCategoryPackage.boxCategoryId === "TWO_GRAIN"
|
||||
? "2粒装"
|
||||
: "未知",
|
||||
boxProductList: boxProducts,
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
id: brandId,
|
||||
boxBrandId: brandId,
|
||||
boxType: firstPackage.boxType,
|
||||
boxBrandName: firstPackage.boxBrandName,
|
||||
boxBrandImage: firstPackage.boxBrandImage,
|
||||
boxCategoryList: boxCategories,
|
||||
};
|
||||
});
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user