- 集成全局用户角色状态管理,实现基于角色的审批权限控制 - 重构审批组件中的订单对象引用为审核对象,提高数据传递准确性 - 新增老板角色审批功能,包括审核通过和驳回操作 - 添加审核驳回后的重新编辑入口,提升审批流程的灵活性 - 优化预览组件中信息确认模块的显示逻辑,仅在草稿状态下显示 - 修改运费校验规则,允许运费为0,调整相关错误提示文案 - 简化市场报价编辑界面,移除弹窗编辑方式,采用直接编辑模式 - 移除包装信息编辑弹窗,优化表格编辑交互体验 - 删除业务服务依赖,优化组件性能和代码结构 - 扩展图标组件,新增复制和钱包图标选项
515 lines
15 KiB
TypeScript
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}
|
|
/>
|
|
</>
|
|
);
|
|
});
|