feat(purchase): 重构采购单相关组件和逻辑

- 删除 TransferOrderSubmitReview 组件,整合到 PurchaseOrderSubmitReview
- 重命名 PurchaseOption 为 MadeOption,TransferOption 为 MarketOption
- 重命名 PurchasePreview 为 MadePreview,TransferPreview 为 MarketPreview
- 更新档口信息组件 StallInfo 和 StallWeigh 的逻辑和字段
- 修改采购单类型判断逻辑,使用 purchase 常量配置替代硬编码
- 调整采购单创建和预览页面路径,支持不同类型采购单跳转
- 移除重复的 TransferOrderItem 组件,统一使用 PurchaseOrderItem
- 优化档口类型切换逻辑,清空相关供应商信息字段
- 调整称重信息校验规则,确保所有字段均通过验证
- 更新采购单列表页面,支持不同类型采购单统一展示和创建
This commit is contained in:
shenyifei 2025-12-22 15:57:22 +08:00
parent 91d9d4bf89
commit e546067226
43 changed files with 851 additions and 1276 deletions

View File

@ -14,36 +14,31 @@ config = {
root: "pages/public", root: "pages/public",
pages: ["login/index", "camera/index", "camera/ocr", "agreement/index"], pages: ["login/index", "camera/index", "camera/ocr", "agreement/index"],
}, },
// 采购单 // 采购单(市场/产地)
{ {
root: "pages/purchase", root: "pages/purchase",
pages: [ pages: [
// 全部采购 // 全部产地采购
"all", "made/all",
// 创建采购单 // 创建产地采购单
"create", "made/create",
// 预览采购单 // 预览产地采购单
"preview", "made/preview",
// 采购单草稿箱 // 产地采购单草稿箱
"drafts", "made/drafts",
// 采购单提审结果页面 // 产地采购单提审结果页面
"result", "made/result",
],
}, // 全部市场采购单
// 调货单 "market/all",
{ // 创建市场采购单
root: "pages/transfer", "market/create",
pages: [ // 预览市场采购单
// 全部调货 "market/preview",
"all", // 市场采购单草稿箱
// 创建调货单 "market/drafts",
"create", // 市场采购单提审结果页面
// 预览调货单 "market/result",
"preview",
// 调货单草稿箱
"drafts",
// 调货单提审结果页面
"result",
], ],
}, },
// 审核 // 审核

View File

@ -6,6 +6,7 @@ import purchaseOrder from "@/constant/purchaseOrder";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { Button, Dialog, Toast } from "@nutui/nutui-react-taro"; import { Button, Dialog, Toast } from "@nutui/nutui-react-taro";
import { business } from "@/services"; import { business } from "@/services";
import { purchase } from "@/constant";
interface IPurchaseOrderItemProps { interface IPurchaseOrderItemProps {
purchaseOrderVO: BusinessAPI.PurchaseOrderVO; purchaseOrderVO: BusinessAPI.PurchaseOrderVO;
@ -67,9 +68,9 @@ export default function PurchaseOrderItem(props: IPurchaseOrderItemProps) {
<View <View
className={"flex flex-col divide-y-2 divide-neutral-100"} className={"flex flex-col divide-y-2 divide-neutral-100"}
onClick={(event) => { onClick={(event) => {
if (purchaseOrderVO.active === 7) { if (purchase.isPreview(purchaseOrderVO)) {
Taro.navigateTo({ Taro.navigateTo({
url: buildUrl("/pages/purchase/preview", { url: buildUrl(purchase.path[purchaseOrderVO.type].preview, {
orderId: purchaseOrderVO.orderId, orderId: purchaseOrderVO.orderId,
}), }),
}); });
@ -138,7 +139,9 @@ export default function PurchaseOrderItem(props: IPurchaseOrderItemProps) {
<View <View
className={"flex flex-row items-center justify-between gap-2.5"} className={"flex flex-row items-center justify-between gap-2.5"}
> >
<Label className={"text-neutral-dark text-sm"}></Label> <Label className={"text-neutral-dark text-sm"}>
{purchase.supplierSlug[purchaseOrderVO.type]}
</Label>
<Text className={"text-neutral-darkest text-sm"}> <Text className={"text-neutral-darkest text-sm"}>
{purchaseOrderVO.orderSupplierList {purchaseOrderVO.orderSupplierList
.map((item) => item.name) .map((item) => item.name)
@ -182,7 +185,7 @@ export default function PurchaseOrderItem(props: IPurchaseOrderItemProps) {
size={"small"} size={"small"}
onClick={(e) => { onClick={(e) => {
Taro.navigateTo({ Taro.navigateTo({
url: buildUrl("/pages/purchase/create", { url: buildUrl(purchase.path[purchaseOrderVO.type].create, {
orderId: purchaseOrderVO.orderId, orderId: purchaseOrderVO.orderId,
}), }),
}); });
@ -191,15 +194,18 @@ export default function PurchaseOrderItem(props: IPurchaseOrderItemProps) {
> >
</Button> </Button>
{purchaseOrderVO.active === 7 && ( {purchase.isPreview(purchaseOrderVO) && (
<Button <Button
type={"primary"} type={"primary"}
size={"small"} size={"small"}
onClick={(e) => { onClick={(e) => {
Taro.navigateTo({ Taro.navigateTo({
url: buildUrl("/pages/purchase/preview", { url: buildUrl(
orderId: purchaseOrderVO.orderId, purchase.path[purchaseOrderVO.type].preview,
}), {
orderId: purchaseOrderVO.orderId,
},
),
}); });
e.stopPropagation(); e.stopPropagation();
}} }}
@ -227,7 +233,7 @@ export default function PurchaseOrderItem(props: IPurchaseOrderItemProps) {
size={"small"} size={"small"}
onClick={(e) => { onClick={(e) => {
Taro.navigateTo({ Taro.navigateTo({
url: buildUrl("/pages/purchase/create", { url: buildUrl(purchase.path[purchaseOrderVO.type].create, {
orderId: purchaseOrderVO.orderId, orderId: purchaseOrderVO.orderId,
}), }),
}); });

View File

@ -6,13 +6,13 @@ import {
PurchaseOrderItem, PurchaseOrderItem,
SupplierPicker, SupplierPicker,
ToolBar, ToolBar,
TransferOrderItem,
} from "@/components"; } from "@/components";
import React, { useRef, useState } from "react"; import React, { useRef, useState } from "react";
import { business } from "@/services"; import { business } from "@/services";
import { View } from "@tarojs/components"; import { View } from "@tarojs/components";
import { buildUrl } from "@/utils"; import { buildUrl } from "@/utils";
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import { purchase } from "@/constant";
interface IPurchaseOrderListProps { interface IPurchaseOrderListProps {
params: BusinessAPI.PurchaseOrderPageQry; params: BusinessAPI.PurchaseOrderPageQry;
@ -117,34 +117,18 @@ export default function PurchaseOrderList(props: IPurchaseOrderListProps) {
actions: [ actions: [
create && ( create && (
<View className={"flex flex-row gap-2 p-3"} key={"create"}> <View className={"flex flex-row gap-2 p-3"} key={"create"}>
{type === "PRODUCTION_PURCHASE" && ( <View className={"flex-1"}>
<View className={"flex-1"}> <View
<View className="bg-primary flex w-full flex-col items-center justify-center space-y-2 rounded-xl py-2.5 text-white"
className="bg-primary flex w-full flex-col items-center justify-center space-y-2 rounded-xl py-2.5 text-white" onClick={() => {
onClick={() => { Taro.navigateTo({
Taro.navigateTo({ url: buildUrl(purchase.path[type].create),
url: buildUrl("/pages/purchase/create"), });
}); }}
}} >
> <View className="text-base font-bold"></View>
<View className="text-base font-bold"></View>
</View>
</View> </View>
)} </View>
{type === "MARKET_PURCHASE" && (
<View className={"flex-1"}>
<View
className="bg-primary flex w-full flex-col items-center justify-center space-y-2 rounded-xl py-2.5 text-white"
onClick={() => {
Taro.navigateTo({
url: buildUrl("/pages/transfer/create"),
});
}}
>
<View className="text-base font-bold"></View>
</View>
</View>
)}
</View> </View>
), ),
], ],
@ -159,18 +143,10 @@ export default function PurchaseOrderList(props: IPurchaseOrderListProps) {
render={(purchaseOrderVO: BusinessAPI.PurchaseOrderVO, index) => { render={(purchaseOrderVO: BusinessAPI.PurchaseOrderVO, index) => {
return ( return (
<View className={"mb-2.5"} key={index}> <View className={"mb-2.5"} key={index}>
{type === "PRODUCTION_PURCHASE" && ( <PurchaseOrderItem
<PurchaseOrderItem purchaseOrderVO={purchaseOrderVO}
purchaseOrderVO={purchaseOrderVO} actionRef={actionRef}
actionRef={actionRef} />
/>
)}
{type === "MARKET_PURCHASE" && (
<TransferOrderItem
purchaseOrderVO={purchaseOrderVO}
actionRef={actionRef}
/>
)}
</View> </View>
); );
}} }}

View File

@ -1,245 +0,0 @@
import { Label, Text, View } from "@tarojs/components";
import Taro from "@tarojs/taro";
import { buildUrl } from "@/utils";
import { CopyText, PurchaseOrderWithdrawReview, State } from "@/components";
import purchaseOrder from "@/constant/purchaseOrder";
import dayjs from "dayjs";
import { Button, Dialog, Toast } from "@nutui/nutui-react-taro";
import { business } from "@/services";
interface IPurchaseOrderItemProps {
purchaseOrderVO: BusinessAPI.PurchaseOrderVO;
actionRef: any;
}
export default function PurchaseOrderItem(props: IPurchaseOrderItemProps) {
const { purchaseOrderVO, actionRef } = props;
// 删除采购订单
const handleDelete = (purchaseOrderVO: BusinessAPI.PurchaseOrderVO) => {
Dialog.open("dialog", {
title: "删除调货单",
content: `确定要删除这个调货单吗?删除后就找不回来了!`,
confirmText: "确定",
cancelText: "取消",
onConfirm: async () => {
try {
const { data } = await business.purchaseOrder.destroyPurchaseOrder({
orderId: purchaseOrderVO.orderId,
});
if (data.success) {
Toast.show("toast", {
icon: "success",
title: "提示",
content: "调货单删除成功",
});
actionRef.current?.reload();
} else {
Toast.show("toast", {
icon: "fail",
title: "提示",
content: data.errMessage || "删除失败",
});
}
} catch (error) {
Toast.show("toast", {
icon: "fail",
title: "提示",
content: "删除失败",
});
} finally {
Dialog.close("dialog");
}
},
onCancel: () => {
Dialog.close("dialog");
},
});
};
return (
<View
className={
"relative flex flex-col divide-y-2 divide-neutral-100 rounded-lg bg-white px-2.5"
}
>
<View
className={"flex flex-col divide-y-2 divide-neutral-100"}
onClick={(event) => {
if (purchaseOrderVO.active === 5) {
Taro.navigateTo({
url: buildUrl("/pages/transfer/preview", {
orderId: purchaseOrderVO.orderId,
}),
});
event.stopPropagation();
}
}}
>
<View className={"py-2.5"}>
<View className={"flex flex-row items-center"}>
<View className={"flex flex-1 flex-col gap-2"}>
<View className={"flex flex-row gap-1"}>
<Text className={"text-neutral-darkest text-xl font-bold"}>
{purchaseOrderVO.orderVehicle?.origin} {" 至 "}
{purchaseOrderVO.orderVehicle?.destination}
</Text>
</View>
<Text className={"text-neutral-dark text-sm"}>
<CopyText copyData={purchaseOrderVO.orderSn}>
{purchaseOrderVO.orderSn}
</CopyText>
</Text>
</View>
<State
state={purchaseOrderVO.state}
stateMap={purchaseOrder.stateMap}
/>
</View>
</View>
<View className={"py-2.5"}>
<View className={"flex flex-col gap-2"}>
<View
className={"flex flex-row items-center justify-between gap-2.5"}
>
<Label className={"text-neutral-dark text-sm"}></Label>
<Text className={"text-neutral-darkest text-sm"}>
{dayjs(purchaseOrderVO.createdAt).format("MM-DD HH:mm")}
</Text>
</View>
<View
className={"flex flex-row items-center justify-between gap-2.5"}
>
<Label className={"text-neutral-dark text-sm"}></Label>
<Text className={"text-neutral-darkest text-sm"}>
{dayjs(purchaseOrderVO.orderVehicle?.deliveryTime).format(
"YYYY年MM月DD日",
)}
</Text>
</View>
<View
className={"flex flex-row items-center justify-between gap-2.5"}
>
<Label className={"text-neutral-dark text-sm"}></Label>
<Text className={"text-neutral-darkest text-sm"}>
{purchaseOrderVO.orderVehicle?.dealerName}
</Text>
</View>
<View
className={"flex flex-row items-center justify-between gap-2.5"}
>
<Label className={"text-neutral-dark text-sm"}></Label>
<Text className={"text-neutral-darkest text-sm"}>
{purchaseOrderVO.orderVehicle?.driver}
{purchaseOrderVO.orderVehicle?.plate}
</Text>
</View>
<View
className={"flex flex-row items-center justify-between gap-2.5"}
>
<Label className={"text-neutral-dark text-sm"}></Label>
<Text className={"text-neutral-darkest text-sm"}>
{purchaseOrderVO.orderSupplierList
.map((item) => item.name)
.join(",")}
</Text>
</View>
</View>
</View>
</View>
<View className={"py-2.5"}>
<View className={"flex flex-row justify-end gap-2"}>
{purchaseOrderVO.state === "DRAFT" && (
<>
<Button
type={"danger"}
size={"small"}
onClick={(e) => {
handleDelete(purchaseOrderVO);
e.stopPropagation();
}}
>
</Button>
{/* 联系司机 */}
{purchaseOrderVO.orderVehicle?.phone && (
<Button
type={"default"}
size={"small"}
onClick={(e) => {
Taro.makePhoneCall({
phoneNumber: purchaseOrderVO.orderVehicle.phone as string,
});
e.stopPropagation();
}}
>
</Button>
)}
<Button
type={"default"}
size={"small"}
onClick={(e) => {
Taro.navigateTo({
url: buildUrl("/pages/transfer/create", {
orderId: purchaseOrderVO.orderId,
}),
});
e.stopPropagation();
}}
>
</Button>
{purchaseOrderVO.active === 7 && (
<Button
type={"primary"}
size={"small"}
onClick={(e) => {
Taro.navigateTo({
url: buildUrl("/pages/transfer/preview", {
orderId: purchaseOrderVO.orderId,
}),
});
e.stopPropagation();
}}
>
</Button>
)}
</>
)}
{purchaseOrderVO.state === "WAITING_AUDIT" && (
<>
<PurchaseOrderWithdrawReview
purchaseOrderVO={purchaseOrderVO}
size={"small"}
onFinish={() => {
actionRef.current?.reload();
}}
/>
</>
)}
{purchaseOrderVO.state === "REJECTED" && (
<>
<Button
type={"default"}
size={"small"}
onClick={(e) => {
Taro.navigateTo({
url: buildUrl("/pages/transfer/create", {
orderId: purchaseOrderVO.orderId,
}),
});
e.stopPropagation();
}}
>
</Button>
</>
)}
</View>
</View>
</View>
);
}

View File

@ -2,6 +2,7 @@ import { Button, ButtonSize, Dialog, Toast } from "@nutui/nutui-react-taro";
import { business } from "@/services"; import { business } from "@/services";
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import { buildUrl } from "@/utils"; import { buildUrl } from "@/utils";
import { purchase } from "@/constant";
interface IPurchaseOrderSubmitReviewProps { interface IPurchaseOrderSubmitReviewProps {
purchaseOrderVO: BusinessAPI.PurchaseOrderVO; purchaseOrderVO: BusinessAPI.PurchaseOrderVO;
@ -83,12 +84,12 @@ export default function PurchaseOrderSubmitReview(
]; ];
Dialog.open("dialog", { Dialog.open("dialog", {
title: "提交审核提醒", title: "提交审核提醒",
content: `这车货目前还在拼车状态。一旦确认车辆已满载,就需要在瓜农信息那里,把“${lastSupplier.name}”的这车货标记为“不需要拼车”。`, content: `这车货目前还在拼车状态。一旦确认车辆已满载,就需要在${purchase.supplierSlug[purchaseOrderVO.type]}信息那里,把“${lastSupplier.name}”的这车货标记为“不需要拼车”。`,
confirmText: "不需要拼车", confirmText: "不需要拼车",
cancelText: "去继续拼车", cancelText: "去继续拼车",
onConfirm: async () => { onConfirm: async () => {
Taro.redirectTo({ Taro.redirectTo({
url: buildUrl("/pages/purchase/create", { url: buildUrl(purchase.path[purchaseOrderVO.type].create, {
orderId: purchaseOrderVO.orderId, orderId: purchaseOrderVO.orderId,
orderSupplierId: lastSupplier.orderSupplierId, orderSupplierId: lastSupplier.orderSupplierId,
step: "2", step: "2",
@ -98,7 +99,7 @@ export default function PurchaseOrderSubmitReview(
}, },
onCancel: () => { onCancel: () => {
Taro.redirectTo({ Taro.redirectTo({
url: buildUrl("/pages/purchase/create", { url: buildUrl(purchase.path[purchaseOrderVO.type].create, {
orderId: purchaseOrderVO.orderId, orderId: purchaseOrderVO.orderId,
step: "6", step: "6",
}), }),
@ -110,36 +111,37 @@ export default function PurchaseOrderSubmitReview(
return; return;
} }
// 检查是否存在合同未上传的瓜农 // 产地采购单需要判断瓜农是否上传合同
const hasNoUpdateContractSupplier = if (purchaseOrderVO.type === "PRODUCTION_PURCHASE") {
purchaseOrderVO.orderSupplierList?.find( // 检查是否存在合同未上传的瓜农
(supplier) => !supplier.contractUpload, const hasNoUpdateContractSupplier =
); purchaseOrderVO.orderSupplierList?.find(
(supplier) => !supplier.contractUpload,
);
console.log("hasNoUpdateContractSupplier", hasNoUpdateContractSupplier); if (hasNoUpdateContractSupplier) {
Dialog.open("dialog", {
if (hasNoUpdateContractSupplier) { title: "提交审核提醒",
Dialog.open("dialog", { content: `检测到瓜农“${hasNoUpdateContractSupplier.name}”未上传合同。请返回票证上传步骤上传合同?`,
title: "提交审核提醒", confirmText: "去票证上传",
content: `检测到瓜农“${hasNoUpdateContractSupplier.name}”未上传合同。请返回票证上传步骤上传合同?`, cancelText: "取消",
confirmText: "去票证上传", onConfirm: async () => {
cancelText: "取消", Taro.redirectTo({
onConfirm: async () => { url: buildUrl(purchase.path[purchaseOrderVO.type].create, {
Taro.redirectTo({ orderId: purchaseOrderVO.orderId,
url: buildUrl("/pages/purchase/create", { supplierId: hasNoUpdateContractSupplier.supplierId,
orderId: purchaseOrderVO.orderId, step: "5",
supplierId: hasNoUpdateContractSupplier.supplierId, }),
step: "5", });
}), Dialog.close("dialog");
}); },
Dialog.close("dialog"); onCancel: () => {
}, Dialog.close("dialog");
onCancel: () => { },
Dialog.close("dialog"); });
}, e.stopPropagation();
}); return;
e.stopPropagation(); }
return;
} }
Dialog.open("dialog", { Dialog.open("dialog", {

View File

@ -1,132 +0,0 @@
import { Button, ButtonSize, Dialog, Toast } from "@nutui/nutui-react-taro";
import { business } from "@/services";
import Taro from "@tarojs/taro";
import { buildUrl } from "@/utils";
interface ITransferOrderSubmitReviewProps {
purchaseOrderVO: BusinessAPI.PurchaseOrderVO;
size?: ButtonSize;
onFinish?: () => void;
}
export default function TransferOrderSubmitReview(
props: ITransferOrderSubmitReviewProps,
) {
const { purchaseOrderVO, size = "normal", onFinish } = props;
const onSubmit = async () => {
if (!purchaseOrderVO || !purchaseOrderVO.orderId) {
Toast.show("toast", {
icon: "warn",
title: "提示",
content: "提交失败",
});
return;
}
let success = false;
let errMessage = "";
try {
// 更新成功后再提交审核
const { data } = await business.purchaseOrder.submitReviewPurchaseOrder({
orderId: purchaseOrderVO.orderId,
});
if (data.success) {
success = data.success;
} else {
errMessage = data?.errMessage || "";
}
if (success) {
Toast.show("toast", {
icon: "success",
title: "提示",
content: "提交成功",
});
// 可以在这里添加跳转逻辑,例如返回列表页
onFinish?.();
} else {
Toast.show("toast", {
icon: "warn",
title: "提示",
content: "提交失败",
});
console.error("提交调货订单失败:", errMessage);
}
} catch (error) {
Toast.show("toast", {
icon: "fail",
title: "提示",
content: "提交失败",
});
console.error("提交调货订单失败:", error);
}
};
return (
<Button
block
type={"primary"}
size={size}
className="btn-large bg-primary ml-2 flex-1 text-white"
onClick={async (e) => {
// 检查是否已标记最后一个供应商
const hasLastSupplier = purchaseOrderVO.orderSupplierList?.some(
(supplier) => supplier.isLast,
);
if (!hasLastSupplier) {
const lastSupplier =
purchaseOrderVO.orderSupplierList[
purchaseOrderVO.orderSupplierList.length - 1
];
Dialog.open("dialog", {
title: "提交审核提醒",
content: `这车货目前还在拼车状态。一旦确认车辆已满载,就需要在档口信息那里,把“${lastSupplier.name}”的这车货标记为“不需要拼车”。`,
confirmText: "不需要拼车",
cancelText: "去继续拼车",
onConfirm: async () => {
Taro.redirectTo({
url: buildUrl("/pages/transfer/create", {
orderId: purchaseOrderVO.orderId,
orderSupplierId: lastSupplier.orderSupplierId,
step: "2",
}),
});
Dialog.close("dialog");
},
onCancel: () => {
Taro.redirectTo({
url: buildUrl("/pages/transfer/create", {
orderId: purchaseOrderVO.orderId,
step: "6",
}),
});
Dialog.close("dialog");
},
});
e.stopPropagation();
return;
}
Dialog.open("dialog", {
title: "提交审核提醒",
content: `提交后报价审核员将看到此审核采购单,请确保所有档口信息都录入进来了,确认提交调货订单?`,
confirmText: "确认",
cancelText: "取消",
onConfirm: async () => {
await onSubmit();
Dialog.close("dialog");
},
onCancel: () => {
Dialog.close("dialog");
},
});
e.stopPropagation();
}}
>
</Button>
);
}

View File

@ -20,18 +20,17 @@ export type { OrderCostItemRef } from "./module/OrderCostItem";
export { default as OrderPackage } from "./module/OrderPackage"; export { default as OrderPackage } from "./module/OrderPackage";
export { default as SupplierList } from "./module/SupplierList"; export { default as SupplierList } from "./module/SupplierList";
export { default as StallList } from "./module/StallList"; export { default as StallList } from "./module/StallList";
export { default as PurchasePreview } from "./module/PurchasePreview"; export { default as PurchasePreview } from "./module/MadePreview";
export { default as TransferPreview } from "./module/TransferPreview"; export { default as MarketPreview } from "./module/MarketPreview";
export { default as PurchaseOption } from "./module/PurchaseOption"; export { default as MadeOption } from "./module/MadeOption";
export type { PurchaseOptionRef } from "./module/PurchaseOption"; export type { MadeOptionRef } from "./module/MadeOption";
export { default as TransferOption } from "./module/TransferOption"; export { default as MarketOption } from "./module/MarketOption";
export type { TransferOptionRef } from "./module/TransferOption"; export type { MarketOptionRef } from "./module/MarketOption";
export { default as PurchaseOrderRejectApprove } from "./button/PurchaseOrderRejectApprove"; export { default as PurchaseOrderRejectApprove } from "./button/PurchaseOrderRejectApprove";
export { default as PurchaseOrderRejectFinal } from "./button/PurchaseOrderRejectFinal"; export { default as PurchaseOrderRejectFinal } from "./button/PurchaseOrderRejectFinal";
export { default as PurchaseOrderSubmitReview } from "./button/PurchaseOrderSubmitReview"; export { default as PurchaseOrderSubmitReview } from "./button/PurchaseOrderSubmitReview";
export { default as PurchaseOrderWithdrawReview } from "./button/PurchaseOrderWithdrawReview"; export { default as PurchaseOrderWithdrawReview } from "./button/PurchaseOrderWithdrawReview";
export { default as TransferOrderSubmitReview } from "./button/TransferOrderSubmitReview";
export { default as PurchaseOrderFinalApprove } from "./button/PurchaseOrderFinalApprove"; export { default as PurchaseOrderFinalApprove } from "./button/PurchaseOrderFinalApprove";
export { default as CompanyInfoSection } from "./section/CompanyInfoSection"; export { default as CompanyInfoSection } from "./section/CompanyInfoSection";
@ -60,7 +59,6 @@ export type { Step1FormRef as PurchaseStep1FormRef } from "./document/Step1Form"
export { default as PurchaseStep2Preview } from "./document/Step2Preview"; export { default as PurchaseStep2Preview } from "./document/Step2Preview";
export { default as PurchaseStep3Success } from "./document/Step3Success"; export { default as PurchaseStep3Success } from "./document/Step3Success";
export { default as TransferOrderItem } from "./TransferOrderItem";
export { default as PurchaseOrderItem } from "./PurchaseOrderItem"; export { default as PurchaseOrderItem } from "./PurchaseOrderItem";
export { default as PurchaseOrderList } from "./PurchaseOrderList"; export { default as PurchaseOrderList } from "./PurchaseOrderList";
export { default as PurchaseOrderAuditList } from "./PurchaseOrderAuditList"; export { default as PurchaseOrderAuditList } from "./PurchaseOrderAuditList";

View File

@ -0,0 +1,502 @@
import { View } from "@tarojs/components";
import { purchase } from "@/constant";
import { Button, Dialog, SafeArea, Toast } from "@nutui/nutui-react-taro";
import React, { forwardRef, useImperativeHandle } from "react";
import { globalStore } from "@/store/global-store";
import Taro from "@tarojs/taro";
import { buildUrl, generateShortId } from "@/utils";
import { business } from "@/services";
// 定义ref暴露的方法接口
export interface MadeOptionRef {
onAdd: () => void;
}
interface IMadeOptionProps {
value: BusinessAPI.PurchaseOrderVO;
onChange: (purchaseOrderVO: BusinessAPI.PurchaseOrderVO) => void;
vehicleRef: React.MutableRefObject<any>;
supplierInfoRefs: React.MutableRefObject<any[]>;
supplierWeighRefs: React.MutableRefObject<any[]>;
supplierPackageRefs: React.MutableRefObject<any[]>;
orderCostRef: React.MutableRefObject<any>;
orderCostItemRef: React.MutableRefObject<any>;
}
export default forwardRef<MadeOptionRef, IMadeOptionProps>(function MadeOption(
props: IMadeOptionProps,
ref,
) {
const {
value,
onChange,
vehicleRef,
supplierInfoRefs,
supplierWeighRefs,
supplierPackageRefs,
orderCostRef,
orderCostItemRef,
} = props;
const { setLoading } = globalStore((state: any) => state);
const { orderSupplierList } = value;
const active = Number(value.active);
const setActive = (active: number) => {
onChange({
...value,
active,
});
};
// 车辆信息和经销商信息的保存
const saveVehicleAndDealerInfo = async () => {
if (!value) {
Toast.show("toast", {
icon: "warn",
title: "提示",
content: "保存失败",
});
return false;
}
try {
let tempOrderId = value.orderId;
if (tempOrderId) {
const { data } = await business.purchaseOrder.savePurchaseOrderStep1({
orderId: tempOrderId,
active: active,
type: "PRODUCTION_PURCHASE",
orderVehicle: value.orderVehicle,
orderDealer: value.orderDealer,
});
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,
type: "PRODUCTION_PURCHASE",
orderVehicle: value.orderVehicle,
orderDealer: value.orderDealer,
});
if (data.success) {
onChange({
...value,
orderId: 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 (!value || !value.orderId) {
Toast.show("toast", {
icon: "warn",
title: "提示",
content: "保存失败",
});
return false;
}
try {
const { data } = await business.purchaseOrder.savePurchaseOrderStep2({
orderId: value.orderId,
active: active,
type: "PRODUCTION_PURCHASE",
orderSupplierList: value.orderSupplierList,
});
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 (!value || !value.orderId) {
Toast.show("toast", {
icon: "warn",
title: "提示",
content: "保存失败",
});
return false;
}
const { data } = await business.purchaseOrder.savePurchaseOrderStep3({
orderId: value.orderId,
active: Number(active + 1),
foreman: value.foreman,
type: "PRODUCTION_PURCHASE",
// 空箱
orderPackageList: value.orderPackageList,
// 费用
orderCostList: value.orderCostList.filter((item) => {
if (item.type === "PRODUCTION_TYPE") {
return item.selected;
}
if (item.type === "ARTIFICIAL_TYPE" || item.type === "MATERIAL_TYPE") {
return (
value.orderCostItemList.filter(
(orderCostItem) =>
item.costItemIds?.includes(orderCostItem.costItemId!) &&
orderCostItem.selected,
).length > 0
);
}
return false;
}),
orderCostItemList: value.orderCostItemList.filter(
(item) => item.selected,
),
});
if (data.success) {
return true;
} else {
Toast.show("toast", {
icon: "warn",
title: "提示",
content: data?.errMessage || "保存失败",
});
return false;
}
};
const onFinish = async () => {
// 只保存第六步的人工和辅料信息
const costSuccess = await saveCostInfo();
if (!costSuccess) {
Dialog.close("dialog");
return;
}
// 跳转到预览页面
Taro.redirectTo({
url: buildUrl("/pages/purchase/made/preview", {
orderId: value.orderId,
}),
});
};
const onAdd = () => {
saveSupplierInfo();
const orderSupplierList = value?.orderSupplierList;
// 获取当前选中的供应商
const selectedIndex = orderSupplierList?.findIndex(
(supplier) => supplier.selected,
);
if (active === 2 && !supplierInfoRefs.current[selectedIndex]?.validate()) {
return;
}
// 在第三步(称重信息)时进行校验
else if (
active === 3 &&
!supplierWeighRefs.current[selectedIndex]?.validate()
) {
return;
} // 在第四步(包装信息)时进行校验
else if (
active === 4 &&
!supplierPackageRefs.current[selectedIndex]?.validate()
) {
return;
}
onChange({
...value,
active: 2,
orderSupplierList: [
...orderSupplierList.map((supplierVO: BusinessAPI.OrderSupplier) => {
supplierVO.selected = false;
return supplierVO;
}),
{
orderSupplierId: generateShortId(),
supplierId: "",
name: "瓜农" + (orderSupplierList.length + 1),
idCard: "",
bankCard: "",
phone: "",
selected: true,
isPaper: orderSupplierList[selectedIndex].isPaper,
orderPackageList: [],
productId: orderSupplierList[selectedIndex]?.productId,
productName: orderSupplierList[selectedIndex]?.productName,
costTemplate: orderSupplierList[selectedIndex]?.costTemplate,
} as any,
],
});
};
// 将校验方法暴露给父组件
useImperativeHandle(ref, () => ({
onAdd,
}));
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 && active <= 7) {
success = await saveCostInfo();
}
Dialog.close("dialog");
if (success) {
Toast.show("toast", {
icon: "success",
title: "提示",
content: "当前采购订单已暂存成功",
});
Taro.redirectTo({
url: "/pages/purchase/made/drafts",
});
}
},
onCancel: () => {
Dialog.close("dialog");
},
});
}
if (!active) {
return;
}
return (
<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 <= purchase.madeSteps.length - 1 && (
<View className={"flex-1"}>
<Button
block
type={"default"}
size={"xlarge"}
className="flex-1 bg-gray-200 text-gray-700"
onClick={() => {
if (active > 1) {
if (active === 5) {
// 获取当前选中的供应商
const selectedIndex = orderSupplierList.findIndex(
(supplier) => supplier.selected,
);
if (
orderSupplierList[selectedIndex].loadingMode ===
"FRAME_WITH_NET"
) {
setActive(active - 2);
} else {
setActive(active - 1);
}
} else {
setActive(active - 1);
}
}
}}
>
</Button>
</View>
)}
{active >= 1 && active <= purchase.madeSteps.length - 1 && (
<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 < purchase.madeSteps.length - 1 && (
<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 &&
supplierInfoRefs.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 &&
supplierWeighRefs.current[selectedIndex]?.validate()
) {
const success = await saveSupplierInfo();
if (success) {
// 判断装箱方式
if (
orderSupplierList[selectedIndex].loadingMode ===
"FRAME_WITH_NET"
) {
setActive(active + 2);
} else {
setActive(active + 1);
}
}
}
} // 在第四步(包装信息)时进行校验
else if (active === 4) {
// 获取当前选中的供应商
const selectedIndex = orderSupplierList.findIndex(
(supplier) => supplier.selected,
);
if (
selectedIndex !== -1 &&
supplierPackageRefs.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 == purchase.madeSteps.length - 1 && (
<>
<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() &&
orderCostItemRef.current?.validate()
) {
await onFinish();
}
setLoading(false);
}}
>
</Button>
</View>
</>
)}
</View>
<SafeArea position={"bottom"} />
</View>
);
});

View File

@ -27,7 +27,7 @@ const groupBy = <T,>(
); );
}; };
export default function PurchasePreview(props: IPurchasePreviewProps) { export default function MadePreview(props: IPurchasePreviewProps) {
const { purchaseOrder } = props; const { purchaseOrder } = props;
const [orderSupplierList, setOrderSupplierList] = useState< const [orderSupplierList, setOrderSupplierList] = useState<
BusinessAPI.OrderSupplier[] BusinessAPI.OrderSupplier[]

View File

@ -5,32 +5,32 @@ import { globalStore } from "@/store/global-store";
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import { buildUrl, generateShortId } from "@/utils"; import { buildUrl, generateShortId } from "@/utils";
import { business } from "@/services"; import { business } from "@/services";
import transfer from "@/constant/transfer"; import purchase from "@/constant/purchase";
// 定义ref暴露的方法接口 // 定义ref暴露的方法接口
export interface TransferOptionRef { export interface MarketOptionRef {
onAdd: () => void; onAdd: () => void;
} }
interface ITransferOptionProps { interface IMarketOptionProps {
value: BusinessAPI.PurchaseOrderVO; value: BusinessAPI.PurchaseOrderVO;
onChange: (purchaseOrderVO: BusinessAPI.PurchaseOrderVO) => void; onChange: (purchaseOrderVO: BusinessAPI.PurchaseOrderVO) => void;
vehicleRef: React.MutableRefObject<any>; vehicleRef: React.MutableRefObject<any>;
melonStallRefs: React.MutableRefObject<any[]>; stallInfoRefs: React.MutableRefObject<any[]>;
staffWeighRefs: React.MutableRefObject<any[]>; stallWeighRefs: React.MutableRefObject<any[]>;
stallPackageRefs: React.MutableRefObject<any[]>; stallPackageRefs: React.MutableRefObject<any[]>;
} }
export default forwardRef<TransferOptionRef, ITransferOptionProps>( export default forwardRef<MarketOptionRef, IMarketOptionProps>(
function TransferOption(props: ITransferOptionProps, ref) { function MarketOption(props: IMarketOptionProps, ref) {
const { const {
value, value,
onChange, onChange,
vehicleRef, vehicleRef,
melonStallRefs, stallInfoRefs,
staffWeighRefs, stallWeighRefs,
stallPackageRefs, stallPackageRefs,
} = props; } = props;
@ -218,7 +218,7 @@ export default forwardRef<TransferOptionRef, ITransferOptionProps>(
// 跳转到预览页面 // 跳转到预览页面
Taro.redirectTo({ Taro.redirectTo({
url: buildUrl("/pages/transfer/preview", { url: buildUrl("/pages/purchase/market/preview", {
orderId: value.orderId, orderId: value.orderId,
}), }),
}); });
@ -231,13 +231,13 @@ export default forwardRef<TransferOptionRef, ITransferOptionProps>(
const selectedIndex = orderSupplierList?.findIndex( const selectedIndex = orderSupplierList?.findIndex(
(supplier) => supplier.selected, (supplier) => supplier.selected,
); );
if (active === 2 && !melonStallRefs.current[selectedIndex]?.validate()) { if (active === 2 && !stallInfoRefs.current[selectedIndex]?.validate()) {
return; return;
} }
// 在第三步(称重信息)时进行校验 // 在第三步(称重信息)时进行校验
else if ( else if (
active === 3 && active === 3 &&
!staffWeighRefs.current[selectedIndex]?.validate() !stallWeighRefs.current[selectedIndex]?.validate()
) { ) {
return; return;
} // 在第四步(包装信息)时进行校验 } // 在第四步(包装信息)时进行校验
@ -313,7 +313,7 @@ export default forwardRef<TransferOptionRef, ITransferOptionProps>(
content: "当前采购订单已暂存成功", content: "当前采购订单已暂存成功",
}); });
Taro.redirectTo({ Taro.redirectTo({
url: "/pages/purchase/drafts", url: "/pages/purchase/made/drafts",
}); });
} }
}, },
@ -330,7 +330,7 @@ export default forwardRef<TransferOptionRef, ITransferOptionProps>(
return ( return (
<View className={"sticky bottom-0 z-10 bg-white"}> <View className={"sticky bottom-0 z-10 bg-white"}>
<View className="flex justify-between gap-2 border-t border-gray-200 p-2.5"> <View className="flex justify-between gap-2 border-t border-gray-200 p-2.5">
{active > 1 && active <= transfer.steps.length - 1 && ( {active > 1 && active <= purchase.marketSteps.length - 1 && (
<View className={"flex-1"}> <View className={"flex-1"}>
<Button <Button
block block
@ -363,7 +363,7 @@ export default forwardRef<TransferOptionRef, ITransferOptionProps>(
</View> </View>
)} )}
{active >= 1 && active <= transfer.steps.length - 1 && ( {active >= 1 && active <= purchase.marketSteps.length - 1 && (
<View className={"flex-1"}> <View className={"flex-1"}>
<Button <Button
block block
@ -379,7 +379,7 @@ export default forwardRef<TransferOptionRef, ITransferOptionProps>(
</View> </View>
)} )}
{active < transfer.steps.length - 1 && ( {active < purchase.marketSteps.length - 1 && (
<View className={"flex-1"}> <View className={"flex-1"}>
<Button <Button
block block
@ -405,7 +405,7 @@ export default forwardRef<TransferOptionRef, ITransferOptionProps>(
); );
if ( if (
selectedIndex !== -1 && selectedIndex !== -1 &&
melonStallRefs.current[selectedIndex]?.validate() stallInfoRefs.current[selectedIndex]?.validate()
) { ) {
const success = await saveSupplierInfo(); const success = await saveSupplierInfo();
if (success) { if (success) {
@ -421,7 +421,7 @@ export default forwardRef<TransferOptionRef, ITransferOptionProps>(
); );
if ( if (
selectedIndex !== -1 && selectedIndex !== -1 &&
staffWeighRefs.current[selectedIndex]?.validate() stallWeighRefs.current[selectedIndex]?.validate()
) { ) {
const success = await saveSupplierInfo(); const success = await saveSupplierInfo();
if (success) { if (success) {
@ -467,7 +467,7 @@ export default forwardRef<TransferOptionRef, ITransferOptionProps>(
</Button> </Button>
</View> </View>
)} )}
{active == transfer.steps.length - 1 && ( {active == purchase.marketSteps.length - 1 && (
<> <>
<View className={"flex-1"}> <View className={"flex-1"}>
<Button <Button

View File

@ -5,7 +5,7 @@ import { formatCurrency, PurchaseOrderCalculator } from "@/utils";
import { Icon } from "@/components"; import { Icon } from "@/components";
import { Decimal } from "decimal.js"; import { Decimal } from "decimal.js";
interface ITransferPreviewProps { interface IMarketPreviewProps {
purchaseOrder: BusinessAPI.PurchaseOrderVO; purchaseOrder: BusinessAPI.PurchaseOrderVO;
} }
@ -27,7 +27,7 @@ const groupBy = <T,>(
); );
}; };
export default function TransferPreview(props: ITransferPreviewProps) { export default function MarketPreview(props: IMarketPreviewProps) {
const { purchaseOrder } = props; const { purchaseOrder } = props;
const [orderSupplierList, setOrderSupplierList] = useState< const [orderSupplierList, setOrderSupplierList] = useState<
BusinessAPI.OrderSupplier[] BusinessAPI.OrderSupplier[]

View File

@ -1,504 +0,0 @@
import { View } from "@tarojs/components";
import { purchase } from "@/constant";
import { Button, Dialog, SafeArea, Toast } from "@nutui/nutui-react-taro";
import React, { forwardRef, useImperativeHandle } from "react";
import { globalStore } from "@/store/global-store";
import Taro from "@tarojs/taro";
import { buildUrl, generateShortId } from "@/utils";
import { business } from "@/services";
// 定义ref暴露的方法接口
export interface PurchaseOptionRef {
onAdd: () => void;
}
interface IPurchaseOptionProps {
value: BusinessAPI.PurchaseOrderVO;
onChange: (purchaseOrderVO: BusinessAPI.PurchaseOrderVO) => void;
vehicleRef: React.MutableRefObject<any>;
melonFarmerRefs: React.MutableRefObject<any[]>;
supplierWeighRefs: React.MutableRefObject<any[]>;
supplierPackageRefs: React.MutableRefObject<any[]>;
orderCostRef: React.MutableRefObject<any>;
orderCostItemRef: React.MutableRefObject<any>;
}
export default forwardRef<PurchaseOptionRef, IPurchaseOptionProps>(
function PurchaseOption(props: IPurchaseOptionProps, ref) {
const {
value,
onChange,
vehicleRef,
melonFarmerRefs,
supplierWeighRefs,
supplierPackageRefs,
orderCostRef,
orderCostItemRef,
} = props;
const { setLoading } = globalStore((state: any) => state);
const { orderSupplierList } = value;
const active = Number(value.active);
const setActive = (active: number) => {
onChange({
...value,
active,
});
};
// 车辆信息和经销商信息的保存
const saveVehicleAndDealerInfo = async () => {
if (!value) {
Toast.show("toast", {
icon: "warn",
title: "提示",
content: "保存失败",
});
return false;
}
try {
let tempOrderId = value.orderId;
if (tempOrderId) {
const { data } = await business.purchaseOrder.savePurchaseOrderStep1({
orderId: tempOrderId,
active: active,
type: "PRODUCTION_PURCHASE",
orderVehicle: value.orderVehicle,
orderDealer: value.orderDealer,
});
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,
type: "PRODUCTION_PURCHASE",
orderVehicle: value.orderVehicle,
orderDealer: value.orderDealer,
});
if (data.success) {
onChange({
...value,
orderId: 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 (!value || !value.orderId) {
Toast.show("toast", {
icon: "warn",
title: "提示",
content: "保存失败",
});
return false;
}
try {
const { data } = await business.purchaseOrder.savePurchaseOrderStep2({
orderId: value.orderId,
active: active,
type: "PRODUCTION_PURCHASE",
orderSupplierList: value.orderSupplierList,
});
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 (!value || !value.orderId) {
Toast.show("toast", {
icon: "warn",
title: "提示",
content: "保存失败",
});
return false;
}
const { data } = await business.purchaseOrder.savePurchaseOrderStep3({
orderId: value.orderId,
active: Number(active + 1),
foreman: value.foreman,
type: "PRODUCTION_PURCHASE",
// 空箱
orderPackageList: value.orderPackageList,
// 费用
orderCostList: value.orderCostList.filter((item) => {
if (item.type === "PRODUCTION_TYPE") {
return item.selected;
}
if (
item.type === "ARTIFICIAL_TYPE" ||
item.type === "MATERIAL_TYPE"
) {
return (
value.orderCostItemList.filter(
(orderCostItem) =>
item.costItemIds?.includes(orderCostItem.costItemId!) &&
orderCostItem.selected,
).length > 0
);
}
return false;
}),
orderCostItemList: value.orderCostItemList.filter(
(item) => item.selected,
),
});
if (data.success) {
return true;
} else {
Toast.show("toast", {
icon: "warn",
title: "提示",
content: data?.errMessage || "保存失败",
});
return false;
}
};
const onFinish = async () => {
// 只保存第六步的人工和辅料信息
const costSuccess = await saveCostInfo();
if (!costSuccess) {
Dialog.close("dialog");
return;
}
// 跳转到预览页面
Taro.redirectTo({
url: buildUrl("/pages/purchase/preview", {
orderId: value.orderId,
}),
});
};
const onAdd = () => {
saveSupplierInfo();
const orderSupplierList = value?.orderSupplierList;
// 获取当前选中的供应商
const selectedIndex = orderSupplierList?.findIndex(
(supplier) => supplier.selected,
);
if (active === 2 && !melonFarmerRefs.current[selectedIndex]?.validate()) {
return;
}
// 在第三步(称重信息)时进行校验
else if (
active === 3 &&
!supplierWeighRefs.current[selectedIndex]?.validate()
) {
return;
} // 在第四步(包装信息)时进行校验
else if (
active === 4 &&
!supplierPackageRefs.current[selectedIndex]?.validate()
) {
return;
}
onChange({
...value,
active: 2,
orderSupplierList: [
...orderSupplierList.map((supplierVO: BusinessAPI.OrderSupplier) => {
supplierVO.selected = false;
return supplierVO;
}),
{
orderSupplierId: generateShortId(),
supplierId: "",
name: "瓜农" + (orderSupplierList.length + 1),
idCard: "",
bankCard: "",
phone: "",
selected: true,
isPaper: orderSupplierList[selectedIndex].isPaper,
orderPackageList: [],
productId: orderSupplierList[selectedIndex]?.productId,
productName: orderSupplierList[selectedIndex]?.productName,
costTemplate: orderSupplierList[selectedIndex]?.costTemplate,
} as any,
],
});
};
// 将校验方法暴露给父组件
useImperativeHandle(ref, () => ({
onAdd,
}));
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 && active <= 7) {
success = await saveCostInfo();
}
Dialog.close("dialog");
if (success) {
Toast.show("toast", {
icon: "success",
title: "提示",
content: "当前采购订单已暂存成功",
});
Taro.redirectTo({
url: "/pages/purchase/drafts",
});
}
},
onCancel: () => {
Dialog.close("dialog");
},
});
}
if (!active) {
return;
}
return (
<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 <= purchase.steps.length - 1 && (
<View className={"flex-1"}>
<Button
block
type={"default"}
size={"xlarge"}
className="flex-1 bg-gray-200 text-gray-700"
onClick={() => {
if (active > 1) {
if (active === 5) {
// 获取当前选中的供应商
const selectedIndex = orderSupplierList.findIndex(
(supplier) => supplier.selected,
);
if (
orderSupplierList[selectedIndex].loadingMode ===
"FRAME_WITH_NET"
) {
setActive(active - 2);
} else {
setActive(active - 1);
}
} else {
setActive(active - 1);
}
}
}}
>
</Button>
</View>
)}
{active >= 1 && active <= purchase.steps.length - 1 && (
<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 < purchase.steps.length - 1 && (
<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 &&
supplierWeighRefs.current[selectedIndex]?.validate()
) {
const success = await saveSupplierInfo();
if (success) {
// 判断装箱方式
if (
orderSupplierList[selectedIndex].loadingMode ===
"FRAME_WITH_NET"
) {
setActive(active + 2);
} else {
setActive(active + 1);
}
}
}
} // 在第四步(包装信息)时进行校验
else if (active === 4) {
// 获取当前选中的供应商
const selectedIndex = orderSupplierList.findIndex(
(supplier) => supplier.selected,
);
if (
selectedIndex !== -1 &&
supplierPackageRefs.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 == purchase.steps.length - 1 && (
<>
<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() &&
orderCostItemRef.current?.validate()
) {
await onFinish();
}
setLoading(false);
}}
>
</Button>
</View>
</>
)}
</View>
<SafeArea position={"bottom"} />
</View>
);
},
);

View File

@ -32,24 +32,13 @@ export default forwardRef<StallInfoRef, IStallInfoProps>(
bankCard: "", bankCard: "",
type: "", type: "",
selected: true, selected: true,
isPaper: false,
orderPackageList: [], orderPackageList: [],
packageUsage: [ packageUsage: [
{ {
boxType: "USED", boxType: "USED",
isUsed: 0, isUsed: 0,
}, },
{
boxType: "EXTRA_USED",
isUsed: 0,
},
{
boxType: "EXTRA",
isUsed: 0,
},
{
boxType: "REMAIN",
isUsed: 0,
},
], ],
} as any, } as any,
]); ]);
@ -526,13 +515,16 @@ export default forwardRef<StallInfoRef, IStallInfoProps>(
}`} }`}
onClick={() => { onClick={() => {
// 自家档口需要选择供应商 // 自家档口需要选择供应商
if (supplierVO.type === "OTHER_STALL") { setSupplierVO({
setSupplierVO({ ...supplierVO,
...supplierVO, supplierId: "",
type: "STALL", name: "",
}); payeeName: "",
setShowSupplierPicker(true); bankCard: "",
} wechatQr: undefined,
type: "STALL",
});
setShowSupplierPicker(true);
}} }}
> >
<Radio <Radio
@ -541,13 +533,16 @@ export default forwardRef<StallInfoRef, IStallInfoProps>(
checked={supplierVO.type === "STALL"} checked={supplierVO.type === "STALL"}
onChange={() => { onChange={() => {
// 自家档口需要选择供应商 // 自家档口需要选择供应商
if (supplierVO.type === "OTHER_STALL") { setSupplierVO({
setSupplierVO({ ...supplierVO,
...supplierVO, supplierId: "",
type: "STALL", name: "",
}); payeeName: "",
setShowSupplierPicker(true); bankCard: "",
} wechatQr: undefined,
type: "STALL",
});
setShowSupplierPicker(true);
}} }}
/> />
<View className="flex-1"> <View className="flex-1">
@ -567,7 +562,23 @@ export default forwardRef<StallInfoRef, IStallInfoProps>(
}`} }`}
onClick={() => { onClick={() => {
// 其他家档口需要清空供应商ID // 其他家档口需要清空供应商ID
if (supplierVO.type === "STALL") { setSupplierVO({
...supplierVO,
supplierId: "",
name: "",
payeeName: "",
bankCard: "",
wechatQr: undefined,
type: "OTHER_STALL",
});
}}
>
<Radio
value="EXTERNAL"
className="mr-2.5"
checked={supplierVO.type === "OTHER_STALL"}
onChange={() => {
// 其他家档口需要清空供应商ID
setSupplierVO({ setSupplierVO({
...supplierVO, ...supplierVO,
supplierId: "", supplierId: "",
@ -577,26 +588,6 @@ export default forwardRef<StallInfoRef, IStallInfoProps>(
wechatQr: undefined, wechatQr: undefined,
type: "OTHER_STALL", type: "OTHER_STALL",
}); });
}
}}
>
<Radio
value="EXTERNAL"
className="mr-2.5"
checked={supplierVO.type === "OTHER_STALL"}
onChange={() => {
// 其他家档口需要清空供应商ID
if (supplierVO.type === "STALL") {
setSupplierVO({
...supplierVO,
supplierId: "",
name: "",
payeeName: "",
bankCard: "",
wechatQr: undefined,
type: "OTHER_STALL",
});
}
}} }}
/> />
<View className="flex-1"> <View className="flex-1">
@ -661,7 +652,7 @@ export default forwardRef<StallInfoRef, IStallInfoProps>(
</View> </View>
{/* 根据档口类型显示不同的表单内容 */} {/* 根据档口类型显示不同的表单内容 */}
{supplierVO.type === "STALL" ? ( {supplierVO.type === "STALL" && (
// 自家档口:显示档口选择器 // 自家档口:显示档口选择器
<> <>
<View className="flex flex-row justify-between"> <View className="flex flex-row justify-between">
@ -749,7 +740,8 @@ export default forwardRef<StallInfoRef, IStallInfoProps>(
</View> </View>
)} )}
</> </>
) : ( )}
{supplierVO.type === "OTHER_STALL" && (
// 其他家档口:显示完整的表单 // 其他家档口:显示完整的表单
<> <>
<View className={"block text-sm font-normal text-[#000000]"}> <View className={"block text-sm font-normal text-[#000000]"}>

View File

@ -31,8 +31,6 @@ export default forwardRef<StallWeighRef, IStallWeighProps>(
const { orderSupplierList } = value; const { orderSupplierList } = value;
const { setLoading } = globalStore((state: any) => state); const { setLoading } = globalStore((state: any) => state);
const isFirst = index === 0;
const setOrderSupplierList = ( const setOrderSupplierList = (
orderSupplierList: BusinessAPI.OrderSupplier[], orderSupplierList: BusinessAPI.OrderSupplier[],
) => { ) => {
@ -42,18 +40,6 @@ export default forwardRef<StallWeighRef, IStallWeighProps>(
}); });
}; };
const changeProduct = (productVO: BusinessAPI.ProductVO) => {
setOrderSupplierList([
...orderSupplierList.map((item: BusinessAPI.OrderSupplier) => {
item.productId = productVO.productId;
item.productName = productVO.name;
item.costIds = productVO.costIds;
item.costTemplate = productVO.costTemplate;
return item;
}),
]);
};
const setSupplierVO = (orderSupplierVO: BusinessAPI.OrderSupplier) => { const setSupplierVO = (orderSupplierVO: BusinessAPI.OrderSupplier) => {
setOrderSupplierList([ setOrderSupplierList([
...orderSupplierList.map((item: BusinessAPI.OrderSupplier) => { ...orderSupplierList.map((item: BusinessAPI.OrderSupplier) => {
@ -147,6 +133,10 @@ export default forwardRef<StallWeighRef, IStallWeighProps>(
return false; return false;
} }
setGrossWeightError((prev) => ({
...prev,
[supplierVO.orderSupplierId]: false,
}));
return true; return true;
}; };
@ -199,7 +189,7 @@ export default forwardRef<StallWeighRef, IStallWeighProps>(
})); }));
const isValid = const isValid =
(isPurchasePriceValid && isProductIdValid) || isGrossWeightValid; isPurchasePriceValid && isProductIdValid && isGrossWeightValid;
if (!isValid) { if (!isValid) {
Toast.show("toast", { Toast.show("toast", {
@ -314,14 +304,6 @@ export default forwardRef<StallWeighRef, IStallWeighProps>(
? customProduct ? customProduct
: productObj.name, : productObj.name,
}); });
changeProduct({
...productObj,
name:
selectedProduct === "其他(请注明)"
? customProduct
: productObj.name,
});
} }
setProductPopupVisible(false); setProductPopupVisible(false);
@ -338,72 +320,62 @@ export default forwardRef<StallWeighRef, IStallWeighProps>(
</View> </View>
</Popup> </Popup>
{isFirst && ( {productList.length > 0 && (
<> <View className="border-primary rounded-lg border-4 bg-white p-2.5 shadow-sm">
{productList.length > 0 && ( <View className={"flex flex-col gap-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={"flex flex-col gap-2.5"}> <View className="text-sm">西</View>
<View className={"flex items-center justify-between gap-2.5"}> <View className="text-neutral-darkest text-sm font-medium">
<View className="text-sm">西</View> <Radio.Group
<View className="text-neutral-darkest text-sm font-medium"> direction="horizontal"
<Radio.Group value={supplierVO.productId}
direction="horizontal" onChange={(value) => {
value={supplierVO.productId} // 清除错误状态
onChange={(value) => { setProductIdError((prev) => ({
// 清除错误状态 ...prev,
setProductIdError((prev) => ({ [supplierVO.orderSupplierId]: false,
...prev, }));
[supplierVO.orderSupplierId]: false,
}));
if (value === "other") { if (value === "other") {
// 点击"其他"时打开弹窗 // 点击"其他"时打开弹窗
setProductPopupVisible(true); setProductPopupVisible(true);
} else { } else {
// 根据用户选择设置西瓜品种 // 根据用户选择设置西瓜品种
const productId = value as string; const productId = value as string;
const productVO = productList.find( const productVO = productList.find(
(p) => p.productId === productId, (p) => p.productId === productId,
); );
console.log("productVO", productVO); if (productVO) {
setSupplierVO({
if (productVO) { ...supplierVO,
setSupplierVO({ productId: productVO?.productId,
...supplierVO, productName: productVO?.name,
productId: productVO?.productId, loadingMode:
productName: productVO?.name, productVO?.name !== "硒砂瓜"
loadingMode: ? "BOX_WITH_TAPE"
productVO?.name !== "硒砂瓜" : undefined,
? "BOX_WITH_TAPE" });
: undefined, }
}); }
}}
changeProduct(productVO); >
} <Radio
} value={supplierVO.productId || productList?.[0].productId}
}} >
> {supplierVO.productName || productList?.[0].name}
<Radio </Radio>
value={ <Radio value="other"></Radio>
supplierVO.productId || productList?.[0].productId </Radio.Group>
}
>
{supplierVO.productName || productList?.[0].name}
</Radio>
<Radio value="other"></Radio>
</Radio.Group>
</View>
</View>
{isProductIdError[supplierVO.orderSupplierId] && (
<View className="mt-1 text-xs text-red-500">
西
</View>
)}
</View> </View>
</View> </View>
)} {isProductIdError[supplierVO.orderSupplierId] && (
</> <View className="mt-1 text-xs text-red-500">
西
</View>
)}
</View>
</View>
)} )}
{/*/!* 瓜农包纸箱吗,包纸箱按照毛重报价,不包按照净重报价 *!/*/} {/*/!* 瓜农包纸箱吗,包纸箱按照毛重报价,不包按照净重报价 *!/*/}

View File

@ -1,2 +1,2 @@
// App 相关常量 // App 相关常量
export const APP_VERSION = "v0.0.43"; export const APP_VERSION = "v0.0.50";

View File

@ -1,4 +1,4 @@
const steps = [ const madeSteps = [
{ {
value: 1, value: 1,
title: "步骤 1/{}: 车辆信息", title: "步骤 1/{}: 车辆信息",
@ -29,4 +29,55 @@ const steps = [
}, },
]; ];
export default { steps }; const marketSteps = [
{
value: 1,
title: "步骤 1/{}: 车辆信息",
},
{
value: 2,
title: "步骤 2/{}: 档口信息",
},
{
value: 3,
title: "步骤 3/{}: 重量信息",
},
{
value: 4,
title: "步骤 4/{}: 包装信息",
},
{
value: 5,
title: "信息确认",
},
];
const path = {
PRODUCTION_PURCHASE: {
create: "/pages/purchase/made/create",
preview: "/pages/purchase/made/preview",
},
MARKET_PURCHASE: {
create: "/pages/purchase/market/create",
preview: "/pages/purchase/market/preview",
},
};
const supplierSlug = {
PRODUCTION_PURCHASE: "瓜农",
MARKET_PURCHASE: "档口",
};
const isPreview = (purchaseVO: BusinessAPI.PurchaseOrderVO) => {
if (purchaseVO.type === "PRODUCTION_PURCHASE") {
return purchaseVO.active === madeSteps.length;
}
if (purchaseVO.type === "MARKET_PURCHASE") {
return purchaseVO.active === marketSteps.length;
}
return false;
};
export default { madeSteps, marketSteps, path, supplierSlug, isPreview };

View File

@ -1,24 +0,0 @@
const steps = [
{
value: 1,
title: "步骤 1/{}: 车辆信息",
},
{
value: 2,
title: "步骤 2/{}: 档口信息",
},
{
value: 3,
title: "步骤 3/{}: 重量信息",
},
{
value: 4,
title: "步骤 4/{}: 包装信息",
},
{
value: 5,
title: "信息确认",
},
];
export default { steps };

View File

@ -118,7 +118,7 @@ const quickActionMap = {
icon: "folder", icon: "folder",
iconColor: "var(--color-blue-600)", iconColor: "var(--color-blue-600)",
bgColorClass: "bg-blue-100", bgColorClass: "bg-blue-100",
path: "/pages/purchase/drafts", path: "/pages/purchase/made/drafts",
}, },
{ {
id: "history", id: "history",
@ -126,7 +126,7 @@ const quickActionMap = {
icon: "clipboard-list", icon: "clipboard-list",
iconColor: "var(--color-green-600)", iconColor: "var(--color-green-600)",
bgColorClass: "bg-green-100", bgColorClass: "bg-green-100",
path: "/pages/purchase/all", path: "/pages/purchase/made/all",
}, },
{ {
id: "invoiceUpload", id: "invoiceUpload",
@ -148,19 +148,19 @@ const quickActionMap = {
"market-buyer": [ "market-buyer": [
{ {
id: "myDraft", id: "myDraft",
title: "待提交的调货单", title: "待提交的采购单",
icon: "folder", icon: "folder",
iconColor: "var(--color-blue-600)", iconColor: "var(--color-blue-600)",
bgColorClass: "bg-blue-100", bgColorClass: "bg-blue-100",
path: "/pages/transfer/drafts", path: "/pages/purchase/market/drafts",
}, },
{ {
id: "history", id: "history",
title: "我的调货单", title: "我的采购单",
icon: "clipboard-list", icon: "clipboard-list",
iconColor: "var(--color-green-600)", iconColor: "var(--color-green-600)",
bgColorClass: "bg-green-100", bgColorClass: "bg-green-100",
path: "/pages/transfer/all", path: "/pages/purchase/market/all",
}, },
{ {
id: "supplierManage", id: "supplierManage",
@ -186,7 +186,7 @@ const quickActionMap = {
icon: "clipboard-list", icon: "clipboard-list",
iconColor: "var(--color-green-600)", iconColor: "var(--color-green-600)",
bgColorClass: "bg-green-100", bgColorClass: "bg-green-100",
path: "/pages/purchase/all", path: "/pages/purchase/made/all",
}, },
{ {
id: "shipOrder", id: "shipOrder",
@ -241,7 +241,7 @@ const quickActionMap = {
icon: "clipboard-list", icon: "clipboard-list",
iconColor: "var(--color-green-600)", iconColor: "var(--color-green-600)",
bgColorClass: "bg-green-100", bgColorClass: "bg-green-100",
path: "/pages/purchase/all", path: "/pages/purchase/made/all",
}, },
{ {
id: "shipOrder", id: "shipOrder",

View File

@ -64,7 +64,7 @@ export default hocAuth(function Page(props: CommonComponent) {
className="bg-primary flex w-full flex-col items-center justify-center space-y-2 rounded-xl py-2.5 text-white" className="bg-primary flex w-full flex-col items-center justify-center space-y-2 rounded-xl py-2.5 text-white"
onClick={() => { onClick={() => {
Taro.navigateTo({ Taro.navigateTo({
url: buildUrl("/pages/purchase/create"), url: buildUrl("/pages/purchase/made/create"),
}); });
}} }}
> >
@ -85,7 +85,7 @@ export default hocAuth(function Page(props: CommonComponent) {
className="bg-primary flex w-full flex-col items-center justify-center space-y-2 rounded-xl py-2.5 text-white" className="bg-primary flex w-full flex-col items-center justify-center space-y-2 rounded-xl py-2.5 text-white"
onClick={() => { onClick={() => {
Taro.navigateTo({ Taro.navigateTo({
url: buildUrl("/pages/transfer/create"), url: buildUrl("/pages/purchase/market/create"),
}); });
}} }}
> >
@ -96,7 +96,7 @@ export default hocAuth(function Page(props: CommonComponent) {
> >
<Icon name="plus" size={18} /> <Icon name="plus" size={18} />
</View> </View>
<View className="text-base font-bold"></View> <View className="text-base font-bold"></View>
</View> </View>
</View> </View>
)} )}

View File

@ -5,14 +5,14 @@ import { purchase } from "@/constant";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import { import {
Icon, Icon,
MadeOption,
MadeOptionRef,
OrderCost, OrderCost,
OrderCostItem, OrderCostItem,
OrderCostItemRef, OrderCostItemRef,
OrderCostRef, OrderCostRef,
OrderVehicle, OrderVehicle,
OrderVehicleRef, OrderVehicleRef,
PurchaseOption,
PurchaseOptionRef,
SupplierInfo, SupplierInfo,
SupplierInfoRef, SupplierInfoRef,
SupplierList, SupplierList,
@ -84,10 +84,10 @@ export default hocAuth(function Page(props: CommonComponent) {
const defaultSupplierId = router.params.supplierId as string; const defaultSupplierId = router.params.supplierId as string;
const defaultOrderSupplierId = router.params.orderSupplierId as string; const defaultOrderSupplierId = router.params.orderSupplierId as string;
const orderOptionRef = useRef<PurchaseOptionRef>(null); const orderOptionRef = useRef<MadeOptionRef>(null);
const vehicleRef = useRef<OrderVehicleRef>(null); const vehicleRef = useRef<OrderVehicleRef>(null);
// 创建MelonFarmer组件的ref数组 // 创建MelonFarmer组件的ref数组
const melonFarmerRefs = useRef<SupplierInfoRef[]>([]); const supplierInfoRefs = useRef<SupplierInfoRef[]>([]);
// 创建Weigh组件的ref数组 // 创建Weigh组件的ref数组
const supplierWeighRefs = useRef<SupplierWeighRef[]>([]); const supplierWeighRefs = useRef<SupplierWeighRef[]>([]);
// 创建OrderCost组件的ref // 创建OrderCost组件的ref
@ -123,7 +123,7 @@ export default hocAuth(function Page(props: CommonComponent) {
) { ) {
if (userRoleVO.slug === "origin-entry") { if (userRoleVO.slug === "origin-entry") {
Taro.redirectTo({ Taro.redirectTo({
url: buildUrl("/pages/purchase/preview", { url: buildUrl("/pages/purchase/made/preview", {
orderId: purchaseOrder.orderId, orderId: purchaseOrder.orderId,
}), }),
}); });
@ -174,7 +174,7 @@ export default hocAuth(function Page(props: CommonComponent) {
active = defaultStep; active = defaultStep;
} else { } else {
active = purchaseOrder.active || 1; active = purchaseOrder.active || 1;
if (active < 1 || active > purchase.steps.length - 1) { if (active < 1 || active > purchase.madeSteps.length - 1) {
active = 1; active = 1;
} }
} }
@ -184,8 +184,8 @@ export default hocAuth(function Page(props: CommonComponent) {
setPurchaseOrder({ setPurchaseOrder({
...purchaseOrder, ...purchaseOrder,
active: active:
active > purchase.steps.length - 1 active > purchase.madeSteps.length - 1
? purchase.steps.length - 1 ? purchase.madeSteps.length - 1
: active, : active,
orderSupplierList: orderSupplierList1, orderSupplierList: orderSupplierList1,
orderCostList: purchaseOrder.orderCostList?.map((item) => { orderCostList: purchaseOrder.orderCostList?.map((item) => {
@ -222,7 +222,7 @@ export default hocAuth(function Page(props: CommonComponent) {
}, [orderId]); }, [orderId]);
useEffect(() => { useEffect(() => {
setStep(purchase.steps[purchaseOrder?.active! - 1]); setStep(purchase.madeSteps[purchaseOrder?.active! - 1]);
}, [purchaseOrder?.active]); }, [purchaseOrder?.active]);
const setOrderSupplierList = ( const setOrderSupplierList = (
@ -267,16 +267,16 @@ export default hocAuth(function Page(props: CommonComponent) {
return ( return (
<> <>
<View className={"sticky top-0 z-11"}> <View className={"sticky top-0 z-11"}>
{step.value < purchase.steps.length && ( {step.value < purchase.madeSteps.length && (
<View className="h-12 bg-white p-2.5 shadow-sm"> <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="step-indicator flex h-2 rounded-full bg-gray-200">
<View <View
className="bg-primary rounded-full" className="bg-primary rounded-full"
style={`width: ${(100 / purchase.steps.length) * step.value}%`} style={`width: ${(100 / purchase.madeSteps.length) * step.value}%`}
></View> ></View>
</View> </View>
<View className="mt-1 text-sm font-bold text-[#000000]"> <View className="mt-1 text-sm font-bold text-[#000000]">
{step.title.replace("{}", purchase.steps.length - 1)} {step.title.replace("{}", purchase.madeSteps.length - 1)}
</View> </View>
</View> </View>
)} )}
@ -287,7 +287,7 @@ export default hocAuth(function Page(props: CommonComponent) {
onChange={(purchaseOrder: BusinessAPI.PurchaseOrderVO) => { onChange={(purchaseOrder: BusinessAPI.PurchaseOrderVO) => {
setPurchaseOrder(purchaseOrder); setPurchaseOrder(purchaseOrder);
}} }}
melonFarmerRefs={melonFarmerRefs} melonFarmerRefs={supplierInfoRefs}
weighRefs={supplierWeighRefs} weighRefs={supplierWeighRefs}
orderPackageRefs={supplierPackageRefs} orderPackageRefs={supplierPackageRefs}
/> />
@ -320,8 +320,8 @@ export default hocAuth(function Page(props: CommonComponent) {
if (step.value === 2) { if (step.value === 2) {
// 确保ref数组足够长 // 确保ref数组足够长
while (melonFarmerRefs.current.length <= index) { while (supplierInfoRefs.current.length <= index) {
melonFarmerRefs.current.push({ supplierInfoRefs.current.push({
validate: () => true, // 默认验证方法 validate: () => true, // 默认验证方法
} as SupplierInfoRef); } as SupplierInfoRef);
} }
@ -345,7 +345,7 @@ export default hocAuth(function Page(props: CommonComponent) {
}} }}
ref={(ref) => { ref={(ref) => {
if (ref) { if (ref) {
melonFarmerRefs.current[index] = ref; supplierInfoRefs.current[index] = ref;
} }
}} }}
/> />
@ -503,7 +503,7 @@ export default hocAuth(function Page(props: CommonComponent) {
</View> </View>
{/* 按钮操作 */} {/* 按钮操作 */}
<PurchaseOption <MadeOption
ref={orderOptionRef} ref={orderOptionRef}
value={purchaseOrder as any} value={purchaseOrder as any}
onChange={(purchaseOrderVO: BusinessAPI.PurchaseOrderVO) => onChange={(purchaseOrderVO: BusinessAPI.PurchaseOrderVO) =>
@ -515,7 +515,7 @@ export default hocAuth(function Page(props: CommonComponent) {
}) })
} }
vehicleRef={vehicleRef} vehicleRef={vehicleRef}
melonFarmerRefs={melonFarmerRefs} supplierInfoRefs={supplierInfoRefs}
supplierWeighRefs={supplierWeighRefs} supplierWeighRefs={supplierWeighRefs}
supplierPackageRefs={supplierPackageRefs} supplierPackageRefs={supplierPackageRefs}
orderCostRef={orderCostRef} orderCostRef={orderCostRef}

View File

@ -11,6 +11,7 @@ import {
import { business } from "@/services"; import { business } from "@/services";
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import { buildUrl } from "@/utils"; import { buildUrl } from "@/utils";
import { purchase } from "@/constant";
export default hocAuth(function Page(props: CommonComponent) { export default hocAuth(function Page(props: CommonComponent) {
const { router } = props; const { router } = props;
@ -65,9 +66,9 @@ export default hocAuth(function Page(props: CommonComponent) {
className="flex-1 bg-gray-200 text-gray-700" className="flex-1 bg-gray-200 text-gray-700"
onClick={() => { onClick={() => {
Taro.redirectTo({ Taro.redirectTo({
url: buildUrl("/pages/purchase/create", { url: buildUrl("/pages/purchase/made/create", {
orderId: purchaseOrder.orderId, orderId: purchaseOrder.orderId,
active: 6, active: purchase.madeSteps.length - 1,
}), }),
}); });
}} }}
@ -81,7 +82,7 @@ export default hocAuth(function Page(props: CommonComponent) {
size={"xlarge"} size={"xlarge"}
onFinish={() => { onFinish={() => {
Taro.switchTab({ Taro.switchTab({
url: buildUrl("/pages/purchase/result", { url: buildUrl("/pages/purchase/made/result", {
orderId: purchaseOrder.orderId, orderId: purchaseOrder.orderId,
}), }),
}); });

View File

@ -50,7 +50,7 @@ export default hocAuth(function Page(props: CommonComponent) {
const viewPurchaseOrderDetail = () => { const viewPurchaseOrderDetail = () => {
if (purchaseOrder?.orderId) { if (purchaseOrder?.orderId) {
Taro.navigateTo({ Taro.navigateTo({
url: buildUrl("/pages/purchase/preview", { url: buildUrl("/pages/purchase/made/preview", {
orderId: purchaseOrder.orderId, orderId: purchaseOrder.orderId,
}), }),
}); });

View File

@ -1,4 +1,4 @@
export default definePageConfig({ export default definePageConfig({
navigationBarTitleText: "全部调货单", navigationBarTitleText: "全部采购单",
navigationBarBackgroundColor: "#fff", navigationBarBackgroundColor: "#fff",
}); });

View File

@ -1,4 +1,4 @@
export default definePageConfig({ export default definePageConfig({
navigationBarBackgroundColor: "#fff", navigationBarBackgroundColor: "#fff",
navigationBarTitleText: "新建调货单", navigationBarTitleText: "新建采购单",
}); });

View File

@ -4,9 +4,10 @@ import { View } from "@tarojs/components";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import { import {
Icon, Icon,
MadeOptionRef,
MarketOption,
OrderVehicle, OrderVehicle,
OrderVehicleRef, OrderVehicleRef,
PurchaseOptionRef,
StallInfo, StallInfo,
StallInfoRef, StallInfoRef,
StallList, StallList,
@ -15,14 +16,13 @@ import {
StallWeigh, StallWeigh,
StallWeighRef, StallWeighRef,
SupplierPackageRef, SupplierPackageRef,
TransferOption
} from "@/components"; } from "@/components";
import { business } from "@/services"; import { business } from "@/services";
import { buildUrl, generateShortId } from "@/utils"; import { buildUrl, generateShortId } from "@/utils";
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import { Button } from "@nutui/nutui-react-taro"; import { Button } from "@nutui/nutui-react-taro";
import { WeightCalculationService } from "@/utils/classes/calculators"; import { WeightCalculationService } from "@/utils/classes/calculators";
import transfer from "@/constant/transfer"; import { purchase } from "@/constant";
const defaultSupplierList: Partial<BusinessAPI.OrderSupplier>[] = [ const defaultSupplierList: Partial<BusinessAPI.OrderSupplier>[] = [
{ {
@ -38,7 +38,7 @@ const defaultSupplierList: Partial<BusinessAPI.OrderSupplier>[] = [
isLast: undefined, isLast: undefined,
// 空磅是否包含纸箱 // 空磅是否包含纸箱
isPaper: true, isPaper: false,
// 默认按照毛重报价 // 默认按照毛重报价
pricingMethod: "BY_GROSS_WEIGHT", pricingMethod: "BY_GROSS_WEIGHT",
// 空磅重量 // 空磅重量
@ -57,18 +57,6 @@ const defaultSupplierList: Partial<BusinessAPI.OrderSupplier>[] = [
boxType: "USED", boxType: "USED",
isUsed: 0, isUsed: 0,
}, },
{
boxType: "EXTRA_USED",
isUsed: 0,
},
{
boxType: "EXTRA",
isUsed: 0,
},
{
boxType: "REMAIN",
isUsed: 0,
},
], ],
}, },
]; ];
@ -82,12 +70,12 @@ export default hocAuth(function Page(props: CommonComponent) {
const defaultSupplierId = router.params.supplierId as string; const defaultSupplierId = router.params.supplierId as string;
const defaultOrderSupplierId = router.params.orderSupplierId as string; const defaultOrderSupplierId = router.params.orderSupplierId as string;
const orderOptionRef = useRef<PurchaseOptionRef>(null); const orderOptionRef = useRef<MadeOptionRef>(null);
const vehicleRef = useRef<OrderVehicleRef>(null); const vehicleRef = useRef<OrderVehicleRef>(null);
// 创建MelonStall组件的ref数组 // 创建MelonStall组件的ref数组
const melonStallRefs = useRef<StallInfoRef[]>([]); const stallInfoRefs = useRef<StallInfoRef[]>([]);
// 创建Weigh组件的ref数组 // 创建Weigh组件的ref数组
const staffWeighRefs = useRef<StallWeighRef[]>([]); const stallWeighRefs = useRef<StallWeighRef[]>([]);
// 创建OrderPackage组件的ref // 创建OrderPackage组件的ref
const stallPackageRefs = useRef<StallPackageRef[]>([]); const stallPackageRefs = useRef<StallPackageRef[]>([]);
@ -117,7 +105,7 @@ export default hocAuth(function Page(props: CommonComponent) {
) { ) {
if (userRoleVO.slug === "market-buyer") { if (userRoleVO.slug === "market-buyer") {
Taro.redirectTo({ Taro.redirectTo({
url: buildUrl("/pages/transfer/preview", { url: buildUrl("/pages/purchase/market/preview", {
orderId: purchaseOrder.orderId, orderId: purchaseOrder.orderId,
}), }),
}); });
@ -169,7 +157,7 @@ export default hocAuth(function Page(props: CommonComponent) {
active = defaultStep; active = defaultStep;
} else { } else {
active = purchaseOrder.active || 1; active = purchaseOrder.active || 1;
if (active < 1 || active > transfer.steps.length - 1) { if (active < 1 || active > purchase.marketSteps.length - 1) {
active = 1; active = 1;
} }
} }
@ -177,8 +165,8 @@ export default hocAuth(function Page(props: CommonComponent) {
setPurchaseOrder({ setPurchaseOrder({
...purchaseOrder, ...purchaseOrder,
active: active:
active > transfer.steps.length - 1 active > purchase.marketSteps.length - 1
? transfer.steps.length - 1 ? purchase.marketSteps.length - 1
: active, : active,
orderSupplierList: orderSupplierList1, orderSupplierList: orderSupplierList1,
orderCostList: purchaseOrder.orderCostList?.map((item) => { orderCostList: purchaseOrder.orderCostList?.map((item) => {
@ -215,7 +203,7 @@ export default hocAuth(function Page(props: CommonComponent) {
}, [orderId]); }, [orderId]);
useEffect(() => { useEffect(() => {
setStep(transfer.steps[purchaseOrder?.active! - 1]); setStep(purchase.marketSteps[purchaseOrder?.active! - 1]);
}, [purchaseOrder?.active]); }, [purchaseOrder?.active]);
const setOrderSupplierList = ( const setOrderSupplierList = (
@ -260,16 +248,16 @@ export default hocAuth(function Page(props: CommonComponent) {
return ( return (
<> <>
<View className={"sticky top-0 z-11"}> <View className={"sticky top-0 z-11"}>
{step.value < transfer.steps.length && ( {step.value < purchase.marketSteps.length && (
<View className="h-12 bg-white p-2.5 shadow-sm"> <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="step-indicator flex h-2 rounded-full bg-gray-200">
<View <View
className="bg-primary rounded-full" className="bg-primary rounded-full"
style={`width: ${(100 / transfer.steps.length) * step.value}%`} style={`width: ${(100 / purchase.marketSteps.length) * step.value}%`}
></View> ></View>
</View> </View>
<View className="mt-1 text-sm font-bold text-[#000000]"> <View className="mt-1 text-sm font-bold text-[#000000]">
{step.title.replace("{}", transfer.steps.length - 1)} {step.title.replace("{}", purchase.marketSteps.length - 1)}
</View> </View>
</View> </View>
)} )}
@ -280,8 +268,8 @@ export default hocAuth(function Page(props: CommonComponent) {
onChange={(purchaseOrder: BusinessAPI.PurchaseOrderVO) => { onChange={(purchaseOrder: BusinessAPI.PurchaseOrderVO) => {
setPurchaseOrder(purchaseOrder); setPurchaseOrder(purchaseOrder);
}} }}
melonStallRefs={melonStallRefs} melonStallRefs={stallInfoRefs}
weighRefs={staffWeighRefs} weighRefs={stallWeighRefs}
orderPackageRefs={stallPackageRefs} orderPackageRefs={stallPackageRefs}
/> />
)} )}
@ -313,8 +301,8 @@ export default hocAuth(function Page(props: CommonComponent) {
if (step.value === 2) { if (step.value === 2) {
// 确保ref数组足够长 // 确保ref数组足够长
while (melonStallRefs.current.length <= index) { while (stallInfoRefs.current.length <= index) {
melonStallRefs.current.push({ stallInfoRefs.current.push({
validate: () => true, // 默认验证方法 validate: () => true, // 默认验证方法
} as StallInfoRef); } as StallInfoRef);
} }
@ -338,7 +326,7 @@ export default hocAuth(function Page(props: CommonComponent) {
}} }}
ref={(ref) => { ref={(ref) => {
if (ref) { if (ref) {
melonStallRefs.current[index] = ref; stallInfoRefs.current[index] = ref;
} }
}} }}
/> />
@ -348,8 +336,8 @@ export default hocAuth(function Page(props: CommonComponent) {
// 称重信息 // 称重信息
if (step.value === 3) { if (step.value === 3) {
// 确保ref数组足够长 // 确保ref数组足够长
while (staffWeighRefs.current.length <= index) { while (stallWeighRefs.current.length <= index) {
staffWeighRefs.current.push({ stallWeighRefs.current.push({
validate: () => true, // 默认验证方法 validate: () => true, // 默认验证方法
} as StallWeighRef); } as StallWeighRef);
} }
@ -373,7 +361,7 @@ export default hocAuth(function Page(props: CommonComponent) {
}} }}
ref={(ref) => { ref={(ref) => {
if (ref) { if (ref) {
staffWeighRefs.current[index] = ref; stallWeighRefs.current[index] = ref;
} }
}} }}
/> />
@ -442,7 +430,7 @@ export default hocAuth(function Page(props: CommonComponent) {
)} )}
{/* 按钮操作 */} {/* 按钮操作 */}
<TransferOption <MarketOption
ref={orderOptionRef} ref={orderOptionRef}
value={purchaseOrder as any} value={purchaseOrder as any}
onChange={(purchaseOrderVO: BusinessAPI.PurchaseOrderVO) => onChange={(purchaseOrderVO: BusinessAPI.PurchaseOrderVO) =>
@ -454,8 +442,8 @@ export default hocAuth(function Page(props: CommonComponent) {
}) })
} }
vehicleRef={vehicleRef} vehicleRef={vehicleRef}
melonStallRefs={melonStallRefs} stallInfoRefs={stallInfoRefs}
staffWeighRefs={staffWeighRefs} stallWeighRefs={stallWeighRefs}
stallPackageRefs={stallPackageRefs} stallPackageRefs={stallPackageRefs}
/> />
</View> </View>

View File

@ -1,4 +1,4 @@
export default definePageConfig({ export default definePageConfig({
navigationBarTitleText: "预览调货单", navigationBarTitleText: "预览采购单",
navigationBarBackgroundColor: "#fff", navigationBarBackgroundColor: "#fff",
}); });

View File

@ -3,14 +3,11 @@ import { CommonComponent } from "@/types/typings";
import { View } from "@tarojs/components"; import { View } from "@tarojs/components";
import { Button, SafeArea } from "@nutui/nutui-react-taro"; import { Button, SafeArea } from "@nutui/nutui-react-taro";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { import { MarketPreview, PurchaseOrderWithdrawReview } from "@/components";
PurchaseOrderWithdrawReview,
TransferOrderSubmitReview,
TransferPreview,
} from "@/components";
import { business } from "@/services"; import { business } from "@/services";
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import { buildUrl } from "@/utils"; import { buildUrl } from "@/utils";
import { purchase } from "@/constant";
export default hocAuth(function Page(props: CommonComponent) { export default hocAuth(function Page(props: CommonComponent) {
const { router } = props; const { router } = props;
@ -49,7 +46,7 @@ export default hocAuth(function Page(props: CommonComponent) {
<> <>
<View className={"overflow-x-hidden overflow-y-auto bg-[#D1D5DB]"}> <View className={"overflow-x-hidden overflow-y-auto bg-[#D1D5DB]"}>
{/* 采购预览 */} {/* 采购预览 */}
<TransferPreview purchaseOrder={purchaseOrder} /> <MarketPreview purchaseOrder={purchaseOrder} />
</View> </View>
{/* 按钮操作 */} {/* 按钮操作 */}
@ -65,9 +62,9 @@ export default hocAuth(function Page(props: CommonComponent) {
className="flex-1 bg-gray-200 text-gray-700" className="flex-1 bg-gray-200 text-gray-700"
onClick={() => { onClick={() => {
Taro.redirectTo({ Taro.redirectTo({
url: buildUrl("/pages/transfer/create", { url: buildUrl("/pages/purchase/market/create", {
orderId: purchaseOrder.orderId, orderId: purchaseOrder.orderId,
active: 4, active: purchase.marketSteps.length - 1,
}), }),
}); });
}} }}
@ -76,12 +73,12 @@ export default hocAuth(function Page(props: CommonComponent) {
</Button> </Button>
</View> </View>
<View className={"flex-1"}> <View className={"flex-1"}>
<TransferOrderSubmitReview <PurchaseOrderWithdrawReview
purchaseOrderVO={purchaseOrder} purchaseOrderVO={purchaseOrder}
size={"xlarge"} size={"xlarge"}
onFinish={() => { onFinish={() => {
Taro.switchTab({ Taro.switchTab({
url: buildUrl("/pages/transfer/result", { url: buildUrl("/pages/purchase/market/result", {
orderId: purchaseOrder.orderId, orderId: purchaseOrder.orderId,
}), }),
}); });

View File

@ -18,7 +18,7 @@ export default hocAuth(function Page(props: CommonComponent) {
const init = async (orderId: string) => { const init = async (orderId: string) => {
setLoading(true); setLoading(true);
try { try {
// 获取调货单信息 // 获取采购单信息
const { data: purchaseData } = const { data: purchaseData } =
await business.purchaseOrder.showPurchaseOrder({ await business.purchaseOrder.showPurchaseOrder({
purchaseOrderShowQry: { purchaseOrderShowQry: {
@ -33,7 +33,7 @@ export default hocAuth(function Page(props: CommonComponent) {
Toast.show("toast", { Toast.show("toast", {
icon: "fail", icon: "fail",
title: "提示", title: "提示",
content: "获取调货单信息失败", content: "获取采购单信息失败",
}); });
} finally { } finally {
setLoading(false); setLoading(false);
@ -46,11 +46,11 @@ export default hocAuth(function Page(props: CommonComponent) {
} }
}, [orderId]); }, [orderId]);
// 查看调货单详情 // 查看采购单详情
const viewPurchaseOrderDetail = () => { const viewPurchaseOrderDetail = () => {
if (purchaseOrder?.orderId) { if (purchaseOrder?.orderId) {
Taro.navigateTo({ Taro.navigateTo({
url: buildUrl("/pages/transfer/preview", { url: buildUrl("/pages/purchase/market/preview", {
orderId: purchaseOrder.orderId, orderId: purchaseOrder.orderId,
}), }),
}); });
@ -65,7 +65,7 @@ export default hocAuth(function Page(props: CommonComponent) {
</View> </View>
<View className="mb-2.5 text-xl font-bold text-gray-800"> <View className="mb-2.5 text-xl font-bold text-gray-800">
</View> </View>
<View className="mb-2.5 text-sm text-gray-600"></View> <View className="mb-2.5 text-sm text-gray-600"></View>
@ -81,7 +81,7 @@ export default hocAuth(function Page(props: CommonComponent) {
<View className="mb-2.5 flex flex-col gap-2.5"> <View className="mb-2.5 flex flex-col gap-2.5">
<View className="flex flex-row justify-between"> <View className="flex flex-row justify-between">
<Text className="text-neutral-darker text-sm">:</Text> <Text className="text-neutral-darker text-sm">:</Text>
<CopyText copyData={purchaseOrder?.orderSn || "-"}> <CopyText copyData={purchaseOrder?.orderSn || "-"}>
<Text className="text-sm font-medium"> <Text className="text-sm font-medium">
{purchaseOrder?.orderSn || "-"} {purchaseOrder?.orderSn || "-"}
@ -116,7 +116,7 @@ export default hocAuth(function Page(props: CommonComponent) {
block block
onClick={viewPurchaseOrderDetail} onClick={viewPurchaseOrderDetail}
> >
</Button> </Button>
</View> </View>
</View> </View>

View File

@ -143,13 +143,13 @@ export default hocAuth(function Page(props: CommonComponent) {
type={"default"} type={"default"}
onClick={() => { onClick={() => {
Taro.navigateTo({ Taro.navigateTo({
url: buildUrl("/pages/transfer/create", { url: buildUrl("/pages/purchase/market/create", {
supplierId: supplierVO.supplierId, supplierId: supplierVO.supplierId,
}), }),
}); });
}} }}
> >
</Button> </Button>
</View> </View>
</View> </View>

View File

@ -165,7 +165,7 @@ export default hocAuth(function Page(props: CommonComponent) {
type={"default"} type={"default"}
onClick={() => { onClick={() => {
Taro.navigateTo({ Taro.navigateTo({
url: buildUrl("/pages/purchase/create", { url: buildUrl("/pages/purchase/made/create", {
supplierId: supplierVO.supplierId, supplierId: supplierVO.supplierId,
}), }),
}); });

View File

@ -4589,7 +4589,7 @@ declare namespace BusinessAPI {
| "QUOTE_REJECTED" | "QUOTE_REJECTED"
| "BOSS_REJECTED"; | "BOSS_REJECTED";
/** 采购类型1_产地采购2_市场采购 */ /** 采购类型1_产地采购2_市场采购 */
type?: "PRODUCTION_PURCHASE" | "MARKET_PURCHASE"; type: "PRODUCTION_PURCHASE" | "MARKET_PURCHASE";
/** 备注 */ /** 备注 */
remark?: string; remark?: string;
/** 创建人ID */ /** 创建人ID */

View File

@ -46,7 +46,7 @@ export class SupplierWeightCalculator {
const weights = this.calculateAllBoxWeights(supplier.orderPackageList || []); const weights = this.calculateAllBoxWeights(supplier.orderPackageList || []);
if (!supplier.isPaper) { if (!supplier.isPaper) {
// 纸箱包装的简化计算 // 不带纸箱包装的简化计算
this.calculateNonPaperSupplier(supplier, weights.used); this.calculateNonPaperSupplier(supplier, weights.used);
} else { } else {
// 纸箱包装的复杂计算 // 纸箱包装的复杂计算