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";
|
import React from "react";
|
||||||
|
|
||||||
export type IconNames =
|
export type IconNames =
|
||||||
|
| "address-book"
|
||||||
| "pen-to-square"
|
| "pen-to-square"
|
||||||
| "location-dot"
|
| "location-dot"
|
||||||
| "clock"
|
| "clock"
|
||||||
|
|||||||
@ -25,11 +25,12 @@ interface IMelonFarmerProps {
|
|||||||
onRemove: (supplierVO: SupplierVO) => void;
|
onRemove: (supplierVO: SupplierVO) => void;
|
||||||
onAdd: () => void;
|
onAdd: () => void;
|
||||||
isLast: boolean; // 添加一个属性来标识是否是最后一个瓜农
|
isLast: boolean; // 添加一个属性来标识是否是最后一个瓜农
|
||||||
|
supplierCount: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
||||||
function MelonFarmer(props, ref) {
|
function MelonFarmer(props, ref) {
|
||||||
const { value, onChange, onRemove, onAdd, isLast } = props;
|
const { value, onChange, onRemove, onAdd, isLast, supplierCount } = props;
|
||||||
|
|
||||||
const [supplierVO, setSupplierVO] = useState<SupplierVO>();
|
const [supplierVO, setSupplierVO] = useState<SupplierVO>();
|
||||||
console.log("supplierVO", supplierVO);
|
console.log("supplierVO", supplierVO);
|
||||||
@ -94,7 +95,7 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
|||||||
);
|
);
|
||||||
const [isLastFarmerError, setIsLastFarmerError] = useState<{
|
const [isLastFarmerError, setIsLastFarmerError] = useState<{
|
||||||
[key: string]: boolean;
|
[key: string]: boolean;
|
||||||
}>({}); // 添加是否为最后一个瓜农的错误状态
|
}>({}); // 添加是否要拼车的错误状态
|
||||||
|
|
||||||
// 校验姓名函数
|
// 校验姓名函数
|
||||||
const validateName = (name: string) => {
|
const validateName = (name: string) => {
|
||||||
@ -136,9 +137,10 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
|||||||
return phoneRegex.test(phone);
|
return phoneRegex.test(phone);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 校验是否为最后一个瓜农函数
|
// 校验是否要拼车函数
|
||||||
|
// 校验是否要拼车函数
|
||||||
const validateIsLastFarmer = (isLast?: boolean) => {
|
const validateIsLastFarmer = (isLast?: boolean) => {
|
||||||
// 必须选择是或否
|
// 必须选择要不要
|
||||||
return isLast !== undefined;
|
return isLast !== undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -151,7 +153,7 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
|||||||
const isIdCardValid = validateIdCard(supplierVO.idCard || "");
|
const isIdCardValid = validateIdCard(supplierVO.idCard || "");
|
||||||
const isBankCardValid = validateBankCard(supplierVO.bankCard || "");
|
const isBankCardValid = validateBankCard(supplierVO.bankCard || "");
|
||||||
const isPhoneValid = validatePhone(supplierVO.phone || "");
|
const isPhoneValid = validatePhone(supplierVO.phone || "");
|
||||||
const isLastFarmerValid = validateIsLastFarmer(supplierVO?.isLast); // 校验是否为最后一个瓜农
|
const isLastFarmerValid = validateIsLastFarmer(supplierVO?.isLast); // 校验是否需要拼车
|
||||||
|
|
||||||
// 更新错误状态
|
// 更新错误状态
|
||||||
setNameError((prev) => ({
|
setNameError((prev) => ({
|
||||||
@ -384,7 +386,13 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
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">
|
<View className="flex items-center rounded-lg border border-blue-200 bg-blue-50 p-2.5">
|
||||||
<Icon
|
<Icon
|
||||||
@ -398,6 +406,61 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
|||||||
</View>
|
</View>
|
||||||
</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 gap-2">
|
||||||
<View className={"flex-1"}>
|
<View className={"flex-1"}>
|
||||||
@ -477,15 +540,22 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
|||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View className="mb-2.5">
|
<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 className={"block text-sm font-normal text-[#000000]"}>
|
||||||
姓名
|
姓名
|
||||||
</View>
|
</View>
|
||||||
<SupplierPicker
|
<SupplierPicker
|
||||||
trigger={
|
trigger={
|
||||||
<Text className={"text-primary ml-1 text-sm font-bold"}>
|
<View className="flex items-center">
|
||||||
点我选瓜农
|
<Icon
|
||||||
</Text>
|
name="address-book"
|
||||||
|
size={16}
|
||||||
|
color="var(--color-primary)"
|
||||||
|
/>
|
||||||
|
<Text className={"text-primary ml-1 text-sm font-bold"}>
|
||||||
|
点我选瓜农
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
}
|
}
|
||||||
onFinish={(supplierVO1) => {
|
onFinish={(supplierVO1) => {
|
||||||
setSupplierVO({
|
setSupplierVO({
|
||||||
@ -516,6 +586,7 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
|||||||
<View
|
<View
|
||||||
className={`flex h-10 w-full items-center rounded-md ${nameError[supplierVO.orderSupplierId] ? "border-4 border-red-500" : "border-4 border-gray-300"}`}
|
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
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="请输入姓名"
|
placeholder="请输入姓名"
|
||||||
@ -527,6 +598,7 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
|||||||
supplierVO.orderSupplierId,
|
supplierVO.orderSupplierId,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
className="flex-1"
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
{nameError[supplierVO.orderSupplierId] && (
|
{nameError[supplierVO.orderSupplierId] && (
|
||||||
@ -540,6 +612,7 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
|||||||
<View
|
<View
|
||||||
className={`flex h-10 w-full items-center rounded-md ${idCardError[supplierVO.orderSupplierId] ? "border-4 border-red-500" : "border-4 border-gray-300"}`}
|
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
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="请输入身份证号"
|
placeholder="请输入身份证号"
|
||||||
@ -551,6 +624,7 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
|||||||
supplierVO.orderSupplierId,
|
supplierVO.orderSupplierId,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
className="flex-1"
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
{idCardError[supplierVO.orderSupplierId] && (
|
{idCardError[supplierVO.orderSupplierId] && (
|
||||||
@ -566,6 +640,12 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
|||||||
<View
|
<View
|
||||||
className={`flex h-10 w-full items-center rounded-md ${bankCardError[supplierVO.orderSupplierId] ? "border-4 border-red-500" : "border-4 border-gray-300"}`}
|
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
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="请输入银行卡号"
|
placeholder="请输入银行卡号"
|
||||||
@ -577,6 +657,7 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
|||||||
supplierVO.orderSupplierId,
|
supplierVO.orderSupplierId,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
className="flex-1"
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
{bankCardError[supplierVO.orderSupplierId] && (
|
{bankCardError[supplierVO.orderSupplierId] && (
|
||||||
@ -592,6 +673,7 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
|||||||
<View
|
<View
|
||||||
className={`flex h-10 w-full items-center rounded-md ${phoneError[supplierVO.orderSupplierId] ? "border-4 border-red-500" : "border-4 border-gray-300"}`}
|
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
|
<Input
|
||||||
type="tel"
|
type="tel"
|
||||||
placeholder="请输入手机号码"
|
placeholder="请输入手机号码"
|
||||||
@ -603,6 +685,7 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
|||||||
supplierVO.orderSupplierId,
|
supplierVO.orderSupplierId,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
className="flex-1"
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
{phoneError[supplierVO.orderSupplierId] && (
|
{phoneError[supplierVO.orderSupplierId] && (
|
||||||
@ -639,56 +722,6 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
|
|||||||
</View>
|
</View>
|
||||||
</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 && (
|
{isLast && !isLastFarmer && isLastFarmer !== null && (
|
||||||
<Button
|
<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);
|
console.log("value", value);
|
||||||
|
|
||||||
return (
|
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>
|
<ScrollView className={"rounded-xl bg-white shadow-sm"} scrollX>
|
||||||
<View className="flex flex-row">
|
<View className="flex flex-row">
|
||||||
{value.map((supplierVO: SupplierVO) => (
|
{value.map((supplierVO: SupplierVO) => (
|
||||||
|
|||||||
@ -264,61 +264,57 @@ export default forwardRef<WeighRef, IWeightProps>(function Weigh(props, ref) {
|
|||||||
|
|
||||||
return (
|
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">
|
||||||
|
<View className="border-primary rounded-lg border-4 bg-white p-2.5 shadow-sm">
|
||||||
|
<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"
|
||||||
|
value={
|
||||||
|
supplierVO.isPaper === true
|
||||||
|
? "true"
|
||||||
|
: supplierVO.isPaper === false
|
||||||
|
? "false"
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
onChange={(value) => {
|
||||||
|
// 清除错误状态
|
||||||
|
setIsPaperError((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[supplierVO.orderSupplierId]: false,
|
||||||
|
}));
|
||||||
|
|
||||||
|
// 根据用户选择设置是否包含空纸箱
|
||||||
|
const isPaperValue =
|
||||||
|
value === "true"
|
||||||
|
? true
|
||||||
|
: value === "false"
|
||||||
|
? false
|
||||||
|
: undefined;
|
||||||
|
setSupplierVO({
|
||||||
|
...supplierVO,
|
||||||
|
isPaper: isPaperValue,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<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="border-primary rounded-lg border-4 bg-white p-2.5 shadow-sm">
|
||||||
<View className="text-primary mb-2.5 text-base font-bold">
|
<View className="text-primary mb-2.5 text-base font-bold">
|
||||||
{supplierVO.name}的称重信息
|
{supplierVO.name}的称重信息
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View className="mb-2.5">
|
<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="text-neutral-darkest text-sm font-medium">
|
|
||||||
<Radio.Group
|
|
||||||
direction="horizontal"
|
|
||||||
value={
|
|
||||||
supplierVO.isPaper === true
|
|
||||||
? "true"
|
|
||||||
: supplierVO.isPaper === false
|
|
||||||
? "false"
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
onChange={(value) => {
|
|
||||||
// 清除错误状态
|
|
||||||
setIsPaperError((prev) => ({
|
|
||||||
...prev,
|
|
||||||
[supplierVO.orderSupplierId]: false,
|
|
||||||
}));
|
|
||||||
|
|
||||||
// 根据用户选择设置是否包含空纸箱
|
|
||||||
const isPaperValue =
|
|
||||||
value === "true"
|
|
||||||
? true
|
|
||||||
: value === "false"
|
|
||||||
? false
|
|
||||||
: undefined;
|
|
||||||
setSupplierVO({
|
|
||||||
...supplierVO,
|
|
||||||
isPaper: isPaperValue,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<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="mb-2.5 flex gap-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="flex-1 rounded-lg bg-blue-50 p-2.5">
|
||||||
<View className="mb-2.5 flex items-center">
|
<View className="mb-2.5 flex items-center">
|
||||||
|
|||||||
@ -37,7 +37,7 @@ export default function SupplierPicker(props: ISupplierPickerProps) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View className={"flex-1"}>
|
<View>
|
||||||
<View
|
<View
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: "iconfont"; /* Project id 5042354 */
|
font-family: "iconfont"; /* Project id 5042354 */
|
||||||
src: url('//at.alicdn.com/t/c/font_5042354_lmz58v86a1h.woff2?t=1761549950025') format('woff2'),
|
src: url('//at.alicdn.com/t/c/font_5042354_wqti51yo9xk.woff2?t=1762227792781') format('woff2'),
|
||||||
url('//at.alicdn.com/t/c/font_5042354_lmz58v86a1h.woff?t=1761549950025') format('woff'),
|
url('//at.alicdn.com/t/c/font_5042354_wqti51yo9xk.woff?t=1762227792781') format('woff'),
|
||||||
url('//at.alicdn.com/t/c/font_5042354_lmz58v86a1h.ttf?t=1761549950025') format('truetype');
|
url('//at.alicdn.com/t/c/font_5042354_wqti51yo9xk.ttf?t=1762227792781') format('truetype');
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconfont {
|
.iconfont {
|
||||||
@ -13,6 +13,10 @@
|
|||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-address-book:before {
|
||||||
|
content: "\e623";
|
||||||
|
}
|
||||||
|
|
||||||
.icon-pen-to-square:before {
|
.icon-pen-to-square:before {
|
||||||
content: "\e630";
|
content: "\e630";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -70,67 +70,67 @@ const sectionList = {
|
|||||||
const sectionConfig = {
|
const sectionConfig = {
|
||||||
supplierInfo: {
|
supplierInfo: {
|
||||||
title: "销售方信息",
|
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",
|
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||||
},
|
},
|
||||||
dealerInfo: {
|
dealerInfo: {
|
||||||
title: "下游经销商信息",
|
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",
|
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||||
},
|
},
|
||||||
basicInfo: {
|
basicInfo: {
|
||||||
title: "基础信息",
|
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",
|
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||||
},
|
},
|
||||||
farmerInfo: {
|
farmerInfo: {
|
||||||
title: "瓜农信息",
|
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",
|
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||||
},
|
},
|
||||||
purchaseCostInfo: {
|
purchaseCostInfo: {
|
||||||
title: "采购成本",
|
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",
|
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||||
},
|
},
|
||||||
packageInfo: {
|
packageInfo: {
|
||||||
title: "包装纸箱费",
|
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",
|
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||||
},
|
},
|
||||||
emptyBoxInfo: {
|
emptyBoxInfo: {
|
||||||
title: "空箱费用",
|
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",
|
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||||
},
|
},
|
||||||
laborInfo: {
|
laborInfo: {
|
||||||
title: "用工信息",
|
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",
|
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||||
},
|
},
|
||||||
packagingCost: {
|
packagingCost: {
|
||||||
title: "包装费",
|
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",
|
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||||
},
|
},
|
||||||
costSummary: {
|
costSummary: {
|
||||||
title: "成本合计",
|
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",
|
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||||
},
|
},
|
||||||
marketPrice: {
|
marketPrice: {
|
||||||
title: "市场报价",
|
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",
|
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||||
},
|
},
|
||||||
rebateCalc: {
|
rebateCalc: {
|
||||||
title: "返点计算",
|
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",
|
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
||||||
},
|
},
|
||||||
profitCalc: {
|
profitCalc: {
|
||||||
title: "利润计算",
|
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",
|
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 { generateShortId } from "@/utils/generateShortId";
|
||||||
import Taro from "@tarojs/taro";
|
import Taro from "@tarojs/taro";
|
||||||
import buildUrl from "@/utils/buildUrl";
|
import buildUrl from "@/utils/buildUrl";
|
||||||
|
import { OrderPackageRef } from "@/components/purchase/OrderPackage";
|
||||||
|
|
||||||
const defaultSupplierList: SupplierVO[] = [
|
const defaultSupplierList: SupplierVO[] = [
|
||||||
{
|
{
|
||||||
@ -62,8 +63,10 @@ export default hocAuth(function Page(props: CommonComponent) {
|
|||||||
const melonFarmerRefs = useRef<MelonFarmerRef[]>([]);
|
const melonFarmerRefs = useRef<MelonFarmerRef[]>([]);
|
||||||
// 创建Weigh组件的ref数组
|
// 创建Weigh组件的ref数组
|
||||||
const weighRefs = useRef<WeighRef[]>([]);
|
const weighRefs = useRef<WeighRef[]>([]);
|
||||||
// 创建Artificial组件的ref
|
// 创建OrderCost组件的ref
|
||||||
const artificialRef = useRef<OrderCostRef>(null);
|
const orderCostRef = useRef<OrderCostRef>(null);
|
||||||
|
// 创建OrderPackage组件的ref
|
||||||
|
const orderPackageRefs = useRef<OrderPackageRef[]>([]);
|
||||||
|
|
||||||
const [purchaseOrder, setPurchaseOrder] =
|
const [purchaseOrder, setPurchaseOrder] =
|
||||||
useState<BusinessAPI.PurchaseOrderCreateCmd>();
|
useState<BusinessAPI.PurchaseOrderCreateCmd>();
|
||||||
@ -355,6 +358,7 @@ export default hocAuth(function Page(props: CommonComponent) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<MelonFarmer
|
<MelonFarmer
|
||||||
|
supplierCount={orderSupplierList.length}
|
||||||
key={item.orderSupplierId}
|
key={item.orderSupplierId}
|
||||||
ref={(ref) => {
|
ref={(ref) => {
|
||||||
if (ref) {
|
if (ref) {
|
||||||
@ -442,9 +446,21 @@ export default hocAuth(function Page(props: CommonComponent) {
|
|||||||
|
|
||||||
// 包装信息
|
// 包装信息
|
||||||
if (step.value === 4) {
|
if (step.value === 4) {
|
||||||
|
// 确保ref数组足够长
|
||||||
|
while (orderPackageRefs.current.length <= index) {
|
||||||
|
orderPackageRefs.current.push({
|
||||||
|
validate: () => true, // 默认验证方法
|
||||||
|
} as OrderPackageRef);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<OrderPackage
|
<OrderPackage
|
||||||
key={item.orderSupplierId}
|
key={item.orderSupplierId}
|
||||||
|
ref={(ref) => {
|
||||||
|
if (ref) {
|
||||||
|
orderPackageRefs.current[index] = ref;
|
||||||
|
}
|
||||||
|
}}
|
||||||
value={item}
|
value={item}
|
||||||
onChange={(supplierVO: SupplierVO) => {
|
onChange={(supplierVO: SupplierVO) => {
|
||||||
orderSupplierList[index] = { ...item, ...supplierVO };
|
orderSupplierList[index] = { ...item, ...supplierVO };
|
||||||
@ -472,7 +488,7 @@ export default hocAuth(function Page(props: CommonComponent) {
|
|||||||
{/* 人工和辅料信息 */}
|
{/* 人工和辅料信息 */}
|
||||||
{step.value === 6 && (
|
{step.value === 6 && (
|
||||||
<OrderCost
|
<OrderCost
|
||||||
ref={artificialRef}
|
ref={orderCostRef}
|
||||||
value={orderCostList}
|
value={orderCostList}
|
||||||
onChange={(costItemList: CostItem[]) =>
|
onChange={(costItemList: CostItem[]) =>
|
||||||
setOrderCostList(costItemList)
|
setOrderCostList(costItemList)
|
||||||
@ -553,6 +569,18 @@ export default hocAuth(function Page(props: CommonComponent) {
|
|||||||
) {
|
) {
|
||||||
setActive(active + 1);
|
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 {
|
} else {
|
||||||
setActive(active + 1);
|
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"
|
className="btn-large bg-primary ml-2 flex-1 text-white"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
// 第六步(人工辅料)时进行校验
|
// 第六步(人工辅料)时进行校验
|
||||||
if (artificialRef.current?.validate()) {
|
if (orderCostRef.current?.validate()) {
|
||||||
await onFinish(true);
|
await onFinish(true);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|||||||
@ -2165,6 +2165,7 @@ declare namespace BusinessAPI {
|
|||||||
boxBrandId: string;
|
boxBrandId: string;
|
||||||
/** 箱子品牌名称 */
|
/** 箱子品牌名称 */
|
||||||
boxBrandName: string;
|
boxBrandName: string;
|
||||||
|
boxBrandImage: string;
|
||||||
/** 箱子分类ID */
|
/** 箱子分类ID */
|
||||||
boxCategoryId: string;
|
boxCategoryId: string;
|
||||||
/** 箱子产品ID */
|
/** 箱子产品ID */
|
||||||
@ -2180,7 +2181,7 @@ declare namespace BusinessAPI {
|
|||||||
/** 销售单价(元/个) */
|
/** 销售单价(元/个) */
|
||||||
boxSalePrice?: number;
|
boxSalePrice?: number;
|
||||||
/** 箱子类型:1_本次使用;2_额外运输;3_已使用额外运输;4_车上剩余; */
|
/** 箱子类型:1_本次使用;2_额外运输;3_已使用额外运输;4_车上剩余; */
|
||||||
boxType: "USED" | "EXTRA" | "EXTRA_USED" | "REMAIN";
|
boxType: "USED" | "EXTRA" | "EXTRA_USED" | "REMAIN" | "OWN" | "DEFAULT";
|
||||||
};
|
};
|
||||||
|
|
||||||
type OrderRebate = {
|
type OrderRebate = {
|
||||||
|
|||||||
@ -32,14 +32,18 @@ export interface BoxBrand {
|
|||||||
id: string;
|
id: string;
|
||||||
boxBrandId: string;
|
boxBrandId: string;
|
||||||
boxBrandName: string;
|
boxBrandName: string;
|
||||||
boxBrandImage: string | undefined;
|
boxBrandImage: string;
|
||||||
|
boxType: "USED" | "EXTRA" | "EXTRA_USED" | "REMAIN" | "OWN" | "DEFAULT";
|
||||||
boxCategoryList: BoxCategory[];
|
boxCategoryList: BoxCategory[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BoxProduct {
|
export interface BoxProduct {
|
||||||
id: string;
|
id: string;
|
||||||
|
boxBrandId: string;
|
||||||
|
boxBrandName: string;
|
||||||
boxProductId: string;
|
boxProductId: string;
|
||||||
boxProductName: string;
|
boxProductName: string;
|
||||||
|
boxCount: number;
|
||||||
boxProductWeight: number;
|
boxProductWeight: number;
|
||||||
boxCategoryId: "FOUR_GRAIN" | "TWO_GRAIN";
|
boxCategoryId: "FOUR_GRAIN" | "TWO_GRAIN";
|
||||||
boxCostPrice: number;
|
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