feat(purchase): 优化采购订单费用管理功能
- 移除调试日志输出 - 新增 requireQuantityAndPrice 字段支持 - 调整页面样式间距统一为 p-2.5 - 交换工头垫付与产地垫付显示逻辑 - 完善费用弹窗编辑功能,支持数量单价分别输入 - 增加新手引导 tour 功能 - 优化订单成本列表更新逻辑,避免重复项 - 导出新增的费用 section 组件 - 替换 LaborInfoSection为 WorkerAdvanceSection - 引入 ProductionAdvanceSection 组件
This commit is contained in:
parent
3f8c6d962a
commit
cbde9caac1
@ -34,3 +34,5 @@ export { default as TaxSubsidySection } from "./section/TaxSubsidySection";
|
|||||||
export { default as TaxProvisionSection } from "./section/TaxProvisionSection";
|
export { default as TaxProvisionSection } from "./section/TaxProvisionSection";
|
||||||
export { default as CostDifferenceSection } from "./section/CostDifferenceSection";
|
export { default as CostDifferenceSection } from "./section/CostDifferenceSection";
|
||||||
export { default as MaterialCostSection } from "./section/MaterialCostSection";
|
export { default as MaterialCostSection } from "./section/MaterialCostSection";
|
||||||
|
export { default as ProductionAdvanceSection } from "./section/ProductionAdvanceSection";
|
||||||
|
export { default as WorkerAdvanceSection } from "./section/WorkerAdvanceSection";
|
||||||
|
|||||||
@ -53,8 +53,6 @@ export default forwardRef<OrderCostRef, IOrderCostProps>(
|
|||||||
(costItem) => costItem.itemId === item.itemId,
|
(costItem) => costItem.itemId === item.itemId,
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log("existingItem", existingItem, value)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
orderCostId: existingItem
|
orderCostId: existingItem
|
||||||
? existingItem.orderCostId
|
? existingItem.orderCostId
|
||||||
@ -68,6 +66,9 @@ export default forwardRef<OrderCostRef, IOrderCostProps>(
|
|||||||
payerType: existingItem ? existingItem.payerType : undefined,
|
payerType: existingItem ? existingItem.payerType : undefined,
|
||||||
principal: existingItem ? existingItem.principal : "",
|
principal: existingItem ? existingItem.principal : "",
|
||||||
costType: item.costType,
|
costType: item.costType,
|
||||||
|
requireQuantityAndPrice: existingItem
|
||||||
|
? existingItem.requireQuantityAndPrice
|
||||||
|
: false,
|
||||||
};
|
};
|
||||||
}) || [];
|
}) || [];
|
||||||
|
|
||||||
@ -91,6 +92,7 @@ export default forwardRef<OrderCostRef, IOrderCostProps>(
|
|||||||
payerType: item.payerType,
|
payerType: item.payerType,
|
||||||
principal: item.principal,
|
principal: item.principal,
|
||||||
costType: item.costType,
|
costType: item.costType,
|
||||||
|
requireQuantityAndPrice: item.requireQuantityAndPrice,
|
||||||
};
|
};
|
||||||
}) || []),
|
}) || []),
|
||||||
]);
|
]);
|
||||||
@ -421,7 +423,7 @@ export default forwardRef<OrderCostRef, IOrderCostProps>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View className="flex flex-1 flex-col bg-[#D1D5DB] p-2.5 pt-2.5 gap-2.5">
|
<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"}>
|
||||||
<View className="text-sm font-bold">人工费用</View>
|
<View className="text-sm font-bold">人工费用</View>
|
||||||
<View className="flex items-center rounded-lg border border-blue-200 bg-blue-50 p-2.5">
|
<View className="flex items-center rounded-lg border border-blue-200 bg-blue-50 p-2.5">
|
||||||
|
|||||||
@ -537,7 +537,10 @@ export default forwardRef<OrderVehicleRef, IOrderVehicleProps>(
|
|||||||
className="min-h-20 w-full !border !border-none p-2.5 !text-lg"
|
className="min-h-20 w-full !border !border-none p-2.5 !text-lg"
|
||||||
placeholder="「粘贴识别」获输入文本,智能拆分车牌号、司机姓名、联系电话、出发地、目的地和运费"
|
placeholder="「粘贴识别」获输入文本,智能拆分车牌号、司机姓名、联系电话、出发地、目的地和运费"
|
||||||
/>
|
/>
|
||||||
<View className="absolute right-0 bottom-0 z-9 flex gap-2">
|
<View
|
||||||
|
className="absolute right-0 bottom-0 z-9 flex gap-2"
|
||||||
|
id={"target1"}
|
||||||
|
>
|
||||||
{text ? (
|
{text ? (
|
||||||
<Button
|
<Button
|
||||||
size={"large"}
|
size={"large"}
|
||||||
@ -667,6 +670,7 @@ export default forwardRef<OrderVehicleRef, IOrderVehicleProps>(
|
|||||||
<View className={"flex flex-row gap-2.5"}>
|
<View className={"flex flex-row gap-2.5"}>
|
||||||
<View>
|
<View>
|
||||||
<View
|
<View
|
||||||
|
id={"target2"}
|
||||||
className={`relative flex h-10 w-full items-center rounded-md ${dealerNameError ? "border-4 border-red-500" : "border-4 border-gray-300"}`}
|
className={`relative flex h-10 w-full items-center rounded-md ${dealerNameError ? "border-4 border-red-500" : "border-4 border-gray-300"}`}
|
||||||
>
|
>
|
||||||
<DealerPicker
|
<DealerPicker
|
||||||
|
|||||||
@ -471,7 +471,7 @@ export default function BasicInfoSection(props: {
|
|||||||
</View>
|
</View>
|
||||||
{readOnly ? (
|
{readOnly ? (
|
||||||
<View
|
<View
|
||||||
className="flex flex-row items-center justify-between rounded-md p-4"
|
className="flex flex-row items-center justify-between rounded-md p-2.5"
|
||||||
style={{
|
style={{
|
||||||
background: "linear-gradient(101deg, #F8FAFF 25%, #F0F5FF 74%)",
|
background: "linear-gradient(101deg, #F8FAFF 25%, #F0F5FF 74%)",
|
||||||
}}
|
}}
|
||||||
@ -507,7 +507,7 @@ export default function BasicInfoSection(props: {
|
|||||||
运费信息
|
运费信息
|
||||||
</View>
|
</View>
|
||||||
<View
|
<View
|
||||||
className="flex flex-row items-center justify-between rounded-md p-4"
|
className="flex flex-row items-center justify-between rounded-md p-2.5"
|
||||||
style={{
|
style={{
|
||||||
background: "linear-gradient(101deg, #F8FAFF 25%, #F0F5FF 74%)",
|
background: "linear-gradient(101deg, #F8FAFF 25%, #F0F5FF 74%)",
|
||||||
}}
|
}}
|
||||||
@ -549,7 +549,7 @@ export default function BasicInfoSection(props: {
|
|||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
className="flex flex-row items-center justify-between rounded-md p-4"
|
className="flex flex-row items-center justify-between rounded-md p-2.5"
|
||||||
style={{
|
style={{
|
||||||
background: "linear-gradient(101deg, #F8FAFF 25%, #F0F5FF 74%)",
|
background: "linear-gradient(101deg, #F8FAFF 25%, #F0F5FF 74%)",
|
||||||
}}
|
}}
|
||||||
|
|||||||
@ -211,10 +211,11 @@ export default function LaborInfoSection(props: {
|
|||||||
})}
|
})}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View className="grid grid-cols-1 gap-2.5">
|
|
||||||
<View className={"text-sm font-bold"}>产地垫付</View>
|
<View className="flex flex-col gap-2.5">
|
||||||
{/* 产地垫付 */}
|
<View className={"text-sm font-bold"}>工头垫付</View>
|
||||||
{productionAdvanceCosts.map((item, index) => {
|
{/* 工头垫付 */}
|
||||||
|
{workerAdvanceCosts.map((item, index) => {
|
||||||
// 初始化编辑值,包括费用承担方和工头姓名
|
// 初始化编辑值,包括费用承担方和工头姓名
|
||||||
initEditValues(
|
initEditValues(
|
||||||
item.orderCostId,
|
item.orderCostId,
|
||||||
@ -261,10 +262,11 @@ export default function LaborInfoSection(props: {
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</View>
|
</View>
|
||||||
<View className="grid grid-cols-1 gap-2.5">
|
|
||||||
<View className={"text-sm font-bold"}>工头垫付</View>
|
<View className="flex flex-col gap-2.5">
|
||||||
{/* 工头垫付 */}
|
<View className={"text-sm font-bold"}>产地垫付</View>
|
||||||
{workerAdvanceCosts.map((item, index) => {
|
{/* 产地垫付 */}
|
||||||
|
{productionAdvanceCosts.map((item, index) => {
|
||||||
// 初始化编辑值,包括费用承担方和工头姓名
|
// 初始化编辑值,包括费用承担方和工头姓名
|
||||||
initEditValues(
|
initEditValues(
|
||||||
item.orderCostId,
|
item.orderCostId,
|
||||||
@ -390,7 +392,7 @@ export default function LaborInfoSection(props: {
|
|||||||
costItems
|
costItems
|
||||||
.filter((item) => item.costType === newCostData.costType)
|
.filter((item) => item.costType === newCostData.costType)
|
||||||
.filter((item) => {
|
.filter((item) => {
|
||||||
if (newCostData.costType === 'PRODUCTION_ADVANCE') {
|
if (newCostData.costType === "PRODUCTION_ADVANCE") {
|
||||||
// 检查该项目是否已经被选择
|
// 检查该项目是否已经被选择
|
||||||
return !productionAdvanceCosts.some(
|
return !productionAdvanceCosts.some(
|
||||||
(hc) => hc.itemId === item.itemId,
|
(hc) => hc.itemId === item.itemId,
|
||||||
@ -604,6 +606,8 @@ export default function LaborInfoSection(props: {
|
|||||||
payerType: newCostData.payerType || "US",
|
payerType: newCostData.payerType || "US",
|
||||||
costType: newCostData.costType!,
|
costType: newCostData.costType!,
|
||||||
principal: "",
|
principal: "",
|
||||||
|
requireQuantityAndPrice:
|
||||||
|
newCostData.requireQuantityAndPrice,
|
||||||
};
|
};
|
||||||
|
|
||||||
// 更新purchaseOrderVO,将新费用添加到orderCostList中
|
// 更新purchaseOrderVO,将新费用添加到orderCostList中
|
||||||
@ -648,7 +652,8 @@ export default function LaborInfoSection(props: {
|
|||||||
{productionAdvanceCosts.map((item) => {
|
{productionAdvanceCosts.map((item) => {
|
||||||
// 获取费用项目的 requireQuantityAndPrice 属性
|
// 获取费用项目的 requireQuantityAndPrice 属性
|
||||||
const costItem = costItems.find((cost) => cost.itemId === item.itemId);
|
const costItem = costItems.find((cost) => cost.itemId === item.itemId);
|
||||||
const requireQuantityAndPrice = costItem?.requireQuantityAndPrice ?? false;
|
const requireQuantityAndPrice =
|
||||||
|
costItem?.requireQuantityAndPrice ?? false;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Popup
|
<Popup
|
||||||
@ -657,10 +662,16 @@ export default function LaborInfoSection(props: {
|
|||||||
position="bottom"
|
position="bottom"
|
||||||
title={`编辑${item.name}`}
|
title={`编辑${item.name}`}
|
||||||
onClose={() =>
|
onClose={() =>
|
||||||
setVisiblePopup((prev) => ({ ...prev, [item.orderCostId]: false }))
|
setVisiblePopup((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: false,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
onOverlayClick={() =>
|
onOverlayClick={() =>
|
||||||
setVisiblePopup((prev) => ({ ...prev, [item.orderCostId]: false }))
|
setVisiblePopup((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: false,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
lockScroll
|
lockScroll
|
||||||
>
|
>
|
||||||
@ -676,7 +687,8 @@ export default function LaborInfoSection(props: {
|
|||||||
placeholder="请输入人数"
|
placeholder="请输入人数"
|
||||||
type="digit"
|
type="digit"
|
||||||
value={
|
value={
|
||||||
tempEditValues[item.orderCostId]?.count?.toString() || ""
|
tempEditValues[item.orderCostId]?.count?.toString() ||
|
||||||
|
""
|
||||||
}
|
}
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
const numValue = validatePrice(value);
|
const numValue = validatePrice(value);
|
||||||
@ -703,7 +715,8 @@ export default function LaborInfoSection(props: {
|
|||||||
placeholder="请输入单价"
|
placeholder="请输入单价"
|
||||||
type="digit"
|
type="digit"
|
||||||
value={
|
value={
|
||||||
tempEditValues[item.orderCostId]?.price?.toString() || ""
|
tempEditValues[item.orderCostId]?.price?.toString() ||
|
||||||
|
""
|
||||||
}
|
}
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
const numValue = validatePrice(value);
|
const numValue = validatePrice(value);
|
||||||
@ -731,9 +744,11 @@ export default function LaborInfoSection(props: {
|
|||||||
className="placeholder:text-neutral-dark"
|
className="placeholder:text-neutral-dark"
|
||||||
placeholder="请输入金额"
|
placeholder="请输入金额"
|
||||||
type="digit"
|
type="digit"
|
||||||
value={
|
value={(
|
||||||
(tempEditValues[item.orderCostId]?.price * tempEditValues[item.orderCostId]?.count || item.price * item.count).toString()
|
tempEditValues[item.orderCostId]?.price *
|
||||||
}
|
tempEditValues[item.orderCostId]?.count ||
|
||||||
|
item.price * item.count
|
||||||
|
).toString()}
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
const numValue = validatePrice(value);
|
const numValue = validatePrice(value);
|
||||||
if (numValue !== undefined) {
|
if (numValue !== undefined) {
|
||||||
@ -817,7 +832,9 @@ export default function LaborInfoSection(props: {
|
|||||||
if (onChange) {
|
if (onChange) {
|
||||||
const newOrderCostList = (
|
const newOrderCostList = (
|
||||||
purchaseOrderVO.orderCostList || []
|
purchaseOrderVO.orderCostList || []
|
||||||
).filter((cost) => cost.orderCostId !== item.orderCostId);
|
).filter(
|
||||||
|
(cost) => cost.orderCostId !== item.orderCostId,
|
||||||
|
);
|
||||||
const newPurchaseOrderVO = {
|
const newPurchaseOrderVO = {
|
||||||
...purchaseOrderVO,
|
...purchaseOrderVO,
|
||||||
orderCostList: newOrderCostList,
|
orderCostList: newOrderCostList,
|
||||||
@ -839,13 +856,15 @@ export default function LaborInfoSection(props: {
|
|||||||
</View>
|
</View>
|
||||||
<SafeArea position="bottom" />
|
<SafeArea position="bottom" />
|
||||||
</Popup>
|
</Popup>
|
||||||
)})}
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
{/* 工头垫付 */}
|
{/* 工头垫付 */}
|
||||||
{workerAdvanceCosts.map((item) => {
|
{workerAdvanceCosts.map((item) => {
|
||||||
// 获取费用项目的 requireQuantityAndPrice 属性
|
// 获取费用项目的 requireQuantityAndPrice 属性
|
||||||
const costItem = costItems.find((cost) => cost.itemId === item.itemId);
|
const costItem = costItems.find((cost) => cost.itemId === item.itemId);
|
||||||
const requireQuantityAndPrice = costItem?.requireQuantityAndPrice ?? false;
|
const requireQuantityAndPrice =
|
||||||
|
costItem?.requireQuantityAndPrice ?? false;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Popup
|
<Popup
|
||||||
@ -854,10 +873,16 @@ export default function LaborInfoSection(props: {
|
|||||||
position="bottom"
|
position="bottom"
|
||||||
title={`编辑${item.name}`}
|
title={`编辑${item.name}`}
|
||||||
onClose={() =>
|
onClose={() =>
|
||||||
setVisiblePopup((prev) => ({ ...prev, [item.orderCostId]: false }))
|
setVisiblePopup((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: false,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
onOverlayClick={() =>
|
onOverlayClick={() =>
|
||||||
setVisiblePopup((prev) => ({ ...prev, [item.orderCostId]: false }))
|
setVisiblePopup((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: false,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
lockScroll
|
lockScroll
|
||||||
>
|
>
|
||||||
@ -873,7 +898,8 @@ export default function LaborInfoSection(props: {
|
|||||||
placeholder="请输入人数"
|
placeholder="请输入人数"
|
||||||
type="digit"
|
type="digit"
|
||||||
value={
|
value={
|
||||||
tempEditValues[item.orderCostId]?.count?.toString() || ""
|
tempEditValues[item.orderCostId]?.count?.toString() ||
|
||||||
|
""
|
||||||
}
|
}
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
const numValue = validatePrice(value);
|
const numValue = validatePrice(value);
|
||||||
@ -900,7 +926,8 @@ export default function LaborInfoSection(props: {
|
|||||||
placeholder="请输入单价"
|
placeholder="请输入单价"
|
||||||
type="digit"
|
type="digit"
|
||||||
value={
|
value={
|
||||||
tempEditValues[item.orderCostId]?.price?.toString() || ""
|
tempEditValues[item.orderCostId]?.price?.toString() ||
|
||||||
|
""
|
||||||
}
|
}
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
const numValue = validatePrice(value);
|
const numValue = validatePrice(value);
|
||||||
@ -928,9 +955,11 @@ export default function LaborInfoSection(props: {
|
|||||||
className="placeholder:text-neutral-dark"
|
className="placeholder:text-neutral-dark"
|
||||||
placeholder="请输入金额"
|
placeholder="请输入金额"
|
||||||
type="digit"
|
type="digit"
|
||||||
value={
|
value={(
|
||||||
(tempEditValues[item.orderCostId]?.price * tempEditValues[item.orderCostId]?.count || item.price * item.count).toString()
|
tempEditValues[item.orderCostId]?.price *
|
||||||
}
|
tempEditValues[item.orderCostId]?.count ||
|
||||||
|
item.price * item.count
|
||||||
|
).toString()}
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
const numValue = validatePrice(value);
|
const numValue = validatePrice(value);
|
||||||
if (numValue !== undefined) {
|
if (numValue !== undefined) {
|
||||||
@ -1014,7 +1043,9 @@ export default function LaborInfoSection(props: {
|
|||||||
if (onChange) {
|
if (onChange) {
|
||||||
const newOrderCostList = (
|
const newOrderCostList = (
|
||||||
purchaseOrderVO.orderCostList || []
|
purchaseOrderVO.orderCostList || []
|
||||||
).filter((cost) => cost.orderCostId !== item.orderCostId);
|
).filter(
|
||||||
|
(cost) => cost.orderCostId !== item.orderCostId,
|
||||||
|
);
|
||||||
const newPurchaseOrderVO = {
|
const newPurchaseOrderVO = {
|
||||||
...purchaseOrderVO,
|
...purchaseOrderVO,
|
||||||
orderCostList: newOrderCostList,
|
orderCostList: newOrderCostList,
|
||||||
@ -1036,7 +1067,8 @@ export default function LaborInfoSection(props: {
|
|||||||
</View>
|
</View>
|
||||||
<SafeArea position="bottom" />
|
<SafeArea position="bottom" />
|
||||||
</Popup>
|
</Popup>
|
||||||
)})}
|
);
|
||||||
|
})}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -606,21 +606,35 @@ export default function MaterialCostSection(props: {
|
|||||||
</Popup>
|
</Popup>
|
||||||
|
|
||||||
{/* 辅料费编辑弹窗 */}
|
{/* 辅料费编辑弹窗 */}
|
||||||
{packagingMaterials.map((item) => (
|
{packagingMaterials.map((item) => {
|
||||||
|
// 获取费用项目的 requireQuantityAndPrice 属性
|
||||||
|
const costItem = costItems.find((cost) => cost.itemId === item.itemId);
|
||||||
|
const requireQuantityAndPrice =
|
||||||
|
costItem?.requireQuantityAndPrice ?? false;
|
||||||
|
|
||||||
|
return (
|
||||||
<Popup
|
<Popup
|
||||||
key={item.orderCostId}
|
key={item.orderCostId}
|
||||||
visible={visiblePopup[item.orderCostId]}
|
visible={visiblePopup[item.orderCostId]}
|
||||||
position="bottom"
|
position="bottom"
|
||||||
title={`编辑${item.name}`}
|
title={`编辑${item.name}`}
|
||||||
onClose={() =>
|
onClose={() =>
|
||||||
setVisiblePopup((prev) => ({ ...prev, [item.orderCostId]: false }))
|
setVisiblePopup((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: false,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
onOverlayClick={() =>
|
onOverlayClick={() =>
|
||||||
setVisiblePopup((prev) => ({ ...prev, [item.orderCostId]: false }))
|
setVisiblePopup((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: false,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
lockScroll
|
lockScroll
|
||||||
>
|
>
|
||||||
<View className="flex flex-col gap-3 p-2.5">
|
<View className="flex flex-col gap-3 p-2.5">
|
||||||
|
{requireQuantityAndPrice ? (
|
||||||
|
<>
|
||||||
<View className="text-neutral-darkest text-sm font-medium">
|
<View className="text-neutral-darkest text-sm font-medium">
|
||||||
数量
|
数量
|
||||||
</View>
|
</View>
|
||||||
@ -631,7 +645,6 @@ export default function MaterialCostSection(props: {
|
|||||||
type="digit"
|
type="digit"
|
||||||
value={
|
value={
|
||||||
tempEditValues[item.orderCostId]?.count?.toString() ||
|
tempEditValues[item.orderCostId]?.count?.toString() ||
|
||||||
editValues[item.orderCostId]?.count?.toString() ||
|
|
||||||
""
|
""
|
||||||
}
|
}
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
@ -647,7 +660,7 @@ export default function MaterialCostSection(props: {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<View className="mr-2">{item.unit}</View>
|
<View className="mr-2">人</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View className="text-neutral-darkest text-sm font-medium">
|
<View className="text-neutral-darkest text-sm font-medium">
|
||||||
@ -660,7 +673,6 @@ export default function MaterialCostSection(props: {
|
|||||||
type="digit"
|
type="digit"
|
||||||
value={
|
value={
|
||||||
tempEditValues[item.orderCostId]?.price?.toString() ||
|
tempEditValues[item.orderCostId]?.price?.toString() ||
|
||||||
editValues[item.orderCostId]?.price?.toString() ||
|
|
||||||
""
|
""
|
||||||
}
|
}
|
||||||
onChange={(value) => {
|
onChange={(value) => {
|
||||||
@ -678,6 +690,40 @@ export default function MaterialCostSection(props: {
|
|||||||
/>
|
/>
|
||||||
<View className="mr-2">元</View>
|
<View className="mr-2">元</View>
|
||||||
</View>
|
</View>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<View className="text-neutral-darkest text-sm font-medium">
|
||||||
|
金额
|
||||||
|
</View>
|
||||||
|
<View className="border-neutral-base flex flex-row items-center rounded-md border border-solid">
|
||||||
|
<Input
|
||||||
|
className="placeholder:text-neutral-dark"
|
||||||
|
placeholder="请输入金额"
|
||||||
|
type="digit"
|
||||||
|
value={(
|
||||||
|
tempEditValues[item.orderCostId]?.price *
|
||||||
|
tempEditValues[item.orderCostId]?.count ||
|
||||||
|
item.price * item.count
|
||||||
|
).toString()}
|
||||||
|
onChange={(value) => {
|
||||||
|
const numValue = validatePrice(value);
|
||||||
|
if (numValue !== undefined) {
|
||||||
|
setTempEditValues((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: {
|
||||||
|
...prev[item.orderCostId],
|
||||||
|
price: numValue as number,
|
||||||
|
count: 1,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<View className="mr-2">元</View>
|
||||||
|
</View>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
<View className="flex w-full flex-col bg-white">
|
<View className="flex w-full flex-col bg-white">
|
||||||
<View className="flex flex-row gap-2 p-3">
|
<View className="flex flex-row gap-2 p-3">
|
||||||
@ -718,11 +764,49 @@ export default function MaterialCostSection(props: {
|
|||||||
保存
|
保存
|
||||||
</Button>
|
</Button>
|
||||||
</View>
|
</View>
|
||||||
|
<View className="flex-1">
|
||||||
|
<Button
|
||||||
|
size="large"
|
||||||
|
block
|
||||||
|
type="danger"
|
||||||
|
onClick={() => {
|
||||||
|
// 删除费用项
|
||||||
|
setEditValues((prev) => {
|
||||||
|
const newEditValues = { ...prev };
|
||||||
|
delete newEditValues[item.orderCostId];
|
||||||
|
return newEditValues;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 更新purchaseOrderVO,移除被删除的费用项
|
||||||
|
if (onChange) {
|
||||||
|
const newOrderCostList = (
|
||||||
|
purchaseOrderVO.orderCostList || []
|
||||||
|
).filter(
|
||||||
|
(cost) => cost.orderCostId !== item.orderCostId,
|
||||||
|
);
|
||||||
|
const newPurchaseOrderVO = {
|
||||||
|
...purchaseOrderVO,
|
||||||
|
orderCostList: newOrderCostList,
|
||||||
|
};
|
||||||
|
onChange(newPurchaseOrderVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭弹窗
|
||||||
|
setVisiblePopup((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: false,
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<SafeArea position="bottom" />
|
<SafeArea position="bottom" />
|
||||||
</Popup>
|
</Popup>
|
||||||
))}
|
);
|
||||||
|
})}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,741 @@
|
|||||||
|
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 { business } from "@/services";
|
||||||
|
import { formatCurrency, validatePrice } from "@/utils/format";
|
||||||
|
import { generateShortId } from "@/utils/generateShortId";
|
||||||
|
|
||||||
|
export default function ProductionAdvanceSection(props: {
|
||||||
|
purchaseOrderVO: BusinessAPI.PurchaseOrderVO;
|
||||||
|
onChange?: (purchaseOrderVO: BusinessAPI.PurchaseOrderVO) => void;
|
||||||
|
readOnly?: boolean;
|
||||||
|
}) {
|
||||||
|
const { purchaseOrderVO, onChange, readOnly } = props;
|
||||||
|
|
||||||
|
// 弹窗相关状态
|
||||||
|
const [visiblePopup, setVisiblePopup] = useState<{ [key: string]: boolean }>(
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
|
||||||
|
// 新增人工费弹窗状态
|
||||||
|
const [showAddCostPopup, setShowAddCostPopup] = useState(false);
|
||||||
|
|
||||||
|
// 新增人工费表单数据
|
||||||
|
const [newCostData, setNewCostData] = useState<any>({
|
||||||
|
costType: "PRODUCTION_ADVANCE", // 费用类型
|
||||||
|
itemId: "", // 费用项目ID
|
||||||
|
name: "", // 费用名称
|
||||||
|
quantity: 0, // 数量(人数)
|
||||||
|
unit: "", // 单位
|
||||||
|
unitPrice: "", // 单价
|
||||||
|
amount: "", // 金额
|
||||||
|
payerType: "US", // 费用承担方,默认我方
|
||||||
|
principal: "", // 工头姓名
|
||||||
|
requireQuantityAndPrice: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("newCostData", newCostData);
|
||||||
|
|
||||||
|
// Picker可见状态
|
||||||
|
const [pickerVisible, setPickerVisible] = useState({
|
||||||
|
costType: false, // 费用类型Picker
|
||||||
|
costItem: false, // 费用项目Picker
|
||||||
|
});
|
||||||
|
|
||||||
|
// 费用项目列表
|
||||||
|
const [costItems, setCostItems] = useState<BusinessAPI.CostItemVO[]>([]);
|
||||||
|
|
||||||
|
// 编辑值的状态
|
||||||
|
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 },
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取费用项目列表
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchCostItems = async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await business.costItem.listCostItem({
|
||||||
|
costItemListQry: {
|
||||||
|
status: true,
|
||||||
|
showInEntry: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
setCostItems(data.data || []);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("获取费用项目列表失败:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchCostItems();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// 产地垫付
|
||||||
|
const productionAdvanceCosts =
|
||||||
|
purchaseOrderVO.orderCostList?.filter(
|
||||||
|
(item) => item.costType === "PRODUCTION_ADVANCE",
|
||||||
|
) || [];
|
||||||
|
|
||||||
|
// 当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 (
|
||||||
|
<>
|
||||||
|
<View className={"flex flex-col gap-2.5 divide-y divide-[#eaeaea]"}>
|
||||||
|
<View className="flex flex-col gap-2.5">
|
||||||
|
<View className={"text-sm font-bold"}>
|
||||||
|
产地负责人:{purchaseOrderVO.originPrincipal}
|
||||||
|
</View>
|
||||||
|
{/* 产地垫付 */}
|
||||||
|
{productionAdvanceCosts.map((item, index) => {
|
||||||
|
// 初始化编辑值,包括费用承担方和工头姓名
|
||||||
|
initEditValues(
|
||||||
|
item.orderCostId,
|
||||||
|
item.count,
|
||||||
|
item.price,
|
||||||
|
item.name,
|
||||||
|
item.principal,
|
||||||
|
item.payerType,
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
className="flex items-center justify-between gap-2.5"
|
||||||
|
key={item.orderCostId}
|
||||||
|
onClick={() =>
|
||||||
|
setVisiblePopup((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: true,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View className="text-neutral-dark flex-shrink-0 text-sm">
|
||||||
|
{index + 1}-{item.name}
|
||||||
|
{item.principal && `(${item.principal})`}
|
||||||
|
</View>
|
||||||
|
<View className="text-neutral-darkest flex flex-row items-center justify-between gap-2.5 text-sm font-medium">
|
||||||
|
{formatCurrency(
|
||||||
|
Number(
|
||||||
|
(editValues[item.orderCostId]?.price || item.price) *
|
||||||
|
(editValues[item.orderCostId]?.count || item.count),
|
||||||
|
),
|
||||||
|
)}
|
||||||
|
{!readOnly && (
|
||||||
|
<View className="ml-1 text-gray-500">
|
||||||
|
<Icon
|
||||||
|
name={"pen-to-square"}
|
||||||
|
size={16}
|
||||||
|
color={"#1a73e8"}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{!readOnly && (
|
||||||
|
<Button
|
||||||
|
type={"primary"}
|
||||||
|
block
|
||||||
|
size={"large"}
|
||||||
|
onClick={() => setShowAddCostPopup(true)}
|
||||||
|
>
|
||||||
|
新增其他产地垫付费用
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* 新增其他产地垫付费用 */}
|
||||||
|
<Popup
|
||||||
|
visible={showAddCostPopup}
|
||||||
|
position="bottom"
|
||||||
|
title="新增其他产地垫付费用"
|
||||||
|
onClose={() => setShowAddCostPopup(false)}
|
||||||
|
onOverlayClick={() => setShowAddCostPopup(false)}
|
||||||
|
lockScroll
|
||||||
|
>
|
||||||
|
<ScrollView scrollY className="max-h-150">
|
||||||
|
<View className="flex flex-col gap-3 p-2.5">
|
||||||
|
{/* 垫付项目 */}
|
||||||
|
{newCostData.costType && (
|
||||||
|
<>
|
||||||
|
<View className="text-neutral-darkest text-sm font-medium">
|
||||||
|
垫付项目
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
className="border-neutral-base relative flex h-10 w-full items-center rounded-md border border-solid"
|
||||||
|
onClick={() =>
|
||||||
|
setPickerVisible((prev) => ({ ...prev, costItem: true }))
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
placeholder="请选择垫付项目"
|
||||||
|
value={newCostData.name || ""}
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
<Icon
|
||||||
|
name="chevron-down"
|
||||||
|
className="absolute -right-1 mr-4"
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<Picker
|
||||||
|
title="请选择垫付项目"
|
||||||
|
visible={pickerVisible.costItem}
|
||||||
|
options={[
|
||||||
|
costItems
|
||||||
|
.filter((item) => item.costType === newCostData.costType)
|
||||||
|
.filter((item) => {
|
||||||
|
// 检查该项目是否已经被选择
|
||||||
|
return !productionAdvanceCosts.some(
|
||||||
|
(hc) => hc.itemId === item.itemId,
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.map((item) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.itemId,
|
||||||
|
})),
|
||||||
|
]}
|
||||||
|
onConfirm={(_, values) => {
|
||||||
|
const selectedValue = values[0] as string;
|
||||||
|
const selectedItem = costItems.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, costItem: false }));
|
||||||
|
}}
|
||||||
|
onCancel={() =>
|
||||||
|
setPickerVisible((prev) => ({ ...prev, costItem: false }))
|
||||||
|
}
|
||||||
|
onClose={() =>
|
||||||
|
setPickerVisible((prev) => ({ ...prev, costItem: false }))
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 数量输入 */}
|
||||||
|
{newCostData.itemId &&
|
||||||
|
newCostData.costType &&
|
||||||
|
newCostData.requireQuantityAndPrice && (
|
||||||
|
<>
|
||||||
|
<View className="text-neutral-darkest text-sm font-medium">
|
||||||
|
数量
|
||||||
|
</View>
|
||||||
|
<View className="border-neutral-base flex flex-row items-center rounded-md border border-solid">
|
||||||
|
<Input
|
||||||
|
className="placeholder:text-neutral-dark flex-1"
|
||||||
|
placeholder="请输入数量"
|
||||||
|
type="digit"
|
||||||
|
value={newCostData.quantity?.toString() || ""}
|
||||||
|
onChange={(value) => {
|
||||||
|
const numValue = validatePrice(value);
|
||||||
|
if (numValue !== undefined) {
|
||||||
|
setNewCostData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
quantity: numValue as any,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<View className="mr-2">{newCostData.unit}</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* 单价输入 */}
|
||||||
|
<View className="text-neutral-darkest text-sm font-medium">
|
||||||
|
单价
|
||||||
|
</View>
|
||||||
|
<View className="border-neutral-base flex flex-row items-center rounded-md border border-solid">
|
||||||
|
<Input
|
||||||
|
className="placeholder:text-neutral-dark flex-1"
|
||||||
|
placeholder="请输入单价"
|
||||||
|
type="digit"
|
||||||
|
value={newCostData.unitPrice?.toString() || ""}
|
||||||
|
onChange={(value) => {
|
||||||
|
const numValue = validatePrice(value);
|
||||||
|
if (numValue !== undefined) {
|
||||||
|
setNewCostData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
unitPrice: numValue as any,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<View className="mr-2">元</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* 金额展示 */}
|
||||||
|
<View className="flex items-center justify-between rounded-md bg-gray-100 p-3">
|
||||||
|
<View className="text-neutral-darkest text-sm font-medium">
|
||||||
|
金额
|
||||||
|
</View>
|
||||||
|
<View className="text-neutral-darkest text-sm font-medium">
|
||||||
|
{formatCurrency(
|
||||||
|
Number(newCostData.quantity || 0) *
|
||||||
|
Number(newCostData.unitPrice || 0),
|
||||||
|
)}{" "}
|
||||||
|
元
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{newCostData.itemId &&
|
||||||
|
newCostData.costType &&
|
||||||
|
!newCostData.requireQuantityAndPrice && (
|
||||||
|
<>
|
||||||
|
<View className="text-neutral-darkest text-sm font-medium">
|
||||||
|
金额
|
||||||
|
</View>
|
||||||
|
<View className="border-neutral-base flex flex-row items-center rounded-md border border-solid">
|
||||||
|
<Input
|
||||||
|
className="placeholder:text-neutral-dark flex-1"
|
||||||
|
placeholder="请输入金额"
|
||||||
|
type="digit"
|
||||||
|
value={newCostData.amount?.toString() || ""}
|
||||||
|
onChange={(value) => {
|
||||||
|
const numValue = validatePrice(value);
|
||||||
|
if (numValue !== undefined) {
|
||||||
|
setNewCostData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
unitPrice: numValue as any,
|
||||||
|
amount: numValue as any,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<View className="mr-2">元</View>
|
||||||
|
</View>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
<View className="flex w-full flex-col bg-white">
|
||||||
|
<View className="flex flex-row gap-2 p-3">
|
||||||
|
<View className="flex-1">
|
||||||
|
<Button
|
||||||
|
size="large"
|
||||||
|
block
|
||||||
|
type="default"
|
||||||
|
onClick={() => {
|
||||||
|
setShowAddCostPopup(false);
|
||||||
|
|
||||||
|
// 重置表单
|
||||||
|
setNewCostData({
|
||||||
|
costType: "PRODUCTION_ADVANCE", // 费用类型
|
||||||
|
itemId: "",
|
||||||
|
name: "", // 费用名称
|
||||||
|
quantity: 0, // 数量(人数)
|
||||||
|
unit: "", // 单位
|
||||||
|
unitPrice: "", // 单价
|
||||||
|
amount: "", // 金额
|
||||||
|
payerType: "", // 费用承担方,默认我方
|
||||||
|
principal: "", // 工头姓名
|
||||||
|
requireQuantityAndPrice: false,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
取消
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
<View className="flex-1">
|
||||||
|
<Button
|
||||||
|
size="large"
|
||||||
|
block
|
||||||
|
type="primary"
|
||||||
|
onClick={() => {
|
||||||
|
// 检查必填项
|
||||||
|
if (!newCostData.itemId) {
|
||||||
|
console.log("请选择辅料项目");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查数量和单价或金额
|
||||||
|
if (
|
||||||
|
newCostData.requireQuantityAndPrice &&
|
||||||
|
(!newCostData.quantity || !newCostData.unitPrice)
|
||||||
|
) {
|
||||||
|
console.log("请填写数量和单价");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!newCostData.requireQuantityAndPrice &&
|
||||||
|
!newCostData.amount
|
||||||
|
) {
|
||||||
|
console.log("请填写金额");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建新的费用项
|
||||||
|
const newOrderCost: BusinessAPI.OrderCost = {
|
||||||
|
orderCostId: generateShortId(),
|
||||||
|
itemId: newCostData.itemId || "",
|
||||||
|
name: newCostData.name,
|
||||||
|
price: Number(newCostData.unitPrice || 0),
|
||||||
|
unit: newCostData.unit,
|
||||||
|
count: Number(newCostData.quantity || 1),
|
||||||
|
//@ts-ignore
|
||||||
|
payerType: newCostData.payerType || "US",
|
||||||
|
costType: newCostData.costType!,
|
||||||
|
principal: "",
|
||||||
|
requireQuantityAndPrice: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 更新purchaseOrderVO,将新费用添加到orderCostList中
|
||||||
|
if (onChange) {
|
||||||
|
const updatedOrderCostList = [
|
||||||
|
...(purchaseOrderVO.orderCostList || []),
|
||||||
|
newOrderCost,
|
||||||
|
];
|
||||||
|
const newPurchaseOrderVO = {
|
||||||
|
...purchaseOrderVO,
|
||||||
|
orderCostList: updatedOrderCostList,
|
||||||
|
};
|
||||||
|
onChange(newPurchaseOrderVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
setShowAddCostPopup(false);
|
||||||
|
// 重置表单
|
||||||
|
setNewCostData({
|
||||||
|
costType: "PRODUCTION_ADVANCE", // 费用类型
|
||||||
|
itemId: "",
|
||||||
|
name: "", // 费用名称
|
||||||
|
quantity: 0, // 数量(人数)
|
||||||
|
unit: "", // 单位
|
||||||
|
unitPrice: "", // 单价
|
||||||
|
amount: "", // 金额
|
||||||
|
payerType: "", // 费用承担方,默认我方
|
||||||
|
principal: "", // 工头姓名
|
||||||
|
requireQuantityAndPrice: false,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<SafeArea position="bottom" />
|
||||||
|
</ScrollView>
|
||||||
|
</Popup>
|
||||||
|
|
||||||
|
{/* 产地垫付 */}
|
||||||
|
{productionAdvanceCosts.map((item) => {
|
||||||
|
return (
|
||||||
|
<Popup
|
||||||
|
key={item.orderCostId}
|
||||||
|
visible={visiblePopup[item.orderCostId]}
|
||||||
|
position="bottom"
|
||||||
|
title={`编辑${item.name}`}
|
||||||
|
onClose={() =>
|
||||||
|
setVisiblePopup((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: false,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
onOverlayClick={() =>
|
||||||
|
setVisiblePopup((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: false,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
lockScroll
|
||||||
|
>
|
||||||
|
<View className="flex flex-col gap-3 p-2.5">
|
||||||
|
{item?.requireQuantityAndPrice ? (
|
||||||
|
<>
|
||||||
|
<View className="text-neutral-darkest text-sm font-medium">
|
||||||
|
人数
|
||||||
|
</View>
|
||||||
|
<View className="border-neutral-base flex flex-row items-center rounded-md border border-solid">
|
||||||
|
<Input
|
||||||
|
className="placeholder:text-neutral-dark"
|
||||||
|
placeholder="请输入人数"
|
||||||
|
type="digit"
|
||||||
|
value={
|
||||||
|
tempEditValues[item.orderCostId]?.count?.toString() ||
|
||||||
|
""
|
||||||
|
}
|
||||||
|
onChange={(value) => {
|
||||||
|
const numValue = validatePrice(value);
|
||||||
|
if (numValue !== undefined) {
|
||||||
|
setTempEditValues((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: {
|
||||||
|
...prev[item.orderCostId],
|
||||||
|
count: numValue as number,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<View className="mr-2">人</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View className="text-neutral-darkest text-sm font-medium">
|
||||||
|
单价
|
||||||
|
</View>
|
||||||
|
<View className="border-neutral-base flex flex-row items-center rounded-md border border-solid">
|
||||||
|
<Input
|
||||||
|
className="placeholder:text-neutral-dark"
|
||||||
|
placeholder="请输入单价"
|
||||||
|
type="digit"
|
||||||
|
value={
|
||||||
|
tempEditValues[item.orderCostId]?.price?.toString() ||
|
||||||
|
""
|
||||||
|
}
|
||||||
|
onChange={(value) => {
|
||||||
|
const numValue = validatePrice(value);
|
||||||
|
if (numValue !== undefined) {
|
||||||
|
setTempEditValues((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: {
|
||||||
|
...prev[item.orderCostId],
|
||||||
|
price: numValue as number,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<View className="mr-2">元</View>
|
||||||
|
</View>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<View className="text-neutral-darkest text-sm font-medium">
|
||||||
|
金额
|
||||||
|
</View>
|
||||||
|
<View className="border-neutral-base flex flex-row items-center rounded-md border border-solid">
|
||||||
|
<Input
|
||||||
|
className="placeholder:text-neutral-dark"
|
||||||
|
placeholder="请输入金额"
|
||||||
|
type="digit"
|
||||||
|
value={(
|
||||||
|
tempEditValues[item.orderCostId]?.price *
|
||||||
|
tempEditValues[item.orderCostId]?.count ||
|
||||||
|
item.price * item.count
|
||||||
|
).toString()}
|
||||||
|
onChange={(value) => {
|
||||||
|
const numValue = validatePrice(value);
|
||||||
|
if (numValue !== undefined) {
|
||||||
|
setTempEditValues((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: {
|
||||||
|
...prev[item.orderCostId],
|
||||||
|
price: numValue as number,
|
||||||
|
count: 1,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<View className="mr-2">元</View>
|
||||||
|
</View>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
<View className="flex w-full flex-col bg-white">
|
||||||
|
<View className="flex flex-row gap-2 p-3">
|
||||||
|
<View className="flex-1">
|
||||||
|
<Button
|
||||||
|
size="large"
|
||||||
|
block
|
||||||
|
type="default"
|
||||||
|
onClick={() => {
|
||||||
|
setVisiblePopup((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: false,
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
取消
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
<View className="flex-1">
|
||||||
|
<Button
|
||||||
|
size="large"
|
||||||
|
block
|
||||||
|
type="primary"
|
||||||
|
onClick={() => {
|
||||||
|
// 保存时才更新editValues状态
|
||||||
|
setEditValues((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: {
|
||||||
|
...tempEditValues[item.orderCostId],
|
||||||
|
// 如果费用承担方是瓜农,清空工头姓名
|
||||||
|
principal:
|
||||||
|
tempEditValues[item.orderCostId]?.payerType ===
|
||||||
|
"OTHER"
|
||||||
|
? ""
|
||||||
|
: tempEditValues[item.orderCostId]?.principal,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
// 这里应该调用更新接口或更新状态
|
||||||
|
setVisiblePopup((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: false,
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
<View className="flex-1">
|
||||||
|
<Button
|
||||||
|
size="large"
|
||||||
|
block
|
||||||
|
type="danger"
|
||||||
|
onClick={() => {
|
||||||
|
// 删除费用项
|
||||||
|
setEditValues((prev) => {
|
||||||
|
const newEditValues = { ...prev };
|
||||||
|
delete newEditValues[item.orderCostId];
|
||||||
|
return newEditValues;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 更新purchaseOrderVO,移除被删除的费用项
|
||||||
|
if (onChange) {
|
||||||
|
const newOrderCostList = (
|
||||||
|
purchaseOrderVO.orderCostList || []
|
||||||
|
).filter(
|
||||||
|
(cost) => cost.orderCostId !== item.orderCostId,
|
||||||
|
);
|
||||||
|
const newPurchaseOrderVO = {
|
||||||
|
...purchaseOrderVO,
|
||||||
|
orderCostList: newOrderCostList,
|
||||||
|
};
|
||||||
|
onChange(newPurchaseOrderVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭弹窗
|
||||||
|
setVisiblePopup((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: false,
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<SafeArea position="bottom" />
|
||||||
|
</Popup>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -0,0 +1,762 @@
|
|||||||
|
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 { business } from "@/services";
|
||||||
|
import { formatCurrency, validatePrice } from "@/utils/format";
|
||||||
|
import { generateShortId } from "@/utils/generateShortId";
|
||||||
|
|
||||||
|
export default function WorkerAdvanceSection(props: {
|
||||||
|
purchaseOrderVO: BusinessAPI.PurchaseOrderVO;
|
||||||
|
onChange?: (purchaseOrderVO: BusinessAPI.PurchaseOrderVO) => void;
|
||||||
|
readOnly?: boolean;
|
||||||
|
}) {
|
||||||
|
const { purchaseOrderVO, onChange, readOnly } = props;
|
||||||
|
|
||||||
|
// 弹窗相关状态
|
||||||
|
const [visiblePopup, setVisiblePopup] = useState<{ [key: string]: boolean }>(
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
|
||||||
|
// 新增人工费弹窗状态
|
||||||
|
const [showAddCostPopup, setShowAddCostPopup] = useState(false);
|
||||||
|
|
||||||
|
// 新增人工费表单数据
|
||||||
|
const [newCostData, setNewCostData] = useState<any>({
|
||||||
|
costType: "WORKER_ADVANCE", // 费用类型
|
||||||
|
itemId: "", // 费用项目ID
|
||||||
|
name: "", // 费用名称
|
||||||
|
quantity: 0, // 数量(人数)
|
||||||
|
unit: "", // 单位
|
||||||
|
unitPrice: "", // 单价
|
||||||
|
amount: "", // 金额
|
||||||
|
payerType: "US", // 费用承担方,默认我方
|
||||||
|
principal: "", // 工头姓名
|
||||||
|
requireQuantityAndPrice: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("newCostData", newCostData);
|
||||||
|
|
||||||
|
// Picker可见状态
|
||||||
|
const [pickerVisible, setPickerVisible] = useState({
|
||||||
|
costType: false, // 费用类型Picker
|
||||||
|
costItem: false, // 费用项目Picker
|
||||||
|
});
|
||||||
|
|
||||||
|
// 费用项目列表
|
||||||
|
const [costItems, setCostItems] = useState<BusinessAPI.CostItemVO[]>([]);
|
||||||
|
|
||||||
|
// 编辑值的状态
|
||||||
|
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 },
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取费用项目列表
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchCostItems = async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await business.costItem.listCostItem({
|
||||||
|
costItemListQry: {
|
||||||
|
status: true,
|
||||||
|
showInEntry: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
setCostItems(data.data || []);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("获取费用项目列表失败:", error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchCostItems();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// 人工费
|
||||||
|
const humanCosts =
|
||||||
|
purchaseOrderVO.orderCostList?.filter(
|
||||||
|
(item) =>
|
||||||
|
item.costType === "HUMAN_COST" &&
|
||||||
|
item.payerType === "US" &&
|
||||||
|
item.count > 0,
|
||||||
|
) || [];
|
||||||
|
|
||||||
|
// 工头垫付
|
||||||
|
const workerAdvanceCosts =
|
||||||
|
purchaseOrderVO.orderCostList?.filter(
|
||||||
|
(item) => item.costType === "WORKER_ADVANCE",
|
||||||
|
) || [];
|
||||||
|
|
||||||
|
// 当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 (
|
||||||
|
<>
|
||||||
|
<View className={"flex flex-col gap-2.5 divide-y divide-[#eaeaea]"}>
|
||||||
|
<View className="flex flex-col gap-2.5">
|
||||||
|
<View className={"flex flex-col gap-2.5"}>
|
||||||
|
<View className={"text-sm font-bold"}>
|
||||||
|
工头:{humanCosts?.[0].principal}
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
className={
|
||||||
|
"text-neutral-dark flex flex-row flex-wrap gap-2.5 text-xs font-medium"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{humanCosts.map((item, index) => {
|
||||||
|
return (
|
||||||
|
<View key={index}>{`${item.name} ${item.count}人`}</View>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
{/* 工头垫付 */}
|
||||||
|
{workerAdvanceCosts.map((item, index) => {
|
||||||
|
// 初始化编辑值,包括费用承担方和工头姓名
|
||||||
|
initEditValues(
|
||||||
|
item.orderCostId,
|
||||||
|
item.count,
|
||||||
|
item.price,
|
||||||
|
item.name,
|
||||||
|
item.principal,
|
||||||
|
item.payerType,
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
className="flex items-center justify-between gap-2.5"
|
||||||
|
key={item.orderCostId}
|
||||||
|
onClick={() =>
|
||||||
|
setVisiblePopup((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: true,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View className="text-neutral-dark flex-shrink-0 text-sm">
|
||||||
|
{index + 1}-{item.name}
|
||||||
|
{item.principal && `(${item.principal})`}
|
||||||
|
</View>
|
||||||
|
<View className="text-neutral-darkest flex flex-row items-center justify-between gap-2.5 text-sm font-medium">
|
||||||
|
{formatCurrency(
|
||||||
|
Number(
|
||||||
|
(editValues[item.orderCostId]?.price || item.price) *
|
||||||
|
(editValues[item.orderCostId]?.count || item.count),
|
||||||
|
),
|
||||||
|
)}
|
||||||
|
{!readOnly && (
|
||||||
|
<View className="ml-1 text-gray-500">
|
||||||
|
<Icon
|
||||||
|
name={"pen-to-square"}
|
||||||
|
size={16}
|
||||||
|
color={"#1a73e8"}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{!readOnly && (
|
||||||
|
<Button
|
||||||
|
type={"primary"}
|
||||||
|
block
|
||||||
|
size={"large"}
|
||||||
|
onClick={() => setShowAddCostPopup(true)}
|
||||||
|
>
|
||||||
|
新增其他工头垫付费用
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* 新增其他工头垫付费用 */}
|
||||||
|
<Popup
|
||||||
|
visible={showAddCostPopup}
|
||||||
|
position="bottom"
|
||||||
|
title="新增其他工头垫付费用"
|
||||||
|
onClose={() => setShowAddCostPopup(false)}
|
||||||
|
onOverlayClick={() => setShowAddCostPopup(false)}
|
||||||
|
lockScroll
|
||||||
|
>
|
||||||
|
<ScrollView scrollY className="max-h-150">
|
||||||
|
<View className="flex flex-col gap-3 p-2.5">
|
||||||
|
{/* 垫付项目 */}
|
||||||
|
{newCostData.costType && (
|
||||||
|
<>
|
||||||
|
<View className="text-neutral-darkest text-sm font-medium">
|
||||||
|
垫付项目
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
className="border-neutral-base relative flex h-10 w-full items-center rounded-md border border-solid"
|
||||||
|
onClick={() =>
|
||||||
|
setPickerVisible((prev) => ({ ...prev, costItem: true }))
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
placeholder="请选择垫付项目"
|
||||||
|
value={newCostData.name || ""}
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
<Icon
|
||||||
|
name="chevron-down"
|
||||||
|
className="absolute -right-1 mr-4"
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<Picker
|
||||||
|
title="请选择垫付项目"
|
||||||
|
visible={pickerVisible.costItem}
|
||||||
|
options={[
|
||||||
|
costItems
|
||||||
|
.filter((item) => item.costType === newCostData.costType)
|
||||||
|
.filter((item) => {
|
||||||
|
return !workerAdvanceCosts.some(
|
||||||
|
(hc) => hc.itemId === item.itemId,
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.map((item) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.itemId,
|
||||||
|
})),
|
||||||
|
]}
|
||||||
|
onConfirm={(_, values) => {
|
||||||
|
const selectedValue = values[0] as string;
|
||||||
|
const selectedItem = costItems.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, costItem: false }));
|
||||||
|
}}
|
||||||
|
onCancel={() =>
|
||||||
|
setPickerVisible((prev) => ({ ...prev, costItem: false }))
|
||||||
|
}
|
||||||
|
onClose={() =>
|
||||||
|
setPickerVisible((prev) => ({ ...prev, costItem: false }))
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 数量输入 */}
|
||||||
|
{newCostData.itemId &&
|
||||||
|
newCostData.costType &&
|
||||||
|
newCostData.requireQuantityAndPrice && (
|
||||||
|
<>
|
||||||
|
<View className="text-neutral-darkest text-sm font-medium">
|
||||||
|
数量
|
||||||
|
</View>
|
||||||
|
<View className="border-neutral-base flex flex-row items-center rounded-md border border-solid">
|
||||||
|
<Input
|
||||||
|
className="placeholder:text-neutral-dark flex-1"
|
||||||
|
placeholder="请输入数量"
|
||||||
|
type="digit"
|
||||||
|
value={newCostData.quantity?.toString() || ""}
|
||||||
|
onChange={(value) => {
|
||||||
|
const numValue = validatePrice(value);
|
||||||
|
if (numValue !== undefined) {
|
||||||
|
setNewCostData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
quantity: numValue as any,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<View className="mr-2">{newCostData.unit}</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* 单价输入 */}
|
||||||
|
<View className="text-neutral-darkest text-sm font-medium">
|
||||||
|
单价
|
||||||
|
</View>
|
||||||
|
<View className="border-neutral-base flex flex-row items-center rounded-md border border-solid">
|
||||||
|
<Input
|
||||||
|
className="placeholder:text-neutral-dark flex-1"
|
||||||
|
placeholder="请输入单价"
|
||||||
|
type="digit"
|
||||||
|
value={newCostData.unitPrice?.toString() || ""}
|
||||||
|
onChange={(value) => {
|
||||||
|
const numValue = validatePrice(value);
|
||||||
|
if (numValue !== undefined) {
|
||||||
|
setNewCostData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
unitPrice: numValue as any,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<View className="mr-2">元</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* 金额展示 */}
|
||||||
|
<View className="flex items-center justify-between rounded-md bg-gray-100 p-3">
|
||||||
|
<View className="text-neutral-darkest text-sm font-medium">
|
||||||
|
金额
|
||||||
|
</View>
|
||||||
|
<View className="text-neutral-darkest text-sm font-medium">
|
||||||
|
{formatCurrency(
|
||||||
|
Number(newCostData.quantity || 0) *
|
||||||
|
Number(newCostData.unitPrice || 0),
|
||||||
|
)}{" "}
|
||||||
|
元
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{newCostData.itemId &&
|
||||||
|
newCostData.costType &&
|
||||||
|
!newCostData.requireQuantityAndPrice && (
|
||||||
|
<>
|
||||||
|
<View className="text-neutral-darkest text-sm font-medium">
|
||||||
|
金额
|
||||||
|
</View>
|
||||||
|
<View className="border-neutral-base flex flex-row items-center rounded-md border border-solid">
|
||||||
|
<Input
|
||||||
|
className="placeholder:text-neutral-dark flex-1"
|
||||||
|
placeholder="请输入金额"
|
||||||
|
type="digit"
|
||||||
|
value={newCostData.amount?.toString() || ""}
|
||||||
|
onChange={(value) => {
|
||||||
|
const numValue = validatePrice(value);
|
||||||
|
if (numValue !== undefined) {
|
||||||
|
setNewCostData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
unitPrice: numValue as any,
|
||||||
|
amount: numValue as any,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<View className="mr-2">元</View>
|
||||||
|
</View>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
<View className="flex w-full flex-col bg-white">
|
||||||
|
<View className="flex flex-row gap-2 p-3">
|
||||||
|
<View className="flex-1">
|
||||||
|
<Button
|
||||||
|
size="large"
|
||||||
|
block
|
||||||
|
type="default"
|
||||||
|
onClick={() => {
|
||||||
|
setShowAddCostPopup(false);
|
||||||
|
|
||||||
|
// 重置表单
|
||||||
|
setNewCostData({
|
||||||
|
costType: "WORKER_ADVANCE", // 费用类型
|
||||||
|
itemId: "",
|
||||||
|
name: "", // 费用名称
|
||||||
|
quantity: 0, // 数量(人数)
|
||||||
|
unit: "", // 单位
|
||||||
|
unitPrice: "", // 单价
|
||||||
|
amount: "", // 金额
|
||||||
|
payerType: "", // 费用承担方,默认我方
|
||||||
|
principal: "", // 工头姓名
|
||||||
|
requireQuantityAndPrice: false,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
取消
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
<View className="flex-1">
|
||||||
|
<Button
|
||||||
|
size="large"
|
||||||
|
block
|
||||||
|
type="primary"
|
||||||
|
onClick={() => {
|
||||||
|
// 检查必填项
|
||||||
|
if (!newCostData.itemId) {
|
||||||
|
console.log("请选择辅料项目");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查数量和单价或金额
|
||||||
|
if (
|
||||||
|
newCostData.requireQuantityAndPrice &&
|
||||||
|
(!newCostData.quantity || !newCostData.unitPrice)
|
||||||
|
) {
|
||||||
|
console.log("请填写数量和单价");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!newCostData.requireQuantityAndPrice &&
|
||||||
|
!newCostData.amount
|
||||||
|
) {
|
||||||
|
console.log("请填写金额");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建新的费用项
|
||||||
|
const newOrderCost: BusinessAPI.OrderCost = {
|
||||||
|
orderCostId: generateShortId(),
|
||||||
|
itemId: newCostData.itemId || "",
|
||||||
|
name: newCostData.name,
|
||||||
|
price: Number(newCostData.unitPrice || 0),
|
||||||
|
unit: newCostData.unit,
|
||||||
|
count: Number(newCostData.quantity || 1),
|
||||||
|
//@ts-ignore
|
||||||
|
payerType: newCostData.payerType || "US",
|
||||||
|
costType: newCostData.costType!,
|
||||||
|
principal: "",
|
||||||
|
requireQuantityAndPrice: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 更新purchaseOrderVO,将新费用添加到orderCostList中
|
||||||
|
if (onChange) {
|
||||||
|
const updatedOrderCostList = [
|
||||||
|
...(purchaseOrderVO.orderCostList || []),
|
||||||
|
newOrderCost,
|
||||||
|
];
|
||||||
|
const newPurchaseOrderVO = {
|
||||||
|
...purchaseOrderVO,
|
||||||
|
orderCostList: updatedOrderCostList,
|
||||||
|
};
|
||||||
|
onChange(newPurchaseOrderVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
setShowAddCostPopup(false);
|
||||||
|
// 重置表单
|
||||||
|
setNewCostData({
|
||||||
|
costType: "PRODUCTION_ADVANCE", // 费用类型
|
||||||
|
itemId: "",
|
||||||
|
name: "", // 费用名称
|
||||||
|
quantity: 0, // 数量(人数)
|
||||||
|
unit: "", // 单位
|
||||||
|
unitPrice: "", // 单价
|
||||||
|
amount: "", // 金额
|
||||||
|
payerType: "", // 费用承担方,默认我方
|
||||||
|
principal: "", // 工头姓名
|
||||||
|
requireQuantityAndPrice: false,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<SafeArea position="bottom" />
|
||||||
|
</ScrollView>
|
||||||
|
</Popup>
|
||||||
|
|
||||||
|
{/* 工头垫付 */}
|
||||||
|
{workerAdvanceCosts.map((item) => {
|
||||||
|
return (
|
||||||
|
<Popup
|
||||||
|
key={item.orderCostId}
|
||||||
|
visible={visiblePopup[item.orderCostId]}
|
||||||
|
position="bottom"
|
||||||
|
title={`编辑${item.name}`}
|
||||||
|
onClose={() =>
|
||||||
|
setVisiblePopup((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: false,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
onOverlayClick={() =>
|
||||||
|
setVisiblePopup((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: false,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
lockScroll
|
||||||
|
>
|
||||||
|
<View className="flex flex-col gap-3 p-2.5">
|
||||||
|
{item?.requireQuantityAndPrice ? (
|
||||||
|
<>
|
||||||
|
<View className="text-neutral-darkest text-sm font-medium">
|
||||||
|
人数
|
||||||
|
</View>
|
||||||
|
<View className="border-neutral-base flex flex-row items-center rounded-md border border-solid">
|
||||||
|
<Input
|
||||||
|
className="placeholder:text-neutral-dark"
|
||||||
|
placeholder="请输入人数"
|
||||||
|
type="digit"
|
||||||
|
value={
|
||||||
|
tempEditValues[item.orderCostId]?.count?.toString() ||
|
||||||
|
""
|
||||||
|
}
|
||||||
|
onChange={(value) => {
|
||||||
|
const numValue = validatePrice(value);
|
||||||
|
if (numValue !== undefined) {
|
||||||
|
setTempEditValues((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: {
|
||||||
|
...prev[item.orderCostId],
|
||||||
|
count: numValue as number,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<View className="mr-2">人</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View className="text-neutral-darkest text-sm font-medium">
|
||||||
|
单价
|
||||||
|
</View>
|
||||||
|
<View className="border-neutral-base flex flex-row items-center rounded-md border border-solid">
|
||||||
|
<Input
|
||||||
|
className="placeholder:text-neutral-dark"
|
||||||
|
placeholder="请输入单价"
|
||||||
|
type="digit"
|
||||||
|
value={
|
||||||
|
tempEditValues[item.orderCostId]?.price?.toString() ||
|
||||||
|
""
|
||||||
|
}
|
||||||
|
onChange={(value) => {
|
||||||
|
const numValue = validatePrice(value);
|
||||||
|
if (numValue !== undefined) {
|
||||||
|
setTempEditValues((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: {
|
||||||
|
...prev[item.orderCostId],
|
||||||
|
price: numValue as number,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<View className="mr-2">元</View>
|
||||||
|
</View>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<View className="text-neutral-darkest text-sm font-medium">
|
||||||
|
金额
|
||||||
|
</View>
|
||||||
|
<View className="border-neutral-base flex flex-row items-center rounded-md border border-solid">
|
||||||
|
<Input
|
||||||
|
className="placeholder:text-neutral-dark"
|
||||||
|
placeholder="请输入金额"
|
||||||
|
type="digit"
|
||||||
|
value={(
|
||||||
|
tempEditValues[item.orderCostId]?.price *
|
||||||
|
tempEditValues[item.orderCostId]?.count ||
|
||||||
|
item.price * item.count
|
||||||
|
).toString()}
|
||||||
|
onChange={(value) => {
|
||||||
|
const numValue = validatePrice(value);
|
||||||
|
if (numValue !== undefined) {
|
||||||
|
setTempEditValues((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: {
|
||||||
|
...prev[item.orderCostId],
|
||||||
|
price: numValue as number,
|
||||||
|
count: 1,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<View className="mr-2">元</View>
|
||||||
|
</View>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
<View className="flex w-full flex-col bg-white">
|
||||||
|
<View className="flex flex-row gap-2 p-3">
|
||||||
|
<View className="flex-1">
|
||||||
|
<Button
|
||||||
|
size="large"
|
||||||
|
block
|
||||||
|
type="default"
|
||||||
|
onClick={() => {
|
||||||
|
setVisiblePopup((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: false,
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
取消
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
<View className="flex-1">
|
||||||
|
<Button
|
||||||
|
size="large"
|
||||||
|
block
|
||||||
|
type="primary"
|
||||||
|
onClick={() => {
|
||||||
|
// 保存时才更新editValues状态
|
||||||
|
setEditValues((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: {
|
||||||
|
...tempEditValues[item.orderCostId],
|
||||||
|
// 如果费用承担方是瓜农,清空工头姓名
|
||||||
|
principal:
|
||||||
|
tempEditValues[item.orderCostId]?.payerType ===
|
||||||
|
"OTHER"
|
||||||
|
? ""
|
||||||
|
: tempEditValues[item.orderCostId]?.principal,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
// 这里应该调用更新接口或更新状态
|
||||||
|
setVisiblePopup((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: false,
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
<View className="flex-1">
|
||||||
|
<Button
|
||||||
|
size="large"
|
||||||
|
block
|
||||||
|
type="danger"
|
||||||
|
onClick={() => {
|
||||||
|
// 删除费用项
|
||||||
|
setEditValues((prev) => {
|
||||||
|
const newEditValues = { ...prev };
|
||||||
|
delete newEditValues[item.orderCostId];
|
||||||
|
return newEditValues;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 更新purchaseOrderVO,移除被删除的费用项
|
||||||
|
if (onChange) {
|
||||||
|
const newOrderCostList = (
|
||||||
|
purchaseOrderVO.orderCostList || []
|
||||||
|
).filter(
|
||||||
|
(cost) => cost.orderCostId !== item.orderCostId,
|
||||||
|
);
|
||||||
|
const newPurchaseOrderVO = {
|
||||||
|
...purchaseOrderVO,
|
||||||
|
orderCostList: newOrderCostList,
|
||||||
|
};
|
||||||
|
onChange(newPurchaseOrderVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭弹窗
|
||||||
|
setVisiblePopup((prev) => ({
|
||||||
|
...prev,
|
||||||
|
[item.orderCostId]: false,
|
||||||
|
}));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<SafeArea position="bottom" />
|
||||||
|
</Popup>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,7 +1,14 @@
|
|||||||
import hocAuth from "@/hocs/auth";
|
import hocAuth from "@/hocs/auth";
|
||||||
import { CommonComponent, CostItem, SupplierVO } from "@/types/typings";
|
import { CommonComponent, CostItem, SupplierVO } from "@/types/typings";
|
||||||
import { View } from "@tarojs/components";
|
import { View } from "@tarojs/components";
|
||||||
import { Button, Dialog, SafeArea, Toast } from "@nutui/nutui-react-taro";
|
import {
|
||||||
|
Button,
|
||||||
|
Dialog,
|
||||||
|
SafeArea,
|
||||||
|
Toast,
|
||||||
|
Tour,
|
||||||
|
TourList,
|
||||||
|
} from "@nutui/nutui-react-taro";
|
||||||
import { purchase } from "@/constant";
|
import { purchase } from "@/constant";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import {
|
import {
|
||||||
@ -61,6 +68,26 @@ export default hocAuth(function Page(props: CommonComponent) {
|
|||||||
const defaultStep = router.params.step as number;
|
const defaultStep = router.params.step as number;
|
||||||
const defaultSupplierId = router.params.supplierId as string;
|
const defaultSupplierId = router.params.supplierId as string;
|
||||||
|
|
||||||
|
const [showTour, setShowTour] = useState(true);
|
||||||
|
|
||||||
|
const closeTour = () => {
|
||||||
|
setShowTour(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const steps: TourList[] = [
|
||||||
|
{
|
||||||
|
content: "粘贴识别",
|
||||||
|
target: "target1",
|
||||||
|
popoverOffset: [0, 12],
|
||||||
|
arrowOffset: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
content: "选择经销商",
|
||||||
|
target: "target2",
|
||||||
|
location: "bottom-left",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const vehicleRef = useRef<OrderVehicleRef>(null);
|
const vehicleRef = useRef<OrderVehicleRef>(null);
|
||||||
// 创建MelonFarmer组件的ref数组
|
// 创建MelonFarmer组件的ref数组
|
||||||
const melonFarmerRefs = useRef<MelonFarmerRef[]>([]);
|
const melonFarmerRefs = useRef<MelonFarmerRef[]>([]);
|
||||||
@ -622,17 +649,28 @@ export default hocAuth(function Page(props: CommonComponent) {
|
|||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
setPurchaseOrder((prev) => {
|
setPurchaseOrder((prev) => {
|
||||||
return {
|
const costItemVOList = productVO.costItemVOList;
|
||||||
...prev!,
|
|
||||||
orderCostList: [
|
// 将 orderCostList 中 不存在与 costItemVOList 的项 删除,剩余项保留
|
||||||
...(prev?.orderCostList?.filter((item) => {
|
const orderCostList = prev?.orderCostList.filter((item) => {
|
||||||
return (
|
return (
|
||||||
item.costType !== "WORKER_ADVANCE" &&
|
(item.costType === "WORKER_ADVANCE" ||
|
||||||
item.costType !== "PRODUCTION_ADVANCE"
|
item.costType === "PRODUCTION_ADVANCE" ||
|
||||||
|
item.costType === "PACKAGING_MATERIALS") &&
|
||||||
|
costItemVOList?.find(
|
||||||
|
(costItemVO) => costItemVO.itemId === item.itemId,
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}) || []),
|
});
|
||||||
...(productVO.costItemVOList?.map((item) => {
|
|
||||||
return {
|
// 添加 costItemVOList 中 不存在与 orderCostList 的项
|
||||||
|
costItemVOList?.forEach((item) => {
|
||||||
|
if (
|
||||||
|
!orderCostList?.find(
|
||||||
|
(costItemVO) => costItemVO.itemId === item.itemId,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
orderCostList?.push({
|
||||||
orderCostId: generateShortId(),
|
orderCostId: generateShortId(),
|
||||||
orderId: purchaseOrder?.orderId,
|
orderId: purchaseOrder?.orderId,
|
||||||
itemId: item.itemId,
|
itemId: item.itemId,
|
||||||
@ -643,8 +681,22 @@ export default hocAuth(function Page(props: CommonComponent) {
|
|||||||
payerType: "US" as any,
|
payerType: "US" as any,
|
||||||
principal: "",
|
principal: "",
|
||||||
costType: item.costType,
|
costType: item.costType,
|
||||||
};
|
requireQuantityAndPrice: item.requireQuantityAndPrice,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
...prev!,
|
||||||
|
orderCostList: [
|
||||||
|
...(prev?.orderCostList?.filter((item) => {
|
||||||
|
return (
|
||||||
|
item.costType !== "WORKER_ADVANCE" &&
|
||||||
|
item.costType !== "PRODUCTION_ADVANCE" &&
|
||||||
|
item.costType !== "PACKAGING_MATERIALS"
|
||||||
|
);
|
||||||
}) || []),
|
}) || []),
|
||||||
|
...(orderCostList || []),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@ -866,6 +918,15 @@ export default hocAuth(function Page(props: CommonComponent) {
|
|||||||
</View>
|
</View>
|
||||||
<SafeArea position={"bottom"} />
|
<SafeArea position={"bottom"} />
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
<Tour
|
||||||
|
className="nut-custom-tour nut-customword-tour hidden"
|
||||||
|
visible={showTour}
|
||||||
|
onClose={closeTour}
|
||||||
|
list={steps}
|
||||||
|
type="step"
|
||||||
|
location="bottom-right"
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -5,13 +5,7 @@ import { business } from "@/services";
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { View } from "@tarojs/components";
|
import { View } from "@tarojs/components";
|
||||||
import purchaseOrder from "@/constant/purchaseOrder";
|
import purchaseOrder from "@/constant/purchaseOrder";
|
||||||
import {
|
import { ActionSheet, Button, Dialog, Input, Popup, SafeArea, TextArea, Toast } from "@nutui/nutui-react-taro";
|
||||||
Button,
|
|
||||||
Dialog,
|
|
||||||
Input,
|
|
||||||
SafeArea,
|
|
||||||
Toast,
|
|
||||||
} from "@nutui/nutui-react-taro";
|
|
||||||
import {
|
import {
|
||||||
BasicInfoSection,
|
BasicInfoSection,
|
||||||
CompanyInfoSection,
|
CompanyInfoSection,
|
||||||
@ -19,16 +13,16 @@ import {
|
|||||||
CostSummarySection,
|
CostSummarySection,
|
||||||
DealerInfoSection,
|
DealerInfoSection,
|
||||||
EmptyBoxInfoSection,
|
EmptyBoxInfoSection,
|
||||||
LaborInfoSection,
|
|
||||||
MarketPriceSection,
|
MarketPriceSection,
|
||||||
MaterialCostSection,
|
MaterialCostSection,
|
||||||
PackageInfoSection,
|
PackageInfoSection,
|
||||||
PackagingCostSection,
|
PackagingCostSection,
|
||||||
PurchaseOrderRejectApprove,
|
ProductionAdvanceSection,
|
||||||
RebateCalcSection,
|
RebateCalcSection,
|
||||||
State,
|
State,
|
||||||
TaxProvisionSection,
|
TaxProvisionSection,
|
||||||
TaxSubsidySection,
|
TaxSubsidySection,
|
||||||
|
WorkerAdvanceSection
|
||||||
} from "@/components";
|
} from "@/components";
|
||||||
import buildUrl from "@/utils/buildUrl";
|
import buildUrl from "@/utils/buildUrl";
|
||||||
import { PurchaseOrderCalculator } from "@/utils/PurchaseOrderCalculator";
|
import { PurchaseOrderCalculator } from "@/utils/PurchaseOrderCalculator";
|
||||||
@ -38,113 +32,86 @@ const sections = {
|
|||||||
marketPrice: {
|
marketPrice: {
|
||||||
component: MarketPriceSection,
|
component: MarketPriceSection,
|
||||||
title: "市场报价",
|
title: "市场报价",
|
||||||
containerClass: "border-l-8 border-l-lime-500",
|
|
||||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
|
||||||
},
|
},
|
||||||
// 我方入账公司
|
// 我方入账公司
|
||||||
supplierInfo: {
|
supplierInfo: {
|
||||||
component: CompanyInfoSection,
|
component: CompanyInfoSection,
|
||||||
title: "我方入账公司",
|
title: "我方入账公司",
|
||||||
containerClass: "border-l-8 border-l-blue-500",
|
|
||||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
|
||||||
},
|
},
|
||||||
// 下游经销商信息
|
// 下游经销商信息
|
||||||
dealerInfo: {
|
dealerInfo: {
|
||||||
component: DealerInfoSection,
|
component: DealerInfoSection,
|
||||||
title: "下游经销商",
|
title: "下游经销商",
|
||||||
containerClass: "border-l-8 border-l-green-500",
|
|
||||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
|
||||||
},
|
},
|
||||||
// 基础信息
|
// 基础信息
|
||||||
basicInfo: {
|
basicInfo: {
|
||||||
component: BasicInfoSection,
|
component: BasicInfoSection,
|
||||||
title: "基础信息",
|
title: "基础信息",
|
||||||
containerClass: "border-l-8 border-l-yellow-500",
|
|
||||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
|
||||||
},
|
},
|
||||||
// // 瓜农信息
|
// // 瓜农信息
|
||||||
// farmerInfo: {
|
// farmerInfo: {
|
||||||
// component: SupplierInfoSection,
|
// component: SupplierInfoSection,
|
||||||
// title: "瓜农信息",
|
// title: "瓜农信息",
|
||||||
// containerClass: "border-l-8 border-l-purple-500",
|
|
||||||
// contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
|
||||||
// },
|
// },
|
||||||
// // 采购成本
|
// // 采购成本
|
||||||
// purchaseCostInfo: {
|
// purchaseCostInfo: {
|
||||||
// component: PurchaseCostInfoSection,
|
// component: PurchaseCostInfoSection,
|
||||||
// title: "采购成本",
|
// title: "采购成本",
|
||||||
// containerClass: "border-l-8 border-l-red-500",
|
|
||||||
// contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
|
||||||
// },
|
// },
|
||||||
// 包装纸箱费
|
// 包装纸箱费
|
||||||
packageInfo: {
|
packageInfo: {
|
||||||
component: PackageInfoSection,
|
component: PackageInfoSection,
|
||||||
title: "包装纸箱费复核",
|
title: "包装纸箱费复核",
|
||||||
containerClass: "border-l-8 border-l-indigo-500",
|
|
||||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
|
||||||
},
|
},
|
||||||
// 空箱费用
|
// 空箱费用
|
||||||
emptyBoxInfo: {
|
emptyBoxInfo: {
|
||||||
component: EmptyBoxInfoSection,
|
component: EmptyBoxInfoSection,
|
||||||
title: "空箱费用复核",
|
title: "空箱费用复核",
|
||||||
containerClass: "border-l-8 border-l-pink-500",
|
|
||||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
|
||||||
},
|
},
|
||||||
// 用工信息
|
// 工头垫付费用复核
|
||||||
laborInfo: {
|
foremanAdvance: {
|
||||||
component: LaborInfoSection,
|
component: WorkerAdvanceSection,
|
||||||
title: "人工费复核",
|
title: "工头垫付费用复核",
|
||||||
containerClass: "border-l-8 border-l-teal-500",
|
},
|
||||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
// 产地垫付费用复核
|
||||||
|
originAdvance: {
|
||||||
|
component: ProductionAdvanceSection,
|
||||||
|
title: "产地垫付费用复核",
|
||||||
},
|
},
|
||||||
// 辅料费用复核
|
// 辅料费用复核
|
||||||
materialCost: {
|
materialCost: {
|
||||||
component: MaterialCostSection,
|
component: MaterialCostSection,
|
||||||
title: "辅料费复核",
|
title: "辅料费复核",
|
||||||
containerClass: "border-l-8 border-l-orange-500",
|
|
||||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
|
||||||
},
|
},
|
||||||
// 其他费用复核
|
// 其他费用复核
|
||||||
otherCost: {
|
otherCost: {
|
||||||
component: PackagingCostSection,
|
component: PackagingCostSection,
|
||||||
title: "其他费用复核",
|
title: "其他费用复核",
|
||||||
containerClass: "border-l-8 border-l-orange-500",
|
|
||||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
|
||||||
},
|
},
|
||||||
// 成本合计
|
// 成本合计
|
||||||
costSummary: {
|
costSummary: {
|
||||||
component: CostSummarySection,
|
component: CostSummarySection,
|
||||||
title: "成本合计",
|
title: "成本合计",
|
||||||
containerClass: "border-l-8 border-l-cyan-500",
|
|
||||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
|
||||||
},
|
},
|
||||||
// 个人返点复核
|
// 个人返点复核
|
||||||
rebateCalc: {
|
rebateCalc: {
|
||||||
component: RebateCalcSection,
|
component: RebateCalcSection,
|
||||||
title: "个人返点复核",
|
title: "个人返点复核",
|
||||||
containerClass: "border-l-8 border-l-amber-500",
|
|
||||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
|
||||||
},
|
},
|
||||||
// 公司返点复核
|
// 公司返点复核
|
||||||
taxSubsidy: {
|
taxSubsidy: {
|
||||||
component: TaxSubsidySection,
|
component: TaxSubsidySection,
|
||||||
title: "公司返点复核",
|
title: "公司返点复核",
|
||||||
containerClass: "border-l-8 border-l-amber-500",
|
|
||||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
|
||||||
},
|
},
|
||||||
// 计提税金复核
|
// 计提税金复核
|
||||||
taxProvision: {
|
taxProvision: {
|
||||||
component: TaxProvisionSection,
|
component: TaxProvisionSection,
|
||||||
title: "计提税金复核",
|
title: "计提税金复核",
|
||||||
containerClass: "border-l-8 border-l-amber-500",
|
|
||||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
|
||||||
},
|
},
|
||||||
// 调诚信志远分红
|
// 调诚信志远分红
|
||||||
costDifference: {
|
costDifference: {
|
||||||
component: CostDifferenceSection,
|
component: CostDifferenceSection,
|
||||||
title: "调诚信志远分红",
|
title: "调诚信志远分红",
|
||||||
containerClass: "border-l-8 border-l-amber-500",
|
|
||||||
contentClass: "p-4 bg-white rounded-b-lg shadow-sm overflow-x-auto",
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -157,16 +124,75 @@ export default hocAuth(function Page(props: CommonComponent) {
|
|||||||
const [purchaseOrderVO, setPurchaseOrderVO] =
|
const [purchaseOrderVO, setPurchaseOrderVO] =
|
||||||
useState<BusinessAPI.PurchaseOrderVO>();
|
useState<BusinessAPI.PurchaseOrderVO>();
|
||||||
|
|
||||||
const [originPrincipal, setOriginPrincipal] = useState("");
|
// 驳回原因弹窗相关状态
|
||||||
|
const [rejectVisible, setRejectVisible] = useState(false);
|
||||||
|
const [rejectReason, setRejectReason] = useState("");
|
||||||
|
|
||||||
const [collapsedSections, setCollapsedSections] = useState<
|
// 驳回操作
|
||||||
Record<string, boolean>
|
const handleReject = () => {
|
||||||
>(Object.keys(sections).reduce((acc, key) => ({ ...acc, [key]: false }), {}));
|
setRejectVisible(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 确认驳回
|
||||||
|
const confirmReject = async () => {
|
||||||
|
if (!purchaseOrderVO) {
|
||||||
|
Toast.show("toast", {
|
||||||
|
icon: "fail",
|
||||||
|
title: "提示",
|
||||||
|
content: "请稍后再试",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rejectReason.trim()) {
|
||||||
|
Toast.show("toast", {
|
||||||
|
icon: "fail",
|
||||||
|
title: "提示",
|
||||||
|
content: "请输入驳回原因",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 调用驳回API
|
||||||
|
await business.purchaseOrder.rejectApprovePurchaseOrder({
|
||||||
|
orderId: purchaseOrderVO?.orderId,
|
||||||
|
rejectReason: rejectReason,
|
||||||
|
});
|
||||||
|
|
||||||
|
Toast.show("toast", {
|
||||||
|
icon: "success",
|
||||||
|
title: "提示",
|
||||||
|
content: "驳回成功,正在跳转我的审核...",
|
||||||
|
});
|
||||||
|
|
||||||
|
// 关闭弹窗
|
||||||
|
setRejectVisible(false);
|
||||||
|
setRejectReason("");
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
Taro.redirectTo({ url: buildUrl("/pages/purchase/reviewer/list") });
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
// 返回采购单页面
|
||||||
|
} catch (error) {
|
||||||
|
Toast.show("toast", {
|
||||||
|
icon: "fail",
|
||||||
|
title: "提示",
|
||||||
|
content: error.message || "驳回失败",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const [originPrincipal, setOriginPrincipal] = useState("");
|
||||||
|
|
||||||
// 暂存和提交审核的Dialog状态
|
// 暂存和提交审核的Dialog状态
|
||||||
const [saveDialogVisible, setSaveDialogVisible] = useState(false);
|
const [saveDialogVisible, setSaveDialogVisible] = useState(false);
|
||||||
const [submitDialogVisible, setSubmitDialogVisible] = useState(false);
|
const [submitDialogVisible, setSubmitDialogVisible] = useState(false);
|
||||||
|
|
||||||
|
// 控制更多操作的ActionSheet显示状态
|
||||||
|
const [moreActionVisible, setMoreActionVisible] = useState(false);
|
||||||
|
|
||||||
const [dealerVO, setDealerVO] = useState<BusinessAPI.DealerVO>();
|
const [dealerVO, setDealerVO] = useState<BusinessAPI.DealerVO>();
|
||||||
|
|
||||||
const initDealer = async (dealerId: BusinessAPI.DealerVO["dealerId"]) => {
|
const initDealer = async (dealerId: BusinessAPI.DealerVO["dealerId"]) => {
|
||||||
@ -180,13 +206,6 @@ export default hocAuth(function Page(props: CommonComponent) {
|
|||||||
setDealerVO(data.data);
|
setDealerVO(data.data);
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleSection = (section: string) => {
|
|
||||||
setCollapsedSections((prev) => ({
|
|
||||||
...prev,
|
|
||||||
[section]: !prev[section],
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
// 暂存操作
|
// 暂存操作
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
setSaveDialogVisible(true);
|
setSaveDialogVisible(true);
|
||||||
@ -335,9 +354,14 @@ export default hocAuth(function Page(props: CommonComponent) {
|
|||||||
const personalProfit = calculator.getPersonalProfit();
|
const personalProfit = calculator.getPersonalProfit();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View className={"flex flex-col gap-2.5"} id={"purchase-order-audit"}>
|
<>
|
||||||
|
<View
|
||||||
|
className={"overflow-x-hidden overflow-y-auto bg-[#D1D5DB]"}
|
||||||
|
id={"purchase-order-audit"}
|
||||||
|
>
|
||||||
|
<View className={"flex flex-col gap-2.5 p-2.5"}>
|
||||||
{/* 顶部导航 */}
|
{/* 顶部导航 */}
|
||||||
<View className="flex flex-col gap-2.5 bg-white p-2.5">
|
<View className="flex flex-col gap-2.5 rounded-md bg-white p-2.5 shadow-sm">
|
||||||
<View className={"flex flex-row justify-between gap-2.5"}>
|
<View className={"flex flex-row justify-between gap-2.5"}>
|
||||||
<View className="text-lg font-bold">
|
<View className="text-lg font-bold">
|
||||||
{purchaseOrderVO?.orderDealer?.shortName || "-"} 第
|
{purchaseOrderVO?.orderDealer?.shortName || "-"} 第
|
||||||
@ -361,7 +385,7 @@ export default hocAuth(function Page(props: CommonComponent) {
|
|||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
className={`flex h-12 w-full items-center rounded-lg border-2 border-gray-300 bg-gray-50 px-3`}
|
className={`flex h-10 flex-1 items-center rounded-md border-4 border-gray-300`}
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
@ -389,7 +413,6 @@ export default hocAuth(function Page(props: CommonComponent) {
|
|||||||
{/* 循环渲染各部分内容 */}
|
{/* 循环渲染各部分内容 */}
|
||||||
{Object.keys(sections).map((sectionKey) => {
|
{Object.keys(sections).map((sectionKey) => {
|
||||||
const section = sections[sectionKey];
|
const section = sections[sectionKey];
|
||||||
const isCollapsed = collapsedSections[sectionKey];
|
|
||||||
|
|
||||||
if (!dealerVO?.enableCompanyRebate && sectionKey === "taxSubsidy") {
|
if (!dealerVO?.enableCompanyRebate && sectionKey === "taxSubsidy") {
|
||||||
return null;
|
return null;
|
||||||
@ -404,40 +427,25 @@ export default hocAuth(function Page(props: CommonComponent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View className="overflow-hidden bg-white" key={sectionKey}>
|
<>
|
||||||
|
<View className="text-sm font-bold">{section.title}</View>
|
||||||
<View
|
<View
|
||||||
className={`z-10 flex items-center justify-between p-4 shadow-sm ${section.containerClass}`}
|
className={`overflow-x-auto rounded-md rounded-b-lg bg-white p-2.5 shadow-sm`}
|
||||||
onClick={() => toggleSection(sectionKey)}
|
|
||||||
>
|
>
|
||||||
<View className="text-base font-bold text-gray-800">
|
|
||||||
{section.title}
|
|
||||||
</View>
|
|
||||||
<View className="text-neutral-darker text-lg">
|
|
||||||
{isCollapsed ? "▲" : "▼"}
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
{!isCollapsed && (
|
|
||||||
<View className={section.contentClass}>
|
|
||||||
<section.component
|
<section.component
|
||||||
dealerVO={dealerVO}
|
dealerVO={dealerVO}
|
||||||
purchaseOrderVO={purchaseOrderVO}
|
purchaseOrderVO={purchaseOrderVO}
|
||||||
onChange={setPurchaseOrderVO}
|
onChange={setPurchaseOrderVO}
|
||||||
// readOnly={
|
|
||||||
// role === "boss" ||
|
|
||||||
// (role === "reviewer" &&
|
|
||||||
// purchaseOrderVO.state !== "WAITING_AUDIT")
|
|
||||||
// }
|
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
)}
|
</>
|
||||||
</View>
|
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
||||||
{/* 个人利润 */}
|
{/* 个人利润 */}
|
||||||
<View
|
<View
|
||||||
className={
|
className={
|
||||||
"m-2.5 flex flex-row items-center rounded-md border border-[#FFBB96] p-4"
|
"flex flex-row items-center rounded-md border border-[#FFBB96] p-4"
|
||||||
}
|
}
|
||||||
style={{
|
style={{
|
||||||
background: "linear-gradient(100deg, #FFF2E8 25%, #FFE7D9 75%)",
|
background: "linear-gradient(100deg, #FFF2E8 25%, #FFE7D9 75%)",
|
||||||
@ -445,40 +453,36 @@ export default hocAuth(function Page(props: CommonComponent) {
|
|||||||
>
|
>
|
||||||
<View className={"flex-1 text-center"}>个人利润</View>
|
<View className={"flex-1 text-center"}>个人利润</View>
|
||||||
{personalProfit > 0 ? (
|
{personalProfit > 0 ? (
|
||||||
<View className={"text-primary flex-1 text-left text-2xl font-bold"}>
|
<View
|
||||||
|
className={"text-primary flex-1 text-left text-2xl font-bold"}
|
||||||
|
>
|
||||||
¥ {personalProfit || "-"}
|
¥ {personalProfit || "-"}
|
||||||
</View>
|
</View>
|
||||||
) : (
|
) : (
|
||||||
<View className={"flex-1 text-left text-2xl font-bold text-red-500"}>
|
<View
|
||||||
|
className={"flex-1 text-left text-2xl font-bold text-red-500"}
|
||||||
|
>
|
||||||
¥ {personalProfit || "-"}
|
¥ {personalProfit || "-"}
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
{/* 按钮操作 */}
|
{/* 按钮操作 */}
|
||||||
<View className={"sticky bottom-0 z-10 bg-white"} id={"bottomBar"}>
|
<View className={"sticky bottom-0 z-10 bg-white"} id={"bottomBar"}>
|
||||||
<View className="flex justify-between gap-2 border-t border-gray-200 p-2.5">
|
<View className="flex justify-between gap-2 border-t border-gray-200 p-2.5">
|
||||||
{purchaseOrderVO.state === "WAITING_AUDIT" && (
|
{purchaseOrderVO.state === "WAITING_AUDIT" && (
|
||||||
<>
|
<>
|
||||||
<View className={"flex-1"}>
|
|
||||||
<PurchaseOrderRejectApprove
|
|
||||||
purchaseOrderVO={purchaseOrderVO}
|
|
||||||
size={"xlarge"}
|
|
||||||
onFinish={() => {
|
|
||||||
// 返回首页
|
|
||||||
Taro.redirectTo({ url: "/pages/purchase/reviewer/list" });
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
<View className={"flex-1"}>
|
<View className={"flex-1"}>
|
||||||
<Button
|
<Button
|
||||||
block
|
block
|
||||||
type={"default"}
|
type={"default"}
|
||||||
size={"xlarge"}
|
size={"xlarge"}
|
||||||
className="bg-gray-200 text-gray-700"
|
className="bg-gray-200 text-gray-700"
|
||||||
onClick={handleSave}
|
onClick={() => setMoreActionVisible(true)}
|
||||||
>
|
>
|
||||||
暂存
|
更多操作
|
||||||
</Button>
|
</Button>
|
||||||
</View>
|
</View>
|
||||||
<View className={"flex-1"}>
|
<View className={"flex-1"}>
|
||||||
@ -489,7 +493,7 @@ export default hocAuth(function Page(props: CommonComponent) {
|
|||||||
className="bg-primary text-white"
|
className="bg-primary text-white"
|
||||||
onClick={handleSubmit}
|
onClick={handleSubmit}
|
||||||
>
|
>
|
||||||
提交老板审核
|
提交老板审批
|
||||||
</Button>
|
</Button>
|
||||||
</View>
|
</View>
|
||||||
</>
|
</>
|
||||||
@ -531,6 +535,86 @@ export default hocAuth(function Page(props: CommonComponent) {
|
|||||||
onCancel={() => setSubmitDialogVisible(false)}
|
onCancel={() => setSubmitDialogVisible(false)}
|
||||||
onConfirm={confirmSubmit}
|
onConfirm={confirmSubmit}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* 更多操作ActionSheet */}
|
||||||
|
<ActionSheet
|
||||||
|
title="更多操作"
|
||||||
|
visible={moreActionVisible}
|
||||||
|
options={[
|
||||||
|
{
|
||||||
|
name: "暂存",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "驳回",
|
||||||
|
description: "此采购单将退回到产地录入员",
|
||||||
|
danger: true,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
onCancel={() => setMoreActionVisible(false)}
|
||||||
|
onSelect={(item) => {
|
||||||
|
setMoreActionVisible(false);
|
||||||
|
if (item.name === "暂存") {
|
||||||
|
// 暂存操作
|
||||||
|
handleSave();
|
||||||
|
} else if (item.name === "驳回") {
|
||||||
|
// 驳回操作
|
||||||
|
handleReject();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
cancelText="取消"
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* 驳回原因弹窗 */}
|
||||||
|
<Popup
|
||||||
|
visible={rejectVisible}
|
||||||
|
position="bottom"
|
||||||
|
onClose={() => {
|
||||||
|
setRejectVisible(false);
|
||||||
|
setRejectReason("");
|
||||||
|
}}
|
||||||
|
closeable
|
||||||
|
destroyOnClose
|
||||||
|
title={"驳回"}
|
||||||
|
description={"此采购单将退回到产地录入员"}
|
||||||
|
>
|
||||||
|
<View className="p-4">
|
||||||
|
<View className="mb-4 text-lg font-bold">请输入驳回原因</View>
|
||||||
|
<TextArea
|
||||||
|
value={rejectReason}
|
||||||
|
onChange={(value) => setRejectReason(value)}
|
||||||
|
placeholder="请输入驳回原因"
|
||||||
|
rows={4}
|
||||||
|
maxLength={200}
|
||||||
|
showCount
|
||||||
|
/>
|
||||||
|
<View className="mt-4 flex justify-between gap-2">
|
||||||
|
<View className="flex-1">
|
||||||
|
<Button
|
||||||
|
size={"large"}
|
||||||
|
block
|
||||||
|
type="default"
|
||||||
|
onClick={() => {
|
||||||
|
setRejectVisible(false);
|
||||||
|
setRejectReason("");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
取消
|
||||||
|
</Button>
|
||||||
</View>
|
</View>
|
||||||
|
<View className="flex-1">
|
||||||
|
<Button
|
||||||
|
size={"large"}
|
||||||
|
block
|
||||||
|
type="primary"
|
||||||
|
onClick={confirmReject}
|
||||||
|
>
|
||||||
|
确认
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<SafeArea position="bottom" />
|
||||||
|
</Popup>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -2392,6 +2392,8 @@ declare namespace BusinessAPI {
|
|||||||
| "FIXED_COST"
|
| "FIXED_COST"
|
||||||
| "WORKER_ADVANCE"
|
| "WORKER_ADVANCE"
|
||||||
| "PRODUCTION_ADVANCE";
|
| "PRODUCTION_ADVANCE";
|
||||||
|
/** 是否需要填写数量和单价 */
|
||||||
|
requireQuantityAndPrice: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type OrderDealer = {
|
type OrderDealer = {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user