refactor(components): 优化采购模块空箱和费用组件实现

- 移除 PageList 组件中对全局 loading 状态的依赖
- 简化 EmptyBoxModule 组件逻辑,使用 PackageList 组件替代原有复杂实现
- 移除冗余的状态管理和弹窗渲染逻辑
- 优化 OrderCost 组件样式和费用项匹配逻辑
- 修复成本项 ID 匹配问题,确保数据正确关联
- 添加边框样式增强视觉效果
- 移除调试日志和无用代码
- 简化组件间数据传递方式
This commit is contained in:
shenyifei 2025-12-11 12:42:01 +08:00
parent 837c27e9bd
commit dfe9a89213
21 changed files with 1033 additions and 1681 deletions

View File

@ -18,7 +18,6 @@ import {
} from "@nutui/nutui-react-taro";
import { Icon } from "@/components";
import classNames from "classnames";
import { globalStore } from "@/store/global-store";
import { ActionType, IRecordListProps, Query, Record } from "./typing";
export default <T extends {}, Q extends Query = Query>(
@ -48,7 +47,6 @@ export default <T extends {}, Q extends Query = Query>(
toolbar?.search?.defaultActiveKey || "",
);
const { loading, setLoading } = globalStore((state: any) => state);
const [lightTheme, setLightTheme] = useState(false);
const [data, setData] = useState<Record<any>[]>();
const [query, setQuery] = useState<Query>();
@ -109,11 +107,10 @@ export default <T extends {}, Q extends Query = Query>(
}
})
.exec();
}, [loading, toolbar]);
}, [toolbar]);
useEffect(() => {
if (query) {
setLoading(true);
request(query as any).then((res: Record<any>) => {
const list = res.data;
if (res.success) {
@ -132,7 +129,6 @@ export default <T extends {}, Q extends Query = Query>(
if (res.hasMore !== undefined) {
setHasMore(res.hasMore);
}
setLoading(false);
}
});
}
@ -141,8 +137,7 @@ export default <T extends {}, Q extends Query = Query>(
const [hasMore, setHasMore] = useState<boolean>();
const loadMore = async () => {
if (hasMore && !loading && query?.pageIndex) {
setLoading(true);
if (hasMore && query?.pageIndex) {
setQuery({
...query,
pageIndex: query.pageIndex + 1,
@ -166,7 +161,7 @@ export default <T extends {}, Q extends Query = Query>(
);
};
if (loading || !data) {
if (!data) {
if (skeleton) {
return renderSkeleton();
}

View File

@ -1,5 +1,6 @@
import {
ActionType,
CopyText,
DealerPicker,
Icon,
PageList,
@ -167,9 +168,11 @@ export default function PurchaseOrderApprovalList(
<Label className={"text-neutral-dark text-sm"}>
</Label>
<CopyText copyData={purchaseOrderVO?.orderSn || "-"}>
<Text className={"text-neutral-darkest text-sm"}>
{purchaseOrderVO.orderSn}
</Text>
</CopyText>
</View>
<View
className={

View File

@ -1,5 +1,6 @@
import {
ActionType,
CopyText,
DealerPicker,
Icon,
PageList,
@ -167,9 +168,11 @@ export default function PurchaseOrderAuditList(
<Label className={"text-neutral-dark text-sm"}>
</Label>
<CopyText copyData={purchaseOrderVO?.orderSn || "-"}>
<Text className={"text-neutral-darkest text-sm"}>
{purchaseOrderVO.orderSn}
</Text>
</CopyText>
</View>
<View
className={

View File

@ -52,6 +52,13 @@ export default function CostCard(props: CostCardComponentProps) {
});
};
if (
orderCostItemList.length == 0 &&
(orderCost.type === "ARTIFICIAL_TYPE" || orderCost.type === "MATERIAL_TYPE")
) {
return;
}
return (
<>
<View className="bg-primary/3 rounded-lg border-b border-gray-100 p-2.5">

View File

@ -1,24 +1,10 @@
import { ScrollView, View } from "@tarojs/components";
import { Icon } from "@/components";
import { View } from "@tarojs/components";
import { PackageList } from "@/components";
import { useEffect, useState } from "react";
import { business } from "@/services";
import {
Button,
Checkbox,
Dialog,
Image,
Input,
Popup,
SafeArea,
Toast,
} from "@nutui/nutui-react-taro";
import { Checkbox } from "@nutui/nutui-react-taro";
import { BoxBrand, BoxProduct, BoxSpec } from "@/types/typings";
import {
convertBoxBrandToOrderPackages,
convertOrderPackagesToBoxBrands,
generateShortId,
} from "@/utils";
import classNames from "classnames";
import { generateShortId } from "@/utils";
export interface IEmptyBoxModuleProps {
orderPackageList: BusinessAPI.OrderPackage[];
@ -28,23 +14,9 @@ export interface IEmptyBoxModuleProps {
export default function EmptyBoxModule(props: IEmptyBoxModuleProps) {
const { orderPackageList, onChange } = props;
// 空箱相关状态
const [emptyBoxList, setEmptyBoxList] = useState<BusinessAPI.OrderPackage[]>(
[],
);
const [hasEmptyBox, setHasEmptyBox] = useState(false);
const [boxBrandList, setBoxBrandList] = useState<BoxBrand[]>();
// 批量添加空箱相关状态
const [selectedBrand, setSelectedBrand] = useState<BoxBrand | null>(null);
const [productCounts, setProductCounts] = useState<Map<string, number>>(
new Map(),
);
const [showBatchModal, setShowBatchModal] = useState(false);
// 编辑空箱弹窗状态
const [showEditModal, setShowEditModal] = useState(false);
const [editingItem, setEditingItem] = useState<BoxBrand | null>(null);
// 初始化空箱品牌数据
const initBoxBrandList = async () => {
const { data } = await business.boxBrand.listBoxBrand({
@ -126,833 +98,51 @@ export default function EmptyBoxModule(props: IEmptyBoxModuleProps) {
// 当传入的value发生变化时重新初始化列表
useEffect(() => {
initBoxBrandList().then();
setEmptyBoxList(orderPackageList);
if (orderPackageList?.length > 0) {
// 根据当前供应商确定需要检查的纸箱类型
let requiredTypes: string[] = ["EMPTY"];
requiredTypes.map((type) => {
setPackageTypeEnabled((prev) => ({
...prev,
[type]: orderPackageList.some((item) => item.boxType === type)
? 1
: 0,
}));
});
setHasEmptyBox(true);
}
}, []);
// 当空箱列表变化时,通知父组件更新
useEffect(() => {
onChange(
emptyBoxList?.map((item) => {
return {
...item,
id: generateShortId(),
};
}),
);
}, [emptyBoxList]);
// 处理批量添加时的品牌选择
const handleBatchBrandSelect = (brand: BoxBrand) => {
// 检查是否已存在该品牌
const isBrandAlreadySelected = emptyBoxList.some(
(pkg) => pkg.boxBrandId === brand.boxBrandId,
);
if (isBrandAlreadySelected) {
Toast.show("toast", {
icon: "fail",
title: "提示",
content: "该空箱品牌已存在,请选择其他品牌或编辑现有信息",
});
return;
}
setSelectedBrand(brand);
// 初始化所有产品的数量为0
const initialCounts = new Map<string, number>();
brand.boxSpecList?.forEach((boxSpec) => {
boxSpec.boxProductList.forEach((product) => {
initialCounts.set(product.id, 0);
});
});
setProductCounts(initialCounts);
};
// 处理产品数量变化
const handleProductCountChange = (productId: string, count: number) => {
setProductCounts((prev) => {
const newCounts = new Map(prev);
newCounts.set(productId, Math.max(0, count)); // 允许为0表示不使用
return newCounts;
});
// 同时更新selectedBrand中的产品数量
if (selectedBrand) {
const updatedBrand = { ...selectedBrand };
updatedBrand.boxSpecList = updatedBrand.boxSpecList?.map((boxSpec) => {
const updatedProducts = boxSpec.boxProductList.map((product) => {
if (product.id === productId) {
return { ...product, boxCount: count };
}
return product;
});
return { ...boxSpec, boxProductList: updatedProducts };
});
setSelectedBrand(updatedBrand);
}
};
// 批量添加空箱信息
const addBatchEmptyBoxInfo = () => {
if (!selectedBrand) {
return;
}
// 使用convertBoxBrandToOrderPackages转换数据
const newOrderPackages = convertBoxBrandToOrderPackages(
selectedBrand,
"EMPTY",
);
// 过滤掉数量为0的项目
const filteredOrderPackages = newOrderPackages.filter((pkg) => {
// 从productCounts中获取对应产品的数量
const product = selectedBrand.boxSpecList
?.flatMap((c) => c.boxProductList)
.find((p) => p.id === pkg.orderPackageId);
const count = product ? productCounts.get(product.id) || 0 : 0;
return count > 0;
});
// 更新数量信息
const updatedOrderPackages = filteredOrderPackages.map((pkg) => {
// 从productCounts中获取对应产品的数量
const product = selectedBrand.boxSpecList
?.flatMap((c) => c.boxProductList)
.find((p) => p.id === pkg.orderPackageId);
const count = product ? productCounts.get(product.id) || 0 : 0;
return {
...pkg,
boxCount: count,
};
});
// 添加到emptyBoxList中
setEmptyBoxList((prev) => [...prev, ...updatedOrderPackages]);
// 重置选择并关闭弹窗
setSelectedBrand(null);
setProductCounts(new Map());
setShowBatchModal(false);
};
// 删除空箱信息
const removeEmptyBoxInfo = (boxBrandId: string) => {
console.log("removeEmptyBoxInfo", boxBrandId);
Dialog.open("dialog", {
title: "提示",
content: "确定要移除此空箱品牌吗?",
confirmText: "确定",
cancelText: "取消",
onConfirm: () => {
const newList = [
...emptyBoxList.filter((item) => item.boxBrandId !== boxBrandId),
];
setEmptyBoxList(newList);
Dialog.close("dialog");
},
onCancel: () => {
Dialog.close("dialog");
},
});
};
// 处理编辑按钮点击
const handleEditItem = (item: BoxBrand) => {
// 从emptyBoxList中找到完整的品牌信息用于编辑
const brandToEdit = convertOrderPackagesToBoxBrands(
emptyBoxList.filter((pkg) => pkg.boxBrandId === item.boxBrandId),
)[0];
// 获取完整品牌信息(包括所有规格)
const fullBrandInfo = boxBrandList?.find(
(brand) => brand.boxBrandId === item.boxBrandId,
);
// 合并已有的数据和完整品牌信息
const mergedBrandInfo = fullBrandInfo
? ({
...fullBrandInfo,
boxType: "EMPTY", // 保持boxType
boxSpecList: fullBrandInfo.boxSpecList?.map((boxSpec) => {
// 找到对应的已存在分类数据
const existingSpec = brandToEdit?.boxSpecList?.find(
(spec) => spec.boxSpecId === boxSpec.boxSpecId,
);
return {
...boxSpec,
boxProductList: boxSpec.boxProductList.map((product) => {
// 找到对应的产品数据
const existingProduct = existingSpec?.boxProductList.find(
(prod) => prod.boxProductId === product.boxProductId,
);
return {
...product,
boxCount: existingProduct?.boxCount || 0,
};
}),
};
}),
} as BoxBrand)
: brandToEdit;
if (mergedBrandInfo) {
setEditingItem(mergedBrandInfo);
setShowEditModal(true);
}
};
// 更新编辑项中的数量
const updateEditingItemCount = (
specIndex: number,
detailIndex: number,
count: number,
) => {
if (!editingItem) return;
// 获取完整品牌信息
const fullBrandInfo = boxBrandList?.find(
(brand) => brand.boxBrandId === editingItem.boxBrandId,
);
if (!fullBrandInfo) return;
const updatedItem = { ...editingItem };
// 确保boxSpecList存在
if (!updatedItem.boxSpecList) {
updatedItem.boxSpecList = fullBrandInfo.boxSpecList.map((boxSpec) => ({
...boxSpec,
boxProductList: boxSpec.boxProductList.map((product) => ({
...product,
boxCount: 0,
})),
}));
}
// 确保spec存在
if (!updatedItem.boxSpecList[specIndex]) {
updatedItem.boxSpecList[specIndex] = {
...fullBrandInfo.boxSpecList[specIndex],
boxProductList: fullBrandInfo.boxSpecList[specIndex].boxProductList.map(
(product) => ({
...product,
boxCount: 0,
}),
),
};
}
// 更新对应的产品数量
const boxSpec = { ...updatedItem.boxSpecList[specIndex] };
// 确保boxProductList存在
if (!boxSpec.boxProductList) {
boxSpec.boxProductList = fullBrandInfo.boxSpecList[
specIndex
].boxProductList.map((product) => ({
...product,
boxCount: 0,
}));
}
const boxProductList = [...boxSpec.boxProductList];
// 确保产品存在
if (!boxProductList[detailIndex]) {
boxProductList[detailIndex] = {
...fullBrandInfo.boxSpecList[specIndex].boxProductList[detailIndex],
boxCount: 0,
};
}
boxProductList[detailIndex] = {
...boxProductList[detailIndex],
boxCount: count,
};
boxSpec.boxProductList = boxProductList;
const updatedSpecList = [...updatedItem.boxSpecList];
updatedSpecList[specIndex] = boxSpec;
updatedItem.boxSpecList = updatedSpecList;
setEditingItem(updatedItem);
};
// 保存编辑的空箱信息
const saveEditedItem = () => {
if (editingItem) {
// 检查是否尝试更改为已存在的品牌(排除自身)
const isBrandAlreadySelected = emptyBoxList.some(
(pkg) =>
pkg.boxBrandId === editingItem.boxBrandId &&
!(pkg.boxBrandId === editingItem.boxBrandId),
);
if (isBrandAlreadySelected) {
Toast.show("toast", {
icon: "fail",
title: "提示",
content: "该空箱品牌已存在,请选择其他品牌",
});
return;
}
// 使用convertBoxBrandToOrderPackages转换编辑后的数据
const updatedOrderPackages = convertBoxBrandToOrderPackages(
editingItem,
"EMPTY",
).filter((pkg) => pkg.boxCount > 0);
// 更新emptyBoxList
const newList = [...emptyBoxList];
// 找到对应品牌和类型的现有项目并替换
const startIndex = newList.findIndex(
(pkg) => pkg.boxBrandId === editingItem.boxBrandId,
);
if (startIndex !== -1) {
// 移除旧的项目
const filteredList = newList.filter(
(pkg) => !(pkg.boxBrandId === editingItem.boxBrandId),
);
// 添加更新后的项目
setEmptyBoxList([...filteredList, ...updatedOrderPackages]);
} else {
// 如果没有找到,直接添加
setEmptyBoxList((prev) => [...prev, ...updatedOrderPackages]);
}
}
setShowEditModal(false);
setEditingItem(null);
};
// 渲染单个空箱信息模块
const renderEmptyBoxItem = (item: BoxBrand) => {
// 获取品牌信息用于展示品牌图片
const brandInfo = boxBrandList?.find(
(brand) => brand.boxBrandId === item.boxBrandId,
);
return (
<View
className="mb-2.5 overflow-hidden rounded-xl border border-gray-200 bg-white p-2.5 shadow-sm"
key={item.id}
>
{/* 品牌背景水印 */}
{brandInfo?.boxBrandImage && (
<View className="absolute top-2 right-2 opacity-10">
<Image
src={brandInfo.boxBrandImage}
className="h-full w-full"
mode="aspectFit"
/>
</View>
)}
{/* 品牌信息和操作按钮放在同一行 */}
<View className="mb-3 flex items-start justify-between">
<View className="flex items-center">
{brandInfo?.boxBrandImage && (
<View className="mr-3 h-10 w-10 overflow-hidden rounded-lg border border-gray-200">
<Image
src={brandInfo.boxBrandImage}
className="h-full w-full"
mode="aspectFit"
/>
</View>
)}
<View>
<View className="text-lg font-bold text-gray-800">
{item.boxBrandName || "未选择品牌"}
</View>
</View>
</View>
{/* 操作按钮与品牌信息放在同一行 */}
<View className="flex gap-2">
<View
className="cursor-pointer rounded-lg bg-blue-100 px-3 py-1 text-xs font-medium text-blue-600 transition-colors hover:bg-blue-200"
onClick={() => handleEditItem(item)}
>
</View>
<View
className="cursor-pointer rounded-lg bg-red-100 px-3 py-1 text-xs font-medium text-red-600 transition-colors hover:bg-red-200"
onClick={() => {
console.log("removeEmptyBoxInfo", item.boxBrandId);
removeEmptyBoxInfo(item.boxBrandId);
}}
>
</View>
</View>
</View>
{/* 详细信息展示,按分类显示 */}
<View className="space-y-2">
{item.boxSpecList &&
item.boxSpecList.map((boxSpec, boxIndex) => (
<View
key={boxIndex}
className="rounded-lg bg-gray-50 p-3 text-sm text-gray-600"
>
<View className="mb-1 font-medium text-gray-700">
{boxSpec.boxSpecName}
</View>
<View>
{boxSpec.boxProductList
.map(
(detail) =>
`${detail.boxProductName}${detail.boxCount}`,
)
.join("")}
</View>
</View>
))}
</View>
</View>
);
};
// 渲染批量添加空箱弹窗
const renderBatchAddModal = () => {
// 检查是否至少有一个产品的数量大于0
const hasAnyProductWithCount = selectedBrand
? Array.from(productCounts.values()).some((count) => count > 0)
: false;
return (
<Popup
duration={150}
style={{
minHeight: "auto",
}}
visible={showBatchModal}
position="bottom"
onClose={() => {
setShowBatchModal(false);
setSelectedBrand(null);
setProductCounts(new Map());
}}
title={"批量添加空箱"}
round
>
<View className="p-2.5">
<ScrollView
scrollY
style={{
height: "65vh",
width: "100%",
}}
>
{/* 品牌选择 */}
<View className="mb-4">
<View className="mb-2 text-sm text-gray-600"></View>
<ScrollView className="mb-2.5" scrollX>
<View className="flex w-fit flex-row gap-2.5">
{boxBrandList
?.filter((item) => item.boxBrandType !== "FARMER_BOX")
?.map((boxBrand) => (
<View
key={boxBrand.id}
className={"flex flex-col items-center justify-center"}
onClick={() => handleBatchBrandSelect(boxBrand)}
>
<View
className={classNames(
"border-primary box-content !size-16 overflow-hidden rounded-xl border-4 object-cover",
{
"border-primary":
selectedBrand?.id === boxBrand.id,
"border-transparent":
selectedBrand?.id !== boxBrand.id,
},
)}
>
<Image
src={boxBrand.boxBrandImage}
className="h-full w-full"
mode={"aspectFill"}
alt={boxBrand.boxBrandImage}
/>
</View>
<View className="text-center text-xs">
{boxBrand.boxBrandName}
</View>
</View>
))}
</View>
</ScrollView>
</View>
{/* 未选择品牌时的提示 */}
{!selectedBrand && (
<View className="mb-4 rounded-lg bg-yellow-50 p-4 text-center">
<View className="text-yellow-800"></View>
</View>
)}
{/* 产品展示 */}
{selectedBrand && (
<View className="mb-4">
<View className="mb-2 text-sm text-gray-600">
+/- 0使
</View>
{selectedBrand.boxSpecList?.map((boxSpec) => (
<View key={boxSpec.id} className="mb-4">
<View className="mb-2 text-base font-medium">
{boxSpec.boxSpecName}
</View>
<View className="space-y-3">
{boxSpec.boxProductList.map((boxProduct) => {
const currentCount =
productCounts.get(boxProduct.id) || 0;
return (
<View
key={boxProduct.id}
className="flex items-center justify-between rounded-lg bg-gray-50 p-3"
>
<View className="text-gray-800">
{boxProduct.boxProductName}
</View>
<View className="flex items-center">
<View
className="flex h-8 w-8 items-center justify-center rounded-l bg-gray-200"
onClick={() => {
handleProductCountChange(
boxProduct.id,
Math.max(0, currentCount - 1),
);
}}
>
<Icon name="minus" size={16} />
</View>
<View className="flex h-8 w-12 items-center justify-center border-y border-gray-200">
<Input
type="number"
value={currentCount.toString()}
align={"center"}
className="!h-8 !w-12 !p-0 !text-center"
onChange={(value) => {
const num = Number(value);
if (!Number.isNaN(num) && num >= 0) {
handleProductCountChange(
boxProduct.id,
num,
);
}
}}
/>
</View>
<View
className="flex h-8 w-8 items-center justify-center rounded-r bg-gray-200"
onClick={() => {
handleProductCountChange(
boxProduct.id,
currentCount + 1,
);
}}
>
<Icon name="plus" size={16} />
</View>
<View className="ml-2 text-gray-800"></View>
</View>
</View>
);
})}
</View>
</View>
))}
</View>
)}
</ScrollView>
{/* 底部按钮 */}
<View className="flex gap-2 pt-4">
<View className="flex-1">
<Button
type={"default"}
size={"large"}
block
onClick={() => {
setShowBatchModal(false);
setSelectedBrand(null);
setProductCounts(new Map());
}}
>
</Button>
</View>
<View className="flex-1">
<Button
type={"primary"}
size={"large"}
block
disabled={!selectedBrand || !hasAnyProductWithCount}
onClick={addBatchEmptyBoxInfo}
>
</Button>
</View>
</View>
<SafeArea position={"bottom"} />
</View>
</Popup>
);
};
// 渲染编辑空箱弹窗
const renderEditModal = () => {
if (!editingItem) return null;
// 获取品牌信息
const brandInfo = boxBrandList?.find(
(brand) => brand.boxBrandId === editingItem.boxBrandId,
);
return (
<Popup
duration={150}
style={{
minHeight: "auto",
}}
visible={showEditModal}
position="bottom"
onClose={() => setShowEditModal(false)}
title={"编辑空箱信息"}
round
>
<View className="p-2.5">
<ScrollView
scrollY
style={{
height: "65vh",
width: "100%",
}}
>
{/* 品牌信息 */}
<View className="mb-4">
<View className="mb-2 text-sm text-gray-600"></View>
<View className="flex items-center rounded-lg bg-gray-50 p-3">
{brandInfo?.boxBrandImage && (
<View className="border-primary mr-3 h-16 w-16 overflow-hidden rounded-xl border-4 object-cover">
<Image
src={brandInfo.boxBrandImage}
className="h-full w-full"
mode="aspectFill"
/>
</View>
)}
<View className="text-base font-medium text-gray-800">
{editingItem.boxBrandName}
</View>
</View>
</View>
{/* 详细信息 */}
<View className="mb-4">
<View className="mb-2 text-sm text-gray-600"></View>
<View className="space-y-3">
{editingItem?.boxSpecList &&
editingItem.boxSpecList.map((boxSpec, specId) => (
<View key={specId} className="rounded-lg bg-gray-50 p-3">
<View className="mb-2 text-base font-medium text-gray-800">
{boxSpec.boxSpecName}
</View>
<View className="space-y-2">
{boxSpec.boxProductList.map((detail, detailIndex) => {
const currentCount = detail?.boxCount || 0;
return (
<View
key={detailIndex}
className="flex items-center justify-between py-1"
>
<View className="text-gray-600">
{detail.boxProductName}
</View>
<View className="flex items-center">
<View
className="flex h-8 w-8 items-center justify-center rounded-l bg-gray-200"
onClick={() => {
const newCount = Math.max(
0,
currentCount - 1,
);
updateEditingItemCount(
specId,
detailIndex,
newCount,
);
}}
>
<Icon name="minus" size={16} />
</View>
<View className="flex h-8 w-12 items-center justify-center border-y border-gray-200">
<Input
type="number"
value={currentCount.toString()}
align={"center"}
className="!h-8 !w-12 !p-0 !text-center"
onChange={(value) => {
const num = Number(value);
if (!Number.isNaN(num) && num >= 0) {
updateEditingItemCount(
specId,
detailIndex,
num,
);
}
}}
/>
</View>
<View
className="flex h-8 w-8 items-center justify-center rounded-r bg-gray-200"
onClick={() => {
updateEditingItemCount(
specId,
detailIndex,
currentCount + 1,
);
}}
>
<Icon name="plus" size={16} />
</View>
<View className="ml-2 font-medium text-gray-800">
</View>
</View>
</View>
);
})}
</View>
</View>
))}
</View>
</View>
</ScrollView>
{/* 底部按钮 */}
<View className="flex gap-2 pt-4">
<View className="flex-1">
<Button
size={"large"}
type={"default"}
block
onClick={() => setShowEditModal(false)}
>
</Button>
</View>
<View className="flex-1">
<Button
type="primary"
size={"large"}
block
onClick={saveEditedItem}
>
</Button>
</View>
</View>
<SafeArea position={"bottom"} />
</View>
</Popup>
);
};
// 获取空箱列表
const emptyBoxes = convertOrderPackagesToBoxBrands(emptyBoxList);
// 新增状态:跟踪每种纸箱类型的启用状态
// 0: 未选, 1: 选择是, 2: 选择否
const [packageTypeEnabled, setPackageTypeEnabled] = useState({
EMPTY: 0,
});
// 处理纸箱类型启用状态切换
const togglePackageType = (
type: BusinessAPI.OrderPackage["boxType"],
value: number, // 0: 未选, 1: 选择是, 2: 选择否
) => {
setPackageTypeEnabled((prev) => ({
...prev,
[type]: value,
}));
};
console.log("orderPackageList", orderPackageList);
return (
<View className={"flex flex-1 flex-col gap-2.5"}>
<View className="flex flex-col gap-2.5 rounded-lg bg-white p-2.5 shadow-sm">
<View className="bg-primary/10 flex flex-col gap-2.5 rounded-lg p-2.5 text-sm text-gray-600">
<View className="flex flex-col gap-2.5">
<View className="flex items-center justify-between">
<View className="text-sm"></View>
<View className="block text-sm font-normal text-[#000000]">
</View>
<View className="flex flex-row items-center">
<Checkbox
className={"flex flex-row items-center"}
checked={packageTypeEnabled.EMPTY === 1}
checked={hasEmptyBox}
onChange={(checked) => {
togglePackageType("EMPTY", checked ? 1 : 0);
setHasEmptyBox(checked);
if (!checked) {
setEmptyBoxList([]);
onChange([]);
}
}}
>
<View className={"text-sm font-normal text-[#000000]"}></View>
<View className={"text-sm font-normal text-[#000000]"}>
</View>
</Checkbox>
</View>
</View>
{/* 空箱信息展示 */}
{packageTypeEnabled.EMPTY === 1 && (
<View>
{emptyBoxes.length > 0 ? (
emptyBoxes.map((item) => renderEmptyBoxItem(item))
) : (
<View className="mb-4 rounded-lg bg-gray-50 p-4 text-center text-gray-500">
</View>
)}
<Button
icon={<Icon name={"plus"} size={20} />}
type={"primary"}
size={"large"}
fill={"outline"}
block
className="border-primary text-primary flex w-full items-center justify-center !border-2 !bg-white"
onClick={() => {
setShowBatchModal(true);
}}
>
<View></View>
</Button>
</View>
{hasEmptyBox && (
<PackageList
boxType={"EMPTY"}
orderPackageList={orderPackageList}
setOrderPackageList={onChange}
boxBrandList={boxBrandList}
/>
)}
</View>
{/* 批量添加弹窗 */}
{renderBatchAddModal()}
{/* 编辑弹窗 */}
{renderEditModal()}
</View>
</View>
);
}

View File

@ -595,7 +595,7 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
{/* 只有最后一个瓜农才显示是否为最后一个瓜农的选项和添加按钮 */}
{isLast && (
<View className="rounded-lg 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 items-center justify-between">
{supplierCount > 1 ? (
<View className="text-sm"></View>
@ -711,7 +711,7 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
</View>
{/* 瓜农信息 */}
<View className="rounded-lg bg-white p-2.5 shadow-sm">
<View className="border-primary rounded-lg border-4 bg-white p-2.5 shadow-sm">
<View className="mb-2.5">
<View className="flex items-center justify-between">
<View className={"text-primary text-sm font-bold"}>
@ -910,7 +910,7 @@ export default forwardRef<MelonFarmerRef, IMelonFarmerProps>(
</View>
{/* 若瓜农无法开发票,则可打款到微信 */}
<View className="rounded-lg 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 w-full border-gray-300`}>
<Uploader
className={"w-full"}

View File

@ -3,6 +3,7 @@ import { Icon } from "@/components";
import { forwardRef, useEffect, useImperativeHandle, useState } from "react";
import { Checkbox, Input, Toast } from "@nutui/nutui-react-taro";
import { generateShortId } from "@/utils";
import { business } from "@/services";
// 定义ref暴露的方法接口
export interface OrderCostRef {
@ -21,11 +22,14 @@ export default forwardRef<OrderCostRef, IOrderCostProps>(
const { value, onChange } = props;
const { orderSupplierList, orderCostList } = value;
console.log("orderCostList", orderCostList);
const supplierVO = orderSupplierList[orderSupplierList.length - 1];
const costTemplate = supplierVO?.costTemplate;
const costIds = supplierVO?.costIds;
console.log("costIds", costIds);
// 解析costTemplate为JSON对象
const parsedCostTemplate = JSON.parse(costTemplate || "[]");
console.log("parsedCostTemplate", parsedCostTemplate);
// 初始化函数
const init = async (costIds: string[]) => {
@ -43,7 +47,7 @@ export default forwardRef<OrderCostRef, IOrderCostProps>(
// 遍历costList将costList中的项目添加到orderCostList中
parsedCostTemplate.productionTypeList?.forEach((item) => {
const existingItem = orderCostMap.get(item.costItemId);
const existingItem = orderCostMap.get(item.costId);
if (existingItem) {
newOrderCostList.push({
@ -62,6 +66,44 @@ export default forwardRef<OrderCostRef, IOrderCostProps>(
price: item.price || 0,
unit: item.unit || "元",
});
orderCostMap.set(item.costId, {
orderCostId: generateShortId(),
costItemIds: item.costItemIds,
costId: item.costId,
name: item.name,
type: item.type,
selected: false,
count: 1,
price: item.price || 0,
unit: item.unit || "元",
});
}
});
const { data } = await business.cost.listCost({
costListQry: {
status: true,
},
});
data.data?.forEach((item) => {
if (
item.costId &&
costIds?.includes(item.costId) &&
!newOrderCostList.some((cost) => cost.costId === item.costId)
) {
newOrderCostList.push({
orderCostId: generateShortId(),
costItemIds: item.costItemIds,
costId: item.costId,
name: item.name,
type: item.type,
selected: false,
count: 1,
price: item.price || 0,
unit: item.unit || "元",
});
}
});
@ -163,8 +205,12 @@ export default forwardRef<OrderCostRef, IOrderCostProps>(
const orderCostId = currentItem?.orderCostId || generateShortId();
return (
<View key={index}>
<View className={"flex flex-col gap-2.5 rounded-lg bg-white p-2.5"}>
<View
key={index}
className={
"bg-primary/10 flex flex-col gap-2.5 rounded-lg p-2.5 text-sm text-gray-600"
}
>
<View className={"flex flex-row justify-between"}>
<View className="block text-sm font-normal text-[#000000]">
{item.name}
@ -214,19 +260,19 @@ export default forwardRef<OrderCostRef, IOrderCostProps>(
</View>
)}
</View>
</View>
);
});
};
return (
<View className="flex flex-1 flex-col gap-2.5 bg-[#D1D5DB] p-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={"flex flex-1 flex-col gap-2.5"}>
<View className="text-sm font-bold"></View>
<View className="flex items-center rounded-lg border border-blue-200 bg-blue-50 p-2.5">
<Icon
className={"mr-1"}
className={"mr-1 leading-4"}
name="circle-info"
color={"var(--color-blue-700)"}
size={18}
@ -236,6 +282,7 @@ export default forwardRef<OrderCostRef, IOrderCostProps>(
{renderItemList(parsedCostTemplate.productionTypeList)}
</View>
</View>
</View>
);
},
);

View File

@ -302,6 +302,19 @@ export default forwardRef<OrderCostItemRef, IOrderCostItemProps>(
onChange?.({
...value,
orderPackageList,
orderCostItemList: orderCostItemList?.map((item1) =>
item1.costItemId === item.costItemId
? {
...item1,
selected,
price: orderPackageList.reduce(
(sum, item) =>
sum + (item.boxSalePrice || 0) * item.boxCount,
0,
),
}
: item1,
),
});
}}
/>
@ -309,8 +322,12 @@ export default forwardRef<OrderCostItemRef, IOrderCostItemProps>(
}
return (
<View key={index}>
<View className={"flex flex-col gap-2.5 rounded-lg bg-white p-2.5"}>
<View
key={index}
className={
"bg-primary/10 flex flex-col gap-2.5 rounded-lg p-2.5 text-sm text-gray-600"
}
>
<View className={"flex flex-row justify-between"}>
<View className="block text-sm font-normal text-[#000000]">
{item.name}
@ -456,9 +473,7 @@ export default forwardRef<OrderCostItemRef, IOrderCostItemProps>(
onBlur={() => validateCount(orderCostItemId, price)}
/>
</View>
<View className={"ml-2.5 text-sm text-gray-500"}>
</View>
<View className={"ml-2.5 text-sm text-gray-500"}></View>
</View>
</View>
@ -470,7 +485,6 @@ export default forwardRef<OrderCostItemRef, IOrderCostItemProps>(
</View>
)}
</View>
</View>
);
});
};
@ -488,29 +502,28 @@ export default forwardRef<OrderCostItemRef, IOrderCostItemProps>(
};
return (
<View className="flex flex-1 flex-col gap-2.5 bg-[#D1D5DB] p-2.5 pt-2.5">
<View className={"flex flex-1 flex-col gap-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={"flex flex-col gap-2.5"}>
<View className="text-sm font-bold"></View>
<View className="flex items-center rounded-lg border border-blue-200 bg-blue-50 p-2.5">
<Icon
className={"mr-1"}
className={"mr-1 leading-4"}
name="circle-info"
color={"var(--color-blue-700)"}
size={18}
/>
<View className={"text-sm text-blue-700"}></View>
<View className={"text-sm text-blue-700"}>
</View>
</View>
{renderItemList(
getItemsByCostType("ARTIFICIAL_TYPE"),
"ARTIFICIAL_TYPE",
)}
{/* 总的工头姓名输入框 */}
{shouldShowPrincipalInput() && (
<View>
<View className="mb-1 text-sm font-medium"></View>
<View className="flex flex-col gap-2.5">
<View className="text-sm font-medium"></View>
<View
className={`flex h-12 items-center rounded-md px-3 ${foremanError ? "border-2 border-red-500 bg-red-100" : "border-2 border-gray-300 bg-white"}`}
className={`flex h-12 items-center rounded-md ${foremanError ? "border-2 border-red-500 bg-red-100" : "border-2 border-gray-300 bg-white"}`}
>
<Input
className="text-base"
@ -530,12 +543,19 @@ export default forwardRef<OrderCostItemRef, IOrderCostItemProps>(
)}
</View>
)}
{renderItemList(
getItemsByCostType("ARTIFICIAL_TYPE"),
"ARTIFICIAL_TYPE",
)}
</View>
<View className={"flex flex-1 flex-col gap-2.5"}>
</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-sm font-bold"></View>
<View className="flex items-center rounded-lg border border-blue-200 bg-blue-50 p-2.5">
<Icon
className={"mr-1"}
className={"mr-1 leading-4"}
name="circle-info"
color={"var(--color-blue-700)"}
size={18}
@ -543,7 +563,11 @@ export default forwardRef<OrderCostItemRef, IOrderCostItemProps>(
<View className={"text-sm text-blue-700"}></View>
</View>
{/* 渲染辅料费用项(不含纸箱) */}
{renderItemList(getItemsByCostType("MATERIAL_TYPE"), "MATERIAL_TYPE")}
{renderItemList(
getItemsByCostType("MATERIAL_TYPE"),
"MATERIAL_TYPE",
)}
</View>
</View>
</View>
);

View File

@ -168,8 +168,10 @@ export default forwardRef<OrderOptionRef, IOrderOptionProps>(
orderId: value.orderId,
active: Number(active + 1),
foreman: value.foreman,
orderCostList: value.orderCostList,
// 空箱
orderPackageList: value.orderPackageList,
// 费用
orderCostList: value.orderCostList.filter((item) => item.selected),
orderCostItemList: value.orderCostItemList.filter(
(item) => item.selected,
),

View File

@ -45,21 +45,18 @@ export default forwardRef<OrderPackageRef, IOrderPackageProps>(
if (supplierVO.isPaper && supplierVO.isLast) {
setPackageTypeEnabled({
USED: usageMap["USED"] || 0,
EXTRA: 0,
EXTRA_USED: usageMap["EXTRA_USED"] || 0,
REMAIN: usageMap["REMAIN"] || 0,
});
} else if (supplierVO.isPaper && !supplierVO.isLast) {
setPackageTypeEnabled({
USED: usageMap["USED"] || 0,
EXTRA: usageMap["EXTRA"] || 0,
EXTRA_USED: 0,
REMAIN: 0,
});
} else if (!supplierVO.isPaper) {
setPackageTypeEnabled({
USED: usageMap["USED"] || 0,
EXTRA: 0,
EXTRA_USED: 0,
REMAIN: 0,
@ -100,16 +97,13 @@ export default forwardRef<OrderPackageRef, IOrderPackageProps>(
// 确定当前供应商需要检查哪些纸箱类型
if (supplierVO.isPaper && supplierVO.isLast) {
// 空磅包含纸箱 + 最后一个瓜农
requiredTypes = ["USED", "EXTRA_USED", "REMAIN"];
requiredTypes = ["EXTRA_USED", "REMAIN"];
} else if (supplierVO.isPaper && !supplierVO.isLast) {
requiredTypes = ["USED", "EXTRA"];
} else if (!supplierVO.isPaper) {
// 空磅不包含纸箱
requiredTypes = ["USED"];
requiredTypes = ["EXTRA"];
}
console.log("requiredTypes", requiredTypes);
if (requiredTypes.length > 0) {
// 检查所需选项是否都已做出选择不是1就是2不能是0
const allRequiredAnswered = requiredTypes.every(
(type) =>
@ -124,6 +118,9 @@ export default forwardRef<OrderPackageRef, IOrderPackageProps>(
});
return false;
}
}
requiredTypes.push("USED");
// 检查所有启用的纸箱类型是否都填写了信息
const enabledTypes = Object.entries(packageTypeEnabled)
@ -141,9 +138,7 @@ export default forwardRef<OrderPackageRef, IOrderPackageProps>(
if (!hasPackagesOfType) {
const typeLabels = {
USED: "记录装车用的纸箱",
EXTRA_USED: supplierVO.isPaper
? "记录用的额外运输纸箱"
: "记录装车用的纸箱",
EXTRA_USED: "记录用的额外运输纸箱",
EXTRA: "记录额外运输来的所有纸箱",
REMAIN: "记录车上没用完的纸箱",
};
@ -250,7 +245,6 @@ export default forwardRef<OrderPackageRef, IOrderPackageProps>(
// 新增状态:跟踪每种纸箱类型的启用状态
// 0: 未选, 1: 选择是, 2: 选择否
const [packageTypeEnabled, setPackageTypeEnabled] = useState({
USED: 0,
EXTRA_USED: 0,
EXTRA: 0,
REMAIN: 0,
@ -269,7 +263,6 @@ export default forwardRef<OrderPackageRef, IOrderPackageProps>(
packageUsage: [
...(Object.entries(
packageTypeEnabled || {
USED: 0,
EXTRA_USED: 0,
EXTRA: 0,
REMAIN: 0,
@ -297,7 +290,8 @@ export default forwardRef<OrderPackageRef, IOrderPackageProps>(
return (
<View className="flex flex-1 flex-col gap-2.5 p-2.5">
{/* 替换原来的Tab导航为问答式选择 */}
<View className="flex flex-col gap-2.5 rounded-lg 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="text-base font-bold">
{supplierVO.name}使
</View>
@ -309,11 +303,13 @@ export default forwardRef<OrderPackageRef, IOrderPackageProps>(
boxBrandList={boxBrandList}
/>
</View>
</View>
{/* 根据供应商属性显示不同的问题 */}
{supplierVO.isPaper && supplierVO.isLast && (
<>
<View className="flex flex-col gap-2.5 rounded-lg 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 items-center justify-between">
<View className="text-sm"></View>
@ -366,8 +362,10 @@ export default forwardRef<OrderPackageRef, IOrderPackageProps>(
/>
)}
</View>
</View>
<View className="flex flex-col gap-2.5 rounded-lg 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 items-center justify-between">
<View className="text-sm"></View>
@ -424,19 +422,23 @@ export default forwardRef<OrderPackageRef, IOrderPackageProps>(
/>
)}
</View>
</View>
</>
)}
{supplierVO.isPaper && !supplierVO.isLast && (
/* 非最后一个瓜农 */
<View className="flex flex-col gap-2.5 rounded-lg 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 items-center justify-between">
<View className="text-sm"></View>
<View className="flex flex-shrink-0 gap-2">
<Button
size="small"
type={packageTypeEnabled.EXTRA === 1 ? "primary" : "default"}
type={
packageTypeEnabled.EXTRA === 1 ? "primary" : "default"
}
onClick={() => {
setPackageTypeEnabled({
...packageTypeEnabled,
@ -448,7 +450,9 @@ export default forwardRef<OrderPackageRef, IOrderPackageProps>(
</Button>
<Button
size="small"
type={packageTypeEnabled.EXTRA === 2 ? "primary" : "default"}
type={
packageTypeEnabled.EXTRA === 2 ? "primary" : "default"
}
onClick={() => {
setPackageTypeEnabled({
...packageTypeEnabled,
@ -478,17 +482,6 @@ export default forwardRef<OrderPackageRef, IOrderPackageProps>(
/>
)}
</View>
)}
{!supplierVO.isPaper && (
/* 空磅不包含纸箱 */
<View className="rounded-lg bg-white p-2.5 shadow-sm">
<PackageList
boxType={"USED"}
orderPackageList={orderPackageList}
setOrderPackageList={setOrderPackageList}
boxBrandList={boxBrandList}
/>
</View>
)}
</View>

View File

@ -535,7 +535,8 @@ export default forwardRef<OrderVehicleRef, IOrderVehicleProps>(
return (
<View className="flex flex-1 flex-col gap-2.5 p-2.5">
<View className="flex flex-col gap-2.5 rounded-lg 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-1 flex-col gap-2.5"}>
<View className="block text-sm font-normal text-[#000000]">
@ -618,7 +619,9 @@ export default forwardRef<OrderVehicleRef, IOrderVehicleProps>(
)}
</View>
</View>
<View className="flex flex-col gap-2.5 rounded-lg bg-white p-2.5 shadow-sm">
</View>
<View className="border-primary rounded-lg border-4 bg-white p-2.5 shadow-sm">
<View className="flex flex-col gap-2.5">
<View className={"flex flex-col gap-2.5"}>
<View className="block text-sm font-normal text-[#000000]">
@ -835,14 +838,18 @@ export default forwardRef<OrderVehicleRef, IOrderVehicleProps>(
>
<View className={"text-sm"}>
{orderVehicle?.deliveryTime
? dayjs(orderVehicle?.deliveryTime).format("YYYY年MM月DD日")
? dayjs(orderVehicle?.deliveryTime).format(
"YYYY年MM月DD日",
)
: "请选择发货时间"}
</View>
<Icon name={"chevron-down"} />
</View>
</View>
{deliveryTimeError && (
<View className="mt-1 text-xs text-red-500"></View>
<View className="mt-1 text-xs text-red-500">
</View>
)}
<DatePicker
title="发货时间选择"
@ -858,6 +865,7 @@ export default forwardRef<OrderVehicleRef, IOrderVehicleProps>(
</View>
</View>
</View>
</View>
);
},
);

View File

@ -49,7 +49,7 @@ export default function PackageCard(props: IPackageCardProps) {
return (
<View
className="mb-2.5 overflow-hidden rounded-xl border border-gray-200 bg-white p-2.5 shadow-sm"
className="overflow-hidden rounded-xl border border-gray-200 bg-white p-2.5 shadow-sm"
key={boxBrand.id}
>
{/* 品牌背景水印 */}

View File

@ -21,7 +21,7 @@ export default function PackageList(props: IPackageListProps) {
// 获取该类型下所有的纸箱
const packagesOfType = convertOrderPackagesToBoxBrands(
orderPackageList.filter((pkg) => pkg.boxType === boxType),
orderPackageList?.filter((pkg) => pkg.boxType === boxType),
);
// 根据类型设置显示标题
@ -30,6 +30,7 @@ export default function PackageList(props: IPackageListProps) {
EXTRA_USED: "用的额外运输纸箱",
EXTRA: "额外运输来的所有纸箱",
REMAIN: "车上没用完的纸箱",
EMPTY: "空箱",
};
if (!boxBrandList) {
@ -37,8 +38,8 @@ export default function PackageList(props: IPackageListProps) {
}
return (
<View key={boxType} className="mb-2.5">
<View className="mb-3 flex items-center justify-between">
<>
<View className="flex items-center justify-between">
<View className="text-base font-bold text-gray-800">
{typeLabels[boxType]}
</View>
@ -56,7 +57,7 @@ export default function PackageList(props: IPackageListProps) {
/>
))
) : (
<View className="mb-4 rounded-lg bg-gray-50 p-4 text-center text-gray-500">
<View className="rounded-lg bg-gray-50 p-4 text-center text-gray-500">
{typeLabels[boxType]}
</View>
)}
@ -83,6 +84,6 @@ export default function PackageList(props: IPackageListProps) {
onClose={() => setShowBatchModal(false)}
onSave={setOrderPackageList}
/>
</View>
</>
);
}

View File

@ -41,7 +41,6 @@ export default hocAuth(function Page(props: CommonComponent) {
) => {
if (!menus || menus.length === 0) return null;
console.log("level", level);
if (level === 1) {
return (
<View className="grid grid-cols-4">

View File

@ -6,6 +6,7 @@ import { Button, SafeArea, Toast } from "@nutui/nutui-react-taro";
import Taro from "@tarojs/taro";
import { business } from "@/services";
import { buildUrl } from "@/utils";
import { CopyText } from "@/components";
export default hocAuth(function Page(props: CommonComponent) {
const { router, setLoading } = props;
@ -123,9 +124,11 @@ export default hocAuth(function Page(props: CommonComponent) {
<View className="mb-2.5 flex flex-col gap-2.5">
<View className="flex flex-row justify-between">
<Text className="text-sm text-gray-600">:</Text>
<CopyText copyData={purchaseOrder?.orderSn || "-"}>
<Text className="text-sm font-medium">
{purchaseOrder?.orderSn || "-"}
</Text>
</CopyText>
</View>
<View className="flex flex-row justify-between">

View File

@ -33,6 +33,7 @@ import {
PurchaseFormSection,
RebateCalcSection,
State,
SupplierInfoSection,
TaxProvisionSection,
TaxSubsidySection,
WorkerAdvanceSection,
@ -40,108 +41,169 @@ import {
import { buildUrl, formatCurrency, PurchaseOrderCalculator } from "@/utils";
import classNames from "classnames";
const sections = {
const defaultSections = [
"marketPrice",
"supplierInfo",
"dealerInfo",
"basicInfo",
"packageInfo",
"emptyBoxInfo",
"foremanAdvance",
"materialCost",
"originAdvance",
"otherCost",
"productionLoss",
"taxSubsidy",
"taxProvision",
"costDifference",
"costSummary",
"rebateCalc",
"deliveryForm",
];
const xylSections = [
"marketPrice",
"supplierInfo",
"dealerInfo",
"basicInfo",
"purchaseCostInfo",
"purchaseForm",
"packageInfo",
"emptyBoxInfo",
"foremanAdvance",
"materialCost",
"originAdvance",
"otherCost",
"productionLoss",
"taxSubsidy",
"taxProvision",
"costDifference",
"costSummary",
"rebateCalc",
];
const fullSections = [
// 市场报价
marketPrice: {
{
name: "marketPrice",
component: MarketPriceSection,
title: "市场报价",
},
// 我方入账公司
supplierInfo: {
{
name: "supplierInfo",
component: CompanyInfoSection,
title: "我方入账公司",
},
// 下游经销商信息
dealerInfo: {
{
name: "dealerInfo",
component: DealerInfoSection,
title: "下游经销商",
},
// 基础信息
basicInfo: {
{
name: "basicInfo",
component: BasicInfoSection,
title: "基础信息",
},
// // 瓜农信息
// farmerInfo: {
// component: SupplierInfoSection,
// title: "瓜农信息",
// },
// 瓜农信息
{
name: "farmerInfo",
component: SupplierInfoSection,
title: "瓜农信息",
},
// 采购成本
purchaseCostInfo: {
{
name: "purchaseCostInfo",
component: PurchaseCostInfoSection,
title: "采购成本复核",
},
// 分单发货复核
purchaseForm: {
{
name: "purchaseForm",
component: PurchaseFormSection,
title: "分单发货复核",
},
// 包装纸箱费
packageInfo: {
{
name: "packageInfo",
component: PackageInfoSection,
title: "包装纸箱费复核",
},
// 空箱费用
emptyBoxInfo: {
{
name: "emptyBoxInfo",
component: EmptyBoxInfoSection,
title: "空箱费用复核",
},
// 人工费用复核
foremanAdvance: {
{
name: "foremanAdvance",
component: WorkerAdvanceSection,
title: "人工费用复核",
},
// 辅料费用复核
materialCost: {
{
name: "materialCost",
component: MaterialCostSection,
title: "辅料费复核",
},
// 产地费用复核
originAdvance: {
{
name: "originAdvance",
component: ProductionAdvanceSection,
title: "产地费用复核",
},
// 其他费用复核
otherCost: {
{
name: "otherCost",
component: PackagingCostSection,
title: "其他费用复核",
},
// 产地损耗复核
productionLoss: {
{
name: "productionLoss",
component: ProductionLossSection,
title: "产地损耗复核",
},
// 公司返点复核
taxSubsidy: {
{
name: "taxSubsidy",
component: TaxSubsidySection,
title: "公司返点复核",
},
// 计提税金复核
taxProvision: {
{
name: "taxProvision",
component: TaxProvisionSection,
title: "计提税金复核",
},
// 调诚信志远分红
costDifference: {
{
name: "costDifference",
component: CostDifferenceSection,
title: "调诚信志远分红",
},
// 成本合计
costSummary: {
{
name: "costSummary",
component: CostSummarySection,
title: "成本合计",
},
// 个人返点复核
rebateCalc: {
{
name: "rebateCalc",
component: RebateCalcSection,
title: "个人返点复核",
},
// 发货单复核
deliveryForm: {
{
name: "deliveryForm",
component: DeliveryFormSection,
title: "发货单复核",
},
};
];
export default hocAuth(function Page(props: CommonComponent) {
const { router, isInitialized, setIsInitialized, userRoleVO, setLoading } =
@ -417,6 +479,11 @@ export default hocAuth(function Page(props: CommonComponent) {
const calculator = new PurchaseOrderCalculator(purchaseOrderVO, true);
const personalProfit = calculator.getPersonalProfit();
const sections =
purchaseOrderVO.orderDealer.shortName === "信誉楼"
? xylSections
: defaultSections;
return (
<>
<View
@ -475,8 +542,15 @@ export default hocAuth(function Page(props: CommonComponent) {
</View>
{/* 循环渲染各部分内容 */}
{Object.keys(sections).map((sectionKey) => {
const section = sections[sectionKey];
{sections.map((sectionKey) => {
const section = fullSections.find(
(section) => section.name === sectionKey,
);
if (!section) {
return null;
}
const orderDealer = purchaseOrderVO.orderDealer;
if (
@ -538,6 +612,7 @@ export default hocAuth(function Page(props: CommonComponent) {
readOnly={purchaseOrderVO.state !== "WAITING_AUDIT"}
purchaseOrderVO={purchaseOrderVO}
onChange={setPurchaseOrderVO}
//@ts-ignore
costList={costList}
calculator={calculator}
/>

View File

@ -6,6 +6,7 @@ import { Button, SafeArea, Toast } from "@nutui/nutui-react-taro";
import Taro from "@tarojs/taro";
import { business } from "@/services";
import { buildUrl } from "@/utils";
import { CopyText } from "@/components";
export default hocAuth(function Page(props: CommonComponent) {
const { router, setLoading } = props;
@ -81,9 +82,11 @@ export default hocAuth(function Page(props: CommonComponent) {
<View className="mb-2.5 flex flex-col gap-2.5">
<View className="flex flex-row justify-between">
<Text className="text-sm text-gray-600">:</Text>
<CopyText copyData={purchaseOrder?.orderSn || "-"}>
<Text className="text-sm font-medium">
{purchaseOrder?.orderSn || "-"}
</Text>
</CopyText>
</View>
<View className="flex flex-row justify-between">

View File

@ -114,6 +114,7 @@ export default hocAuth(function Page(props: CommonComponent) {
// 如果订单状态不是草稿,则跳转到预览页面
if (
purchaseOrder.state !== "DRAFT" &&
purchaseOrder.state !== "REJECTED" &&
userRoleVO.slug === "origin-entry"
) {
Taro.redirectTo({
@ -411,6 +412,7 @@ export default hocAuth(function Page(props: CommonComponent) {
...prev!,
foreman: purchaseOrder.foreman,
orderCostItemList: purchaseOrder.orderCostItemList,
orderPackageList: purchaseOrder.orderPackageList,
};
});
}}
@ -437,7 +439,7 @@ export default hocAuth(function Page(props: CommonComponent) {
!purchaseOrder?.orderSupplierList[
purchaseOrder?.orderSupplierList.length - 1
]?.isLast && (
<View className="flex flex-1 flex-col gap-2.5 bg-[#D1D5DB] p-2.5 pt-2.5">
<View className="flex flex-1 flex-col gap-2.5 bg-[#D1D5DB] p-2.5">
<View className={"flex flex-1 flex-col gap-2.5"}>
<View className="text-sm font-bold"></View>
<Button

View File

@ -6,6 +6,7 @@ import { Button, SafeArea, Toast } from "@nutui/nutui-react-taro";
import Taro from "@tarojs/taro";
import { business } from "@/services";
import { buildUrl } from "@/utils";
import { CopyText } from "@/components";
export default hocAuth(function Page(props: CommonComponent) {
const { router, setLoading } = props;
@ -81,9 +82,11 @@ export default hocAuth(function Page(props: CommonComponent) {
<View className="mb-2.5 flex flex-col gap-2.5">
<View className="flex flex-row justify-between">
<Text className="text-sm text-gray-600">:</Text>
<CopyText copyData={purchaseOrder?.orderSn || "-"}>
<Text className="text-sm font-medium">
{purchaseOrder?.orderSn || "-"}
</Text>
</CopyText>
</View>
<View className="flex flex-row justify-between">

View File

@ -1,11 +1,5 @@
import { View } from "@tarojs/components";
import {
Button,
Input,
Toast,
Uploader,
UploaderFileItem,
} from "@nutui/nutui-react-taro";
import { Button, Input, Toast, Uploader, UploaderFileItem } from "@nutui/nutui-react-taro";
import { Icon } from "@/components";
import hocAuth from "@/hocs/auth";
import { CommonComponent } from "@/types/typings";
@ -368,7 +362,7 @@ export default hocAuth(function Page(props: CommonComponent) {
{/* 功能提醒 */}
<View className="flex items-center rounded-lg border border-blue-200 bg-blue-50 p-2.5">
<Icon
className={"mr-1"}
className={"mr-1 leading-4"}
name="circle-info"
color={"var(--color-blue-700)"}
size={18}

View File

@ -913,7 +913,7 @@ declare namespace BusinessAPI {
/** 状态1_启用0_禁用 */
status: boolean;
/** 成本项ID */
costItemIds?: number[];
costItemIds?: string[];
};
type CostDestroyCmd = {
@ -1123,7 +1123,7 @@ declare namespace BusinessAPI {
/** 状态1_启用0_禁用 */
status: boolean;
/** 成本项ID */
costItemIds?: number[];
costItemIds?: string[];
};
type CostVO = {
@ -1150,7 +1150,7 @@ declare namespace BusinessAPI {
/** 状态1_启用0_禁用 */
status: boolean;
/** 项目id集合 */
costItemIds?: number[];
costItemIds?: string[];
/** 创建时间 */
createdAt?: string;
/** 项目列表 */
@ -2648,7 +2648,7 @@ declare namespace BusinessAPI {
| "PRODUCTION_TYPE"
| "OTHER_TYPE";
/** 关联项目id */
costItemIds?: number[];
costItemIds?: string[];
/** 是否选中 */
selected: boolean;
};