feat(purchase): 新增采购订单相关列表组件及常量配置
- 新增 PurchaseOrderList、PurchaseOrderAuditList、PurchaseOrderApprovalList 三个列表组件 - 在 purchase/index.ts 中导出新增的三个组件 - 更新 purchaseOrder 常量配置,增加审核与审批相关的状态列表和映射 - 修改 PageList 组件从 globalStore 获取 loading 状态 - 调整部分页面路径配置 - 新增发票上传相关页面及功能实现 - 优化部分组件导入和状态管理逻辑
This commit is contained in:
parent
d37626d5bf
commit
4276945320
@ -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: {
|
||||
|
||||
@ -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>();
|
||||
|
||||
@ -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,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -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,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -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,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -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",
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -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,
|
||||
};
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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);
|
||||
|
||||
4
packages/app-client/src/pages/invoice/pending.config.ts
Normal file
4
packages/app-client/src/pages/invoice/pending.config.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: "上传发票",
|
||||
navigationBarBackgroundColor: "#fff",
|
||||
});
|
||||
362
packages/app-client/src/pages/invoice/pending.tsx
Normal file
362
packages/app-client/src/pages/invoice/pending.tsx
Normal 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,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
});
|
||||
4
packages/app-client/src/pages/invoice/upload.config.ts
Normal file
4
packages/app-client/src/pages/invoice/upload.config.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: "上传发票",
|
||||
navigationBarBackgroundColor: "#fff",
|
||||
});
|
||||
362
packages/app-client/src/pages/invoice/upload.tsx
Normal file
362
packages/app-client/src/pages/invoice/upload.tsx
Normal 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,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
});
|
||||
@ -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"),
|
||||
});
|
||||
}}
|
||||
>
|
||||
|
||||
49
packages/app-client/src/pages/purchase/approval/all.tsx
Normal file
49
packages/app-client/src/pages/purchase/approval/all.tsx
Normal 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,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@ -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>
|
||||
27
packages/app-client/src/pages/purchase/approval/pending.tsx
Normal file
27
packages/app-client/src/pages/purchase/approval/pending.tsx
Normal 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",
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: "采购单驳回",
|
||||
navigationBarBackgroundColor: "#fff",
|
||||
});
|
||||
27
packages/app-client/src/pages/purchase/approval/rejected.tsx
Normal file
27
packages/app-client/src/pages/purchase/approval/rejected.tsx
Normal 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",
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@ -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",
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@ -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,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: "采购单",
|
||||
navigationBarBackgroundColor: "#fff",
|
||||
});
|
||||
49
packages/app-client/src/pages/purchase/audit/all.tsx
Normal file
49
packages/app-client/src/pages/purchase/audit/all.tsx
Normal 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,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@ -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>
|
||||
@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: "采购单审核",
|
||||
navigationBarBackgroundColor: "#fff",
|
||||
});
|
||||
27
packages/app-client/src/pages/purchase/audit/pending.tsx
Normal file
27
packages/app-client/src/pages/purchase/audit/pending.tsx
Normal 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",
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: "采购单驳回",
|
||||
navigationBarBackgroundColor: "#fff",
|
||||
});
|
||||
27
packages/app-client/src/pages/purchase/audit/rejected.tsx
Normal file
27
packages/app-client/src/pages/purchase/audit/rejected.tsx
Normal 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",
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@ -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,
|
||||
}),
|
||||
});
|
||||
@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: "采购单审核",
|
||||
navigationBarBackgroundColor: "#fff",
|
||||
});
|
||||
26
packages/app-client/src/pages/purchase/audit/reviewing.tsx
Normal file
26
packages/app-client/src/pages/purchase/audit/reviewing.tsx
Normal 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",
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: "采购单",
|
||||
navigationBarBackgroundColor: "#fff",
|
||||
});
|
||||
46
packages/app-client/src/pages/purchase/enter/all.tsx
Normal file
46
packages/app-client/src/pages/purchase/enter/all.tsx
Normal 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,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@ -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"*/}
|
||||
{/*/>*/}
|
||||
</>
|
||||
);
|
||||
});
|
||||
27
packages/app-client/src/pages/purchase/enter/drafts.tsx
Normal file
27
packages/app-client/src/pages/purchase/enter/drafts.tsx
Normal 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",
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@ -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,
|
||||
}),
|
||||
@ -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,
|
||||
}),
|
||||
});
|
||||
@ -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,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@ -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,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@ -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,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@ -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>
|
||||
4
packages/app-client/src/pages/supplier/create.config.ts
Normal file
4
packages/app-client/src/pages/supplier/create.config.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export default definePageConfig({
|
||||
navigationBarTitleText: "瓜农管理",
|
||||
navigationBarBackgroundColor: "#fff",
|
||||
});
|
||||
604
packages/app-client/src/pages/supplier/create.tsx
Normal file
604
packages/app-client/src/pages/supplier/create.tsx
Normal 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>
|
||||
</>
|
||||
);
|
||||
});
|
||||
@ -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 */
|
||||
|
||||
@ -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
Loading…
Reference in New Issue
Block a user