feat(purchase): 优化采购订单计算逻辑和界面展示

- 引入decimal.js提升金额计算精度
- 重构成本计算方法,明确区分各类费用构成
- 优化采购预览界面,增加计算明细展示
- 改进开票信息展示样式和计算公式说明
- 完善纸箱重量和销售金额的精确计算
- 调整界面布局,提升用户体验和信息可读性
- 修复成本项过滤逻辑,确保数据准确性
- 新增快速导航功能,便于页面内快速定位
- 更新图标资源,支持计算器和指南针图标
- 优化数字格式化处理,统一保留合适的小数位数
This commit is contained in:
shenyifei 2025-12-13 11:08:25 +08:00
parent a79fc0ef9f
commit 3d217b1122
13 changed files with 481 additions and 295 deletions

View File

@ -3,6 +3,8 @@ import classNames from "classnames";
import React from "react"; import React from "react";
export type IconNames = export type IconNames =
| "calculator"
| "compass"
| "eye" | "eye"
| "eye-slash" | "eye-slash"
| "phone-flip" | "phone-flip"

View File

@ -156,15 +156,13 @@ export default function CostList(props: {
)} )}
{orderCosts.map((orderCost) => { {orderCosts.map((orderCost) => {
if (type === "MATERIAL_TYPE") { if (
if ( orderCost.name === "空箱费" ||
orderCost.name === "空箱费" || orderCost.name === "纸箱费" ||
orderCost.name === "纸箱费" || orderCost.name === "运费" ||
orderCost.name === "运费" || orderCost.name === "草帘费"
orderCost.name === "草帘费" ) {
) { return <></>;
return <></>;
}
} }
return ( return (
<CostCard <CostCard

View File

@ -6,6 +6,8 @@ import {
OrderSupplierCalculator, OrderSupplierCalculator,
PurchaseOrderCalculator, PurchaseOrderCalculator,
} from "@/utils"; } from "@/utils";
import { Icon } from "@/components";
import { Decimal } from "decimal.js";
interface IPurchasePreviewProps { interface IPurchasePreviewProps {
purchaseOrder: BusinessAPI.PurchaseOrderVO; purchaseOrder: BusinessAPI.PurchaseOrderVO;
@ -61,9 +63,10 @@ export default function PurchasePreview(props: IPurchasePreviewProps) {
title: "重量(斤)", title: "重量(斤)",
key: "boxProductWeight", key: "boxProductWeight",
render: (record: any) => { render: (record: any) => {
return ( return new Decimal(record.boxProductWeight)
<View>{(record.boxProductWeight * record.boxCount).toFixed(2)}</View> .mul(new Decimal(record.boxCount))
); .toDecimalPlaces(0, Decimal.ROUND_HALF_UP)
.toNumber();
}, },
}, },
]); ]);
@ -148,10 +151,10 @@ export default function PurchasePreview(props: IPurchasePreviewProps) {
return ( return (
<View <View
className="rounded-lg bg-white p-2.5 shadow-sm" className="flex flex-col gap-2.5 rounded-lg bg-white p-2.5 shadow-sm"
key={supplier.orderSupplierId} key={supplier.orderSupplierId}
> >
<View className="mb-2 flex items-center justify-between"> <View className="flex items-center justify-between">
<View <View
className="text-lg font-semibold" className="text-lg font-semibold"
style="font-size: 18px;" style="font-size: 18px;"
@ -162,50 +165,71 @@ export default function PurchasePreview(props: IPurchasePreviewProps) {
{supplier.isLast ? "最后一个" : "不是最后一个"} {supplier.isLast ? "最后一个" : "不是最后一个"}
</View> </View>
</View> </View>
<View className="mb-3 flex flex-col gap-2 border-b pb-3">
<View className="flex items-center justify-between"> <View className="flex items-center justify-between">
<View className="text-sm text-gray-600"></View> <View className="text-sm text-gray-600"></View>
<View className="text-sm font-medium"> <View className="text-primary text-sm font-medium">
{formatCurrency(supplier.emptyWeight)} KG {supplier.invoiceAmount} {" "}
{supplier.isDepositPaid
? `(含定金:${calculator.getDepositPaidAmount()}元)`
: ""}
</View>
</View>
{/* 计算公式区域 */}
<View className="rounded-lg border border-gray-200 bg-gray-50 p-3">
<View className="mb-2 flex items-center">
<Icon
name="calculator"
className="mr-2 leading-4"
size={20}
/>
<View className="text-sm font-medium text-gray-700">
</View> </View>
</View> </View>
<View className="flex items-center justify-between"> <View className="space-y-1">
<View className="text-sm text-gray-600"></View> <View className="flex justify-between text-sm">
<View className="text-sm font-medium"> <View className="text-gray-600">kg</View>
{formatCurrency(supplier.totalWeight || 0)} KG <View className="font-medium text-gray-800">
{supplier.totalWeight || 0}
</View>
</View> </View>
</View> <View className="flex justify-between text-sm">
<View className="flex items-center justify-between"> <View className="text-gray-600">kg</View>
<View className="text-sm text-gray-600"></View> <View className="font-medium text-gray-800">
<View className="text-sm font-medium"> {supplier.emptyWeight || 0}
{formatCurrency(calculator.getGrossWeight())} </View>
</View> </View>
</View> <View className="flex justify-between text-sm">
<View className="flex items-center justify-between"> <View className="text-gray-600"></View>
<View className="text-sm text-gray-600"></View> <View className="font-medium text-gray-800">
<View className="text-primary text-sm font-medium"> {calculator.calculateBoxesTotalWeight("USED") || 0}
{formatCurrency(calculator.getNetWeight())} </View>
</View> </View>
</View> <View className="flex justify-between text-sm">
<View className="flex items-center justify-between"> <View className="text-gray-600"></View>
<View className="text-sm text-gray-600"></View> <View className="font-medium text-gray-800">
<View className="text-sm font-medium"> {supplier.netWeight || 0}
{formatCurrency(calculator.getBoxWeight())} </View>
</View> </View>
</View> <View className="flex justify-between text-sm">
<View className="flex items-center justify-between"> <View className="text-gray-600">/</View>
<View className="text-sm text-gray-600"></View> <View className="font-medium text-gray-800">
<View className="text-primary text-sm font-medium"> {supplier.purchasePrice || 0}
{formatCurrency(calculator.getPurchasePrice())} / </View>
</View> </View>
</View> <View className="flex justify-between text-sm">
<View className="mt-2 flex items-center justify-between"> <View className="text-gray-600"></View>
<View className="text-sm text-gray-600"></View> <View className="font-medium text-gray-800">
<View className="text-primary text-sm font-medium"> {supplier.pricingMethod === "BY_GROSS_WEIGHT"
{formatCurrency(calculator.getTotalAmount())} {" "} ? "毛重"
{supplier.isDepositPaid : "净重"}
? `(含定金:${formatCurrency(calculator.getDepositPaidAmount())}元)` </View>
: ""} </View>
<View className="my-2 h-px bg-gray-300"></View>
<View className="text-center text-xs text-gray-500">
×
</View> </View>
</View> </View>
</View> </View>
@ -221,7 +245,7 @@ export default function PurchasePreview(props: IPurchasePreviewProps) {
return Object.entries(groupedPackageInfo).map( return Object.entries(groupedPackageInfo).map(
([brandName, packageInfos]) => ( ([brandName, packageInfos]) => (
<View key={brandName} className="mb-2.5"> <View key={brandName} className={"flex flex-col gap-2.5"}>
<View className="text-primary text-base font-bold"> <View className="text-primary text-base font-bold">
{brandName} {brandName}
</View> </View>
@ -238,11 +262,11 @@ export default function PurchasePreview(props: IPurchasePreviewProps) {
<View className="rounded-lg bg-white p-2.5 shadow-md"> <View className="rounded-lg bg-white p-2.5 shadow-md">
<View className="flex items-center justify-between text-sm font-bold"> <View className="flex items-center justify-between text-sm font-bold">
<View></View> <View></View>
<View>{formatCurrency(calculator.getBoxCount())} </View> <View>{calculator.getBoxCount()} </View>
</View> </View>
<View className="mt-2 flex items-center justify-between text-sm font-bold"> <View className="mt-2 flex items-center justify-between text-sm font-bold">
<View></View> <View></View>
<View>{formatCurrency(calculator.getBoxWeight())} </View> <View>{calculator.getBoxWeight()} </View>
</View> </View>
</View> </View>
</View> </View>

View File

@ -1,7 +1,7 @@
import { Image, View } from "@tarojs/components"; import { Image, View } from "@tarojs/components";
import { Icon } from "@/components"; import { Icon } from "@/components";
import { Button, Price, Toast } from "@nutui/nutui-react-taro"; import { Button, Toast } from "@nutui/nutui-react-taro";
import { uploadFile } from "@/utils"; import { OrderSupplierCalculator, uploadFile } from "@/utils";
import Taro from "@tarojs/taro"; import Taro from "@tarojs/taro";
import { globalStore } from "@/store/global-store"; import { globalStore } from "@/store/global-store";
@ -29,33 +29,91 @@ export default function TicketUpload(props: ITicketUploadProps) {
if (!supplierVO) { if (!supplierVO) {
return; return;
} }
const calculator = new OrderSupplierCalculator(
value as any,
supplierVO as any,
);
return ( return (
<View className="flex flex-1 flex-col bg-[#D1D5DB] px-2.5 pt-2.5"> <View className="flex flex-1 flex-col gap-2.5 bg-[#D1D5DB] p-2.5">
<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="flex flex-col gap-2.5"> <View className="flex flex-col gap-2.5">
<View className="text-primary text-base font-bold"> <View className="text-primary text-base font-bold">
{supplierVO.name} {supplierVO.name}
</View> </View>
<View className="bg-primary/10 flex items-center justify-between rounded-lg p-2.5">
<View {/* 应开票金额突出显示 */}
className={"flex flex-1 flex-row items-center justify-between"} <View className="rounded-xl bg-gradient-to-r from-green-500 to-green-600 p-4 text-white shadow-md">
> <View className="text-center">
<View className="block text-sm font-normal text-[#000000]"> <View className="mb-1 text-sm font-medium opacity-90">
</View> </View>
<View className="text-primary mt-1 text-base font-semibold"> <View className="text-4xl font-bold">
<Price {supplierVO.invoiceAmount || 0}
price={supplierVO.invoiceAmount || 0}
thousands
size={"xlarge"}
/>
</View> </View>
</View> </View>
</View> </View>
<View className="block text-sm font-normal text-[#000000]"> {/* 计算公式区域 */}
<View className="rounded-lg border border-gray-200 bg-gray-50 p-3">
<View className="mb-2 flex items-center">
<Icon name="calculator" className="mr-2 leading-4" size={20} />
<View className="text-sm font-medium text-gray-700">
</View>
</View>
<View className="space-y-1">
<View className="flex justify-between text-sm">
<View className="text-gray-600">kg</View>
<View className="font-medium text-gray-800">
{supplierVO.totalWeight || 0}
</View>
</View>
<View className="flex justify-between text-sm">
<View className="text-gray-600">kg</View>
<View className="font-medium text-gray-800">
{supplierVO.emptyWeight || 0}
</View>
</View>
<View className="flex justify-between text-sm">
<View className="text-gray-600"></View>
<View className="font-medium text-gray-800">
{calculator.calculateBoxesTotalWeight("USED") || 0}
</View>
</View>
<View className="flex justify-between text-sm">
<View className="text-gray-600"></View>
<View className="font-medium text-gray-800">
{supplierVO.netWeight || 0}
</View>
</View>
<View className="flex justify-between text-sm">
<View className="text-gray-600">/</View>
<View className="font-medium text-gray-800">
{supplierVO.purchasePrice || 0}
</View>
</View>
<View className="flex justify-between text-sm">
<View className="text-gray-600"></View>
<View className="font-medium text-gray-800">
{supplierVO.pricingMethod === "BY_GROSS_WEIGHT"
? "毛重"
: "净重"}
</View>
</View>
<View className="my-2 h-px bg-gray-300"></View>
<View className="text-center text-xs text-gray-500">
×
</View>
</View>
</View>
</View>
</View>
<View className="border-primary rounded-lg border-4 bg-white p-2.5 shadow-sm">
<View className="flex flex-col gap-2.5">
<View className="text-primary text-base font-bold">
{supplierVO.name}
</View> </View>
{supplierVO.invoiceUpload ? ( {supplierVO.invoiceUpload ? (
@ -213,9 +271,13 @@ export default function TicketUpload(props: ITicketUploadProps) {
</View> </View>
</View> </View>
)} )}
</View>
</View>
<View className="block text-sm font-normal text-[#000000]"> <View className="border-primary rounded-lg border-4 bg-white p-2.5 shadow-sm">
<View className="flex flex-col gap-2.5">
<View className="text-primary text-base font-bold">
{supplierVO.name}
</View> </View>
{supplierVO.contractUpload && {supplierVO.contractUpload &&
supplierVO.contractImg && supplierVO.contractImg &&

View File

@ -3,6 +3,7 @@ import { useEffect, useState } from "react";
import { Button, Input, Popup, SafeArea, Table } from "@nutui/nutui-react-taro"; import { Button, Input, Popup, SafeArea, Table } from "@nutui/nutui-react-taro";
import { Icon } from "@/components"; import { Icon } from "@/components";
import { View } from "@tarojs/components"; import { View } from "@tarojs/components";
import { Decimal } from "decimal.js";
export default function EmptyBoxInfoSection(props: { export default function EmptyBoxInfoSection(props: {
purchaseOrderVO: BusinessAPI.PurchaseOrderVO; purchaseOrderVO: BusinessAPI.PurchaseOrderVO;
@ -336,11 +337,10 @@ export default function EmptyBoxInfoSection(props: {
</span> </span>
); );
} }
return formatCurrency( return new Decimal(rowData?.boxSalePrice || 0)
Number( .mul(rowData.boxProductCount)
(rowData?.boxSalePrice || 0) * rowData.boxProductCount, .toDecimalPlaces(0, Decimal.ROUND_HALF_UP)
) as number, .toNumber();
);
}, },
}; };
} else if (column.key === "boxProductWeight") { } else if (column.key === "boxProductWeight") {

View File

@ -133,7 +133,7 @@ export default function MarketPriceSection(props: {
// 销售金额 // 销售金额
const saleAmount = calculator.getSalesAmount(); const saleAmount = calculator.getSalesAmount();
const totalAmount = calculator.getTotalAmount(); const totalAmount = calculator.getMarketPrice();
// 计算平均单价(所有供应商单价的平均值) // 计算平均单价(所有供应商单价的平均值)
const averagePurchasePrice = calculator.getAverageSalesPrice(); const averagePurchasePrice = calculator.getAverageSalesPrice();
@ -210,26 +210,25 @@ export default function MarketPriceSection(props: {
<View className="flex items-center justify-between"> <View className="flex items-center justify-between">
<Text className="text-sm text-gray-500"></Text> <Text className="text-sm text-gray-500"></Text>
<Text className="text-sm font-medium"> <Text className="text-sm font-medium">
{(supplier.grossWeight || 0).toFixed(2)} {supplier.grossWeight || 0}
</Text> </Text>
</View> </View>
<View className="flex items-center justify-between"> <View className="flex items-center justify-between">
<Text className="text-sm text-gray-500"></Text> <Text className="text-sm text-gray-500"></Text>
<Text className="text-sm font-medium"> <Text className="text-sm font-medium">
{(supplier.netWeight || 0).toFixed(2)} {supplier.netWeight || 0}
</Text> </Text>
</View> </View>
<View className="flex items-center justify-between"> <View className="flex items-center justify-between">
<Text className="text-sm text-gray-500"></Text> <Text className="text-sm text-gray-500"></Text>
<Text className="text-sm font-medium"> <Text className="text-sm font-medium">
{(supplier.grossWeight - supplier.netWeight).toFixed(2)}{" "} {supplier.grossWeight - supplier.netWeight}
</Text> </Text>
</View> </View>
<View className="flex items-center justify-between"> <View className="flex items-center justify-between">
<Text className="text-sm text-gray-500"></Text> <Text className="text-sm text-gray-500"></Text>
<Text className="text-sm font-medium"> <Text className="text-sm font-medium">
{supplier.purchasePrice.toFixed(2)} / {supplier.purchasePrice} /
</Text> </Text>
</View> </View>
{supplier.isDepositPaid && ( {supplier.isDepositPaid && (

View File

@ -3,6 +3,7 @@ import { useEffect, useState } from "react";
import { Button, Input, Popup, SafeArea, Table } from "@nutui/nutui-react-taro"; import { Button, Input, Popup, SafeArea, Table } from "@nutui/nutui-react-taro";
import { Icon } from "@/components"; import { Icon } from "@/components";
import { View } from "@tarojs/components"; import { View } from "@tarojs/components";
import { Decimal } from "decimal.js";
export default function PackageInfoSection(props: { export default function PackageInfoSection(props: {
purchaseOrderVO: BusinessAPI.PurchaseOrderVO; purchaseOrderVO: BusinessAPI.PurchaseOrderVO;
@ -69,15 +70,6 @@ export default function PackageInfoSection(props: {
{ {
title: "销售金额(元)", title: "销售金额(元)",
key: "boxSalePayment", key: "boxSalePayment",
render: (
value: BusinessAPI.OrderPackage & {
boxProductCount: number;
isTotalRow?: boolean;
},
) =>
formatCurrency(
Number((value?.boxSalePrice || 0) * value.boxProductCount) as number,
),
}, },
{ {
title: "箱重(斤)", title: "箱重(斤)",
@ -189,23 +181,29 @@ export default function PackageInfoSection(props: {
} }
// 计算各项合计 // 计算各项合计
let totalBoxProductCount = 0; let totalBoxProductCount = new Decimal(0);
let totalBoxSalePayment = 0; let totalBoxSalePayment = new Decimal(0);
let totalBoxProductWeight = 0; let totalBoxProductWeight = new Decimal(0);
packageData.forEach((pkg: any) => { packageData.forEach((pkg: any) => {
totalBoxProductCount += pkg.boxProductCount || 0; totalBoxProductCount = totalBoxProductCount.add(pkg.boxProductCount || 0);
totalBoxSalePayment += totalBoxSalePayment = totalBoxSalePayment.add(
Number((pkg?.boxSalePrice || 0) * pkg.boxProductCount) || 0; new Decimal(pkg?.boxSalePrice || 0)
totalBoxProductWeight += .mul(pkg.boxProductCount || 0)
Number((pkg?.boxProductWeight || 0) * pkg.boxProductCount) || 0; .toDecimalPlaces(0, Decimal.ROUND_HALF_UP),
);
totalBoxProductWeight = totalBoxProductWeight.add(
new Decimal(pkg?.boxProductWeight || 0)
.mul(pkg.boxProductCount || 0)
.toDecimalPlaces(0, Decimal.ROUND_HALF_UP),
);
}); });
return { return {
boxProductName: "合计", boxProductName: "合计",
boxProductCount: totalBoxProductCount, boxProductCount: totalBoxProductCount.toNumber(),
boxSalePayment: totalBoxSalePayment, boxSalePayment: totalBoxSalePayment.toNumber(),
boxProductWeight: totalBoxProductWeight, boxProductWeight: totalBoxProductWeight.toNumber(),
isTotalRow: true, // 标记这是合计行 isTotalRow: true, // 标记这是合计行
}; };
}; };
@ -351,11 +349,10 @@ export default function PackageInfoSection(props: {
</span> </span>
); );
} }
return formatCurrency( return new Decimal(rowData?.boxSalePrice || 0)
Number( .mul(rowData.boxProductCount)
(rowData?.boxSalePrice || 0) * rowData.boxProductCount, .toDecimalPlaces(0, Decimal.ROUND_HALF_UP)
) as number, .toNumber();
);
}, },
}; };
} else if (column.key === "boxProductWeight") { } else if (column.key === "boxProductWeight") {

View File

@ -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_hkkkrqw0kin.woff2?t=1763456511295') format('woff2'), src: url('//at.alicdn.com/t/c/font_5042354_gjumaiad8dh.woff2?t=1765554257380') format('woff2'),
url('//at.alicdn.com/t/c/font_5042354_hkkkrqw0kin.woff?t=1763456511295') format('woff'), url('//at.alicdn.com/t/c/font_5042354_gjumaiad8dh.woff?t=1765554257380') format('woff'),
url('//at.alicdn.com/t/c/font_5042354_hkkkrqw0kin.ttf?t=1763456511295') format('truetype'); url('//at.alicdn.com/t/c/font_5042354_gjumaiad8dh.ttf?t=1765554257380') format('truetype');
} }
.iconfont { .iconfont {
@ -13,6 +13,14 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.icon-calculator:before {
content: "\e626";
}
.icon-compass:before {
content: "\e625";
}
.icon-phone-flip:before { .icon-phone-flip:before {
content: "\e624"; content: "\e624";
} }

View File

@ -106,7 +106,7 @@ export default hocAuth(function Page(props: CommonComponent) {
item.price * item.count > 0 && ( item.price * item.count > 0 && (
<View <View
className="cost-item flex flex-col px-3 py-2" className="cost-item flex flex-col px-3 py-2"
key={item.itemId} key={item.costId}
> >
<View className="text-sm text-gray-500">{item.name}</View> <View className="text-sm text-gray-500">{item.name}</View>
<View className="font-medium"> <View className="font-medium">

View File

@ -1,6 +1,6 @@
import hocAuth from "@/hocs/auth"; import hocAuth from "@/hocs/auth";
import { CommonComponent } from "@/types/typings"; import { CommonComponent } from "@/types/typings";
import Taro from "@tarojs/taro"; import Taro, { usePageScroll } from "@tarojs/taro";
import { business } from "@/services"; import { business } from "@/services";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { View } from "@tarojs/components"; import { View } from "@tarojs/components";
@ -23,6 +23,7 @@ import {
DealerInfoSection, DealerInfoSection,
DeliveryFormSection, DeliveryFormSection,
EmptyBoxInfoSection, EmptyBoxInfoSection,
Icon,
MarketPriceSection, MarketPriceSection,
MaterialCostSection, MaterialCostSection,
PackageInfoSection, PackageInfoSection,
@ -190,11 +191,11 @@ const fullSections = [
component: CostDifferenceSection, component: CostDifferenceSection,
title: "待分红金额复核", title: "待分红金额复核",
}, },
// 成本合计 // 成本合计复核
{ {
name: "costSummary", name: "costSummary",
component: CostSummarySection, component: CostSummarySection,
title: "成本合计", title: "成本合计复核",
}, },
// 个人返点复核 // 个人返点复核
{ {
@ -309,6 +310,10 @@ export default hocAuth(function Page(props: CommonComponent) {
// 控制更多操作的ActionSheet显示状态 // 控制更多操作的ActionSheet显示状态
const [moreActionVisible, setMoreActionVisible] = useState(false); const [moreActionVisible, setMoreActionVisible] = useState(false);
// 控制快速导航的显示状态
const [showQuickNav, setShowQuickNav] = useState(false);
const [quickNavExpanded, setQuickNavExpanded] = useState(false);
const [dealerRebateCustomerVOList, setDealerRebateCustomerVOList] = const [dealerRebateCustomerVOList, setDealerRebateCustomerVOList] =
useState<BusinessAPI.DealerRebateCustomerVO[]>(); useState<BusinessAPI.DealerRebateCustomerVO[]>();
@ -426,6 +431,31 @@ export default hocAuth(function Page(props: CommonComponent) {
setProvisionZeroConfirmVisible(false); setProvisionZeroConfirmVisible(false);
}; };
// 跳转到指定section
const scrollToSection = (sectionKey: string) => {
if (process.env.TARO_ENV === "h5") {
// H5环境使用DOM API
const element = document.getElementById(`section-${sectionKey}`);
if (element) {
element.scrollIntoView({ behavior: "smooth", block: "start" });
}
} else {
// 小程序环境使用Taro的节点查询
Taro.createSelectorQuery()
.select(`#section-${sectionKey}`)
.boundingClientRect((rect) => {
if (rect) {
Taro.pageScrollTo({
//@ts-ignore
scrollTop: rect.top,
duration: 300,
});
}
})
.exec();
}
};
// 表单校验 // 表单校验
const validateForm = () => { const validateForm = () => {
// 校验销售方 // 校验销售方
@ -568,6 +598,12 @@ export default hocAuth(function Page(props: CommonComponent) {
} }
}, []); }, []);
// 使用Taro的页面滚动监听
usePageScroll((res) => {
const scrollTop = res.scrollTop;
setShowQuickNav(scrollTop > 300); // 滚动超过300px时显示快速导航
});
if (!purchaseOrderVO || !dealerRebateCustomerVOList || !costList) { if (!purchaseOrderVO || !dealerRebateCustomerVOList || !costList) {
return; return;
} }
@ -575,16 +611,84 @@ export default hocAuth(function Page(props: CommonComponent) {
const calculator = new PurchaseOrderCalculator(purchaseOrderVO, true); const calculator = new PurchaseOrderCalculator(purchaseOrderVO, true);
const personalProfit = calculator.getPersonalProfit(); const personalProfit = calculator.getPersonalProfit();
const sections = const sections = (
purchaseOrderVO.orderDealer.shortName === "信誉楼" purchaseOrderVO.orderDealer.shortName === "信誉楼"
? xylSections ? xylSections
: defaultSections; : defaultSections
)
.map((sectionKey) => {
const section = fullSections.find(
(section) => section.name === sectionKey,
);
if (!section) {
return false;
}
const orderDealer = purchaseOrderVO.orderDealer;
if (!orderDealer?.enableCompanyRebate && sectionKey === "taxSubsidy") {
return false;
}
if (!orderDealer?.enableAccrualTax && sectionKey === "taxProvision") {
return false;
}
if (!orderDealer?.shareAdjusted && sectionKey === "costDifference") {
return false;
}
if (!orderDealer?.enableLoss && sectionKey === "productionLoss") {
return false;
}
// 如果没有返点人这个模块,则不渲染
if (
(!dealerRebateCustomerVOList ||
dealerRebateCustomerVOList.length === 0) &&
sectionKey === "rebateCalc"
) {
return false;
}
if (
(!purchaseOrderVO.orderPackageList ||
purchaseOrderVO?.orderPackageList.length === 0) &&
sectionKey === "emptyBoxInfo"
) {
return false;
}
if (
sectionKey === "purchaseForm" &&
purchaseOrderVO.orderDealer.shortName !== "信誉楼"
) {
return false;
}
if (
sectionKey === "deliveryForm" &&
purchaseOrderVO.orderDealer.shortName === "信誉楼"
) {
return false;
}
return section;
})
.filter(Boolean);
return ( return (
<> <>
<View <View
className={"overflow-x-hidden overflow-y-auto bg-[#D1D5DB]"} className={"overflow-x-hidden overflow-y-auto bg-[#D1D5DB]"}
id={"purchase-order-audit"} id={"purchase-order-audit"}
onClick={() => {
// 点击页面其他区域时收起导航菜单
if (quickNavExpanded) {
setQuickNavExpanded(false);
}
}}
> >
<View className={"flex flex-col gap-2.5 p-2.5"}> <View className={"flex flex-col gap-2.5 p-2.5"}>
{/* 顶部导航 */} {/* 顶部导航 */}
@ -638,75 +742,13 @@ export default hocAuth(function Page(props: CommonComponent) {
</View> </View>
{/* 循环渲染各部分内容 */} {/* 循环渲染各部分内容 */}
{sections.map((sectionKey) => { {sections.map((section: any) => {
const section = fullSections.find(
(section) => section.name === sectionKey,
);
if (!section) {
return null;
}
const orderDealer = purchaseOrderVO.orderDealer;
if (
!orderDealer?.enableCompanyRebate &&
sectionKey === "taxSubsidy"
) {
return null;
}
if (
!orderDealer?.enableAccrualTax &&
sectionKey === "taxProvision"
) {
return null;
}
if (
!orderDealer?.shareAdjusted &&
sectionKey === "costDifference"
) {
return null;
}
if (!orderDealer?.enableLoss && sectionKey === "productionLoss") {
return null;
}
// 如果没有返点人这个模块,则不渲染
if (
(!dealerRebateCustomerVOList ||
dealerRebateCustomerVOList.length === 0) &&
sectionKey === "rebateCalc"
) {
return null;
}
if (
(!purchaseOrderVO.orderPackageList ||
purchaseOrderVO?.orderPackageList.length === 0) &&
sectionKey === "emptyBoxInfo"
) {
return null;
}
if (
sectionKey === "purchaseForm" &&
purchaseOrderVO.orderDealer.shortName !== "信誉楼"
) {
return null;
}
if (
sectionKey === "deliveryForm" &&
purchaseOrderVO.orderDealer.shortName === "信誉楼"
) {
return null;
}
return ( return (
<View key={sectionKey} className={"flex flex-col gap-2.5"}> <View
key={section.name}
id={`section-${section.name}`}
className={"flex flex-col gap-2.5"}
>
<View className="text-sm font-bold">{section.title}</View> <View className="text-sm font-bold">{section.title}</View>
<View <View
className={`overflow-x-auto rounded-md rounded-b-lg bg-white p-2.5 shadow-sm`} className={`overflow-x-auto rounded-md rounded-b-lg bg-white p-2.5 shadow-sm`}
@ -914,6 +956,66 @@ export default hocAuth(function Page(props: CommonComponent) {
<SafeArea position="bottom" /> <SafeArea position="bottom" />
</Popup> </Popup>
{/* 快速导航目录 */}
{showQuickNav && (
<View
className={`fixed left-4 z-40 bg-white shadow-lg transition-all duration-300 ${
quickNavExpanded ? "top-4 w-48" : "top-4 h-10 w-10"
} rounded-lg`}
style={{
opacity: showQuickNav ? 1 : 0,
}}
>
{/* 导航触发按钮 */}
<View
className="relative flex h-10 w-10 cursor-pointer items-center justify-center"
onClick={() => setQuickNavExpanded(!quickNavExpanded)}
>
<Icon
name="compass"
className={`text-blue-600 transition-transform duration-300 ${
quickNavExpanded ? "rotate-180" : ""
}`}
></Icon>
</View>
{/* 展开的导航菜单 */}
{quickNavExpanded && (
<View
className="absolute top-0 left-10 w-48 rounded-lg border border-gray-200 bg-white shadow-lg"
onClick={(e) => e.stopPropagation()} // 防止事件冒泡
>
<View className="border-b border-gray-200 px-3 py-2">
<View className="text-xs font-medium text-gray-700">
</View>
</View>
<View className="max-h-96 overflow-y-auto">
{sections.map((section: any) => (
<View
key={section.name}
className="cursor-pointer border-b border-gray-100 px-3 py-2 text-sm text-gray-600 transition-colors last:border-b-0 hover:bg-blue-50 hover:text-blue-600"
onClick={() => {
scrollToSection(section.name);
setQuickNavExpanded(false); // 跳转后自动收起
}}
>
{section.title}
</View>
))}
</View>
{/* 收起按钮 */}
<View
className="cursor-pointer border-t border-gray-200 px-3 py-2 text-xs text-gray-500 hover:bg-gray-50"
onClick={() => setQuickNavExpanded(false)}
>
</View>
</View>
)}
</View>
)}
</> </>
); );
}); });

View File

@ -22,10 +22,9 @@ export class OrderSupplierCalculator {
* *
*/ */
private init() { private init() {
// this.purchaseOrderVO.orderDealer
Decimal.set({ Decimal.set({
precision: 20, precision: 20,
rounding: 0, // 0 = ROUND_DOWN rounding: Decimal.ROUND_HALF_UP, // 使用常量更清晰
toExpNeg: -7, toExpNeg: -7,
toExpPos: 21, toExpPos: 21,
}); });
@ -65,7 +64,9 @@ export class OrderSupplierCalculator {
* *
*/ */
getTotalAmount(): number { getTotalAmount(): number {
if (this.orderSupplier.orderPackageList?.some((pkg) => pkg.boxType === "USED")) { if (
this.orderSupplier.orderPackageList?.some((pkg) => pkg.boxType === "USED")
) {
return new Decimal(this.getNetWeight()) return new Decimal(this.getNetWeight())
.mul(this.getPurchasePrice()) .mul(this.getPurchasePrice())
.toNumber(); .toNumber();
@ -85,4 +86,25 @@ export class OrderSupplierCalculator {
} }
return new Decimal(this.orderSupplier.depositAmount || 0).toNumber(); return new Decimal(this.orderSupplier.depositAmount || 0).toNumber();
} }
/**
*
* @param {string} boxType - ('USED' 'EXTRA')
* @returns {number}
*/
calculateBoxesTotalWeight(boxType?: any): number {
return (
this.orderSupplier.orderPackageList
?.filter((pkg) => pkg.boxType === boxType)
.reduce((sum, pkg) => {
// 纸箱重量单位是斤,直接使用
const boxWeight = pkg.boxProductWeight || 0;
return new Decimal(sum)
.add(
new Decimal(pkg.boxCount || 0).mul(boxWeight).toDecimalPlaces(0),
)
.toNumber();
}, 0) || 0
);
}
} }

View File

@ -18,30 +18,29 @@ export class PurchaseOrderCalculator {
console.table([ console.table([
{ {
成本项总和: this.getTotalCostItemAmount(), 成本项总和: this.getTotalCostAmount(),
辅料费: this.getCostAmount("MATERIAL_TYPE"),
人工费: this.getCostAmount("ARTIFICIAL_TYPE"), 人工费: this.getCostAmount("ARTIFICIAL_TYPE"),
辅料费: this.getCostAmount("MATERIAL_TYPE"),
产地垫付: this.getCostAmount("PRODUCTION_TYPE"), 产地垫付: this.getCostAmount("PRODUCTION_TYPE"),
: 空箱费: this.getCostAmount("MATERIAL_TYPE", "空箱费"),
this.getCostAmount("MATERIAL_TYPE", "纸箱费") || this.getBoxSale(), 纸箱费: this.getCostAmount("MATERIAL_TYPE", "纸箱费"),
计提费: this.getCostAmount("OTHER_TYPE", "计提费"), 计提费: this.getCostAmount("OTHER_TYPE", "计提费"),
收代办费: this.getCostAmount("OTHER_TYPE", "收代办费"), 收代办费: this.getCostAmount("OTHER_TYPE", "收代办费"),
王超费用: this.getCostAmount("OTHER_TYPE", "王超费用"), 王超费用: this.getCostAmount("OTHER_TYPE", "王超费用"),
其他费用: this.getCostAmount("OTHER_TYPE"), 草帘费: this.getCostAmount("OTHER_TYPE", "草帘费"),
草帘费: this.getStrawCurtainCost(),
}, },
]); ]);
console.table([ console.table([
{ {
西瓜采购成本: this.getSupplierPurchaseCost(), 西瓜采购成本: this.getMelonPurchaseCost(),
成本项总和: this.getTotalCostItemAmount(), 西瓜成本1: this.getMelonCost1(),
西瓜成本2: this.getMelonCost2(),
成本项总和: this.getTotalCostAmount(),
税费补贴: this.getTaxSubsidy(), 税费补贴: this.getTaxSubsidy(),
计提税金: this.getTaxProvision(), 计提税金: this.getTaxProvision(),
成本差异: this.getCostDifference(), 成本差异: this.getCostDifference(),
"采购成本(不包含运费)": this.getTotalPurchaseCost(),
运费: this.getDeliveryFee(), 运费: this.getDeliveryFee(),
"采购成本(含运费)": this.getMelonCost1(), 销售金额: this.getSalesAmount(),
市场报价: this.getSalesAmount(),
平均单价: this.getAverageSalesPrice(), 平均单价: this.getAverageSalesPrice(),
}, },
]); ]);
@ -62,7 +61,7 @@ export class PurchaseOrderCalculator {
private init() { private init() {
Decimal.set({ Decimal.set({
precision: 20, precision: 20,
rounding: 0, // 0 = ROUND_DOWN rounding: Decimal.ROUND_HALF_UP, // 使用常量更清晰
toExpNeg: -7, toExpNeg: -7,
toExpPos: 21, toExpPos: 21,
}); });
@ -79,39 +78,25 @@ export class PurchaseOrderCalculator {
?.filter((item) => item.type === type && (!name || item.name === name)) ?.filter((item) => item.type === type && (!name || item.name === name))
.reduce((sum, cost) => { .reduce((sum, cost) => {
return new Decimal(sum) return new Decimal(sum)
.plus(new Decimal(cost.price || 0).mul(cost.count || 0)) .plus(new Decimal(cost.price || 0).mul(cost.count || 0).toDecimalPlaces(0))
.toNumber(); .toNumber();
}, 0); }, 0);
} }
/** /**
* = + + + + + + + + * = + + + + + + + + +
*/ */
getTotalCostItemAmount(): number { getTotalCostAmount(): number {
const costItemsCost = this.purchaseOrderVO.orderCostList?.reduce( return this.purchaseOrderVO.orderCostList?.reduce((sum, cost) => {
(sum, cost) => { if (cost.name === "运费" && !this.purchaseOrderVO.orderDealer?.freightCostFlag) {
// 先过滤一下 return new Decimal(sum).toNumber();
if (cost.name === "纸箱费") { }
return new Decimal(sum).toNumber(); return new Decimal(sum)
} .plus(
return new Decimal(sum) new Decimal(cost.price || 0).mul(cost.count || 0).toDecimalPlaces(0),
.plus(new Decimal(cost.price || 0).mul(cost.count || 0)) )
.toNumber(); .toNumber();
}, }, 0);
0,
);
const boxCost = this.getBoxSale();
// 计算草帘费
const strawCurtainCost = this.purchaseOrderVO.orderDealer?.strawMatCostFlag
? this.getStrawCurtainCost()
: 0;
return new Decimal(costItemsCost)
.plus(boxCost)
.plus(strawCurtainCost)
.toNumber();
} }
/** /**
@ -119,17 +104,6 @@ export class PurchaseOrderCalculator {
*/ */
getSupplierPurchaseCost(): number { getSupplierPurchaseCost(): number {
return this.purchaseOrderVO.orderSupplierList.reduce((sum, supplier) => { return this.purchaseOrderVO.orderSupplierList.reduce((sum, supplier) => {
const ownBoxWeight =
supplier.orderPackageList
?.filter((pkg) => pkg.boxType === "USED")
?.reduce((sum, pkg) => {
return new Decimal(sum)
.plus(
new Decimal(pkg.boxCount || 0).mul(pkg.boxProductWeight || 0),
)
.toNumber();
}, 0) || 0;
return new Decimal(sum) return new Decimal(sum)
.plus( .plus(
new Decimal( new Decimal(
@ -137,8 +111,8 @@ export class PurchaseOrderCalculator {
? supplier.grossWeight ? supplier.grossWeight
: supplier.netWeight, : supplier.netWeight,
) )
.plus(ownBoxWeight) .mul(supplier.purchasePrice || 0)
.mul(supplier.purchasePrice || 0), .toDecimalPlaces(0),
) )
.toNumber(); .toNumber();
}, 0); }, 0);
@ -150,7 +124,7 @@ export class PurchaseOrderCalculator {
*/ */
getTotalPurchaseCost(): number { getTotalPurchaseCost(): number {
return new Decimal(this.getSupplierPurchaseCost()) return new Decimal(this.getSupplierPurchaseCost())
.plus(this.getTotalCostItemAmount()) .plus(this.getTotalCostAmount())
.plus(this.getTaxSubsidy()) .plus(this.getTaxSubsidy())
.plus(this.getTaxProvision()) .plus(this.getTaxProvision())
.plus(this.getCostDifference()) .plus(this.getCostDifference())
@ -158,17 +132,29 @@ export class PurchaseOrderCalculator {
} }
/** /**
* 西1 = + * 西
*/
getMelonPurchaseCost(): number {
return this.getSupplierPurchaseCost();
}
/**
* 西1 = 西 +
*/ */
getMelonCost1(): number { getMelonCost1(): number {
const totalPurchaseCost = this.getTotalPurchaseCost(); const melonPurchaseCost = this.getMelonPurchaseCost();
const totalCostAmount = this.getTotalCostAmount();
// 计算运费 return new Decimal(melonPurchaseCost).plus(totalCostAmount).toNumber();
const deliveryFee = this.purchaseOrderVO.orderDealer?.freightCostFlag }
? this.getDeliveryFee()
: 0;
return new Decimal(totalPurchaseCost).plus(deliveryFee).toNumber(); /**
* 西2 = 西1 + (
*/
getMelonCost2(): number {
return new Decimal(this.getMelonCost1())
.plus(this.getCostDifference())
.toNumber();
} }
/** /**
@ -230,7 +216,11 @@ export class PurchaseOrderCalculator {
?.filter((pkg) => pkg.boxType === "USED") ?.filter((pkg) => pkg.boxType === "USED")
.reduce((sum, pkg) => { .reduce((sum, pkg) => {
return new Decimal(sum) return new Decimal(sum)
.plus(new Decimal(pkg.boxCount || 0).mul(pkg.boxSalePrice || 0)) .plus(
new Decimal(pkg.boxCount || 0)
.mul(pkg.boxSalePrice || 0)
.toDecimalPlaces(0),
)
.toNumber(); .toNumber();
}, 0) || 0, }, 0) || 0,
) )
@ -320,22 +310,12 @@ export class PurchaseOrderCalculator {
* 西 = - 西1 * 西 = - 西1
*/ */
getMelonGrossProfit(): number { getMelonGrossProfit(): number {
// 计算各种金额
const salesAmount = this.getMarketPrice(); // 市场报价 const salesAmount = this.getMarketPrice(); // 市场报价
const melonCost1 = this.getMelonCost1(); // 西瓜成本1 const melonCost1 = this.getMelonCost1(); // 西瓜成本1
return new Decimal(salesAmount).minus(melonCost1).toNumber(); // 西瓜毛利 return new Decimal(salesAmount).minus(melonCost1).toNumber(); // 西瓜毛利
} }
/**
* 西2 = 西1 + (
*/
getMelonCost2(): number {
return new Decimal(this.getMelonCost1())
.plus(this.getCostDifference())
.toNumber();
}
/** /**
* ( * (
*/ */
@ -376,13 +356,6 @@ export class PurchaseOrderCalculator {
return 0; return 0;
} }
/**
*
*/
getMarketPrice(): number {
return new Decimal(this.getSalesAmount()).toNumber();
}
/** /**
* *
*/ */
@ -412,14 +385,14 @@ export class PurchaseOrderCalculator {
/** /**
* + * +
*/ */
getTotalAmount(): number { getMarketPrice(): number {
const decimal = new Decimal(this.getSalesAmount()); const decimal = new Decimal(this.getSalesAmount());
const includePackingFlag = const includePackingFlag =
this.purchaseOrderVO.orderDealer?.includePackingFlag; this.purchaseOrderVO.orderDealer?.includePackingFlag;
if (includePackingFlag) { if (includePackingFlag) {
return decimal.plus(this.getTotalCostItemAmount()).toNumber(); return decimal.plus(this.getTotalCostAmount()).toNumber();
} }
return decimal.toNumber(); return decimal.toNumber();
@ -439,7 +412,10 @@ export class PurchaseOrderCalculator {
? supplier.grossWeight ? supplier.grossWeight
: supplier.netWeight; : supplier.netWeight;
return new Decimal(weight || 0).mul(salePrice || 0).toNumber(); return new Decimal(weight || 0)
.mul(salePrice || 0)
.toDecimalPlaces(0)
.toNumber();
} }
/** /**
@ -447,7 +423,7 @@ export class PurchaseOrderCalculator {
*/ */
getDefaultTaxProvision(): number { getDefaultTaxProvision(): number {
if (this.purchaseOrderVO.orderDealer?.enableAccrualTax) { if (this.purchaseOrderVO.orderDealer?.enableAccrualTax) {
const totalAmount = this.getTotalAmount(); const totalAmount = this.getMarketPrice();
const taxSubsidyValue = this.getTaxSubsidy(); const taxSubsidyValue = this.getTaxSubsidy();
return new Decimal(totalAmount) return new Decimal(totalAmount)
@ -465,7 +441,7 @@ export class PurchaseOrderCalculator {
*/ */
getDefaultTaxSubsidy(): number { getDefaultTaxSubsidy(): number {
if (this.purchaseOrderVO.orderDealer?.enableCompanyRebate) { if (this.purchaseOrderVO.orderDealer?.enableCompanyRebate) {
const totalPackagingCost = this.getTotalCostItemAmount(); const totalPackagingCost = this.getTotalCostAmount();
const salesAmount1 = this.getSalesAmount(); const salesAmount1 = this.getSalesAmount();
return new Decimal(salesAmount1) return new Decimal(salesAmount1)
@ -487,7 +463,10 @@ export class PurchaseOrderCalculator {
supplier.orderPackageList supplier.orderPackageList
?.filter((pkg) => pkg.boxType === "USED") ?.filter((pkg) => pkg.boxType === "USED")
?.reduce((sum, pkg) => { ?.reduce((sum, pkg) => {
return new Decimal(sum).plus(pkg.boxCount || 0).toNumber(); return new Decimal(sum)
.plus(pkg.boxCount || 0)
.toDecimalPlaces(0)
.toNumber();
}, 0) || 0, }, 0) || 0,
) )
.toNumber(); .toNumber();
@ -506,7 +485,9 @@ export class PurchaseOrderCalculator {
?.reduce((sum, pkg) => { ?.reduce((sum, pkg) => {
return new Decimal(sum) return new Decimal(sum)
.plus( .plus(
new Decimal(pkg.boxProductWeight || 0).mul(pkg.boxCount || 0), new Decimal(pkg.boxProductWeight || 0)
.mul(pkg.boxCount || 0)
.toDecimalPlaces(0),
) )
.toNumber(); .toNumber();
}, 0) || 0, }, 0) || 0,

View File

@ -18,7 +18,7 @@ export class SupplierWeightCalculator {
private init() { private init() {
Decimal.set({ Decimal.set({
precision: 20, precision: 20,
rounding: 0, // 向下舍入(更保守的计算方式) rounding: Decimal.ROUND_HALF_UP, // 使用常量更清晰
toExpNeg: -7, toExpNeg: -7,
toExpPos: 21, toExpPos: 21,
}); });
@ -29,7 +29,7 @@ export class SupplierWeightCalculator {
* @returns {Array} * @returns {Array}
*/ */
calculate(): BusinessAPI.OrderSupplier[] { calculate(): BusinessAPI.OrderSupplier[] {
console.log("开始计算采购订单的农户重量信息..."); console.log("开始计算采购订单的农户重量信息...", this.suppliers);
if (!this.suppliers || this.suppliers.length === 0) { if (!this.suppliers || this.suppliers.length === 0) {
return this.suppliers; return this.suppliers;
} }
@ -51,16 +51,7 @@ export class SupplierWeightCalculator {
} }
// 计算本次使用纸箱的总重量(斤) // 计算本次使用纸箱的总重量(斤)
const usedBoxesWeight = new Decimal( const usedBoxesWeight = this.calculateBoxesTotalWeight(supplier.orderPackageList || [], "USED")
this.calculateBoxesTotalWeight(supplier.orderPackageList || [], "USED"),
)
.toNumber();
// 计算额外配送的已使用纸箱总重量(斤)
const extraUsedBoxesWeight = this.calculateBoxesTotalWeight(
supplier.orderPackageList || [],
"EXTRA_USED",
);
if (!supplier.isPaper) { if (!supplier.isPaper) {
// 如果不是纸箱包装直接使用原始重量kg转斤 // 如果不是纸箱包装直接使用原始重量kg转斤
@ -71,12 +62,12 @@ export class SupplierWeightCalculator {
supplier.netWeight = new Decimal(supplier.grossWeight || 0) supplier.netWeight = new Decimal(supplier.grossWeight || 0)
.sub(usedBoxesWeight) .sub(usedBoxesWeight)
.sub(extraUsedBoxesWeight)
.toNumber(); .toNumber();
previousTotalWeight = supplier.totalWeight; previousTotalWeight = supplier.totalWeight;
supplier.invoiceAmount = new Decimal(supplier.netWeight || 0) supplier.invoiceAmount = new Decimal(supplier.netWeight || 0)
.mul(supplier.purchasePrice || 0) .mul(supplier.purchasePrice || 0)
.toDecimalPlaces(0)
.toNumber(); .toNumber();
continue; continue;
} }
@ -93,15 +84,15 @@ export class SupplierWeightCalculator {
"REMAIN", "REMAIN",
); );
// 计算额外配送的已使用纸箱总重量(斤)
const extraUsedBoxesWeight = this.calculateBoxesTotalWeight(
supplier.orderPackageList || [],
"EXTRA_USED",
);
if (isFirstSupplier && isLastSupplier) { if (isFirstSupplier && isLastSupplier) {
// 既是第一个也是最后一个瓜农(单个瓜农情况)- 优先使用最后一个瓜农算法 // 既是第一个也是最后一个瓜农(单个瓜农情况)- 优先使用最后一个瓜农算法
// 净重 = (总磅 - 空磅) * 2 + 剩余空箱子重量 - 已使用额外纸箱重量 // 净重 = (总磅 - 空磅) * 2 + 剩余空箱子重量 - 已使用额外纸箱重量
console.log("总磅", supplier.totalWeight);
console.log("空磅", initialEmptyWeight);
console.log("剩余空箱子重量", remainingBoxesWeight);
console.log("已使用额外纸箱重量", extraUsedBoxesWeight);
supplier.netWeight = new Decimal(supplier.totalWeight || 0) supplier.netWeight = new Decimal(supplier.totalWeight || 0)
.sub(initialEmptyWeight) .sub(initialEmptyWeight)
.mul(2) .mul(2)
@ -183,7 +174,7 @@ export class SupplierWeightCalculator {
// 纸箱重量单位是斤,直接使用 // 纸箱重量单位是斤,直接使用
const boxWeight = pkg.boxProductWeight || 0; const boxWeight = pkg.boxProductWeight || 0;
return new Decimal(sum) return new Decimal(sum)
.add(new Decimal(pkg.boxCount || 0).mul(boxWeight)) .add(new Decimal(pkg.boxCount || 0).mul(boxWeight).toDecimalPlaces(0))
.toNumber(); .toNumber();
}, 0); }, 0);
} }