import { ScrollView, View } from "@tarojs/components";
import {
Button,
Input,
Picker,
Popup,
SafeArea,
} from "@nutui/nutui-react-taro";
import { useEffect, useState } from "react";
import { Icon } from "@/components";
import { formatCurrency, validatePrice } from "@/utils/format";
import { generateShortId } from "@/utils/generateShortId";
export default function PackagingCostSection(props: {
purchaseOrderVO: BusinessAPI.PurchaseOrderVO;
costItemVOList: BusinessAPI.CostItemVO[];
onChange?: (purchaseOrderVO: BusinessAPI.PurchaseOrderVO) => void;
readOnly?: boolean;
}) {
const { purchaseOrderVO, onChange, readOnly, costItemVOList } = props;
// 弹窗相关状态
const [visiblePopup, setVisiblePopup] = useState<{ [key: string]: boolean }>(
{},
);
// 新增包装费弹窗状态
const [showAddCostPopup, setShowAddCostPopup] = useState(false);
// 新增包装费表单数据
const [newCostData, setNewCostData] = useState({
costType: "FIXED_COST", // 费用类型
itemId: "", // 费用项目ID
name: "", // 费用名称
quantity: 0, // 数量(人数)
unit: "", // 单位
unitPrice: "", // 单价
amount: "", // 金额
payerType: "US", // 费用承担方,默认我方
principal: "", // 工头姓名
requireQuantityAndPrice: false,
});
// Picker可见状态
const [pickerVisible, setPickerVisible] = useState({
costType: false, // 费用类型Picker
costItem: false, // 费用项目Picker
fixedCost: false, // 固定费用Picker
});
// 编辑值的状态
const [editValues, setEditValues] = useState<{
[key: string]: {
count: number;
price: number;
name?: string;
principal?: string;
payerType?: "US" | "OTHER";
};
}>({});
// 临时编辑值的状态(用于在保存前暂存编辑的值)
const [tempEditValues, setTempEditValues] = useState<{
[key: string]: {
count: number;
price: number;
name?: string;
principal?: string;
payerType?: "US" | "OTHER";
};
}>({});
// 初始化编辑值
const initEditValues = (
itemId: string,
count: number,
price: number,
name?: string,
principal?: string,
payerType?: "US" | "OTHER",
) => {
if (!editValues[itemId]) {
setEditValues((prev) => ({
...prev,
[itemId]: { count, price, name, principal, payerType },
}));
}
// 同时初始化临时编辑值
if (!tempEditValues[itemId]) {
setTempEditValues((prev) => ({
...prev,
[itemId]: { count, price, name, principal, payerType },
}));
}
};
// 费用类型选项
const costTypeOptions = [
{ label: "固定费用", value: "FIXED_COST" },
{ label: "其他费用", value: "OTHER_COST" },
];
// 固定费用
const fixedCosts =
purchaseOrderVO.orderCostList?.filter(
(item) => item.costType === "FIXED_COST",
) || [];
// 其他费用
const otherCosts =
purchaseOrderVO.orderCostList?.filter(
(item) => item.costType === "OTHER_COST",
) || [];
// 检查是否存在计提费,如果不存在则添加一个默认的计提费
useEffect(() => {
if (onChange) {
// 检查是否已存在计提费
const accrualFeeItem = costItemVOList.find(
(item) => item.name === "计提费" && item.costType === "FIXED_COST",
);
const hasAccrualFee = fixedCosts.some((item) => item.name === "计提费");
if (!hasAccrualFee && accrualFeeItem) {
// 创建默认计提费
const defaultAccrualFee: BusinessAPI.OrderCost = {
itemId: accrualFeeItem.itemId,
orderCostId: generateShortId(),
name: "计提费",
costType: "FIXED_COST",
price: 0,
count: 1,
unit: "项",
payerType: "US",
requireQuantityAndPrice: false,
};
// 更新purchaseOrderVO,添加默认计提费
const updatedOrderCostList = [
...(purchaseOrderVO.orderCostList || []),
defaultAccrualFee,
];
const newPurchaseOrderVO = {
...purchaseOrderVO,
orderCostList: updatedOrderCostList,
};
onChange(newPurchaseOrderVO as any);
}
}
}, [purchaseOrderVO.orderCostList, onChange, fixedCosts]);
// 当editValues发生变化时,更新purchaseOrderVO
useEffect(() => {
// 只有当onChange存在时才更新
if (onChange) {
// 获取现有的orderCostList
const existingOrderCostList = purchaseOrderVO.orderCostList || [];
// 更新已有的成本项
const updatedOrderCostList = existingOrderCostList.map((item) => {
if (editValues[item.orderCostId]) {
return {
...item,
price:
editValues[item.orderCostId].price !== undefined
? editValues[item.orderCostId].price
: item.price,
count:
editValues[item.orderCostId].count !== undefined
? editValues[item.orderCostId].count
: item.count,
name:
editValues[item.orderCostId].name !== undefined
? editValues[item.orderCostId].name
: item.name,
principal:
editValues[item.orderCostId].principal !== undefined
? editValues[item.orderCostId].principal
: item.principal,
payerType:
editValues[item.orderCostId].payerType !== undefined
? editValues[item.orderCostId].payerType
: item.payerType,
};
}
// 未修改的成本项保持原样
return item;
});
// 创建新的purchaseOrderVO对象
const newPurchaseOrderVO = {
...purchaseOrderVO,
orderCostList: updatedOrderCostList,
};
// 调用onChange回调
onChange(newPurchaseOrderVO as any);
}
}, [editValues]);
return (
<>
{/* 固定费用 */}
{fixedCosts.map((item, index) => {
// 初始化编辑值
initEditValues(item.orderCostId, item.count, item.price);
return (
setVisiblePopup((prev) => ({
...prev,
[item.orderCostId]: true,
}))
}
>
{index + 1}-{item.name}
{formatCurrency(
Number(
(editValues[item.orderCostId]?.price || item.price) *
(editValues[item.orderCostId]?.count || item.count),
),
)}
{!readOnly && (
)}
);
})}
{/* 其他费用 */}
{otherCosts.map((item, index) => {
// 初始化编辑值
initEditValues(
item.orderCostId,
item.count,
item.price,
item.name,
item.principal,
);
return (
setVisiblePopup((prev) => ({
...prev,
[item.orderCostId]: true,
}))
}
>
{fixedCosts.length + index + 1}-
{editValues[item.orderCostId]?.name || item.name}
{formatCurrency(
Number(
(editValues[item.orderCostId]?.price || item.price) *
(editValues[item.orderCostId]?.count || item.count),
),
)}
{!readOnly && (
)}
);
})}
{!readOnly && (
)}
{/* 新增其他费用*/}
setShowAddCostPopup(false)}
onOverlayClick={() => setShowAddCostPopup(false)}
lockScroll
>
{/* 费用类型选择 */}
费用类型
{costTypeOptions.map((option) => (
{
setNewCostData((prev) => ({
...prev,
costType: option.value,
itemId: "",
name: "", // 费用名称
quantity: 0, // 数量
unit: "", // 单位
unitPrice: "", // 单价
amount: "", // 金额
requireQuantityAndPrice: false,
}));
}}
>
{option.label}
))}
{/* 固定费用子类型 */}
{newCostData.costType === "FIXED_COST" && (
<>
固定费用类型
setPickerVisible((prev) => ({ ...prev, fixedCost: true }))
}
>
item.costType === newCostData.costType)
.filter((item) => {
// 检查该项目是否已经被选择
return !fixedCosts.some(
(hc) => hc.itemId === item.itemId,
);
})
.map((item) => ({
label: item.name,
value: item.itemId,
})),
]}
onConfirm={(_, values) => {
const selectedValue = values[0] as string;
const selectedItem = costItemVOList.find(
(item) => item.itemId === selectedValue,
);
if (selectedItem) {
setNewCostData((prev) => ({
...prev,
itemId: selectedValue,
name: selectedItem.name,
payerType: "US",
quantity: selectedItem.requireQuantityAndPrice ? 0 : 1,
unit: selectedItem.requireQuantityAndPrice
? selectedItem.unit
: "元", // 单位
unitPrice: "", // 单价
amount: "", // 金额
principal: "", // 工头姓名
requireQuantityAndPrice:
selectedItem.requireQuantityAndPrice,
}));
}
setPickerVisible((prev) => ({ ...prev, fixedCost: false }));
}}
onCancel={() =>
setPickerVisible((prev) => ({ ...prev, fixedCost: false }))
}
onClose={() =>
setPickerVisible((prev) => ({ ...prev, fixedCost: false }))
}
/>
>
)}
{/* 其他费用名称输入 */}
{newCostData.costType === "OTHER_COST" && (
<>
费用名称
{
setNewCostData((prev) => ({
...prev,
name: value,
}));
}}
/>
收款人姓名
{
setNewCostData((prev) => ({
...prev,
payee: value,
}));
}}
/>
>
)}
{/* 金额输入(固定费用和其他费用)*/}
{((newCostData.costType === "FIXED_COST" && newCostData.name) ||
newCostData.costType === "OTHER_COST") && (
<>
金额
{
const numValue = validatePrice(value);
if (numValue !== undefined) {
setNewCostData((prev) => ({
...prev,
amount: numValue as any,
}));
}
}}
/>
元
>
)}
{/* 固定费用编辑弹窗 */}
{fixedCosts.map((item) => (
setVisiblePopup((prev) => ({ ...prev, [item.orderCostId]: false }))
}
onOverlayClick={() =>
setVisiblePopup((prev) => ({ ...prev, [item.orderCostId]: false }))
}
lockScroll
>
金额
{
const numValue = validatePrice(value);
if (numValue !== undefined) {
setTempEditValues((prev) => ({
...prev,
[item.orderCostId]: {
...prev[item.orderCostId],
price: numValue as number,
count: 1,
},
}));
}
}}
/>
元
))}
{/* 其他费用编辑弹窗 */}
{otherCosts.map((item) => (
setVisiblePopup((prev) => ({ ...prev, [item.orderCostId]: false }))
}
onOverlayClick={() =>
setVisiblePopup((prev) => ({ ...prev, [item.orderCostId]: false }))
}
lockScroll
>
费用名称
{
setTempEditValues((prev) => ({
...prev,
[item.orderCostId]: {
...prev[item.orderCostId],
name: value,
},
}));
}}
/>
收款人姓名
{
setTempEditValues((prev) => ({
...prev,
[item.orderCostId]: {
...prev[item.orderCostId],
principal: value,
},
}));
}}
/>
金额
{
const numValue = validatePrice(value);
if (numValue !== undefined) {
setTempEditValues((prev) => ({
...prev,
[item.orderCostId]: {
...prev[item.orderCostId],
price: numValue as number,
count: 1,
},
}));
}
}}
/>
元
))}
>
);
}