ERPTurbo_Client/packages/app-client/src/pages/purchase/approver/audit/audit.tsx
shenyifei 5eefd62d85 feat(purchase): 优化采购单驳回逻辑与界面交互
- 在 PurchaseOrderRejectApprove 和 PurchaseOrderRejectFinal 组件中增加对 API 返回结果的判断,若驳回失败则展示错误提示
- 调整驳回弹窗内输入框样式,增强视觉效果与用户体验
- 为多个采购单相关 Section 组件传入统一的 calculator 实例,避免重复创建提升性能
- 移除冗余的状态管理逻辑,直接使用 calculator 计算值进行展示
- 更新采购单状态常量定义及文案描述,新增“已驳回”状态及相关路径配置
- 修改工作台菜单标题及跳转路径,如将“我的草稿”改为“待提交草稿”
- 调整审批页面路由结构,重命名 approver/approve.tsx 为 audit/audit.tsx 并更新引用路径
- 新增 purchaser/result.tsx 页面用于展示采购单提交审核后的结果,并支持查看详情或返回首页
- 修复部分条件渲染逻辑,确保仅在满足条件下才渲染特定内容
- 升级 app 版本号从 v0.0.22 到 v0.0.24
2025-11-20 15:58:53 +08:00

220 lines
8.1 KiB
TypeScript

import hocAuth from "@/hocs/auth";
import { CommonComponent } from "@/types/typings";
import Taro, { useDidShow } from "@tarojs/taro";
import { business } from "@/services";
import { useEffect, useState } from "react";
import { View } from "@tarojs/components";
import { SafeArea } from "@nutui/nutui-react-taro";
import {
PurchaseOrderFinalApprove,
PurchaseOrderRejectFinal,
} from "@/components";
import buildUrl from "@/utils/buildUrl";
import { formatCurrency, formatUnitPrice } from "@/utils/format";
import { PurchaseOrderCalculator } from "@/utils/PurchaseOrderCalculator";
export default hocAuth(function Page(props: CommonComponent) {
const { router, isInitialized, setIsInitialized } = props;
const orderId = router.params
.orderId as BusinessAPI.PurchaseOrderVO["orderId"];
const [purchaseOrderVO, setPurchaseOrderVO] =
useState<BusinessAPI.PurchaseOrderVO>();
const init = async (orderId: BusinessAPI.PurchaseOrderVO["orderId"]) => {
const { data } = await business.purchaseOrder.showPurchaseOrder({
purchaseOrderShowQry: {
orderId,
},
});
if (data.success) {
setPurchaseOrderVO(data.data);
}
};
useEffect(() => {
if (orderId && !isInitialized) {
init(orderId).then(() => {
setIsInitialized(true);
});
}
}, []);
useDidShow(() => {
if (orderId && isInitialized) {
init(orderId).then();
}
});
if (!purchaseOrderVO) {
return;
}
const calculator = new PurchaseOrderCalculator(purchaseOrderVO);
return (
<>
<View
className={"flex flex-1 flex-col gap-2.5 p-2.5"}
id={"purchase-order-approve"}
>
<View>
<View className="flex justify-between space-x-2.5">
<View className="price-card flex-1 rounded-lg bg-white p-3">
<View className="mb-1 text-center text-sm text-gray-500">
</View>
<View className="flex flex-row items-center justify-center gap-2.5 text-center">
<View className="text-primary text-3xl">
{formatUnitPrice(calculator.getAveragePurchasePrice())}
</View>
<View className="text-sm text-gray-500">/</View>
</View>
</View>
<View className="price-card flex-1 rounded-lg bg-white p-3">
<View className="mb-1 text-center text-sm text-gray-500">
</View>
<View className="flex flex-row items-center justify-center gap-2.5 text-center">
<View className="text-primary text-2xl">
{formatUnitPrice(calculator.getAverageSalesPrice())}
</View>
<View className="text-sm text-gray-500">/</View>
</View>
</View>
</View>
</View>
<View className="overflow-hidden rounded-lg bg-white shadow-sm">
<View className="border-b border-gray-100 px-4 py-3">
<View className="text-sm font-bold"></View>
</View>
<View className="grid grid-cols-2 divide-x divide-y divide-gray-100">
<View className="cost-item flex flex-col px-3 py-2">
<View className="text-sm text-gray-500">西</View>
<View className="font-medium">
{formatCurrency(calculator.getSupplierPurchaseCost())}
</View>
</View>
{purchaseOrderVO.orderDealer?.freightCostFlag && (
<View className="cost-item flex flex-col px-3 py-2">
<View className="text-sm text-gray-500"></View>
<View className="font-medium">
{purchaseOrderVO.orderVehicle.price}
</View>
</View>
)}
{purchaseOrderVO.orderCostList.map((item) => {
return (
item.price * item.count > 0 && (
<View
className="cost-item flex flex-col px-3 py-2"
key={item.itemId}
>
<View className="text-sm text-gray-500">{item.name}</View>
<View className="font-medium">
{item.price * item.count}
</View>
{item.name === "人工费" && (
<View className="text-xs text-gray-500">
:
{purchaseOrderVO.foreman}
</View>
)}
</View>
)
);
})}
{purchaseOrderVO.orderDealer?.taxSubsidy && (
<View className="cost-item flex flex-col px-3 py-2">
<View className="text-sm text-gray-500"></View>
<View className="font-medium">
{purchaseOrderVO.orderDealer?.taxSubsidy}
</View>
</View>
)}
{purchaseOrderVO.orderDealer?.taxProvision && (
<View className="cost-item flex flex-col px-3 py-2">
<View className="text-sm text-gray-500"></View>
<View className="font-medium">
{purchaseOrderVO.orderDealer?.taxProvision}
</View>
</View>
)}
{purchaseOrderVO.orderDealer?.costDifference && (
<View className="cost-item flex flex-col px-3 py-2">
<View className="text-sm text-gray-500"></View>
<View className="font-medium">
{purchaseOrderVO.orderDealer?.costDifference}
</View>
</View>
)}
<View className="cost-total col-span-2 grid grid-cols-2 bg-yellow-50 px-3 py-2">
<View className="flex flex-col">
<View className="text-sm text-gray-500"></View>
<View className="font-bold">
{calculator.getMelonCost1()}
</View>
</View>
<View className="flex flex-col">
<View className="text-sm text-gray-500"></View>
<View className="font-bold">
{calculator.getSingleCost()} /
</View>
</View>
</View>
</View>
</View>
<View className="rounded-lg bg-white p-2.5 shadow-sm">
<View className="flex items-center justify-between">
<View className="text-gray-500"></View>
<View className="profit-highlight text-primary text-3xl">
{calculator.getShareProfit()}
</View>
</View>
</View>
</View>
{/* 按钮操作 */}
<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">
{purchaseOrderVO.state === "WAITING_APPROVE" && (
<>
<View className={"flex-1"}>
<PurchaseOrderRejectFinal
purchaseOrderVO={purchaseOrderVO}
size={"xlarge"}
onFinish={() => {
// 返回首页
Taro.redirectTo({
url: "/pages/purchase/approver/audit/list",
});
}}
/>
</View>
<View className={"flex-1"}>
<PurchaseOrderFinalApprove
purchaseOrderVO={purchaseOrderVO}
size={"xlarge"}
onFinish={() => {
// 关闭当前页面并跳转到采购单审核通过页面
Taro.redirectTo({
url: buildUrl(`/pages/purchase/approver/audit/result`, {
orderId: purchaseOrderVO?.orderId,
}),
});
}}
/>
</View>
</>
)}
</View>
<SafeArea position={"bottom"} />
</View>
</>
);
});