ERPTurbo_Client/packages/app-client/src/components/purchase/PurchaseOrderApprovalList.tsx
shenyifei 47c7bdf357 feat(purchase): 新增费用编辑功能及优化瓜农信息管理
- 添加 PriceEditor 组件用于直接编辑费用金额
- 实现 CostCard 和 CostCreate 组件以支持费用的增删改查
- 在 PurchaseOrderSubmitReview 中修正参数名 supplierId 为 orderSupplierId
- 重构 MelonFarmer 组件,改进瓜农信息处理逻辑
- 引入 generateShortId 工具函数生成唯一标识符
- 新增 OrderCostItem 模块用于处理订单费用项初始化与校验
- 优化费用模板解析和默认值填充逻辑
- 增强费用承担方及数量的验证机制
- 调整工头姓名输入时的实时更新与失焦校验功能
2025-11-27 10:37:24 +08:00

257 lines
8.7 KiB
TypeScript

import {
ActionType,
DealerPicker,
Icon,
PageList,
PurchaseOrderRejectFinal,
State,
SupplierPicker,
ToolBar,
} from "@/components";
import React, { useRef, useState } from "react";
import { business } from "@/services";
import { Label, Text, View } from "@tarojs/components";
import { buildUrl } from "@/utils";
import { Button } from "@nutui/nutui-react-taro";
import dayjs from "dayjs";
import purchaseOrder from "@/constant/purchaseOrder";
import Taro from "@tarojs/taro";
interface IPurchaseOrderApprovalListProps {
params: BusinessAPI.PurchaseOrderPageQry;
toolbar?: ToolBar;
actionRef?: React.MutableRefObject<ActionType | undefined>;
}
export default function PurchaseOrderApprovalList(
props: IPurchaseOrderApprovalListProps,
) {
const {
params: bizParams,
toolbar: defaultToolbar,
actionRef: externalActionRef,
} = props;
const internalActionRef = useRef<ActionType>();
const actionRef = externalActionRef || internalActionRef;
const [dealerVO, setDealerVO] = useState<BusinessAPI.DealerVO>();
const [supplierVO, setSupplierVO] = useState<BusinessAPI.SupplierVO>();
const toolbar: ToolBar = {
...defaultToolbar,
search: {
activeKey: "plate",
defaultActiveKey: "plate",
items: [
{
key: "plate",
name: "车牌号",
placeholder: "请输入车牌号",
},
],
},
render: () => (
<View className={"item-start flex flex-row gap-2.5"}>
<View>
<DealerPicker
onFinish={(dealerVO) => {
setDealerVO(dealerVO);
actionRef.current?.reload();
}}
trigger={
<View
className={`"border-2 border-primary flex h-6 items-center rounded-md px-2.5`}
>
<View className={"text-primary text-xs"}>
{dealerVO?.shortName || "经销商"}
</View>
{dealerVO?.shortName ? (
<Icon
name={"circle-xmark"}
size={16}
onClick={(event) => {
setDealerVO(undefined);
actionRef.current?.reload();
event.stopPropagation();
}}
/>
) : (
<Icon name={"chevron-down"} size={16} />
)}
</View>
}
/>
</View>
<View>
<SupplierPicker
onFinish={(supplierVO) => {
setSupplierVO(supplierVO);
actionRef.current?.reload();
}}
trigger={
<View
className={`"border-2 border-primary flex h-6 items-center rounded-md px-2.5`}
>
<View className={"text-primary text-xs"}>
{supplierVO?.name || "瓜农"}
</View>
{supplierVO?.name ? (
<Icon
name={"circle-xmark"}
size={16}
onClick={(event) => {
setSupplierVO(undefined);
actionRef.current?.reload();
event.stopPropagation();
}}
/>
) : (
<Icon name={"chevron-down"} size={16} />
)}
</View>
}
/>
</View>
</View>
),
};
return (
<PageList<BusinessAPI.PurchaseOrderVO, BusinessAPI.PurchaseOrderPageQry>
rowId={"purchaseOrderId"}
itemHeight={182}
toolbar={toolbar}
type={"infinite"}
actionRef={actionRef}
render={(purchaseOrderVO: BusinessAPI.PurchaseOrderVO, index) => {
return (
<View className={"mb-2.5"} key={index}>
<View
className={
"relative flex flex-col divide-y-2 divide-neutral-100 rounded-lg bg-white px-2.5"
}
>
<View className={"flex flex-col divide-y-2 divide-neutral-100"}>
<View className={"py-2.5"}>
<View className={"flex flex-row items-center"}>
<View className={"flex flex-1 flex-col gap-2"}>
<View className={"flex flex-row gap-1"}>
{/* 复制 */}
<Text
className={"text-neutral-darkest text-xl font-bold"}
>
{purchaseOrderVO.orderVehicle?.dealerName}{" "}
{purchaseOrderVO.orderVehicle?.vehicleNo
? "第" +
purchaseOrderVO.orderVehicle?.vehicleNo +
"车"
: "暂未生成车次"}
</Text>
</View>
<Text className={"text-neutral-dark text-sm"}>
{purchaseOrderVO.orderVehicle?.origin} {" 至 "}
{purchaseOrderVO.orderVehicle?.destination}
</Text>
</View>
<State
state={purchaseOrderVO.auditState}
stateMap={purchaseOrder.approvalStateMap}
/>
</View>
</View>
<View className={"py-2.5"}>
<View className={"flex flex-col gap-2"}>
<View
className={
"flex flex-row items-center justify-between gap-2.5"
}
>
<Label className={"text-neutral-dark text-sm"}>
</Label>
<Text className={"text-neutral-darkest text-sm"}>
{purchaseOrderVO.orderSn}
</Text>
</View>
<View
className={
"flex flex-row items-center justify-between gap-2.5"
}
>
<Label className={"text-neutral-dark text-sm"}>
</Label>
<Text className={"text-neutral-darkest text-sm"}>
{purchaseOrderVO.createdByName}
</Text>
</View>
<View
className={
"flex flex-row items-center justify-between gap-2.5"
}
>
<Label className={"text-neutral-dark text-sm"}>
</Label>
<Text className={"text-neutral-darkest text-sm"}>
{dayjs(purchaseOrderVO.createdAt).format("MM-DD HH:mm")}
</Text>
</View>
</View>
</View>
</View>
<View className={"py-2.5"}>
<View className={"flex flex-row justify-end gap-2"}>
{purchaseOrderVO.state === "WAITING_AUDIT" &&
purchaseOrderVO.auditState === "PENDING_BOSS_APPROVAL" && (
<View className={"flex flex-row justify-end gap-2"}>
<PurchaseOrderRejectFinal
purchaseOrderVO={purchaseOrderVO}
size={"small"}
onFinish={() => {
actionRef.current?.reload();
}}
/>
<Button
type={"primary"}
size={"small"}
onClick={(e) => {
Taro.navigateTo({
url: buildUrl("/pages/purchase/approval/audit", {
orderId: purchaseOrderVO.orderId,
}),
});
e.stopPropagation();
}}
>
</Button>
</View>
)}
</View>
</View>
</View>
</View>
);
}}
request={async (params) => {
const {
data: { data, success, notEmpty },
} = await business.purchaseOrder.pagePurchaseOrder({
purchaseOrderPageQry: {
...params,
...bizParams,
},
});
return {
data,
success,
hasMore: notEmpty,
};
}}
pagination={{
pageSize: 10,
}}
/>
);
}