- 调整采购订单最终审批成功后的提示逻辑,确保只在审批成功时显示 - 更新采购订单提交审核组件,增加调试日志输出 - 修改采购订单撤回提审按钮样式类型为危险类型 - 优化 MelonFarmer 组件中的身份证和银行卡输入框类型 - 重构 OrderPackage 组件中的纸箱类型启用逻辑,根据供应商条件动态设置 - 调整 TicketUpload 组件中发票和合同上传状态管理方式 - 改进 Weigh 组件中空车过磅纸箱选择逻辑,仅对首个瓜农显示选择项 - 更新 BasicInfoSection 组件中开关按钮的显示文案 - 优化 SupplierInfoSection 组件中图片预览逻辑 - 调整工作台常量配置,修改历史记录标题并增加采购记录菜单项 - 优化发货单文档页面中的日期选择范围和表单字段渲染逻辑
383 lines
13 KiB
TypeScript
383 lines
13 KiB
TypeScript
import {
|
|
Button,
|
|
Popup,
|
|
SafeArea,
|
|
Tabs,
|
|
Uploader,
|
|
UploaderFileItem,
|
|
} from "@nutui/nutui-react-taro";
|
|
import { View } from "@tarojs/components";
|
|
import { useState } from "react";
|
|
import Taro from "@tarojs/taro";
|
|
import { uploadFile } from "@/utils/uploader";
|
|
|
|
export default function SupplierInfoSection(props: {
|
|
purchaseOrderVO: BusinessAPI.PurchaseOrderVO;
|
|
onChange?: (purchaseOrderVO: BusinessAPI.PurchaseOrderVO) => void;
|
|
readOnly?: boolean;
|
|
}) {
|
|
const { purchaseOrderVO, readOnly, onChange } = props;
|
|
|
|
const [tab, setTab] = useState<string | number>("0");
|
|
|
|
// 为每个供应商维护未上传状态
|
|
const [uploadStates, setUploadStates] = useState<
|
|
Record<
|
|
string,
|
|
{
|
|
emptyWeightImg?: UploaderFileItem[];
|
|
totalWeightImg?: UploaderFileItem[];
|
|
contractImg?: UploaderFileItem[];
|
|
invoiceImg?: UploaderFileItem[];
|
|
}
|
|
>
|
|
>({});
|
|
|
|
// 控制弹窗显示状态
|
|
const [popupVisible, setPopupVisible] = useState(false);
|
|
const [currentSupplier, setCurrentSupplier] =
|
|
useState<BusinessAPI.OrderSupplier | null>(null);
|
|
const [currentUploadType, setCurrentUploadType] = useState<string>("");
|
|
|
|
// 判断供应商是否所有附件都已未上传
|
|
const isSupplierFullyUploaded = (supplier: BusinessAPI.OrderSupplier) => {
|
|
return (
|
|
supplier.emptyWeightImg &&
|
|
supplier.totalWeightImg &&
|
|
supplier.invoiceUpload &&
|
|
supplier.contractUpload
|
|
);
|
|
};
|
|
|
|
// 获取显示的标签文本
|
|
const getTabTitle = (supplier: BusinessAPI.OrderSupplier) => {
|
|
if (isSupplierFullyUploaded(supplier)) {
|
|
return `${supplier.name} - 票证已未上传`;
|
|
} else {
|
|
return `${supplier.name} - 待补充`;
|
|
}
|
|
};
|
|
|
|
// 处理未上传按钮点击
|
|
const handleUploadClick = (
|
|
supplier: BusinessAPI.OrderSupplier,
|
|
type: string,
|
|
) => {
|
|
if (readOnly) return;
|
|
setCurrentSupplier(supplier);
|
|
setCurrentUploadType(type);
|
|
setPopupVisible(true);
|
|
};
|
|
|
|
// 处理查看按钮点击 - 使用 Taro.previewImage 预览图片
|
|
const handleViewClick = (
|
|
supplier: BusinessAPI.OrderSupplier,
|
|
type: string,
|
|
) => {
|
|
// 构造图片 URL 数组
|
|
const imageUrls: string[] = [];
|
|
|
|
console.log("supplier", supplier, type)
|
|
if (type === "emptyWeightImg" && supplier.emptyWeightImg) {
|
|
imageUrls.push(supplier.emptyWeightImg);
|
|
} else if (type === "totalWeightImg" && supplier.totalWeightImg) {
|
|
imageUrls.push(supplier.totalWeightImg);
|
|
} else if (type === "contractImg" && supplier.contractUpload) {
|
|
supplier.contractImg?.forEach((file) => {
|
|
if (file) {
|
|
imageUrls.push(file);
|
|
}
|
|
});
|
|
} else if (type === "invoiceImg" && supplier.invoiceUpload) {
|
|
supplier.invoiceImg?.forEach((file) => {
|
|
if (file) {
|
|
imageUrls.push(file);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 使用 Taro.previewImage 预览图片
|
|
if (imageUrls.length > 0) {
|
|
Taro.previewImage({
|
|
urls: imageUrls,
|
|
});
|
|
}
|
|
};
|
|
|
|
// 处理上传确认
|
|
const handleUploadConfirm = () => {
|
|
if (!currentSupplier || !currentUploadType) return;
|
|
|
|
// 获取当前上传的文件列表
|
|
const uploadedFiles = uploadStates[currentSupplier.orderSupplierId]?.[currentUploadType];
|
|
|
|
if (!uploadedFiles) return;
|
|
|
|
// 创建新的 purchaseOrderVO 副本
|
|
const updatedPurchaseOrderVO = { ...purchaseOrderVO };
|
|
if (updatedPurchaseOrderVO.orderSupplierList) {
|
|
updatedPurchaseOrderVO.orderSupplierList = [...updatedPurchaseOrderVO.orderSupplierList];
|
|
}
|
|
|
|
// 找到当前供应商在列表中的索引
|
|
const supplierIndex = updatedPurchaseOrderVO.orderSupplierList?.findIndex(
|
|
(supplier) => supplier.orderSupplierId === currentSupplier.orderSupplierId
|
|
);
|
|
|
|
if (supplierIndex === undefined || supplierIndex === -1) return;
|
|
|
|
// 更新对应的供应商字段
|
|
const updatedSupplier = { ...updatedPurchaseOrderVO.orderSupplierList[supplierIndex] };
|
|
|
|
switch (currentUploadType) {
|
|
case "emptyWeightImg":
|
|
// 空磅照片只取第一张图片的 URL
|
|
updatedSupplier.emptyWeightImg = uploadedFiles[0]?.url || "";
|
|
break;
|
|
case "totalWeightImg":
|
|
// 总磅照片只取第一张图片的 URL
|
|
updatedSupplier.totalWeightImg = uploadedFiles[0]?.url || "";
|
|
break;
|
|
case "contractImg":
|
|
// 合同图片可以有多张,保存所有 URL
|
|
updatedSupplier.contractImg = uploadedFiles
|
|
.filter(file => file.url)
|
|
.map(file => file.url!);
|
|
updatedSupplier.contractUpload = uploadedFiles.length > 0;
|
|
break;
|
|
case "invoiceImg":
|
|
// 发票图片可以有多张,保存所有 URL
|
|
updatedSupplier.invoiceImg = uploadedFiles
|
|
.filter(file => file.url)
|
|
.map(file => file.url!);
|
|
updatedSupplier.invoiceUpload = uploadedFiles.length > 0;
|
|
break;
|
|
}
|
|
|
|
// 更新供应商列表
|
|
if (updatedPurchaseOrderVO.orderSupplierList) {
|
|
updatedPurchaseOrderVO.orderSupplierList[supplierIndex] = updatedSupplier;
|
|
}
|
|
|
|
// 调用 onChange 回调更新父组件状态
|
|
if (onChange) {
|
|
onChange(updatedPurchaseOrderVO);
|
|
}
|
|
|
|
// 重置弹窗状态
|
|
setPopupVisible(false);
|
|
setCurrentSupplier(null);
|
|
setCurrentUploadType("");
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<Tabs
|
|
style={{
|
|
// @ts-ignore
|
|
"--nutui-tabs-tabpane-padding": 0,
|
|
}}
|
|
value={tab}
|
|
onChange={(value) => {
|
|
setTab(value);
|
|
}}
|
|
>
|
|
{purchaseOrderVO?.orderSupplierList?.map((item, index) => (
|
|
<Tabs.TabPane title={getTabTitle(item)} key={index}>
|
|
{/* 瓜农凭证信息 */}
|
|
<View className="flex w-full flex-col gap-2.5">
|
|
<View className="flex !h-8 flex-row items-center justify-between">
|
|
<View className="text-neutral-dark flex-shrink-0 text-sm">
|
|
空磅照片
|
|
</View>
|
|
<View className="text-neutral-darkest text-sm font-medium">
|
|
{item.emptyWeightImg ? (
|
|
<Button
|
|
fill={"none"}
|
|
type={"primary"}
|
|
className="edit-btn"
|
|
onClick={() => handleViewClick(item, "emptyWeightImg")}
|
|
>
|
|
查看
|
|
</Button>
|
|
) : readOnly ? (
|
|
<Button fill={"none"} type={"default"} disabled>
|
|
未上传
|
|
</Button>
|
|
) : (
|
|
<Button
|
|
fill={"none"}
|
|
type={"primary"}
|
|
className="edit-btn"
|
|
onClick={() => handleUploadClick(item, "emptyWeightImg")}
|
|
>
|
|
未上传
|
|
</Button>
|
|
)}
|
|
</View>
|
|
</View>
|
|
<View className="flex !h-8 flex-row items-center justify-between">
|
|
<View className="text-neutral-dark flex-shrink-0 text-sm">
|
|
总磅照片
|
|
</View>
|
|
<View className="text-neutral-darkest text-sm font-medium">
|
|
{item.totalWeightImg ? (
|
|
<Button
|
|
fill={"none"}
|
|
type={"primary"}
|
|
className="edit-btn"
|
|
onClick={() => handleViewClick(item, "totalWeightImg")}
|
|
>
|
|
查看
|
|
</Button>
|
|
) : readOnly ? (
|
|
<Button fill={"none"} type={"default"} disabled>
|
|
未上传
|
|
</Button>
|
|
) : (
|
|
<Button
|
|
fill={"none"}
|
|
type={"primary"}
|
|
className="edit-btn"
|
|
onClick={() => handleUploadClick(item, "totalWeightImg")}
|
|
>
|
|
未上传
|
|
</Button>
|
|
)}
|
|
</View>
|
|
</View>
|
|
<View className="flex !h-8 flex-row items-center justify-between">
|
|
<View className="text-neutral-dark flex-shrink-0 text-sm">
|
|
合同
|
|
</View>
|
|
<View className="text-neutral-darkest text-sm font-medium">
|
|
{item.contractUpload ? (
|
|
<Button
|
|
fill={"none"}
|
|
type={"primary"}
|
|
className="edit-btn"
|
|
onClick={() => handleViewClick(item, "contractImg")}
|
|
>
|
|
查看
|
|
</Button>
|
|
) : readOnly ? (
|
|
<Button fill={"none"} type={"default"} disabled>
|
|
未上传
|
|
</Button>
|
|
) : (
|
|
<Button
|
|
fill={"none"}
|
|
type={"primary"}
|
|
className="edit-btn"
|
|
onClick={() => handleUploadClick(item, "contractImg")}
|
|
>
|
|
未上传
|
|
</Button>
|
|
)}
|
|
</View>
|
|
</View>
|
|
<View className="flex !h-8 flex-row items-center justify-between">
|
|
<View className="text-neutral-dark flex-shrink-0 text-sm">
|
|
发票
|
|
</View>
|
|
<View className="text-neutral-darkest text-sm font-medium">
|
|
{item.invoiceUpload ? (
|
|
<Button
|
|
fill={"none"}
|
|
type={"primary"}
|
|
className="edit-btn"
|
|
onClick={() => handleViewClick(item, "invoiceImg")}
|
|
>
|
|
查看
|
|
</Button>
|
|
) : readOnly ? (
|
|
<Button fill={"none"} type={"default"} disabled>
|
|
未上传
|
|
</Button>
|
|
) : (
|
|
<Button
|
|
fill={"none"}
|
|
type={"primary"}
|
|
className="edit-btn"
|
|
onClick={() => handleUploadClick(item, "invoiceImg")}
|
|
>
|
|
未上传
|
|
</Button>
|
|
)}
|
|
</View>
|
|
</View>
|
|
</View>
|
|
</Tabs.TabPane>
|
|
))}
|
|
</Tabs>
|
|
|
|
{/* 未上传弹窗 */}
|
|
<Popup
|
|
visible={popupVisible && !readOnly}
|
|
position="bottom"
|
|
onClose={() => setPopupVisible(false)}
|
|
round
|
|
lockScroll
|
|
>
|
|
<View className="flex h-full flex-col p-4">
|
|
<View className="mb-4 text-lg font-bold">
|
|
{currentUploadType === "emptyWeightImg" && "空磅照片"}
|
|
{currentUploadType === "totalWeightImg" && "总磅照片"}
|
|
{currentUploadType === "contractImg" && "合同"}
|
|
{currentUploadType === "invoiceImg" && "发票"}
|
|
</View>
|
|
|
|
<View className="mb-4 flex-1 overflow-y-auto">
|
|
<Uploader
|
|
multiple={currentUploadType === "contractImg"}
|
|
maxCount={currentUploadType === "contractImg" ? 9 : 1}
|
|
//@ts-ignore
|
|
upload={uploadFile}
|
|
defaultValue={
|
|
currentSupplier
|
|
? uploadStates[currentSupplier.orderSupplierId]?.[currentUploadType] || []
|
|
: []
|
|
}
|
|
onChange={(fileList) => {
|
|
if (currentSupplier) {
|
|
setUploadStates((prev) => ({
|
|
...prev,
|
|
[currentSupplier.orderSupplierId]: {
|
|
...prev[currentSupplier.orderSupplierId],
|
|
[currentUploadType]: fileList,
|
|
},
|
|
}));
|
|
}
|
|
}}
|
|
/>
|
|
</View>
|
|
|
|
<View className="flex justify-end gap-2">
|
|
<View className={"flex-1"}>
|
|
<Button
|
|
size="large"
|
|
block
|
|
type="default"
|
|
onClick={() => setPopupVisible(false)}
|
|
>
|
|
关闭
|
|
</Button>
|
|
</View>
|
|
<View className={"flex-1"}>
|
|
<Button
|
|
size="large"
|
|
block
|
|
type="primary"
|
|
onClick={handleUploadConfirm}
|
|
>
|
|
确定
|
|
</Button>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
<SafeArea position={"bottom"} />
|
|
</Popup>
|
|
</>
|
|
);
|
|
}
|