ERPTurbo_Client/packages/app-client/src/pages/purchase/made/create.tsx
shenyifei 480e372085 feat(audit): 完善审批流程和权限控制
- 集成全局用户角色状态管理,实现基于角色的审批权限控制
- 重构审批组件中的订单对象引用为审核对象,提高数据传递准确性
- 新增老板角色审批功能,包括审核通过和驳回操作
- 添加审核驳回后的重新编辑入口,提升审批流程的灵活性
- 优化预览组件中信息确认模块的显示逻辑,仅在草稿状态下显示
- 修改运费校验规则,允许运费为0,调整相关错误提示文案
- 简化市场报价编辑界面,移除弹窗编辑方式,采用直接编辑模式
- 移除包装信息编辑弹窗,优化表格编辑交互体验
- 删除业务服务依赖,优化组件性能和代码结构
- 扩展图标组件,新增复制和钱包图标选项
2025-12-26 09:13:57 +08:00

515 lines
15 KiB
TypeScript

import hocAuth from "@/hocs/auth";
import { CommonComponent } from "@/types/typings";
import { View } from "@tarojs/components";
import { purchase } from "@/constant";
import { useEffect, useRef, useState } from "react";
import {
Icon,
MadeOption,
MadeOptionRef,
OrderCost,
OrderCostItem,
OrderCostItemRef,
OrderCostRef,
OrderVehicle,
OrderVehicleRef,
SupplierInfo,
SupplierInfoRef,
SupplierList,
SupplierPackage,
SupplierPackageRef,
SupplierWeigh,
SupplierWeighRef,
TicketUpload,
} from "@/components";
import { business } from "@/services";
import { buildUrl, generateShortId } from "@/utils";
import Taro from "@tarojs/taro";
import { Button } from "@nutui/nutui-react-taro";
import { WeightCalculationService } from "@/utils/classes/calculators";
const defaultSupplierList: Partial<BusinessAPI.OrderSupplier>[] = [
{
orderSupplierId: generateShortId(),
supplierId: "",
name: "瓜农1",
payeeName: "",
idCard: "",
bankCard: "",
phone: "",
selected: true,
wechatQr: "",
isLast: undefined,
// 空磅是否包含纸箱
isPaper: undefined,
// 空磅重量
emptyWeight: undefined,
// 总磅重量
totalWeight: undefined,
// 采购单价
purchasePrice: undefined,
// 空磅照片
emptyWeightImg: "",
// 总磅照片
totalWeightImg: "",
orderPackageList: [],
packageUsage: [
{
boxType: "USED",
isUsed: 0,
},
{
boxType: "EXTRA_USED",
isUsed: 0,
},
{
boxType: "EXTRA",
isUsed: 0,
},
{
boxType: "REMAIN",
isUsed: 0,
},
],
},
];
export default hocAuth(function Page(props: CommonComponent) {
const { router, userRoleVO, setLoading } = props;
const orderId = router.params.orderId as string;
const defaultStep = router.params.step as number;
const defaultActive = router.params.active as number;
const defaultSupplierId = router.params.supplierId as string;
const defaultOrderSupplierId = router.params.orderSupplierId as string;
const orderOptionRef = useRef<MadeOptionRef>(null);
const vehicleRef = useRef<OrderVehicleRef>(null);
// 创建MelonFarmer组件的ref数组
const supplierInfoRefs = useRef<SupplierInfoRef[]>([]);
// 创建Weigh组件的ref数组
const supplierWeighRefs = useRef<SupplierWeighRef[]>([]);
// 创建OrderCost组件的ref
const orderCostRef = useRef<OrderCostRef>(null);
// 创建OrderCostItem组件的ref
const orderCostItemRef = useRef<OrderCostItemRef>(null);
// 创建OrderPackage组件的ref
const supplierPackageRefs = useRef<SupplierPackageRef[]>([]);
const [order, setOrder] = useState<BusinessAPI.OrderVO>();
const [step, setStep] = useState<any>();
useEffect(() => {
if (orderId) {
setLoading(true);
business.order
.showOrder({
orderShowQry: {
orderId: orderId,
type: "PRODUCTION_PURCHASE",
},
})
.then(({ data: { data: order, success } }) => {
if (success && order) {
// 如果订单状态不是草稿,则跳转到预览页面
if (order.state !== "DRAFT") {
if (userRoleVO.slug === "origin-entry") {
Taro.redirectTo({
url: buildUrl("/pages/purchase/made/preview", {
orderId: order.orderId,
}),
});
return;
}
if (userRoleVO.slug === "reviewer") {
Taro.redirectTo({
url: buildUrl("/pages/audit/audit", {
orderId: order.orderId,
}),
});
return;
}
if (userRoleVO.slug === "boss") {
Taro.redirectTo({
url: buildUrl("/pages/approval/audit", {
orderId: order.orderId,
}),
});
return;
}
}
if (
!(order.orderSupplierList && order.orderSupplierList.length > 0)
) {
order.orderSupplierList = defaultSupplierList as any;
}
setOrder(order);
const orderSupplierList1 = order.orderSupplierList as any;
if (defaultOrderSupplierId) {
const index = orderSupplierList1.findIndex(
(item: any) => item.orderSupplierId === defaultOrderSupplierId,
);
orderSupplierList1[index].selected = true;
} else {
orderSupplierList1[0].selected = true;
}
console.log("defaultStep", defaultStep);
let active: number;
if (defaultActive) {
active = defaultActive;
} else if (defaultStep) {
active = defaultStep;
} else {
active = order.active || 1;
if (active < 1 || active > purchase.madeSteps.length - 1) {
active = 1;
}
}
console.log("active", active);
setOrder({
...order,
active:
active > purchase.madeSteps.length - 1
? purchase.madeSteps.length - 1
: active,
orderSupplierList: orderSupplierList1,
orderCostList: order.orderCostList?.map((item) => {
return {
...item,
selected: true,
};
}),
orderCostItemList: order.orderCostItemList?.map((item) => {
return {
...item,
selected: true,
};
}),
});
}
})
.catch((err) => {
console.error("获取采购订单失败:", err);
})
.finally(() => {
setLoading(false);
});
} else {
setOrder({
...order!,
active: 1,
orderSupplierList: defaultSupplierList as any,
type: "PRODUCTION_PURCHASE",
});
}
}, [orderId]);
useEffect(() => {
setStep(purchase.madeSteps[order?.active! - 1]);
}, [order?.active]);
const setOrderSupplierList = (
orderSupplierList: BusinessAPI.OrderSupplier[],
) => {
setOrder((prev) => ({
...prev!,
orderSupplierList,
}));
};
useEffect(() => {
if (defaultSupplierId) {
setLoading(true);
business.supplier
.showSupplier({
supplierShowQry: {
supplierId: defaultSupplierId,
},
})
.then(({ data: { data: supplierVO } }) => {
if (supplierVO) {
setOrderSupplierList([
{
orderSupplierId: generateShortId(),
...supplierVO,
selected: true,
} as any,
]);
}
})
.finally(() => {
setLoading(false);
});
}
}, [defaultSupplierId]);
if (step === undefined) {
return;
}
return (
<>
<View className={"sticky top-0 z-11"}>
{step.value < purchase.madeSteps.length && (
<View className="h-12 bg-white p-2.5 shadow-sm">
<View className="step-indicator flex h-2 rounded-full bg-gray-200">
<View
className="bg-primary rounded-full"
style={`width: ${(100 / purchase.madeSteps.length) * step.value}%`}
></View>
</View>
<View className="mt-1 text-sm font-bold text-[#000000]">
{step.title.replace("{}", purchase.madeSteps.length - 1)}
</View>
</View>
)}
{step.value >= 2 && step.value <= 5 && (
<SupplierList
value={order as any}
onChange={(orderVO: BusinessAPI.OrderVO) => {
setOrder(orderVO);
}}
melonFarmerRefs={supplierInfoRefs}
weighRefs={supplierWeighRefs}
orderPackageRefs={supplierPackageRefs}
/>
)}
</View>
<View className={"flex flex-1 flex-col bg-[#D1D5DB]"}>
{/* 车辆信息 */}
{step.value === 1 && (
<OrderVehicle
value={order as any}
onChange={(orderVO: BusinessAPI.OrderVO) => {
setOrder((prev) => {
return {
...prev!,
...orderVO,
};
});
}}
ref={vehicleRef}
/>
)}
{/* 瓜农信息 */}
{order?.orderSupplierList?.map(
(item: BusinessAPI.OrderSupplier, index) => {
if (!item.selected) {
return;
}
if (step.value === 2) {
// 确保ref数组足够长
while (supplierInfoRefs.current.length <= index) {
supplierInfoRefs.current.push({
validate: () => true, // 默认验证方法
} as SupplierInfoRef);
}
return (
<SupplierInfo
index={index}
key={item.orderSupplierId}
value={order as any}
onChange={(orderVO: BusinessAPI.OrderVO) => {
setOrder((prev) => {
return {
...prev!,
...orderVO,
orderSupplierList:
WeightCalculationService.calculateWeights(
orderVO?.orderSupplierList,
),
};
});
}}
ref={(ref) => {
if (ref) {
supplierInfoRefs.current[index] = ref;
}
}}
/>
);
}
// 称重信息
if (step.value === 3) {
// 确保ref数组足够长
while (supplierWeighRefs.current.length <= index) {
supplierWeighRefs.current.push({
validate: () => true, // 默认验证方法
} as SupplierWeighRef);
}
return (
<SupplierWeigh
index={index}
key={item.orderSupplierId}
value={order as any}
onChange={(orderVO: BusinessAPI.OrderVO) => {
setOrder((prev) => {
return {
...prev!,
...orderVO,
orderSupplierList:
WeightCalculationService.calculateWeights(
orderVO?.orderSupplierList,
),
};
});
}}
ref={(ref) => {
if (ref) {
supplierWeighRefs.current[index] = ref;
}
}}
/>
);
}
// 包装信息
if (step.value === 4) {
// 确保ref数组足够长
while (supplierPackageRefs.current.length <= index) {
supplierPackageRefs.current.push({
validate: () => true, // 默认验证方法
} as SupplierPackageRef);
}
return (
<SupplierPackage
index={index}
key={item.orderSupplierId}
value={order as any}
onChange={(orderVO: BusinessAPI.OrderVO) => {
setOrder((prev) => {
return {
...prev!,
...orderVO,
orderSupplierList:
WeightCalculationService.calculateWeights(
orderVO.orderSupplierList,
),
};
});
}}
ref={(ref) => {
if (ref) {
supplierPackageRefs.current[index] = ref;
}
}}
/>
);
}
// 票证上传
if (step.value === 5) {
return (
<TicketUpload
index={index}
key={item.orderSupplierId}
value={order as any}
onChange={(orderVO: BusinessAPI.OrderVO) => {
setOrder((prev) => {
return {
...prev!,
...orderVO,
};
});
}}
/>
);
}
},
)}
{/* 人工和辅料信息 */}
{step.value === 6 && (
<OrderCostItem
ref={orderCostItemRef}
value={order as any}
onChange={(orderVO: BusinessAPI.OrderVO) => {
setOrder((prev) => {
return {
...prev!,
foreman: orderVO.foreman,
orderCostItemList: orderVO.orderCostItemList,
orderPackageList: orderVO.orderPackageList,
};
});
}}
/>
)}
{/* 费用 */}
{step.value === 6 && (
<OrderCost
value={order as any}
onChange={(orderVO: BusinessAPI.OrderVO) => {
setOrder((prev) => {
return {
...prev!,
orderCostList: orderVO.orderCostList,
};
});
}}
ref={orderCostRef}
/>
)}
{(step.value === 6 || step.value === 5) &&
!order?.orderSupplierList[order?.orderSupplierList.length - 1]
?.isLast && (
<View className="flex flex-col gap-2.5 bg-[#D1D5DB] p-2.5">
<View className={"flex flex-1 flex-col gap-2.5"}>
<View className="text-sm font-bold"></View>
<Button
icon={<Icon name={"plus"} size={20} />}
type={"primary"}
size={"large"}
fill={"outline"}
block
className="border-primary text-primary flex w-full items-center justify-center !border-4 !bg-white"
onClick={() => {
orderOptionRef.current?.onAdd();
}}
>
<View></View>
</Button>
</View>
</View>
)}
</View>
{/* 按钮操作 */}
<MadeOption
ref={orderOptionRef}
value={order as any}
onChange={(orderVO: BusinessAPI.OrderVO) =>
setOrder((prev) => {
return {
...prev!,
...orderVO,
};
})
}
vehicleRef={vehicleRef}
supplierInfoRefs={supplierInfoRefs}
supplierWeighRefs={supplierWeighRefs}
supplierPackageRefs={supplierPackageRefs}
orderCostRef={orderCostRef}
orderCostItemRef={orderCostItemRef}
/>
</>
);
});