feat(purchase): 新增采购订单相关列表组件及常量配置

- 新增 PurchaseOrderList、PurchaseOrderAuditList、PurchaseOrderApprovalList 三个列表组件
- 在 purchase/index.ts 中导出新增的三个组件
- 更新 purchaseOrder 常量配置,增加审核与审批相关的状态列表和映射
- 修改 PageList 组件从 globalStore 获取 loading 状态
- 调整部分页面路径配置
- 新增发票上传相关页面及功能实现
- 优化部分组件导入和状态管理逻辑
This commit is contained in:
shenyifei 2025-11-24 23:28:26 +08:00
parent d37626d5bf
commit 4276945320
62 changed files with 3065 additions and 1455 deletions

View File

@ -18,24 +18,40 @@ config = {
{
root: "pages/purchase",
pages: [
"history",
// 采购员(市场/产地)
"purchaser/create",
"purchaser/preview",
"purchaser/result",
// 采购员(草稿)
"purchaser/draft/list",
// 审核员(报价)
"reviewer/audit/audit",
"reviewer/audit/list",
"reviewer/audit/result",
// 审批员(老板)
"approver/audit/audit",
"approver/audit/list",
"approver/audit/result",
// 全部采购
"enter/all",
// 创建采购单
"enter/create",
// 预览采购单
"enter/preview",
// 采购单提审结果页面
"enter/result",
// 采购单草稿箱
"enter/drafts",
// 采购单审核
"audit/audit",
// 采购单待审核
"audit/pending",
// 采购单审核中
"audit/reviewing",
// 采购单审核结果页面
"audit/result",
// 采购单审核拒绝
"audit/rejected",
// 全部采购单审核
"audit/all",
// 采购单审批
"approval/audit",
// 采购单待审批
"approval/pending",
// 采购单审批中
"approval/reviewing",
// 采购单审批结果页面
"approval/result",
// 采购单审批拒绝
"approval/rejected",
// 全部采购单审批
"approval/all",
],
},
// 发货单
@ -46,7 +62,12 @@ config = {
// 瓜农
{
root: "pages/supplier",
pages: ["list", "purchase/invoice"],
pages: ["create", "all"],
},
// 发票
{
root: "pages/invoice",
pages: ["upload", "all", "pending"],
},
],
permission: {

View File

@ -18,6 +18,7 @@ import {
} from "@nutui/nutui-react-taro";
import { Icon } from "@/components";
import classNames from "classnames";
import { globalStore } from "@/store/global-store";
import { ActionType, IRecordListProps, Query, Record } from "./typing";
export default <T extends {}, Q extends Query = Query>(
@ -47,8 +48,7 @@ export default <T extends {}, Q extends Query = Query>(
toolbar?.search?.defaultActiveKey || "",
);
const [loading, setLoading] = useState<boolean>(true);
const { loading, setLoading } = globalStore((state: any) => state);
const [lightTheme, setLightTheme] = useState(false);
const [data, setData] = useState<Record<any>[]>();
const [query, setQuery] = useState<Query>();

View File

@ -0,0 +1,256 @@
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,
}}
/>
);
}

View File

@ -0,0 +1,256 @@
import {
ActionType,
DealerPicker,
Icon,
PageList,
PurchaseOrderRejectApprove,
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 IPurchaseOrderAuditListProps {
params: BusinessAPI.PurchaseOrderPageQry;
toolbar?: ToolBar;
actionRef?: React.MutableRefObject<ActionType | undefined>;
}
export default function PurchaseOrderAuditList(
props: IPurchaseOrderAuditListProps,
) {
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.auditStateMap}
/>
</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_QUOTE_APPROVAL" && (
<View className={"flex flex-row justify-end gap-2"}>
<PurchaseOrderRejectApprove
purchaseOrderVO={purchaseOrderVO}
size={"small"}
onFinish={() => {
actionRef.current?.reload();
}}
/>
<Button
type={"primary"}
size={"small"}
onClick={(e) => {
Taro.navigateTo({
url: buildUrl("/pages/purchase/audit/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,
}}
/>
);
}

View File

@ -0,0 +1,400 @@
import {
ActionType,
CopyText,
DealerPicker,
Icon,
PageList,
PurchaseOrderWithdrawReview,
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, Dialog, Toast } from "@nutui/nutui-react-taro";
import dayjs from "dayjs";
import purchaseOrder from "@/constant/purchaseOrder";
import Taro from "@tarojs/taro";
interface IPurchaseOrderListProps {
params: BusinessAPI.PurchaseOrderPageQry;
create?: boolean;
toolbar?: ToolBar;
actionRef?: React.MutableRefObject<ActionType | undefined>;
}
export default function PurchaseOrderList(props: IPurchaseOrderListProps) {
const {
params: bizParams,
create = false,
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>
),
actions: [
create && (
<View className={"flex flex-row gap-2 p-3"} key={"create"}>
<View className={"flex-1"}>
<View
className="bg-primary flex w-full flex-col items-center justify-center space-y-2 rounded-xl py-2.5 text-white"
onClick={() => {
Taro.navigateTo({
url: buildUrl("/pages/purchase/enter/create"),
});
}}
>
<View className="text-base font-bold"></View>
</View>
</View>
</View>
),
],
};
// 删除采购订单
const handleDelete = (purchaseOrderVO: BusinessAPI.PurchaseOrderVO) => {
Dialog.open("dialog", {
title: "删除采购单",
content: `确定要删除这个采购单吗?删除后就找不回来了!`,
confirmText: "确定",
cancelText: "取消",
onConfirm: async () => {
try {
const { data } = await business.purchaseOrder.destroyPurchaseOrder({
orderId: purchaseOrderVO.orderId,
});
if (data.success) {
Toast.show("toast", {
icon: "success",
title: "提示",
content: "采购单删除成功",
});
actionRef.current?.reload();
} else {
Toast.show("toast", {
icon: "fail",
title: "提示",
content: data.errMessage || "删除失败",
});
}
} catch (error) {
Toast.show("toast", {
icon: "fail",
title: "提示",
content: "删除失败",
});
} finally {
Dialog.close("dialog");
}
},
onCancel: () => {
Dialog.close("dialog");
},
});
};
return (
<PageList<BusinessAPI.PurchaseOrderVO, BusinessAPI.PurchaseOrderPageQry>
rowId={"purchaseOrderId"}
itemHeight={182}
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"}
onClick={(event) => {
if (purchaseOrderVO.active === 7) {
Taro.navigateTo({
url: buildUrl("/pages/purchase/enter/preview", {
orderId: purchaseOrderVO.orderId,
}),
});
event.stopPropagation();
}
}}
>
<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?.origin} {" 至 "}
{purchaseOrderVO.orderVehicle?.destination}
</Text>
</View>
<Text className={"text-neutral-dark text-sm"}>
<CopyText copyData={purchaseOrderVO.orderSn}>
{purchaseOrderVO.orderSn}
</CopyText>
</Text>
</View>
<State
state={purchaseOrderVO.state}
stateMap={purchaseOrder.stateMap}
/>
</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"}>
{dayjs(purchaseOrderVO.createdAt).format("MM-DD HH:mm")}
</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.orderVehicle?.deliveryTime,
).format("YYYY年MM月DD日")}
</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.orderVehicle.dealerName}
</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.orderVehicle?.driver}
{purchaseOrderVO.orderVehicle?.plate}
</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.orderSupplierList
.map((item) => item.name)
.join(",")}
</Text>
</View>
</View>
</View>
</View>
<View className={"py-2.5"}>
<View className={"flex flex-row justify-end gap-2"}>
{purchaseOrderVO.state === "DRAFT" && (
<>
<Button
type={"danger"}
size={"small"}
onClick={(e) => {
handleDelete(purchaseOrderVO);
e.stopPropagation();
}}
>
</Button>
{/* 联系司机 */}
{purchaseOrderVO.orderVehicle.phone && (
<Button
type={"default"}
size={"small"}
onClick={(e) => {
Taro.makePhoneCall({
phoneNumber: purchaseOrderVO.orderVehicle
.phone as string,
});
e.stopPropagation();
}}
>
</Button>
)}
<Button
type={"default"}
size={"small"}
onClick={(e) => {
Taro.navigateTo({
url: buildUrl("/pages/purchase/enter/create", {
orderId: purchaseOrderVO.orderId,
}),
});
e.stopPropagation();
}}
>
</Button>
{purchaseOrderVO.active === 7 && (
<Button
type={"primary"}
size={"small"}
onClick={(e) => {
Taro.navigateTo({
url: buildUrl("/pages/purchase/enter/preview", {
orderId: purchaseOrderVO.orderId,
}),
});
e.stopPropagation();
}}
>
</Button>
)}
</>
)}
{purchaseOrderVO.state === "WAITING_AUDIT" && (
<>
<PurchaseOrderWithdrawReview
purchaseOrderVO={purchaseOrderVO}
size={"small"}
onFinish={() => {
actionRef.current?.reload();
}}
/>
</>
)}
</View>
</View>
</View>
</View>
);
}}
toolbar={toolbar}
request={async (params) => {
const {
data: { data, success, notEmpty },
} = await business.purchaseOrder.pagePurchaseOrder({
purchaseOrderPageQry: {
...params,
...bizParams,
},
});
return {
data,
success,
hasMore: notEmpty,
};
}}
pagination={{
pageSize: 10,
}}
/>
);
}

View File

@ -88,7 +88,7 @@ export default function PurchaseOrderSubmitReview(
cancelText: "取消",
onConfirm: async () => {
Taro.redirectTo({
url: buildUrl("/pages/purchase/purchaser/create", {
url: buildUrl("/pages/purchase/enter/create", {
orderId: purchaseOrderVO.orderId,
supplierId: lastSupplier.supplierId,
step: "2",
@ -120,7 +120,7 @@ export default function PurchaseOrderSubmitReview(
cancelText: "取消",
onConfirm: async () => {
Taro.redirectTo({
url: buildUrl("/pages/purchase/purchaser/create", {
url: buildUrl("/pages/purchase/enter/create", {
orderId: purchaseOrderVO.orderId,
supplierId: hasNoUpdateContractSupplier.supplierId,
step: "5",

View File

@ -41,3 +41,7 @@ export { default as PurchaseStep1Form } from "./document/Step1Form";
export type { Step1FormRef as PurchaseStep1FormRef } from "./document/Step1Form";
export { default as PurchaseStep2Preview } from "./document/Step2Preview";
export { default as PurchaseStep3Success } from "./document/Step3Success";
export { default as PurchaseOrderList } from "./PurchaseOrderList";
export { default as PurchaseOrderAuditList } from "./PurchaseOrderAuditList";
export { default as PurchaseOrderApprovalList } from "./PurchaseOrderApprovalList";

View File

@ -1,41 +1,15 @@
/**
* 采购订单状态: 0_草稿1_审核中2_审批中3_待发货4_已发货5_已付款6_已完结7_已驳回8_已关闭
DRAFT(0, "草稿"),
WAITING_AUDIT(1, "审核中"),
WAITING_APPROVE(2, "审批中"),
WAITING_SHIPMENT(3, "待发货"),
SHIPPED(4, "已发货"),
PAID(5, "已付款"),
COMPLETED(6, "已完结"),
REJECTED(7, "已驳回"),
*
*/
const stateList = [
{
title: "全部",
value: "ALL",
title: "草稿",
value: "DRAFT",
},
{
title: "审核中",
value: "WAITING_AUDIT",
},
{
title: "审批中",
value: "WAITING_APPROVE",
},
{
title: "待发货",
value: "WAITING_SHIPMENT",
},
{
title: "已发货",
value: "SHIPPED",
},
{
title: "已付款",
value: "PAID",
},
{
title: "已完结",
value: "COMPLETED",
@ -44,9 +18,11 @@ const stateList = [
title: "已驳回",
value: "REJECTED",
},
{
title: "已关闭",
value: "CLOSED",
},
];
// 定义需求状态映射 - 优化颜色方案
const stateMap = {
DRAFT: {
label: "草稿",
@ -55,35 +31,11 @@ const stateMap = {
borderColor: "#EA580C",
},
WAITING_AUDIT: {
label: "审核",
label: "审核",
color: "#1E40AF",
bgColor: "#DBEAFE",
borderColor: "#3B82F6",
},
WAITING_APPROVE: {
label: "待老板审批",
color: "#7C2D12",
bgColor: "#FDE68A",
borderColor: "#F59E0B",
},
WAITING_SHIPMENT: {
label: "待发货",
color: "#7C2D12",
bgColor: "#FDE68A",
borderColor: "#F59E0B",
},
SHIPPED: {
label: "已发货(待付款)",
color: "#86198F",
bgColor: "#F3E8FF",
borderColor: "#A855F7",
},
PAID: {
label: "已付款",
color: "#065F46",
bgColor: "#A7F3D0",
borderColor: "#10B981",
},
COMPLETED: {
label: "已完结",
color: "#374151",
@ -95,10 +47,106 @@ const stateMap = {
color: "#991B1B",
bgColor: "#FEE2E2",
borderColor: "#EF4444",
}
},
CLOSED: {
label: "已关闭",
color: "#6B7280",
bgColor: "#F3F4F6",
borderColor: "#6B7280",
},
};
/**
*
*/
const auditStateList = [
{
title: "待我审核",
value: "PENDING_QUOTE_APPROVAL",
},
{
title: "审批中",
value: "PENDING_BOSS_APPROVAL",
},
{
title: "已通过",
value: "BOSS_APPROVED",
},
{
title: "已驳回",
value: "BOSS_REJECTED",
},
];
const auditStateMap = {
PENDING_QUOTE_APPROVAL: {
label: "待我审核",
color: "#7C2D12",
bgColor: "#FED7AA",
borderColor: "#EA580C",
},
PENDING_BOSS_APPROVAL: {
label: "审批中",
color: "#1E40AF",
bgColor: "#DBEAFE",
borderColor: "#3B82F6",
},
BOSS_APPROVED: {
label: "已通过",
color: "#374151",
bgColor: "#E5E7EB",
borderColor: "#6B7280",
},
BOSS_REJECTED: {
label: "已驳回",
color: "#6B7280",
bgColor: "#F3F4F6",
borderColor: "#6B7280",
},
};
/**
*
*/
const approvalStateList = [
{
title: "待我审批",
value: "PENDING_BOSS_APPROVAL",
},
{
title: "已通过",
value: "BOSS_APPROVED",
},
{
title: "已驳回",
value: "BOSS_REJECTED",
},
];
const approvalStateMap = {
PENDING_BOSS_APPROVAL: {
label: "待我审批",
color: "#7C2D12",
bgColor: "#FED7AA",
borderColor: "#EA580C",
},
BOSS_APPROVED: {
label: "已通过",
color: "#374151",
bgColor: "#E5E7EB",
borderColor: "#6B7280",
},
BOSS_REJECTED: {
label: "已驳回",
color: "#991B1B",
bgColor: "#FEE2E2",
borderColor: "#EF4444",
},
};
export default {
stateList,
stateMap: stateMap,
stateMap,
auditStateList,
auditStateMap,
approvalStateList,
approvalStateMap,
};

View File

@ -170,7 +170,7 @@ const quickActionMap = {
icon: "file-signature",
iconColor: "var(--color-primary)",
bgColorClass: "bg-primary/10",
path: "/pages/purchase/reviewer/audit/list",
path: "/pages/purchase/audit/pending",
},
{
id: "history",

View File

@ -16,11 +16,12 @@ const hocAuth = (
base((props: any) => {
const { options, router } = props;
const user = userStore(useShallow((state) => state.user));
const { userRoleVO, setUserRoleVO } = globalStore((state: any) => state);
const { userRoleVO, setUserRoleVO, loading, setLoading } = globalStore(
(state: any) => state,
);
const [longitude, setLongitude] = useState<number>();
const [latitude, setLatitude] = useState<number>();
const [loading, setLoading] = useState<boolean>(false);
// 控制是否已初始化
const [isInitialized, setIsInitialized] = useState(false);

View File

@ -0,0 +1,4 @@
export default definePageConfig({
navigationBarTitleText: "上传发票",
navigationBarBackgroundColor: "#fff",
});

View File

@ -0,0 +1,362 @@
import {
ActionType,
Icon,
PageList,
SupplierPicker,
ToolBar,
} from "@/components";
import { useShareAppMessage } from "@tarojs/taro";
import { useRef, useState } from "react";
import { business } from "@/services";
import hocAuth from "@/hocs/auth";
import { CommonComponent } from "@/types/typings";
import { View } from "@tarojs/components";
import dayjs from "dayjs";
import {
Button,
Popup,
SafeArea,
Toast,
Uploader,
UploaderFileItem,
} from "@nutui/nutui-react-taro";
import { uploadFile } from "@/utils";
export default hocAuth(function Page(props: CommonComponent) {
const { shareOptions } = props;
const [supplierVO, setSupplierVO] = useState<BusinessAPI.SupplierVO>();
const [popupVisible, setPopupVisible] = useState(false);
const [selectedOrders, setSelectedOrders] = useState<
BusinessAPI.OrderSupplierVO[]
>([]);
const [contractFiles, setContractFiles] = useState<any[]>([]);
const [invoiceFiles, setInvoiceFiles] = useState<any[]>([]);
// 发票照片
const [invoiceImgList, setInvoiceImgList] = useState<UploaderFileItem[]>([]);
// 合同照片
const [contractImgList, setContractImgList] = useState<UploaderFileItem[]>(
[],
);
// 发票照片变更处理函数
const handleInvoiceImgChange = (files: UploaderFileItem[]) => {
setInvoiceImgList(files);
// 如果有文件且上传成功保存URL到supplierVO
if (files.length > 0 && files[0].url) {
setSupplierVO((prev) => ({
...prev!,
invoiceImg: [files[0].url!],
invoiceUpload: true,
}));
} else {
// 如果没有文件清空URL
setSupplierVO((prev) => ({
...prev!,
invoiceImg: undefined,
invoiceUpload: false,
}));
}
};
// 合同照片变更处理函数
const handleContractImgChange = (files: UploaderFileItem[]) => {
setContractImgList(files);
// 保存所有文件URL到supplierVO
const urls = files.map((file) => file.url).filter((url) => url) as string[];
setSupplierVO((prev) => ({
...prev!,
contractImg: urls,
contractUpload: urls.length > 0,
}));
};
const actionRef = useRef<ActionType>();
const toolbar: ToolBar = {
selectRow: {
onClick: async (orderSupplierVOList: BusinessAPI.OrderSupplierVO[]) => {
console.log("orderSupplierVOList", orderSupplierVOList);
// 点击弹出popup
setSelectedOrders(orderSupplierVOList);
setPopupVisible(true);
},
},
search: {
activeKey: "vehicleNo",
defaultActiveKey: "vehicleNo",
items: [
{
key: "vehicleNo",
name: "车次号",
placeholder: "请输入车次号",
},
{
key: "plate",
name: "车牌号",
placeholder: "请输入车牌号",
},
],
},
render: () => (
<>
{/* Popup 弹窗 */}
<Popup
duration={150}
style={{
minHeight: "auto",
}}
visible={popupVisible}
position="bottom"
onClose={() => setPopupVisible(false)}
onOverlayClick={() => setPopupVisible(false)}
lockScroll
round
>
<View className="border-t border-green-100 bg-green-50 p-3">
{/* 统计信息 */}
<View className="mb-2 flex items-center justify-between">
<View className="text-sm font-medium text-gray-800">
{" "}
<View className="text-primary inline">
{selectedOrders.length}
</View>{" "}
</View>
<View className="text-sm font-medium text-gray-800">
<View className="text-primary inline">{totalWeight}</View>
</View>
<View className="text-sm font-medium text-gray-800">
{" "}
<View className="text-primary inline">
{totalAmount.toFixed(2)}
</View>
</View>
</View>
{/* 上传发票 */}
<View className="mb-2 flex items-center justify-between">
<View className="flex-1">
<Uploader
className={"w-full"}
value={invoiceImgList}
onChange={handleInvoiceImgChange}
sourceType={["album", "camera"]}
uploadIcon={<Icon name={"camera"} size={36} />}
uploadLabel={
<View className={"flex flex-col items-center"}>
<View className="text-sm"></View>
<View className="mt-1 text-xs text-gray-400">
</View>
</View>
}
maxCount={1}
//@ts-ignore
upload={uploadFile}
multiple
/>
</View>
</View>
{/* 上传合同 */}
<View className="mb-2 flex items-center justify-between">
<View className="flex-1">
<Uploader
className={"w-full"}
value={contractImgList}
onChange={handleContractImgChange}
sourceType={["album", "camera"]}
uploadIcon={<Icon name={"camera"} size={36} />}
uploadLabel={
<View className={"flex flex-col items-center"}>
<View className="text-sm"></View>
<View className="mt-1 text-xs text-gray-400">
</View>
</View>
}
maxCount={9}
//@ts-ignore
upload={uploadFile}
multiple
/>
</View>
</View>
<View className={"flex flex-1 flex-row gap-2.5"}>
<View className={"flex-1"}>
<Button
size={"xlarge"}
block
type="default"
onClick={() => setPopupVisible(false)}
>
</Button>
</View>
{/* 提交按钮 */}
<View className={"flex-1"}>
<Button
size={"xlarge"}
block
type="primary"
disabled={
contractFiles.length === 0 || invoiceFiles.length === 0
}
onClick={handleSubmit}
>
</Button>
</View>
</View>
<SafeArea position={"bottom"} />
</View>
</Popup>
<View className={"flex flex-row gap-2.5"}>
<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>
</>
),
};
useShareAppMessage((res) => {
console.log("useShareAppMessage1", res, shareOptions);
// 如果是按钮触发的转发,使用默认配置
if (res.from === "button") {
return shareOptions;
}
// 页面转发使用设置的配置
return {};
});
// 计算选中车次的总重量和总金额
const calculateTotals = () => {
return selectedOrders.reduce(
(totals, order) => {
totals.totalWeight += order.netWeight || 0;
totals.totalAmount += order.invoiceAmount || 0;
return totals;
},
{ totalWeight: 0, totalAmount: 0 },
);
};
const { totalWeight, totalAmount } = calculateTotals();
// 提交申请
const handleSubmit = async () => {
// 这里添加提交申请的逻辑
Toast.show("提交申请成功", { duration: 1500 });
setPopupVisible(false);
// 重置状态
setContractFiles([]);
setInvoiceFiles([]);
};
return (
<>
<PageList<BusinessAPI.OrderSupplierVO, BusinessAPI.OrderSupplierPageQry>
rowId={"orderSupplierId"}
itemHeight={182}
type={"infinite"}
actionRef={actionRef}
render={(orderSupplierVO: BusinessAPI.OrderSupplierVO, index) => (
<View className={"flex-1"} key={index}>
<View
className={"relative flex flex-col divide-y-2 divide-neutral-100"}
>
<View className="flex-1">
<View className="flex items-start justify-between">
<View>
<View className="text-base font-medium text-gray-800">
{orderSupplierVO.name} (
{orderSupplierVO.orderVehicle?.origin}-
{orderSupplierVO.orderVehicle?.destination})
</View>
</View>
{/*<View className="rounded bg-gray-100 px-2 py-1 text-xs text-gray-800">*/}
{/* 草稿*/}
{/*</View>*/}
</View>
<View className="my-1 flex flex-row flex-wrap gap-1 text-sm text-gray-600">
<View className="text-primary">
{orderSupplierVO.orderVehicle?.vehicleNo
? "第" + orderSupplierVO.orderVehicle?.vehicleNo + "车"
: "暂未生成车次"}
</View>
<View>
{dayjs(orderSupplierVO.orderVehicle?.deliveryTime).format(
"MM-DD",
)}
</View>
<View>|</View>
<View>{orderSupplierVO.netWeight}</View>
<View>|</View>
<View>¥{orderSupplierVO.invoiceAmount}</View>
</View>
<View className="text-xs text-gray-500">
{`${orderSupplierVO.productName} | 品种:`}
</View>
</View>
</View>
</View>
)}
toolbar={toolbar}
request={async (params) => {
const {
data: { data, success, notEmpty },
} = await business.orderSupplier.pageOrderSupplier({
orderSupplierPageQry: {
...params,
...(supplierVO
? {
supplierId: supplierVO.supplierId,
}
: {}),
},
});
return {
data,
success,
hasMore: notEmpty,
};
}}
pagination={{
pageSize: 10,
}}
/>
</>
);
});

View File

@ -0,0 +1,4 @@
export default definePageConfig({
navigationBarTitleText: "上传发票",
navigationBarBackgroundColor: "#fff",
});

View File

@ -0,0 +1,362 @@
import {
ActionType,
Icon,
PageList,
SupplierPicker,
ToolBar,
} from "@/components";
import { useShareAppMessage } from "@tarojs/taro";
import { useRef, useState } from "react";
import { business } from "@/services";
import hocAuth from "@/hocs/auth";
import { CommonComponent } from "@/types/typings";
import { View } from "@tarojs/components";
import dayjs from "dayjs";
import {
Button,
Popup,
SafeArea,
Toast,
Uploader,
UploaderFileItem,
} from "@nutui/nutui-react-taro";
import { uploadFile } from "@/utils";
export default hocAuth(function Page(props: CommonComponent) {
const { shareOptions } = props;
const [supplierVO, setSupplierVO] = useState<BusinessAPI.SupplierVO>();
const [popupVisible, setPopupVisible] = useState(false);
const [selectedOrders, setSelectedOrders] = useState<
BusinessAPI.OrderSupplierVO[]
>([]);
const [contractFiles, setContractFiles] = useState<any[]>([]);
const [invoiceFiles, setInvoiceFiles] = useState<any[]>([]);
// 发票照片
const [invoiceImgList, setInvoiceImgList] = useState<UploaderFileItem[]>([]);
// 合同照片
const [contractImgList, setContractImgList] = useState<UploaderFileItem[]>(
[],
);
// 发票照片变更处理函数
const handleInvoiceImgChange = (files: UploaderFileItem[]) => {
setInvoiceImgList(files);
// 如果有文件且上传成功保存URL到supplierVO
if (files.length > 0 && files[0].url) {
setSupplierVO((prev) => ({
...prev!,
invoiceImg: [files[0].url!],
invoiceUpload: true,
}));
} else {
// 如果没有文件清空URL
setSupplierVO((prev) => ({
...prev!,
invoiceImg: undefined,
invoiceUpload: false,
}));
}
};
// 合同照片变更处理函数
const handleContractImgChange = (files: UploaderFileItem[]) => {
setContractImgList(files);
// 保存所有文件URL到supplierVO
const urls = files.map((file) => file.url).filter((url) => url) as string[];
setSupplierVO((prev) => ({
...prev!,
contractImg: urls,
contractUpload: urls.length > 0,
}));
};
const actionRef = useRef<ActionType>();
const toolbar: ToolBar = {
selectRow: {
onClick: async (orderSupplierVOList: BusinessAPI.OrderSupplierVO[]) => {
console.log("orderSupplierVOList", orderSupplierVOList);
// 点击弹出popup
setSelectedOrders(orderSupplierVOList);
setPopupVisible(true);
},
},
search: {
activeKey: "vehicleNo",
defaultActiveKey: "vehicleNo",
items: [
{
key: "vehicleNo",
name: "车次号",
placeholder: "请输入车次号",
},
{
key: "plate",
name: "车牌号",
placeholder: "请输入车牌号",
},
],
},
render: () => (
<>
{/* Popup 弹窗 */}
<Popup
duration={150}
style={{
minHeight: "auto",
}}
visible={popupVisible}
position="bottom"
onClose={() => setPopupVisible(false)}
onOverlayClick={() => setPopupVisible(false)}
lockScroll
round
>
<View className="border-t border-green-100 bg-green-50 p-3">
{/* 统计信息 */}
<View className="mb-2 flex items-center justify-between">
<View className="text-sm font-medium text-gray-800">
{" "}
<View className="text-primary inline">
{selectedOrders.length}
</View>{" "}
</View>
<View className="text-sm font-medium text-gray-800">
<View className="text-primary inline">{totalWeight}</View>
</View>
<View className="text-sm font-medium text-gray-800">
{" "}
<View className="text-primary inline">
{totalAmount.toFixed(2)}
</View>
</View>
</View>
{/* 上传发票 */}
<View className="mb-2 flex items-center justify-between">
<View className="flex-1">
<Uploader
className={"w-full"}
value={invoiceImgList}
onChange={handleInvoiceImgChange}
sourceType={["album", "camera"]}
uploadIcon={<Icon name={"camera"} size={36} />}
uploadLabel={
<View className={"flex flex-col items-center"}>
<View className="text-sm"></View>
<View className="mt-1 text-xs text-gray-400">
</View>
</View>
}
maxCount={1}
//@ts-ignore
upload={uploadFile}
multiple
/>
</View>
</View>
{/* 上传合同 */}
<View className="mb-2 flex items-center justify-between">
<View className="flex-1">
<Uploader
className={"w-full"}
value={contractImgList}
onChange={handleContractImgChange}
sourceType={["album", "camera"]}
uploadIcon={<Icon name={"camera"} size={36} />}
uploadLabel={
<View className={"flex flex-col items-center"}>
<View className="text-sm"></View>
<View className="mt-1 text-xs text-gray-400">
</View>
</View>
}
maxCount={9}
//@ts-ignore
upload={uploadFile}
multiple
/>
</View>
</View>
<View className={"flex flex-1 flex-row gap-2.5"}>
<View className={"flex-1"}>
<Button
size={"xlarge"}
block
type="default"
onClick={() => setPopupVisible(false)}
>
</Button>
</View>
{/* 提交按钮 */}
<View className={"flex-1"}>
<Button
size={"xlarge"}
block
type="primary"
disabled={
contractFiles.length === 0 || invoiceFiles.length === 0
}
onClick={handleSubmit}
>
</Button>
</View>
</View>
<SafeArea position={"bottom"} />
</View>
</Popup>
<View className={"flex flex-row gap-2.5"}>
<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>
</>
),
};
useShareAppMessage((res) => {
console.log("useShareAppMessage1", res, shareOptions);
// 如果是按钮触发的转发,使用默认配置
if (res.from === "button") {
return shareOptions;
}
// 页面转发使用设置的配置
return {};
});
// 计算选中车次的总重量和总金额
const calculateTotals = () => {
return selectedOrders.reduce(
(totals, order) => {
totals.totalWeight += order.netWeight || 0;
totals.totalAmount += order.invoiceAmount || 0;
return totals;
},
{ totalWeight: 0, totalAmount: 0 },
);
};
const { totalWeight, totalAmount } = calculateTotals();
// 提交申请
const handleSubmit = async () => {
// 这里添加提交申请的逻辑
Toast.show("提交申请成功", { duration: 1500 });
setPopupVisible(false);
// 重置状态
setContractFiles([]);
setInvoiceFiles([]);
};
return (
<>
<PageList<BusinessAPI.OrderSupplierVO, BusinessAPI.OrderSupplierPageQry>
rowId={"orderSupplierId"}
itemHeight={182}
type={"infinite"}
actionRef={actionRef}
render={(orderSupplierVO: BusinessAPI.OrderSupplierVO, index) => (
<View className={"flex-1"} key={index}>
<View
className={"relative flex flex-col divide-y-2 divide-neutral-100"}
>
<View className="flex-1">
<View className="flex items-start justify-between">
<View>
<View className="text-base font-medium text-gray-800">
{orderSupplierVO.name} (
{orderSupplierVO.orderVehicle?.origin}-
{orderSupplierVO.orderVehicle?.destination})
</View>
</View>
{/*<View className="rounded bg-gray-100 px-2 py-1 text-xs text-gray-800">*/}
{/* 草稿*/}
{/*</View>*/}
</View>
<View className="my-1 flex flex-row flex-wrap gap-1 text-sm text-gray-600">
<View className="text-primary">
{orderSupplierVO.orderVehicle?.vehicleNo
? "第" + orderSupplierVO.orderVehicle?.vehicleNo + "车"
: "暂未生成车次"}
</View>
<View>
{dayjs(orderSupplierVO.orderVehicle?.deliveryTime).format(
"MM-DD",
)}
</View>
<View>|</View>
<View>{orderSupplierVO.netWeight}</View>
<View>|</View>
<View>¥{orderSupplierVO.invoiceAmount}</View>
</View>
<View className="text-xs text-gray-500">
{`${orderSupplierVO.productName} | 品种:`}
</View>
</View>
</View>
</View>
)}
toolbar={toolbar}
request={async (params) => {
const {
data: { data, success, notEmpty },
} = await business.orderSupplier.pageOrderSupplier({
orderSupplierPageQry: {
...params,
...(supplierVO
? {
supplierId: supplierVO.supplierId,
}
: {}),
},
});
return {
data,
success,
hasMore: notEmpty,
};
}}
pagination={{
pageSize: 10,
}}
/>
</>
);
});

View File

@ -55,7 +55,7 @@ export default hocAuth(function Page(props: CommonComponent) {
className="bg-primary flex w-full flex-col items-center justify-center space-y-2 rounded-xl py-2.5 text-white"
onClick={() => {
Taro.navigateTo({
url: buildUrl("/pages/purchase/purchaser/create"),
url: buildUrl("/pages/purchase/enter/create"),
});
}}
>

View File

@ -0,0 +1,49 @@
import { ActionType, PurchaseOrderApprovalList } from "@/components";
import { useShareAppMessage } from "@tarojs/taro";
import { useRef, useState } from "react";
import hocAuth from "@/hocs/auth";
import { CommonComponent } from "@/types/typings";
import purchaseOrder from "@/constant/purchaseOrder";
export default hocAuth(function Page(props: CommonComponent) {
const { shareOptions } = props;
const [auditState, setAuditState] = useState<
BusinessAPI.PurchaseOrderPageQry["auditState"]
>("PENDING_BOSS_APPROVAL");
const actionRef = useRef<ActionType>();
useShareAppMessage((res) => {
console.log("useShareAppMessage1", res, shareOptions);
// 如果是按钮触发的转发,使用默认配置
if (res.from === "button") {
return shareOptions;
}
// 页面转发使用设置的配置
return {};
});
return (
<PurchaseOrderApprovalList
actionRef={actionRef}
toolbar={{
tabs: {
activeKey: "state",
defaultActiveKey: auditState!,
items: purchaseOrder.approvalStateList,
onChange: (item) => {
setAuditState(
item as BusinessAPI.PurchaseOrderPageQry["auditState"],
);
actionRef.current?.reload();
},
},
}}
params={{
state: "WAITING_AUDIT",
auditState: auditState,
}}
/>
);
});

View File

@ -178,36 +178,37 @@ export default hocAuth(function Page(props: CommonComponent) {
{/* 按钮操作 */}
<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>
</>
)}
{purchaseOrderVO.state === "WAITING_AUDIT" &&
purchaseOrderVO.auditState === "PENDING_BOSS_APPROVAL" && (
<>
<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>

View File

@ -0,0 +1,27 @@
import { PurchaseOrderApprovalList } from "@/components";
import { useShareAppMessage } from "@tarojs/taro";
import hocAuth from "@/hocs/auth";
import { CommonComponent } from "@/types/typings";
export default hocAuth(function Page(props: CommonComponent) {
const { shareOptions } = props;
useShareAppMessage((res) => {
console.log("useShareAppMessage1", res, shareOptions);
// 如果是按钮触发的转发,使用默认配置
if (res.from === "button") {
return shareOptions;
}
// 页面转发使用设置的配置
return {};
});
return (
<PurchaseOrderApprovalList
params={{
state: "WAITING_AUDIT",
auditState: "PENDING_BOSS_APPROVAL",
}}
/>
);
});

View File

@ -0,0 +1,4 @@
export default definePageConfig({
navigationBarTitleText: "采购单驳回",
navigationBarBackgroundColor: "#fff",
});

View File

@ -0,0 +1,27 @@
import { PurchaseOrderApprovalList } from "@/components";
import { useShareAppMessage } from "@tarojs/taro";
import hocAuth from "@/hocs/auth";
import { CommonComponent } from "@/types/typings";
export default hocAuth(function Page(props: CommonComponent) {
const { shareOptions } = props;
useShareAppMessage((res) => {
console.log("useShareAppMessage1", res, shareOptions);
// 如果是按钮触发的转发,使用默认配置
if (res.from === "button") {
return shareOptions;
}
// 页面转发使用设置的配置
return {};
});
return (
<PurchaseOrderApprovalList
params={{
state: "REJECTED",
auditState: "BOSS_REJECTED",
}}
/>
);
});

View File

@ -0,0 +1,27 @@
import { PurchaseOrderAuditList } from "@/components";
import { useShareAppMessage } from "@tarojs/taro";
import hocAuth from "@/hocs/auth";
import { CommonComponent } from "@/types/typings";
export default hocAuth(function Page(props: CommonComponent) {
const { shareOptions } = props;
useShareAppMessage((res) => {
console.log("useShareAppMessage1", res, shareOptions);
// 如果是按钮触发的转发,使用默认配置
if (res.from === "button") {
return shareOptions;
}
// 页面转发使用设置的配置
return {};
});
return (
<PurchaseOrderAuditList
params={{
state: "WAITING_AUDIT",
auditState: "PENDING_BOSS_APPROVAL",
}}
/>
);
});

View File

@ -1,224 +0,0 @@
import {
ActionType,
PageList,
PurchaseOrderRejectFinal,
State,
} from "@/components";
import Taro, { useShareAppMessage } from "@tarojs/taro";
import { useRef } from "react";
import { business } from "@/services";
import hocAuth from "@/hocs/auth";
import { CommonComponent } from "@/types/typings";
import { Label, Text, View } from "@tarojs/components";
import { buildUrl, formatCurrency, PurchaseOrderCalculator } from "@/utils";
import { Button } from "@nutui/nutui-react-taro";
import purchaseOrder from "@/constant/purchaseOrder";
import dayjs from "dayjs";
export default hocAuth(function Page(props: CommonComponent) {
const { shareOptions } = props;
const actionRef = useRef<ActionType>();
useShareAppMessage((res) => {
console.log("useShareAppMessage1", res, shareOptions);
// 如果是按钮触发的转发,使用默认配置
if (res.from === "button") {
return shareOptions;
}
// 页面转发使用设置的配置
return {};
});
return (
<PageList<BusinessAPI.PurchaseOrderVO, BusinessAPI.PurchaseOrderPageQry>
rowId={"purchaseOrderId"}
itemHeight={182}
type={"infinite"}
actionRef={actionRef}
render={(purchaseOrderVO: BusinessAPI.PurchaseOrderVO, index) => {
const calculator = new PurchaseOrderCalculator(purchaseOrderVO);
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?.vehicleNo
? "第" +
purchaseOrderVO.orderVehicle?.vehicleNo +
"车"
: "暂未生成车次"}
</Text>
</View>
<Text className={"text-neutral-dark text-sm"}>
{purchaseOrderVO.orderSn}
</Text>
</View>
<State
state={purchaseOrderVO.state}
stateMap={purchaseOrder.stateMap}
/>
</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.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
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.orderVehicle?.origin} {"->"}
{purchaseOrderVO.orderVehicle?.destination}
</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.orderVehicle.dealerName}
</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.orderVehicle?.plate}
</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.orderSupplierList.length}
</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"}>
{formatCurrency(calculator.getTotalGrossWeight())}{" "}
/ {" "}
{formatCurrency(calculator.getTotalNetWeight())}
</Text>
</View>
</View>
</View>
</View>
<View className={"py-2.5"}>
<View className={"flex flex-row justify-end gap-2"}>
{purchaseOrderVO.state === "WAITING_APPROVE" && (
<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/approver/audit/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,
state: "WAITING_APPROVE",
},
});
return {
data,
success,
hasMore: notEmpty,
};
}}
pagination={{
pageSize: 10,
}}
/>
);
});

View File

@ -0,0 +1,4 @@
export default definePageConfig({
navigationBarTitleText: "采购单",
navigationBarBackgroundColor: "#fff",
});

View File

@ -0,0 +1,49 @@
import { ActionType, PurchaseOrderAuditList } from "@/components";
import { useShareAppMessage } from "@tarojs/taro";
import { useRef, useState } from "react";
import hocAuth from "@/hocs/auth";
import { CommonComponent } from "@/types/typings";
import purchaseOrder from "@/constant/purchaseOrder";
export default hocAuth(function Page(props: CommonComponent) {
const { shareOptions } = props;
const [auditState, setAuditState] = useState<
BusinessAPI.PurchaseOrderPageQry["auditState"]
>("PENDING_QUOTE_APPROVAL");
const actionRef = useRef<ActionType>();
useShareAppMessage((res) => {
console.log("useShareAppMessage1", res, shareOptions);
// 如果是按钮触发的转发,使用默认配置
if (res.from === "button") {
return shareOptions;
}
// 页面转发使用设置的配置
return {};
});
return (
<PurchaseOrderAuditList
actionRef={actionRef}
toolbar={{
tabs: {
activeKey: "state",
defaultActiveKey: auditState!,
items: purchaseOrder.auditStateList,
onChange: (item) => {
setAuditState(
item as BusinessAPI.PurchaseOrderPageQry["auditState"],
);
actionRef.current?.reload();
},
},
}}
params={{
state: "WAITING_AUDIT",
auditState: auditState,
}}
/>
);
});

View File

@ -217,7 +217,7 @@ export default hocAuth(function Page(props: CommonComponent) {
setTimeout(() => {
Taro.redirectTo({
url: buildUrl("/pages/purchase/reviewer/audit/list"),
url: buildUrl("/pages/purchase/audit/pending"),
});
}, 1000);
@ -281,7 +281,7 @@ export default hocAuth(function Page(props: CommonComponent) {
content: "暂存成功",
});
// 返回采购单页面
Taro.redirectTo({ url: "/pages/purchase/reviewer/audit/list" });
Taro.redirectTo({ url: "/pages/purchase/audit/pending" });
}
};
@ -322,7 +322,7 @@ export default hocAuth(function Page(props: CommonComponent) {
});
// 跳转到提交结果页面
Taro.redirectTo({
url: buildUrl("/pages/purchase/reviewer/audit/result", {
url: buildUrl("/pages/purchase/audit/result", {
orderId: purchaseOrderVO!.orderId,
}),
});
@ -544,48 +544,50 @@ export default hocAuth(function Page(props: CommonComponent) {
{/* 按钮操作 */}
<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_AUDIT" && (
<>
<View className={"flex-1"}>
<Button
block
type={"default"}
size={"xlarge"}
className="bg-gray-200 text-gray-700"
onClick={() => setMoreActionVisible(true)}
>
</Button>
</View>
<View className={"flex-1"}>
<Button
block
type={"primary"}
size={"xlarge"}
className="bg-primary text-white"
onClick={handleSubmit}
>
</Button>
</View>
</>
)}
{purchaseOrderVO.state === "WAITING_APPROVE" && (
<>
<View className={"flex-1"}>
<Button
block
type={"default"}
size={"xlarge"}
onClick={() => {
Taro.redirectTo({ url: "/pages/main/index/index" });
}}
>
</Button>
</View>
</>
)}
{purchaseOrderVO.state === "WAITING_AUDIT" &&
purchaseOrderVO.auditState === "PENDING_QUOTE_APPROVAL" && (
<>
<View className={"flex-1"}>
<Button
block
type={"default"}
size={"xlarge"}
className="bg-gray-200 text-gray-700"
onClick={() => setMoreActionVisible(true)}
>
</Button>
</View>
<View className={"flex-1"}>
<Button
block
type={"primary"}
size={"xlarge"}
className="bg-primary text-white"
onClick={handleSubmit}
>
</Button>
</View>
</>
)}
{purchaseOrderVO.state === "WAITING_AUDIT" &&
purchaseOrderVO.auditState === "PENDING_BOSS_APPROVAL" && (
<>
<View className={"flex-1"}>
<Button
block
type={"default"}
size={"xlarge"}
onClick={() => {
Taro.redirectTo({ url: "/pages/main/index/index" });
}}
>
</Button>
</View>
</>
)}
</View>
<SafeArea position={"bottom"} />
</View>

View File

@ -0,0 +1,4 @@
export default definePageConfig({
navigationBarTitleText: "采购单审核",
navigationBarBackgroundColor: "#fff",
});

View File

@ -0,0 +1,27 @@
import { PurchaseOrderAuditList } from "@/components";
import { useShareAppMessage } from "@tarojs/taro";
import hocAuth from "@/hocs/auth";
import { CommonComponent } from "@/types/typings";
export default hocAuth(function Page(props: CommonComponent) {
const { shareOptions } = props;
useShareAppMessage((res) => {
console.log("useShareAppMessage1", res, shareOptions);
// 如果是按钮触发的转发,使用默认配置
if (res.from === "button") {
return shareOptions;
}
// 页面转发使用设置的配置
return {};
});
return (
<PurchaseOrderAuditList
params={{
state: "WAITING_AUDIT",
auditState: "PENDING_QUOTE_APPROVAL",
}}
/>
);
});

View File

@ -0,0 +1,4 @@
export default definePageConfig({
navigationBarTitleText: "采购单驳回",
navigationBarBackgroundColor: "#fff",
});

View File

@ -0,0 +1,27 @@
import { PurchaseOrderList } from "@/components";
import { useShareAppMessage } from "@tarojs/taro";
import hocAuth from "@/hocs/auth";
import { CommonComponent } from "@/types/typings";
export default hocAuth(function Page(props: CommonComponent) {
const { shareOptions } = props;
useShareAppMessage((res) => {
console.log("useShareAppMessage1", res, shareOptions);
// 如果是按钮触发的转发,使用默认配置
if (res.from === "button") {
return shareOptions;
}
// 页面转发使用设置的配置
return {};
});
return (
<PurchaseOrderList
params={{
state: "REJECTED",
auditState: "QUOTE_REJECTED",
}}
/>
);
});

View File

@ -49,7 +49,7 @@ export default hocAuth(function Page(props: CommonComponent) {
const viewPurchaseOrderDetail = () => {
if (purchaseOrder?.orderId) {
Taro.navigateTo({
url: buildUrl("/pages/purchase/reviewer/audit/audit", {
url: buildUrl("/pages/purchase/audit/audit", {
orderId: purchaseOrder.orderId,
}),
});

View File

@ -0,0 +1,4 @@
export default definePageConfig({
navigationBarTitleText: "采购单审核",
navigationBarBackgroundColor: "#fff",
});

View File

@ -0,0 +1,26 @@
import { PurchaseOrderList } from "@/components";
import { useShareAppMessage } from "@tarojs/taro";
import hocAuth from "@/hocs/auth";
import { CommonComponent } from "@/types/typings";
export default hocAuth(function Page(props: CommonComponent) {
const { shareOptions } = props;
useShareAppMessage((res) => {
console.log("useShareAppMessage1", res, shareOptions);
// 如果是按钮触发的转发,使用默认配置
if (res.from === "button") {
return shareOptions;
}
// 页面转发使用设置的配置
return {};
});
return (
<PurchaseOrderList
params={{
state: "WAITING_AUDIT",
}}
/>
);
});

View File

@ -0,0 +1,4 @@
export default definePageConfig({
navigationBarTitleText: "采购单",
navigationBarBackgroundColor: "#fff",
});

View File

@ -0,0 +1,46 @@
import { ActionType, PurchaseOrderList } from "@/components";
import { useShareAppMessage } from "@tarojs/taro";
import { useRef, useState } from "react";
import hocAuth from "@/hocs/auth";
import { CommonComponent } from "@/types/typings";
import purchaseOrder from "@/constant/purchaseOrder";
export default hocAuth(function Page(props: CommonComponent) {
const { shareOptions } = props;
const [state, setState] =
useState<BusinessAPI.PurchaseOrderPageQry["state"]>("DRAFT");
const actionRef = useRef<ActionType>();
useShareAppMessage((res) => {
console.log("useShareAppMessage1", res, shareOptions);
// 如果是按钮触发的转发,使用默认配置
if (res.from === "button") {
return shareOptions;
}
// 页面转发使用设置的配置
return {};
});
return (
<PurchaseOrderList
actionRef={actionRef}
toolbar={{
tabs: {
activeKey: "state",
defaultActiveKey: state!,
items: purchaseOrder.stateList,
onChange: (item) => {
setState(item as BusinessAPI.PurchaseOrderPageQry["state"]);
actionRef.current?.reload();
},
},
}}
create
params={{
state: state,
}}
/>
);
});

View File

@ -1,14 +1,7 @@
import hocAuth from "@/hocs/auth";
import { CommonComponent, CostItem, SupplierVO } from "@/types/typings";
import { View } from "@tarojs/components";
import {
Button,
Dialog,
SafeArea,
Toast,
Tour,
TourList,
} from "@nutui/nutui-react-taro";
import { Button, Dialog, SafeArea, Toast } from "@nutui/nutui-react-taro";
import { purchase } from "@/constant";
import { useEffect, useRef, useState } from "react";
import {
@ -65,31 +58,34 @@ const defaultSupplierList: SupplierVO[] = [
export default hocAuth(function Page(props: CommonComponent) {
const { router, userRoleVO, setLoading } = props;
const supplierId = router.params
.supplierId as BusinessAPI.SupplierVO["supplierId"];
const [orderId, setOrderId] = useState(
router.params.orderId as BusinessAPI.PurchaseOrderShowQry["orderId"],
);
const defaultStep = router.params.step as number;
const defaultSupplierId = router.params.supplierId as string;
const [showTour, setShowTour] = useState(true);
const closeTour = () => {
setShowTour(false);
};
const steps: TourList[] = [
{
content: "粘贴识别",
target: "target1",
popoverOffset: [0, 12],
arrowOffset: 0,
},
{
content: "选择经销商",
target: "target2",
location: "bottom-left",
},
];
// const [showTour, setShowTour] = useState(true);
//
// const closeTour = () => {
// setShowTour(false);
// };
//
// const steps: TourList[] = [
// {
// content: "粘贴识别",
// target: "target1",
// popoverOffset: [0, 12],
// arrowOffset: 0,
// },
// {
// content: "选择经销商",
// target: "target2",
// location: "bottom-left",
// },
// ];
const vehicleRef = useRef<OrderVehicleRef>(null);
// 创建MelonFarmer组件的ref数组
@ -104,11 +100,9 @@ export default hocAuth(function Page(props: CommonComponent) {
const [purchaseOrder, setPurchaseOrder] =
useState<BusinessAPI.PurchaseOrderCreateCmd>();
console.log("purchaseOrder", purchaseOrder);
const [step, setStep] = useState<any>();
const [active, setActive] = useState<number>(1);
const [active, setActive] = useState<number>(defaultStep || 1);
const [orderVehicle, setOrderVehicle] =
useState<BusinessAPI.PurchaseOrderCreateCmd["orderVehicle"]>();
const [orderDealer, setOrderDealer] =
@ -161,7 +155,7 @@ export default hocAuth(function Page(props: CommonComponent) {
userRoleVO.slug === "origin-entry"
) {
Taro.redirectTo({
url: buildUrl("/pages/purchase/purchaser/preview", {
url: buildUrl("/pages/purchase/enter/preview", {
orderId: purchaseOrder.orderId,
}),
});
@ -191,7 +185,6 @@ export default hocAuth(function Page(props: CommonComponent) {
setActive(active);
}
}
setActive(4);
const orderCostList1 = purchaseOrder.orderCostList.map(
(item: CostItem) => ({
...item,
@ -214,11 +207,37 @@ export default hocAuth(function Page(props: CommonComponent) {
setLoading(false);
});
}
}, []);
}, [orderId]);
useEffect(() => {
if (supplierId) {
setLoading(true);
business.supplier
.showSupplier({
supplierShowQry: {
supplierId: supplierId,
},
})
.then(({ data: { data: supplierVO } }) => {
if (supplierVO) {
setOrderSupplierList([
{
orderSupplierId: generateShortId(),
...supplierVO,
selected: true,
},
]);
}
})
.finally(() => {
setLoading(false);
});
}
}, [supplierId]);
useEffect(() => {
if (active) {
setStep(purchase.steps.find((item) => item.value === active));
setStep(purchase.steps.find((item) => item.value == active));
// 同步更新purchaseOrder中的active值
setPurchaseOrder((prev) => ({ ...prev!, active }));
}
@ -264,6 +283,7 @@ export default hocAuth(function Page(props: CommonComponent) {
}));
}, [orderPackageList]);
console.log("step", step);
if (step === undefined) {
return;
}
@ -475,7 +495,7 @@ export default hocAuth(function Page(props: CommonComponent) {
// 跳转到预览页面
Taro.redirectTo({
url: buildUrl("/pages/purchase/purchaser/preview", {
url: buildUrl("/pages/purchase/enter/preview", {
orderId: orderId,
}),
});
@ -1045,14 +1065,14 @@ export default hocAuth(function Page(props: CommonComponent) {
<SafeArea position={"bottom"} />
</View>
<Tour
className="nut-custom-tour nut-customword-tour hidden"
visible={showTour}
onClose={closeTour}
list={steps}
type="step"
location="bottom-right"
/>
{/*<Tour*/}
{/* className="nut-custom-tour nut-customword-tour hidden"*/}
{/* visible={showTour}*/}
{/* onClose={closeTour}*/}
{/* list={steps}*/}
{/* type="step"*/}
{/* location="bottom-right"*/}
{/*/>*/}
</>
);
});

View File

@ -0,0 +1,27 @@
import { PurchaseOrderList } from "@/components";
import hocAuth from "@/hocs/auth";
import { CommonComponent } from "@/types/typings";
import { useShareAppMessage } from "@tarojs/taro";
export default hocAuth(function Page(props: CommonComponent) {
const { shareOptions } = props;
useShareAppMessage((res) => {
console.log("useShareAppMessage1", res, shareOptions);
// 如果是按钮触发的转发,使用默认配置
if (res.from === "button") {
return shareOptions;
}
// 页面转发使用设置的配置
return {};
});
return (
<PurchaseOrderList
create
params={{
state: "DRAFT",
}}
/>
);
});

View File

@ -64,7 +64,7 @@ export default hocAuth(function Page(props: CommonComponent) {
className="flex-1 bg-gray-200 text-gray-700"
onClick={() => {
Taro.redirectTo({
url: buildUrl("/pages/purchase/purchaser/create", {
url: buildUrl("/pages/purchase/enter/create", {
orderId: purchaseOrder.orderId,
active: 6,
}),

View File

@ -49,7 +49,7 @@ export default hocAuth(function Page(props: CommonComponent) {
const viewPurchaseOrderDetail = () => {
if (purchaseOrder?.orderId) {
Taro.navigateTo({
url: buildUrl("/pages/purchase/purchaser/preview", {
url: buildUrl("/pages/purchase/enter/preview", {
orderId: purchaseOrder.orderId,
}),
});

View File

@ -1,462 +0,0 @@
import {
ActionType,
DealerPicker,
Icon,
PageList,
PurchaseOrderRejectApprove,
PurchaseOrderRejectFinal,
PurchaseOrderWithdrawReview,
State,
ToolBar,
} from "@/components";
import Taro, { useShareAppMessage } from "@tarojs/taro";
import { useRef, useState } from "react";
import { business } from "@/services";
import hocAuth from "@/hocs/auth";
import { CommonComponent } from "@/types/typings";
import { Label, Text, View } from "@tarojs/components";
import { buildUrl, formatCurrency, PurchaseOrderCalculator } from "@/utils";
import { Button } from "@nutui/nutui-react-taro";
import purchaseOrder from "@/constant/purchaseOrder";
import dayjs from "dayjs";
export default hocAuth(function Page(props: CommonComponent) {
const { userRoleVO, shareOptions } = props;
const [state, setState] =
useState<BusinessAPI.PurchaseOrderPageQry["state"]>();
const [dealerVO, setDealerVO] = useState<BusinessAPI.DealerVO>();
const actionRef = useRef<ActionType>();
const toolbar: ToolBar = {
search: {
activeKey: "vehicleNo",
defaultActiveKey: "vehicleNo",
items: [
{
key: "vehicleNo",
name: "车次号",
placeholder: "请输入车次号",
},
{
key: "plate",
name: "车牌号",
placeholder: "请输入车牌号",
},
{
key: "supplierName",
name: "瓜农姓名",
placeholder: "请输入瓜农姓名",
},
],
},
tabs: {
activeKey: "state",
defaultActiveKey: state || "ALL",
items: purchaseOrder.stateList.filter((item) => {
if (userRoleVO.slug === "reviewer") {
return item.value !== "DRAFT";
}
return item;
}),
onChange: (item) => {
setState(item as BusinessAPI.PurchaseOrderPageQry["state"]);
actionRef.current?.reload();
},
},
render: () => (
<View className={"flex flex-row gap-2.5"}>
<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>
),
actions: [
userRoleVO.slug === "origin-entry" && (
<View className={"flex flex-row gap-2 p-3"} key={"create"}>
<View className={"flex-1"}>
<View
className="bg-primary flex w-full flex-col items-center justify-center space-y-2 rounded-xl py-2.5 text-white"
onClick={() => {
Taro.navigateTo({
url: buildUrl("/pages/purchase/purchaser/create"),
});
}}
>
<View className="text-base font-bold"></View>
</View>
</View>
</View>
),
],
};
useShareAppMessage((res) => {
console.log("useShareAppMessage1", res, shareOptions);
// 如果是按钮触发的转发,使用默认配置
if (res.from === "button") {
return shareOptions;
}
// 页面转发使用设置的配置
return {};
});
return (
<PageList<BusinessAPI.PurchaseOrderVO, BusinessAPI.PurchaseOrderPageQry>
rowId={"purchaseOrderId"}
itemHeight={182}
type={"infinite"}
actionRef={actionRef}
render={(purchaseOrderVO: BusinessAPI.PurchaseOrderVO, index) => {
const calculator = new PurchaseOrderCalculator(purchaseOrderVO);
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"}
onClick={(event) => {
if (purchaseOrderVO.active === 7) {
Taro.navigateTo({
url: buildUrl("/pages/purchase/purchaser/preview", {
orderId: purchaseOrderVO.orderId,
}),
});
event.stopPropagation();
}
}}
>
<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?.vehicleNo
? "第" +
purchaseOrderVO.orderVehicle?.vehicleNo +
"车"
: "暂未生成车次"}
</Text>
</View>
<Text className={"text-neutral-dark text-sm"}>
{purchaseOrderVO.orderSn}
</Text>
</View>
<State
state={purchaseOrderVO.state}
stateMap={purchaseOrder.stateMap}
/>
</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.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
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.orderVehicle?.origin} {"->"}
{purchaseOrderVO.orderVehicle?.destination}
</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.orderVehicle.dealerName}
</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.orderVehicle?.plate}
</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.orderSupplierList.length}
</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"}>
{formatCurrency(calculator.getTotalGrossWeight())}{" "}
/ {" "}
{formatCurrency(calculator.getTotalNetWeight())}
</Text>
</View>
</View>
</View>
</View>
{userRoleVO.slug === "boss" && (
<View className={"py-2.5"}>
{purchaseOrderVO.state === "WAITING_APPROVE" && (
<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/approver/audit/audit",
{
orderId: purchaseOrderVO.orderId,
},
),
});
e.stopPropagation();
}}
>
</Button>
</View>
)}
</View>
)}
{userRoleVO.slug === "reviewer" && (
<View className={"py-2.5"}>
{purchaseOrderVO.state === "WAITING_AUDIT" && (
<View className={"flex flex-row justify-end gap-2"}>
<PurchaseOrderRejectApprove
purchaseOrderVO={purchaseOrderVO}
size={"small"}
onFinish={() => {
actionRef.current?.reload();
}}
/>
<Button
type={"primary"}
size={"small"}
onClick={(e) => {
Taro.navigateTo({
url: buildUrl(
"/pages/purchase/reviewer/audit/audit",
{
orderId: purchaseOrderVO.orderId,
},
),
});
e.stopPropagation();
}}
>
</Button>
</View>
)}
{purchaseOrderVO.state === "WAITING_APPROVE" && (
<View className={"flex flex-row justify-end gap-2"}>
<Button
type={"primary"}
size={"small"}
onClick={(e) => {
Taro.navigateTo({
url: buildUrl(
"/pages/purchase/reviewer/audit/result",
{
orderId: purchaseOrderVO.orderId,
},
),
});
e.stopPropagation();
}}
>
</Button>
</View>
)}
</View>
)}
{userRoleVO.slug === "origin-entry" && (
<View className={"py-2.5"}>
{purchaseOrderVO.state === "DRAFT" && (
<View className={"flex flex-row justify-end gap-2"}>
<Button
type={"default"}
size={"small"}
onClick={(e) => {
Taro.navigateTo({
url: buildUrl("/pages/purchase/purchaser/create", {
orderId: purchaseOrderVO.orderId,
}),
});
e.stopPropagation();
}}
>
</Button>
{purchaseOrderVO.active === 7 && (
<Button
type={"primary"}
size={"small"}
onClick={(e) => {
Taro.navigateTo({
url: buildUrl(
"/pages/purchase/purchaser/preview",
{
orderId: purchaseOrderVO.orderId,
},
),
});
e.stopPropagation();
}}
>
</Button>
)}
<Button type={"danger"} size={"small"}>
</Button>
</View>
)}
{purchaseOrderVO.state === "WAITING_AUDIT" && (
<View className={"flex flex-row justify-end gap-2"}>
<Button
type={"default"}
size={"small"}
onClick={(e) => {
Taro.navigateTo({
url: buildUrl("/pages/purchase/purchaser/preview", {
orderId: purchaseOrderVO.orderId,
}),
});
e.stopPropagation();
}}
>
</Button>
<PurchaseOrderWithdrawReview
purchaseOrderVO={purchaseOrderVO}
size={"small"}
onFinish={() => {
actionRef.current?.reload();
}}
/>
</View>
)}
</View>
)}
</View>
</View>
);
}}
toolbar={toolbar}
request={async (params) => {
const {
data: { data, success, notEmpty },
} = await business.purchaseOrder.pagePurchaseOrder({
purchaseOrderPageQry: {
...params,
//@ts-ignore
state: state !== "ALL" ? state : undefined,
...(dealerVO
? {
dealerId: dealerVO.dealerId,
}
: {}),
},
});
return {
data,
success,
hasMore: notEmpty,
};
}}
pagination={{
pageSize: 10,
}}
/>
);
});

View File

@ -1,279 +0,0 @@
import {
ActionType,
PageList,
PurchaseOrderWithdrawReview,
State,
ToolBar,
} from "@/components";
import Taro, { useShareAppMessage } from "@tarojs/taro";
import { useRef } from "react";
import { business } from "@/services";
import hocAuth from "@/hocs/auth";
import { CommonComponent } from "@/types/typings";
import { Label, Text, View } from "@tarojs/components";
import { buildUrl, formatCurrency, PurchaseOrderCalculator } from "@/utils";
import { Button } from "@nutui/nutui-react-taro";
import purchaseOrder from "@/constant/purchaseOrder";
import dayjs from "dayjs";
export default hocAuth(function Page(props: CommonComponent) {
const { shareOptions } = props;
const actionRef = useRef<ActionType>();
const toolbar: ToolBar = {
actions: [
<View className={"flex flex-row gap-2 p-3"} key={"create"}>
<View className={"flex-1"}>
<View
className="bg-primary flex w-full flex-col items-center justify-center space-y-2 rounded-xl py-2.5 text-white"
onClick={() => {
Taro.navigateTo({
url: buildUrl("/pages/purchase/purchaser/create"),
});
}}
>
<View className="text-base font-bold"></View>
</View>
</View>
</View>,
],
};
useShareAppMessage((res) => {
console.log("useShareAppMessage1", res, shareOptions);
// 如果是按钮触发的转发,使用默认配置
if (res.from === "button") {
return shareOptions;
}
// 页面转发使用设置的配置
return {};
});
return (
<PageList<BusinessAPI.PurchaseOrderVO, BusinessAPI.PurchaseOrderPageQry>
rowId={"purchaseOrderId"}
itemHeight={182}
type={"infinite"}
actionRef={actionRef}
render={(purchaseOrderVO: BusinessAPI.PurchaseOrderVO, index) => {
const calculator = new PurchaseOrderCalculator(purchaseOrderVO);
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"}
onClick={(event) => {
if (purchaseOrderVO.active === 7) {
Taro.navigateTo({
url: buildUrl("/pages/purchase/purchaser/preview", {
orderId: purchaseOrderVO.orderId,
}),
});
event.stopPropagation();
}
}}
>
<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?.vehicleNo
? "第" +
purchaseOrderVO.orderVehicle?.vehicleNo +
"车"
: "暂未生成车次"}
</Text>
</View>
<Text className={"text-neutral-dark text-sm"}>
{purchaseOrderVO.orderSn}
</Text>
</View>
<State
state={purchaseOrderVO.state}
stateMap={purchaseOrder.stateMap}
/>
</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.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
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.orderVehicle?.origin} {"->"}
{purchaseOrderVO.orderVehicle?.destination}
</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.orderVehicle.dealerName}
</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.orderVehicle?.plate}
</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.orderSupplierList.length}
</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"}>
{formatCurrency(calculator.getTotalGrossWeight())}{" "}
/ {" "}
{formatCurrency(calculator.getTotalNetWeight())}
</Text>
</View>
</View>
</View>
</View>
<View className={"py-2.5"}>
<View className={"flex flex-row justify-end gap-2"}>
{purchaseOrderVO.state === "DRAFT" && (
<>
<Button
type={"default"}
size={"small"}
onClick={(e) => {
Taro.navigateTo({
url: buildUrl("/pages/purchase/purchaser/create", {
orderId: purchaseOrderVO.orderId,
}),
});
e.stopPropagation();
}}
>
</Button>
{purchaseOrderVO.active === 7 && (
<Button
type={"primary"}
size={"small"}
onClick={(e) => {
Taro.navigateTo({
url: buildUrl(
"/pages/purchase/purchaser/preview",
{
orderId: purchaseOrderVO.orderId,
},
),
});
e.stopPropagation();
}}
>
</Button>
)}
<Button type={"danger"} size={"small"}>
</Button>
</>
)}
{purchaseOrderVO.state === "WAITING_AUDIT" && (
<>
<PurchaseOrderWithdrawReview
purchaseOrderVO={purchaseOrderVO}
size={"small"}
onFinish={() => {
actionRef.current?.reload();
}}
/>
</>
)}
</View>
</View>
</View>
</View>
);
}}
toolbar={toolbar}
request={async (params) => {
const {
data: { data, success, notEmpty },
} = await business.purchaseOrder.pagePurchaseOrder({
purchaseOrderPageQry: {
...params,
state: "DRAFT",
},
});
return {
data,
success,
hasMore: notEmpty,
};
}}
pagination={{
pageSize: 10,
}}
/>
);
});

View File

@ -1,224 +0,0 @@
import {
ActionType,
PageList,
PurchaseOrderRejectApprove,
State,
} from "@/components";
import Taro, { useShareAppMessage } from "@tarojs/taro";
import { useRef } from "react";
import { business } from "@/services";
import hocAuth from "@/hocs/auth";
import { CommonComponent } from "@/types/typings";
import { Label, Text, View } from "@tarojs/components";
import { buildUrl, formatCurrency, PurchaseOrderCalculator } from "@/utils";
import { Button } from "@nutui/nutui-react-taro";
import purchaseOrder from "@/constant/purchaseOrder";
import dayjs from "dayjs";
export default hocAuth(function Page(props: CommonComponent) {
const { shareOptions } = props;
const actionRef = useRef<ActionType>();
useShareAppMessage((res) => {
console.log("useShareAppMessage1", res, shareOptions);
// 如果是按钮触发的转发,使用默认配置
if (res.from === "button") {
return shareOptions;
}
// 页面转发使用设置的配置
return {};
});
return (
<PageList<BusinessAPI.PurchaseOrderVO, BusinessAPI.PurchaseOrderPageQry>
rowId={"purchaseOrderId"}
itemHeight={182}
type={"infinite"}
actionRef={actionRef}
render={(purchaseOrderVO: BusinessAPI.PurchaseOrderVO, index) => {
const calculator = new PurchaseOrderCalculator(purchaseOrderVO);
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?.vehicleNo
? "第" +
purchaseOrderVO.orderVehicle?.vehicleNo +
"车"
: "暂未生成车次"}
</Text>
</View>
<Text className={"text-neutral-dark text-sm"}>
{purchaseOrderVO.orderSn}
</Text>
</View>
<State
state={purchaseOrderVO.state}
stateMap={purchaseOrder.stateMap}
/>
</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.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
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.orderVehicle?.origin} {"->"}
{purchaseOrderVO.orderVehicle?.destination}
</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.orderVehicle.dealerName}
</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.orderVehicle?.plate}
</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.orderSupplierList.length}
</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"}>
{formatCurrency(calculator.getTotalGrossWeight())}{" "}
/ {" "}
{formatCurrency(calculator.getTotalNetWeight())}
</Text>
</View>
</View>
</View>
</View>
<View className={"py-2.5"}>
<View className={"flex flex-row justify-end gap-2"}>
{purchaseOrderVO.state === "WAITING_AUDIT" && (
<View className={"flex flex-row justify-end gap-2"}>
<PurchaseOrderRejectApprove
purchaseOrderVO={purchaseOrderVO}
size={"small"}
onFinish={() => {
actionRef.current?.reload();
}}
/>
<Button
type={"primary"}
size={"small"}
onClick={(e) => {
Taro.navigateTo({
url: buildUrl(
"/pages/purchase/reviewer/audit/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,
state: "WAITING_AUDIT",
},
});
return {
data,
success,
hasMore: notEmpty,
};
}}
pagination={{
pageSize: 10,
}}
/>
);
});

View File

@ -1,12 +1,13 @@
import { ActionType, PageList, ToolBar } from "@/components";
import { useShareAppMessage } from "@tarojs/taro";
import { ActionType, Icon, PageList, Phone, ToolBar } from "@/components";
import Taro, { useShareAppMessage } from "@tarojs/taro";
import { useRef } from "react";
import { business } from "@/services";
import hocAuth from "@/hocs/auth";
import { CommonComponent } from "@/types/typings";
import { Label, Text, View } from "@tarojs/components";
import dayjs from "dayjs";
import Phone from "../../components/biz/Phone";
import { buildUrl } from "@/utils";
import { Button } from "@nutui/nutui-react-taro";
export default hocAuth(function Page(props: CommonComponent) {
const { shareOptions } = props;
@ -24,6 +25,22 @@ export default hocAuth(function Page(props: CommonComponent) {
},
],
},
actions: [
<View className={"flex flex-row gap-2 p-3"} key={"create"}>
<View className={"flex-1"}>
<View
className="bg-primary flex w-full flex-col items-center justify-center space-y-2 rounded-xl py-2.5 text-white"
onClick={() => {
Taro.navigateTo({
url: buildUrl("/pages/supplier/create"),
});
}}
>
<View className="text-base font-bold"></View>
</View>
</View>
</View>,
],
};
useShareAppMessage((res) => {
@ -62,6 +79,19 @@ export default hocAuth(function Page(props: CommonComponent) {
</Text>
</View>
</View>
<Button
size={"small"}
type={"primary"}
fill={"none"}
icon={<Icon name={"pen-to-square"} size={18} />}
onClick={() => {
Taro.navigateTo({
url: buildUrl("/pages/supplier/create", {
supplierId: supplierVO.supplierId,
}),
});
}}
/>
</View>
</View>
<View className={"py-2.5"}>
@ -94,11 +124,68 @@ export default hocAuth(function Page(props: CommonComponent) {
<Phone phone={supplierVO.phone} />
</View>
</View>
<View
className={
"flex flex-row items-center justify-between gap-2.5"
}
>
<Label className={"text-neutral-dark text-sm"}>
</Label>
<View
className={
"flex flex-1 flex-row items-center justify-end gap-1"
}
>
12 | 2
</View>
</View>
</View>
</View>
</View>
<View className={"py-2.5"}>
<View className={"flex flex-row justify-end gap-2"}></View>
<View className={"flex flex-row justify-end gap-2"}>
{/* 联系 */}
<Button
size={"small"}
type={"default"}
onClick={() => {
Taro.makePhoneCall({
phoneNumber: supplierVO.phone,
});
}}
>
</Button>
{/* 新建采购 */}
<Button
size={"small"}
type={"default"}
onClick={() => {
Taro.navigateTo({
url: buildUrl("/pages/purchase/enter/create", {
supplierId: supplierVO.supplierId,
}),
});
}}
>
</Button>
{/* 协助开票 */}
<Button
size={"small"}
type={"primary"}
onClick={() => {
Taro.navigateTo({
url: buildUrl("/pages/invoice/upload", {
supplierId: supplierVO.supplierId,
}),
});
}}
>
</Button>
</View>
</View>
</View>
</View>

View File

@ -0,0 +1,4 @@
export default definePageConfig({
navigationBarTitleText: "瓜农管理",
navigationBarBackgroundColor: "#fff",
});

View File

@ -0,0 +1,604 @@
import { View } from "@tarojs/components";
import {
Button,
Input,
Toast,
Uploader,
UploaderFileItem,
} from "@nutui/nutui-react-taro";
import { Icon } from "@/components";
import hocAuth from "@/hocs/auth";
import { CommonComponent } from "@/types/typings";
import { useEffect, useState } from "react";
import { business } from "@/services";
import Taro from "@tarojs/taro";
import { buildUrl, generateShortId, uploadFile } from "@/utils";
export default hocAuth(function Page(props: CommonComponent) {
const { setLoading, router } = props;
const supplierId = router.params
.supplierId as BusinessAPI.SupplierVO["supplierId"];
const [supplierVO, setSupplierVO] = useState<BusinessAPI.SupplierCreateCmd>({
supplierId: generateShortId(),
name: "",
idCard: "",
phone: "",
bankCard: "",
status: true,
});
const [btnLoading, setBtnLoading] = useState(false);
const [picList, setPicList] = useState<UploaderFileItem[]>([]);
// 错误状态
const [nameError, setNameError] = useState(false);
const [idCardError, setIdCardError] = useState(false);
const [bankCardError, setBankCardError] = useState(false);
const [phoneError, setPhoneError] = useState(false);
const [nameDuplicateError, setNameDuplicateError] = useState(false); // 姓名重复错误
// 初始化微信二维码图片列表
useEffect(() => {
if (supplierId) {
setLoading(true);
business.supplier
.showSupplier({
supplierShowQry: {
supplierId: supplierId,
},
})
.then(({ data: { data: supplierVO } }) => {
if (supplierVO) {
setSupplierVO({
...supplierVO,
});
if (supplierVO.wechatQr) {
setPicList([
{
url: supplierVO.wechatQr,
name: "wechat-qrcode",
status: "success",
},
]);
}
}
})
.finally(() => {
setLoading(false);
});
}
}, [supplierId]);
// 微信二维码变更处理函数
const handleWechatQrChange = (files: UploaderFileItem[]) => {
setPicList(files);
// 如果有文件且上传成功保存URL到supplierVO
if (files.length > 0 && files[0].url) {
setSupplierVO((prev) => ({
...prev,
wechatQr: files[0].url,
}));
} else {
// 如果没有文件清空URL
setSupplierVO((prev) => ({
...prev,
wechatQr: undefined,
}));
}
};
// 校验姓名函数
const validateName = (name: string) => {
if (!name) {
return false;
}
// 姓名至少2个字符
return name.length >= 2;
};
// 校验身份证号函数
const validateIdCard = (idCard: string) => {
if (!idCard) {
return false;
}
// 18位身份证号正则表达式
const idCardRegex =
/^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
return idCardRegex.test(idCard);
};
// 校验银行卡号函数
const validateBankCard = (bankCard: string) => {
if (!bankCard) {
return false;
}
// 银行卡号一般为16-19位数字
const bankCardRegex = /^\d{16,19}$/;
return bankCardRegex.test(bankCard);
};
// 校验手机号函数 (使用项目中已有的规则)
const validatePhone = (phone: string) => {
if (!phone) {
return false;
}
// 使用项目规范的手机号正则表达式
const phoneRegex = /^1[3456789]\d{9}$/;
return phoneRegex.test(phone);
};
// 处理姓名变化
const handleNameChange = (value: string) => {
setSupplierVO({
...supplierVO,
name: value,
});
// 校验并更新错误状态
const isValid = validateName(value);
setNameError(!isValid && value !== "");
if (isValid) {
setNameError(false);
}
// 清除姓名重复错误提示
setNameDuplicateError(false);
};
// 处理姓名失焦
const handleNameBlur = async (value: string) => {
if (value && !validateName(value)) {
setNameError(true);
return;
} else {
setNameError(false);
}
// 检查瓜农姓名是否在系统中存在
if (value) {
setLoading(true);
try {
const { data } = await business.supplier.checkSupplier({
supplierCheckQry: {
name: value,
},
});
if (data.success && data.data) {
// 系统中已存在该瓜农信息,设置姓名重复错误状态
setNameDuplicateError(true);
} else {
setNameDuplicateError(false);
}
} catch (error) {
console.error("检查瓜农信息失败", error);
setNameDuplicateError(false);
} finally {
setLoading(false);
}
}
};
// 处理身份证号变化
const handleIdCardChange = (value: string) => {
setSupplierVO({
...supplierVO,
idCard: value,
});
// 校验并更新错误状态
const isValid = validateIdCard(value);
setIdCardError(!isValid && value !== "");
if (isValid) {
setIdCardError(false);
}
};
// 处理身份证号失焦
const handleIdCardBlur = (value: string) => {
if (value && !validateIdCard(value)) {
setIdCardError(true);
} else {
setIdCardError(false);
}
};
// 处理银行卡号变化
const handleBankCardChange = (value: string) => {
setSupplierVO({
...supplierVO,
bankCard: value,
});
// 校验并更新错误状态
const isValid = validateBankCard(value);
setBankCardError(!isValid && value !== "");
if (isValid) {
setBankCardError(false);
}
};
// 处理银行卡号失焦
const handleBankCardBlur = (value: string) => {
if (value && !validateBankCard(value)) {
setBankCardError(true);
} else {
setBankCardError(false);
}
};
// 处理手机号变化
const handlePhoneChange = (value: string) => {
setSupplierVO({
...supplierVO,
phone: value,
});
// 校验并更新错误状态
const isValid = validatePhone(value);
setPhoneError(!isValid && value !== "");
if (isValid) {
setPhoneError(false);
}
};
// 处理手机号失焦
const handlePhoneBlur = (value: string) => {
if (value && !validatePhone(value)) {
setPhoneError(true);
} else {
setPhoneError(false);
}
};
const handleSave = async () => {
// 校验表单
const isNameValid = validateName(supplierVO.name || "");
const isIdCardValid = validateIdCard(supplierVO.idCard || "");
const isBankCardValid = validateBankCard(supplierVO.bankCard || "");
const isPhoneValid = validatePhone(supplierVO.phone || "");
setNameError(!isNameValid);
setIdCardError(!isIdCardValid);
setBankCardError(!isBankCardValid);
setPhoneError(!isPhoneValid);
// 检查是否已存在同名瓜农
let isDuplicate = false;
if (isNameValid) {
try {
setBtnLoading(true);
const { data: checkData } = await business.supplier.checkSupplier({
supplierCheckQry: {
name: supplierVO.name,
},
});
if (checkData.success && checkData.data) {
isDuplicate = true;
setNameDuplicateError(true);
}
} catch (error) {
console.error("检查瓜农信息失败", error);
} finally {
setBtnLoading(false);
}
}
const isValid =
isNameValid &&
isIdCardValid &&
isBankCardValid &&
isPhoneValid &&
!isDuplicate;
if (!isValid) {
if (isDuplicate) {
Toast.show("toast", {
icon: "fail",
title: "提示",
content: "该瓜农已存在,请勿重复创建",
});
} else {
Toast.show("toast", {
icon: "fail",
title: "提示",
content: "请完善瓜农信息后再进行保存操作",
});
}
return;
}
// 创建新瓜农
try {
setBtnLoading(true);
const { data } = await business.supplier.createSupplier({
supplierId: supplierVO.supplierId,
name: supplierVO.name,
idCard: supplierVO.idCard,
phone: supplierVO.phone,
bankCard: supplierVO.bankCard,
wechatQr: supplierVO.wechatQr,
status: supplierVO.status,
});
if (data.success) {
Toast.show("toast", {
icon: "success",
title: "成功",
content: "瓜农创建成功",
});
setTimeout(() => {
Taro.navigateBack();
}, 1500);
} else {
Toast.show("toast", {
icon: "fail",
title: "失败",
content: data.errMessage || "创建失败",
});
}
} catch (error) {
Toast.show("toast", {
icon: "fail",
title: "错误",
content: "创建过程中发生错误",
});
console.error("创建瓜农失败:", error);
} finally {
setBtnLoading(false);
}
};
return (
<>
<View className="flex-1">
<View
className="flex flex-1 flex-col gap-2.5 p-2.5"
style={{
//@ts-ignore
"--nutui-input-padding": 0,
}}
>
{/* 功能提醒 */}
<View className="flex items-center rounded-lg border border-blue-200 bg-blue-50 p-2.5">
<Icon
className={"mr-1"}
name="circle-info"
color={"var(--color-blue-700)"}
size={18}
/>
<View className={"text-sm text-blue-700"}>
</View>
</View>
{/* 快捷工具 */}
<View className="flex gap-2">
<View className={"flex-1"}>
<Button
block
icon={<Icon name={"id-card"} size={28} color={"white"} />}
type={"primary"}
size={"xlarge"}
className="bg-primary flex flex-1 items-center justify-center text-white"
onClick={() => {
Taro.navigateTo({
url: buildUrl("/pages/public/camera/ocr", {
type: "idcard",
}),
complete: () => {
Taro.eventCenter.on("ocr", (res) => {
console.log("识别结果为:", res.result);
setSupplierVO({
...supplierVO,
name: res.result.name,
idCard: res.result.idCard,
});
Taro.eventCenter.off("ocr");
});
},
});
}}
>
<View></View>
</Button>
</View>
<View className={"flex-1"}>
<Button
block
icon={<Icon name={"credit-card"} size={28} color={"white"} />}
type={"primary"}
size={"xlarge"}
className="bg-primary flex flex-1 items-center justify-center text-white"
onClick={() => {
Taro.navigateTo({
url: buildUrl("/pages/public/camera/ocr", {
type: "bankcard",
}),
complete: () => {
Taro.eventCenter.on("ocr", (res) => {
console.log("识别结果为:", res.result);
setSupplierVO({
...supplierVO,
bankCard: res.result.number,
});
Taro.eventCenter.off("ocr");
});
},
});
}}
>
<View></View>
</Button>
</View>
</View>
{/* 瓜农信息 */}
<View className="rounded-lg bg-white p-2.5 shadow-sm">
<View className="mb-2.5">
<View className="flex items-center justify-between">
<View className={"text-primary text-sm font-bold"}>
{supplierVO.name || "瓜农"}
</View>
</View>
</View>
<View className="mb-2.5">
<View className="mb-1 block text-sm font-normal text-[#000000]">
</View>
<View
className={`flex h-10 w-full items-center rounded-md ${nameError || nameDuplicateError ? "border-4 border-red-500" : "border-4 border-gray-300"}`}
>
<Icon name="user" size={16} color="#999" className="mx-2" />
<Input
type="text"
placeholder="请输入姓名"
value={supplierVO.name}
onChange={(value) => handleNameChange(value)}
onBlur={() => handleNameBlur(supplierVO.name || "")}
className="flex-1"
/>
</View>
{nameError && (
<View className="mt-1 text-xs text-red-500">
{`姓名"${supplierVO.name}"至少2个字符`}
</View>
)}
{nameDuplicateError && (
<View className="mt-1 text-xs text-red-500">
</View>
)}
</View>
<View className="mb-2.5">
<View className="mb-1 block text-sm font-normal text-[#000000]">
</View>
<View
className={`flex h-10 w-full items-center rounded-md ${idCardError ? "border-4 border-red-500" : "border-4 border-gray-300"}`}
>
<Icon name="id-card" size={16} color="#999" className="mx-2" />
<Input
type="idcard"
placeholder="请输入身份证号"
value={supplierVO.idCard}
onChange={(value) => handleIdCardChange(value)}
onBlur={() => handleIdCardBlur(supplierVO.idCard || "")}
className="flex-1"
/>
</View>
{idCardError && (
<View className="mt-1 text-xs text-red-500">
</View>
)}
</View>
<View className="mb-2.5">
<View className="mb-1 block text-sm font-normal text-[#000000]">
</View>
<View
className={`flex h-10 w-full items-center rounded-md ${bankCardError ? "border-4 border-red-500" : "border-4 border-gray-300"}`}
>
<Icon
name="credit-card"
size={16}
color="#999"
className="mx-2"
/>
<Input
type="digit"
placeholder="请输入银行卡号"
value={supplierVO.bankCard}
onChange={(value) => handleBankCardChange(value)}
onBlur={() => handleBankCardBlur(supplierVO.bankCard || "")}
className="flex-1"
/>
</View>
{bankCardError && (
<View className="mt-1 text-xs text-red-500">
</View>
)}
</View>
<View className="mb-2.5">
<View className="mb-1 block text-sm font-normal text-[#000000]">
</View>
<View
className={`flex h-10 w-full items-center rounded-md ${phoneError ? "border-4 border-red-500" : "border-4 border-gray-300"}`}
>
<Icon name="phone" size={16} color="#999" className="mx-2" />
<Input
type="tel"
placeholder="请输入手机号码"
value={supplierVO.phone}
onChange={(value) => handlePhoneChange(value)}
onBlur={() => handlePhoneBlur(supplierVO.phone || "")}
className="flex-1"
/>
</View>
{phoneError && (
<View className="mt-1 text-xs text-red-500">
</View>
)}
</View>
</View>
{/* 若瓜农无法开发票,则可打款到微信 */}
<View className="rounded-lg bg-white p-2.5 shadow-sm">
<View className={`flex w-full border-gray-300`}>
<Uploader
className={"w-full"}
value={picList}
onChange={handleWechatQrChange}
sourceType={["album", "camera"]}
uploadIcon={<Icon name={"camera"} size={36} />}
uploadLabel={
<View className={"flex flex-col items-center"}>
<View className="text-sm"></View>
<View className="mt-1 text-xs text-gray-400">
</View>
<View className="mt-1 text-xs text-gray-400">
</View>
</View>
}
maxCount={1}
//@ts-ignore
upload={uploadFile}
multiple
/>
</View>
</View>
</View>
</View>
<View className="sticky bottom-0 z-10 bg-white">
<View className="flex justify-between gap-2 border-t border-gray-200 p-2.5">
<View className={"flex-1"}>
<Button
block
type="primary"
size={"xlarge"}
onClick={handleSave}
loading={btnLoading}
>
</Button>
</View>
</View>
</View>
</>
);
});

View File

@ -2912,8 +2912,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: AgreementVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponseBoxBrandVO = {
@ -2925,8 +2925,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: BoxBrandVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponseBoxProductVO = {
@ -2938,8 +2938,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: BoxProductVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponseBoxSpecVO = {
@ -2951,8 +2951,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: BoxSpecVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponseChannelVO = {
@ -2964,8 +2964,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: ChannelVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponseCompanyPaymentAccountVO = {
@ -2977,8 +2977,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: CompanyPaymentAccountVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponseCompanyVO = {
@ -2990,8 +2990,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: CompanyVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponseCostItemVO = {
@ -3003,8 +3003,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: CostItemVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponseDealerPaymentAccountVO = {
@ -3016,8 +3016,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: DealerPaymentAccountVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponseDealerRebateCustomerVO = {
@ -3029,8 +3029,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: DealerRebateCustomerVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponseDealerVO = {
@ -3042,8 +3042,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: DealerVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponseDealerWarehouseVO = {
@ -3055,8 +3055,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: DealerWarehouseVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponseDictionaryVO = {
@ -3068,8 +3068,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: DictionaryVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponseEmployeeVO = {
@ -3081,8 +3081,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: EmployeeVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponseGiftBoxVO = {
@ -3094,8 +3094,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: GiftBoxVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponseMaterialVO = {
@ -3107,8 +3107,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: MaterialVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponseOrderSupplierVO = {
@ -3120,8 +3120,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: OrderSupplierVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponsePermissionVO = {
@ -3133,8 +3133,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: PermissionVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponsePlatformVO = {
@ -3146,8 +3146,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: PlatformVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponseProductVO = {
@ -3159,8 +3159,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: ProductVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponsePurchaseOrderVO = {
@ -3172,8 +3172,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: PurchaseOrderVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponseRoleVO = {
@ -3185,8 +3185,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: RoleVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponseShipOrderVO = {
@ -3198,8 +3198,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: ShipOrderVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponseSupplierVO = {
@ -3211,8 +3211,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: SupplierVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type PageResponseUserVO = {
@ -3224,8 +3224,8 @@ declare namespace BusinessAPI {
pageIndex?: number;
data?: UserVO[];
empty?: boolean;
totalPages?: number;
notEmpty?: boolean;
totalPages?: number;
};
type pageRoleParams = {
@ -3479,16 +3479,16 @@ declare namespace BusinessAPI {
type PurchaseOrderCountQry = {
/** 状态1_启用0_禁用 */
status?: boolean;
/** 采购订单状态: 0_草稿1_审核中2_审批中3_待发货4_已发货5_已驳回6_已撤回7_已关闭8_已完结 */
state?:
| "DRAFT"
| "WAITING_AUDIT"
| "WAITING_APPROVE"
| "WAITING_SHIPMENT"
| "SHIPPED"
| "PAID"
| "COMPLETED"
| "REJECTED";
/** 采购订单状态: 0_草稿1_审核中2_已完成3_已驳回4_已关闭 */
state?: "DRAFT" | "WAITING_AUDIT" | "COMPLETED" | "REJECTED" | "CLOSED";
/** 采购单审核状态: 1_待报价审核2_待老板审批3_老板审批通过4_报价审核驳回5_老板审批驳回 */
auditState?:
| "NONE"
| "PENDING_QUOTE_APPROVAL"
| "PENDING_BOSS_APPROVAL"
| "BOSS_APPROVED"
| "QUOTE_REJECTED"
| "BOSS_REJECTED";
};
type PurchaseOrderCreateCmd = {
@ -3552,16 +3552,16 @@ declare namespace BusinessAPI {
vehicleNo?: string;
/** 采购订单编号 */
orderSn?: string;
/** 采购订单状态: 0_草稿1_审核中2_审批中3_待发货4_已发货5_已驳回6_已撤回7_已关闭8_已完结 */
state?:
| "DRAFT"
| "WAITING_AUDIT"
| "WAITING_APPROVE"
| "WAITING_SHIPMENT"
| "SHIPPED"
| "PAID"
| "COMPLETED"
| "REJECTED";
/** 采购订单状态: 0_草稿1_审核中2_已完成3_已驳回4_已关闭 */
state?: "DRAFT" | "WAITING_AUDIT" | "COMPLETED" | "REJECTED" | "CLOSED";
/** 采购单审核状态: 1_待报价审核2_待老板审批3_老板审批通过4_报价审核驳回5_老板审批驳回 */
auditState?:
| "NONE"
| "PENDING_QUOTE_APPROVAL"
| "PENDING_BOSS_APPROVAL"
| "BOSS_APPROVED"
| "QUOTE_REJECTED"
| "BOSS_REJECTED";
/** 供应商名称 */
supplierName?: string;
/** 经销商ID */
@ -3688,16 +3688,16 @@ declare namespace BusinessAPI {
freightCharge?: number;
/** 瓜农数量 */
supplierCount?: number;
/** 采购订单状态: 0_草稿1_审核中2_审批中3_待发货4_已发货5_已驳回6_已撤回7_已关闭8_已完结 */
state?:
| "DRAFT"
| "WAITING_AUDIT"
| "WAITING_APPROVE"
| "WAITING_SHIPMENT"
| "SHIPPED"
| "PAID"
| "COMPLETED"
| "REJECTED";
/** 采购订单状态: 0_草稿1_审核中2_已完成3_已驳回4_已关闭 */
state?: "DRAFT" | "WAITING_AUDIT" | "COMPLETED" | "REJECTED" | "CLOSED";
/** 采购单审核状态: 1_待报价审核2_待老板审批3_老板审批通过4_报价审核驳回5_老板审批驳回 */
auditState?:
| "NONE"
| "PENDING_QUOTE_APPROVAL"
| "PENDING_BOSS_APPROVAL"
| "BOSS_APPROVED"
| "QUOTE_REJECTED"
| "BOSS_REJECTED";
/** 备注 */
remark?: string;
/** 创建人ID */

View File

@ -5,11 +5,13 @@ type State = {
selected?: number;
};
userRoleVO?: AuthAPI.UserRoleVO;
loading?: boolean;
};
type Action = {
setTabBar: (selected: number) => void;
setUserRoleVO: (userRoleVO: AuthAPI.UserRoleVO) => void;
setLoading: (loading: boolean) => void;
};
export const globalStore = create<State & Action>((set) => ({
@ -25,4 +27,9 @@ export const globalStore = create<State & Action>((set) => ({
userRoleVO: userRoleVO,
}));
},
setLoading: (loading: boolean) => {
set(() => ({
loading: loading,
}));
},
}));

File diff suppressed because one or more lines are too long