feat(components): 添加供应商瓜农组件和支付任务管理功能
- 添加 SupplierFarmerList 和 SupplierStallList 组件 - 添加 PaymentTaskList、PaymentTaskCreate、InvoicerStatisticCard 等支付任务相关组件 - 将 MelonFarmerList 重命名为 SupplierFarmerList 并移至 Supplier 目录 - 在 BizContainer 中添加 supplier 类型渲染支持 - 为 BizDetail 组件添加 formContextMode 属性和渲染逻辑 - 添加供应商类型到 BizValueType 类型定义中 - 添加开票方统计卡片和订单供应商发票列表组件 - 更新组件导出配置和本地化文件
This commit is contained in:
parent
d8920e9c37
commit
b53d26ec65
@ -1,7 +1,6 @@
|
||||
export { default as MelonFarmerList } from './MelonFarmerList';
|
||||
export { default as BoxProductList } from './BoxProductList'
|
||||
export { default as BoxBrandList } from './BoxBrandList';
|
||||
export { default as CostList } from './CostList';
|
||||
export { default as CostItemList } from './CostItemList';
|
||||
export { default as BoxProductList } from './BoxProductList';
|
||||
export { default as BoxSpecList } from './BoxSpecList';
|
||||
export { default as CostItemList } from './CostItemList';
|
||||
export { default as CostList } from './CostList';
|
||||
export { default as ProductDataList } from './ProductDataList';
|
||||
|
||||
@ -15,12 +15,13 @@ import {
|
||||
BizValueType,
|
||||
DealerFormItem,
|
||||
DealerList,
|
||||
PageContainer,
|
||||
OrderFormItem,
|
||||
OrderList,
|
||||
PageContainer,
|
||||
Remark,
|
||||
RemarkFormItem,
|
||||
SmartActionBar,
|
||||
SupplierFarmerList,
|
||||
UserFormItem,
|
||||
UserList,
|
||||
} from '@/components';
|
||||
@ -847,11 +848,27 @@ export default function BizContainer<
|
||||
);
|
||||
},
|
||||
},
|
||||
supplier: {
|
||||
render: (supplierVO: BusinessAPI.SupplierVO) => {
|
||||
return (
|
||||
supplierVO && (
|
||||
<SupplierFarmerList
|
||||
ghost={true}
|
||||
mode={'detail'}
|
||||
supplierId={supplierVO.supplierId}
|
||||
trigger={() => (
|
||||
<Space>
|
||||
<a>{supplierVO.name}</a>
|
||||
</Space>
|
||||
)}
|
||||
/>
|
||||
)
|
||||
);
|
||||
},
|
||||
},
|
||||
order: {
|
||||
renderFormItem: (_, props) => {
|
||||
return (
|
||||
<OrderFormItem {...props} {...props?.fieldProps} />
|
||||
);
|
||||
return <OrderFormItem {...props} {...props?.fieldProps} />;
|
||||
},
|
||||
render: (orderVO: BusinessAPI.OrderVO) => {
|
||||
return (
|
||||
|
||||
@ -27,6 +27,7 @@ export default function BizDetail<
|
||||
methodUpper,
|
||||
func,
|
||||
formContext,
|
||||
formContextMode = 'tab',
|
||||
trigger,
|
||||
fieldProps,
|
||||
initValues,
|
||||
@ -40,6 +41,63 @@ export default function BizDetail<
|
||||
|
||||
const intl = useIntl();
|
||||
|
||||
/** 渲染 formContext 内容 */
|
||||
const renderFormContext = (data: any, form: any, colSpan: number) => {
|
||||
if (!formContext) return null;
|
||||
|
||||
const contextItems = formContext(data?.[`${method}VO`], async () => {
|
||||
const { data } = await func?.[`show${methodUpper}`]({
|
||||
[`${method}ShowQry`]: {
|
||||
[`${rowKey}`]: rowId,
|
||||
},
|
||||
});
|
||||
form.setFieldValue(`${method}VO`, data);
|
||||
})?.filter((item) => {
|
||||
// @ts-ignore
|
||||
return !item.display || item.display(data?.[`${method}VO`]);
|
||||
});
|
||||
|
||||
// 平铺模式:直接垂直堆叠所有内容
|
||||
if (formContextMode === 'flat') {
|
||||
return (
|
||||
<ProCard ghost={true} direction={'column'}>
|
||||
{contextItems?.map((item, index) => (
|
||||
<ProCard
|
||||
key={item.key || index}
|
||||
bordered={true}
|
||||
headerBordered={false}
|
||||
title={item.label}
|
||||
style={{
|
||||
marginBottom: 16,
|
||||
}}
|
||||
// @ts-ignore
|
||||
subTitle={item.subTitle}
|
||||
>
|
||||
{item.children}
|
||||
</ProCard>
|
||||
))}
|
||||
</ProCard>
|
||||
);
|
||||
}
|
||||
|
||||
// Tab 模式:使用 tabs 渲染
|
||||
return (
|
||||
<ProCard
|
||||
bordered={true}
|
||||
headerBordered={true}
|
||||
colSpan={colSpan}
|
||||
tabs={{
|
||||
tabPosition: 'top',
|
||||
activeKey: data.activeKey,
|
||||
items: contextItems,
|
||||
onChange: (key) => {
|
||||
form.setFieldValue('activeKey', key);
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
let rest = {
|
||||
title: intl.formatMessage({
|
||||
id: intlPrefix + '.modal.view.title',
|
||||
@ -115,40 +173,7 @@ export default function BizDetail<
|
||||
column={column(data.isMobile, formContext)}
|
||||
/>
|
||||
</ProCard>
|
||||
{formContext && (
|
||||
<ProCard
|
||||
bordered={true}
|
||||
headerBordered={true}
|
||||
colSpan={data.isMobile ? 24 : 18}
|
||||
tabs={{
|
||||
tabPosition: 'top',
|
||||
activeKey: data.activeKey,
|
||||
items: formContext?.(
|
||||
data?.[`${method}VO`],
|
||||
async () => {
|
||||
const { data } = await func?.[
|
||||
`show${methodUpper}`
|
||||
]({
|
||||
[`${method}ShowQry`]: {
|
||||
[`${rowKey}`]: rowId,
|
||||
},
|
||||
});
|
||||
|
||||
form.setFieldValue(`${method}VO`, data);
|
||||
},
|
||||
)?.filter((item) => {
|
||||
//@ts-ignore
|
||||
return (
|
||||
!item.display ||
|
||||
item.display(data?.[`${method}VO`])
|
||||
);
|
||||
}),
|
||||
onChange: (key) => {
|
||||
form.setFieldValue('activeKey', key);
|
||||
},
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{renderFormContext(data, form, data.isMobile ? 24 : 18)}
|
||||
</ProCard>
|
||||
);
|
||||
}}
|
||||
@ -179,7 +204,7 @@ export default function BizDetail<
|
||||
{...rest}
|
||||
>
|
||||
{columns && (
|
||||
<ProFormDependency name={[`${method}VO`, 'isMobile']}>
|
||||
<ProFormDependency name={[`${method}VO`, 'isMobile', 'activeKey']}>
|
||||
{(data, form) => {
|
||||
return (
|
||||
<ProCard ghost={true} gutter={24} direction={'row'}>
|
||||
@ -202,40 +227,7 @@ export default function BizDetail<
|
||||
column={column(data.isMobile, formContext)}
|
||||
/>
|
||||
</ProCard>
|
||||
{formContext && (
|
||||
<ProCard
|
||||
bordered={true}
|
||||
headerBordered={true}
|
||||
colSpan={data.isMobile ? 24 : 18}
|
||||
tabs={{
|
||||
tabPosition: 'top',
|
||||
activeKey: data.activeKey,
|
||||
items: formContext?.(
|
||||
data?.[`${method}VO`],
|
||||
async () => {
|
||||
const { data } = await func?.[
|
||||
`show${methodUpper}`
|
||||
]({
|
||||
[`${method}ShowQry`]: {
|
||||
[`${rowKey}`]: rowId,
|
||||
},
|
||||
});
|
||||
|
||||
form.setFieldValue(`${method}VO`, data);
|
||||
},
|
||||
)?.filter((item) => {
|
||||
//@ts-ignore
|
||||
return (
|
||||
!item.display ||
|
||||
item.display(data?.[`${method}VO`])
|
||||
);
|
||||
}),
|
||||
onChange: (key) => {
|
||||
form.setFieldValue('activeKey', key);
|
||||
},
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{renderFormContext(data, form, data.isMobile ? 24 : 18)}
|
||||
</ProCard>
|
||||
);
|
||||
}}
|
||||
|
||||
@ -9,11 +9,11 @@ import {
|
||||
ProDescriptionsItemProps,
|
||||
ProTableProps,
|
||||
} from '@ant-design/pro-components';
|
||||
import { ProListMetas, ProListProps } from '@ant-design/pro-list';
|
||||
import { TourStepProps } from 'antd';
|
||||
import { TabsProps } from 'antd/es/tabs';
|
||||
import { Dayjs } from 'dayjs';
|
||||
import React, { MutableRefObject } from 'react';
|
||||
import { ProListMetas, ProListProps } from '@ant-design/pro-list';
|
||||
|
||||
export type BizValueType =
|
||||
| 'user'
|
||||
@ -21,7 +21,8 @@ export type BizValueType =
|
||||
| 'status'
|
||||
| 'remark'
|
||||
| 'order'
|
||||
| 'dealer';
|
||||
| 'dealer'
|
||||
| 'supplier';
|
||||
export type FormType = 'modal' | 'drawer' | 'step';
|
||||
export type ModeType =
|
||||
| 'tree'
|
||||
@ -176,6 +177,8 @@ export interface BizCalenderProps<
|
||||
trigger?: () => React.ReactNode;
|
||||
}
|
||||
|
||||
export type FormContextMode = 'tab' | 'flat';
|
||||
|
||||
export type BizDetailProps<
|
||||
BizVO extends Record<string, any>,
|
||||
Func extends Record<string, any>,
|
||||
@ -187,6 +190,7 @@ export type BizDetailProps<
|
||||
record: BizVO,
|
||||
onValueChange: () => void,
|
||||
) => TabsProps['items'];
|
||||
formContextMode?: FormContextMode;
|
||||
initValues?: (rowId: string) => Record<string, any>;
|
||||
onFinish?: (record: BizVO) => void;
|
||||
trigger?: (record?: BizVO) => React.ReactNode;
|
||||
|
||||
@ -0,0 +1,402 @@
|
||||
import { OrderList } from '@/components';
|
||||
import { business } from '@/services';
|
||||
import { formatParam } from '@/utils/formatParam';
|
||||
import { pagination } from '@/utils/pagination';
|
||||
import { useIntl } from '@@/exports';
|
||||
import {
|
||||
ActionType,
|
||||
LightFilter,
|
||||
ProColumns,
|
||||
ProFormSelect,
|
||||
} from '@ant-design/pro-components';
|
||||
import { SelectModal } from '@chageable/components';
|
||||
import { Alert, ModalProps, Row, Space, Tag } from 'antd';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
|
||||
export interface IOrderSupplierModalProps extends ModalProps {
|
||||
title: string;
|
||||
selectedList?: BusinessAPI.OrderSupplierVO[];
|
||||
onFinish: (orderSupplierVOList: BusinessAPI.OrderSupplierVO[]) => void;
|
||||
type: 'checkbox' | 'radio' | undefined;
|
||||
params?: BusinessAPI.OrderSupplierPageQry;
|
||||
num?: number;
|
||||
tips?: string;
|
||||
extraFilter?: React.ReactNode[];
|
||||
extraColumns?: ProColumns<BusinessAPI.OrderSupplierVO>[];
|
||||
}
|
||||
|
||||
export default function OrderSupplierModal(props: IOrderSupplierModalProps) {
|
||||
const {
|
||||
title,
|
||||
onFinish,
|
||||
type,
|
||||
selectedList,
|
||||
params: initParams,
|
||||
num = 10,
|
||||
tips,
|
||||
extraFilter = [],
|
||||
extraColumns: initExtraColumns = [],
|
||||
...rest
|
||||
} = props;
|
||||
const actionRef = useRef<ActionType>();
|
||||
const sessionKey = `orderSupplierList`;
|
||||
const intl = useIntl();
|
||||
const intlPrefix = 'orderSupplier';
|
||||
const [params, setParams] = useState<BusinessAPI.OrderSupplierPageQry>(
|
||||
initParams || {},
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (initParams) {
|
||||
setParams({
|
||||
...params,
|
||||
...initParams,
|
||||
});
|
||||
}
|
||||
}, [initParams]);
|
||||
|
||||
const columns: ProColumns<BusinessAPI.OrderSupplierVO>[] = [
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.order' }),
|
||||
dataIndex: ['orderVO', 'orderSn'],
|
||||
key: 'orderSn',
|
||||
search: false,
|
||||
render: (_, orderSupplierVO: BusinessAPI.OrderSupplierVO) => {
|
||||
const orderVO = orderSupplierVO.orderVO;
|
||||
return (
|
||||
orderVO && (
|
||||
<OrderList
|
||||
ghost={true}
|
||||
mode={'detail'}
|
||||
orderId={orderVO.orderId}
|
||||
trigger={() => (
|
||||
<Space>
|
||||
<a>
|
||||
{`${orderVO.orderVehicle?.dealerName} - 第 ${orderVO.orderVehicle?.vehicleNo || '暂无'} 车 - ${orderVO.orderSn || '暂无'}`}
|
||||
</a>
|
||||
</Space>
|
||||
)}
|
||||
/>
|
||||
)
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.name' }),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
renderText: (text: string) => <span className="font-medium">{text}</span>,
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.idCard' }),
|
||||
dataIndex: 'idCard',
|
||||
key: 'idCard',
|
||||
search: false,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.phone' }),
|
||||
dataIndex: 'phone',
|
||||
key: 'phone',
|
||||
search: false,
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.bankName' }),
|
||||
dataIndex: 'bankName',
|
||||
key: 'bankName',
|
||||
search: false,
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.bankCard' }),
|
||||
dataIndex: 'bankCard',
|
||||
key: 'bankCard',
|
||||
search: false,
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.invoiceAmount' }),
|
||||
dataIndex: 'invoiceAmount',
|
||||
key: 'invoiceAmount',
|
||||
valueType: 'money',
|
||||
search: false,
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.depositAmount' }),
|
||||
dataIndex: 'depositAmount',
|
||||
key: 'depositAmount',
|
||||
valueType: 'money',
|
||||
search: false,
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({
|
||||
id: intlPrefix + '.column.remainingAmount',
|
||||
}),
|
||||
dataIndex: 'remainingAmount',
|
||||
key: 'remainingAmount',
|
||||
valueType: 'money',
|
||||
search: false,
|
||||
renderText: (_, record) => {
|
||||
return record.invoiceAmount - record.depositAmount || 0;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.orderCompany' }),
|
||||
dataIndex: ['orderCompany', 'shortName'],
|
||||
key: 'orderCompany',
|
||||
search: false,
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.isPaid' }),
|
||||
dataIndex: 'isPaid',
|
||||
key: 'isPaid',
|
||||
valueType: 'select',
|
||||
valueEnum: {
|
||||
true: {
|
||||
text: intl.formatMessage({ id: intlPrefix + '.column.isPaid.paid' }),
|
||||
status: 'Success',
|
||||
},
|
||||
false: {
|
||||
text: intl.formatMessage({
|
||||
id: intlPrefix + '.column.isPaid.unpaid',
|
||||
}),
|
||||
status: 'Default',
|
||||
},
|
||||
},
|
||||
},
|
||||
// {
|
||||
// title: intl.formatMessage({ id: intlPrefix + '.column.type' }),
|
||||
// dataIndex: 'type',
|
||||
// key: 'type',
|
||||
// valueType: 'select',
|
||||
// valueEnum: {
|
||||
// FARMER: { text: intl.formatMessage({ id: intlPrefix + '.column.type.farmer' }), status: 'Default' },
|
||||
// STALL: { text: intl.formatMessage({ id: intlPrefix + '.column.type.stall' }), status: 'Processing' },
|
||||
// OTHER_STALL: { text: intl.formatMessage({ id: intlPrefix + '.column.type.otherStall' }), status: 'Warning' },
|
||||
// },
|
||||
// },
|
||||
...(initExtraColumns || []),
|
||||
];
|
||||
|
||||
function setOrderSupplierVOStorage(
|
||||
orderSupplierVO: BusinessAPI.OrderSupplierVO,
|
||||
) {
|
||||
const localOrderSupplierList = localStorage.getItem(sessionKey);
|
||||
const orderSupplierList = localOrderSupplierList
|
||||
? JSON.parse(localOrderSupplierList)
|
||||
: [];
|
||||
orderSupplierList.forEach(
|
||||
(item: BusinessAPI.OrderSupplierVO, index: number) => {
|
||||
if (item.orderSupplierId === orderSupplierVO.orderSupplierId) {
|
||||
orderSupplierList.splice(index, 1);
|
||||
}
|
||||
},
|
||||
);
|
||||
if (orderSupplierList.length < 5) {
|
||||
orderSupplierList.unshift(orderSupplierVO);
|
||||
localStorage.setItem(sessionKey, JSON.stringify(orderSupplierList));
|
||||
} else {
|
||||
orderSupplierList.pop();
|
||||
orderSupplierList.unshift(orderSupplierVO);
|
||||
localStorage.setItem(sessionKey, JSON.stringify(orderSupplierList));
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<SelectModal<BusinessAPI.OrderSupplierVO, BusinessAPI.OrderSupplierPageQry>
|
||||
rowKey={'orderSupplierId'}
|
||||
modalProps={{
|
||||
title: title || '选择瓜农订单',
|
||||
...rest,
|
||||
destroyOnHidden: true,
|
||||
afterOpenChange: (open) => {
|
||||
if (!open) {
|
||||
setParams({
|
||||
...initParams,
|
||||
});
|
||||
}
|
||||
},
|
||||
}}
|
||||
selectedList={selectedList}
|
||||
tableProps={{
|
||||
rowKey: 'orderSupplierId',
|
||||
columns: columns,
|
||||
columnsState: {
|
||||
persistenceType: 'sessionStorage',
|
||||
persistenceKey: 'orderSupplierModalColumnStateKey',
|
||||
},
|
||||
params: {
|
||||
...params,
|
||||
},
|
||||
request: async (params, sorter, filter) => {
|
||||
const { data, success, totalCount } =
|
||||
await business.orderSupplier.pageOrderSupplier({
|
||||
orderSupplierPageQry: formatParam<typeof params>(
|
||||
params,
|
||||
sorter,
|
||||
filter,
|
||||
),
|
||||
});
|
||||
|
||||
return {
|
||||
data: data || [],
|
||||
total: totalCount,
|
||||
success,
|
||||
};
|
||||
},
|
||||
pagination: {
|
||||
...pagination(),
|
||||
position: ['bottomRight'],
|
||||
},
|
||||
tableAlertRender: ({ selectedRowKeys, selectedRows }) => {
|
||||
const selectedRowsMap = new Map<
|
||||
string,
|
||||
BusinessAPI.OrderSupplierVO
|
||||
>();
|
||||
selectedRows.forEach((item: BusinessAPI.OrderSupplierVO) => {
|
||||
if (item) {
|
||||
if (!selectedRowsMap.has(item.orderSupplierId)) {
|
||||
selectedRowsMap.set(item.orderSupplierId, item);
|
||||
}
|
||||
}
|
||||
});
|
||||
selectedList?.forEach((item: BusinessAPI.OrderSupplierVO) => {
|
||||
if (!selectedRowsMap.has(item.orderSupplierId)) {
|
||||
selectedRowsMap.set(item.orderSupplierId, item);
|
||||
}
|
||||
});
|
||||
let selectedTempList: BusinessAPI.OrderSupplierVO[] = [];
|
||||
selectedRowsMap.forEach((item: BusinessAPI.OrderSupplierVO) => {
|
||||
if (selectedRowKeys.includes(item.orderSupplierId)) {
|
||||
selectedTempList.push(item);
|
||||
}
|
||||
});
|
||||
return (
|
||||
<Space size={12}>
|
||||
<span>已选 {selectedRowKeys.length} 项</span>
|
||||
<Space wrap={true}>
|
||||
{selectedTempList?.map((item: BusinessAPI.OrderSupplierVO) => {
|
||||
return (
|
||||
item && <span key={item.orderSupplierId}>{item.name}</span>
|
||||
);
|
||||
})}
|
||||
</Space>
|
||||
</Space>
|
||||
);
|
||||
},
|
||||
...(tips && {
|
||||
tableExtraRender: () => {
|
||||
return tips && <Alert type={'info'} message={tips} />;
|
||||
},
|
||||
}),
|
||||
...(type === 'radio' && {
|
||||
tableExtraRender: () => {
|
||||
const localOrderSupplierList = localStorage.getItem(sessionKey);
|
||||
if (localOrderSupplierList) {
|
||||
const orderSupplierList = JSON.parse(localOrderSupplierList);
|
||||
return (
|
||||
<>
|
||||
{tips && <Alert type={'info'} message={tips} />}
|
||||
<Row gutter={16}>
|
||||
{orderSupplierList.map(
|
||||
(item: BusinessAPI.OrderSupplierVO) => {
|
||||
return (
|
||||
<Tag
|
||||
style={{
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
onClick={() => {
|
||||
// 直接使用 localStorage 中保存的数据
|
||||
onFinish([item]);
|
||||
setOrderSupplierVOStorage(item);
|
||||
}}
|
||||
key={item.orderSupplierId}
|
||||
>
|
||||
{item.name}
|
||||
</Tag>
|
||||
);
|
||||
},
|
||||
)}
|
||||
</Row>
|
||||
</>
|
||||
);
|
||||
}
|
||||
},
|
||||
}),
|
||||
actionRef: actionRef,
|
||||
toolbar: {
|
||||
filter: (
|
||||
<LightFilter
|
||||
onFinish={async (values) => {
|
||||
setParams({
|
||||
...initParams,
|
||||
...values,
|
||||
});
|
||||
}}
|
||||
>
|
||||
{extraFilter}
|
||||
{/*<ProFormSelect*/}
|
||||
{/* label={'供应商类型'}*/}
|
||||
{/* name={'type'}*/}
|
||||
{/* placeholder={'请选择供应商类型'}*/}
|
||||
{/* valueEnum={{*/}
|
||||
{/* FARMER: intl.formatMessage({*/}
|
||||
{/* id: intlPrefix + '.column.type.farmer',*/}
|
||||
{/* }),*/}
|
||||
{/* STALL: intl.formatMessage({*/}
|
||||
{/* id: intlPrefix + '.column.type.stall',*/}
|
||||
{/* }),*/}
|
||||
{/* OTHER_STALL: intl.formatMessage({*/}
|
||||
{/* id: intlPrefix + '.column.type.otherStall',*/}
|
||||
{/* }),*/}
|
||||
{/* }}*/}
|
||||
{/* fieldProps={{*/}
|
||||
{/* showSearch: true,*/}
|
||||
{/* allowClear: true,*/}
|
||||
{/* autoClearSearchValue: true,*/}
|
||||
{/* }}*/}
|
||||
{/*/>*/}
|
||||
<ProFormSelect
|
||||
label={'是否付款'}
|
||||
name={'isPaid'}
|
||||
placeholder={'请选择是否付款'}
|
||||
valueEnum={{
|
||||
true: intl.formatMessage({
|
||||
id: intlPrefix + '.column.isPaid.paid',
|
||||
}),
|
||||
false: intl.formatMessage({
|
||||
id: intlPrefix + '.column.isPaid.unpaid',
|
||||
}),
|
||||
}}
|
||||
fieldProps={{
|
||||
showSearch: true,
|
||||
allowClear: true,
|
||||
autoClearSearchValue: true,
|
||||
}}
|
||||
/>
|
||||
</LightFilter>
|
||||
),
|
||||
search: {
|
||||
placeholder: '请输入供应商姓名',
|
||||
onSearch: async (value: string) => {
|
||||
setParams({
|
||||
...params,
|
||||
//@ts-ignore
|
||||
name: value,
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
}}
|
||||
onFinish={(orderSupplierVOList) => {
|
||||
if (type === 'radio') {
|
||||
if (orderSupplierVOList.length > 0) {
|
||||
setOrderSupplierVOStorage(orderSupplierVOList[0]);
|
||||
}
|
||||
}
|
||||
|
||||
onFinish(orderSupplierVOList);
|
||||
}}
|
||||
num={num}
|
||||
type={type}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
import { formatCurrency } from '@/utils/format';
|
||||
import { ProCard } from '@ant-design/pro-components';
|
||||
|
||||
type IInvoicerStatisticCardProps = {
|
||||
/** 开票方统计 */
|
||||
title: string;
|
||||
/** 车次 */
|
||||
count: number;
|
||||
/** 金额 */
|
||||
amount: number;
|
||||
/** 颜色 */
|
||||
color: string;
|
||||
};
|
||||
/** 开票方统计卡片组件 */
|
||||
export default function InvoicerStatisticCard(
|
||||
props: IInvoicerStatisticCardProps,
|
||||
) {
|
||||
const { title, count, amount, color } = props;
|
||||
return (
|
||||
<ProCard bordered style={{ backgroundColor: color + '10' }}>
|
||||
<div style={{ fontSize: 14, fontWeight: 500, marginBottom: 8, color }}>
|
||||
{title}
|
||||
</div>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<div>
|
||||
<div style={{ fontSize: 12, color: '#999' }}>车次</div>
|
||||
<div style={{ fontSize: 20, fontWeight: 600 }}>{count}</div>
|
||||
</div>
|
||||
<div style={{ textAlign: 'right' }}>
|
||||
<div style={{ fontSize: 12, color: '#999' }}>开票金额</div>
|
||||
<div style={{ fontSize: 20, fontWeight: 600 }}>
|
||||
{formatCurrency(amount)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ProCard>
|
||||
);
|
||||
}
|
||||
@ -0,0 +1,84 @@
|
||||
import { OrderList, SupplierFarmerList } from '@/components';
|
||||
import { Space, Table, TableProps } from 'antd';
|
||||
|
||||
type IOrderSupplierInvoiceListProps = TableProps<BusinessAPI.OrderSupplierVO>;
|
||||
|
||||
export default function OrderSupplierInvoiceList(
|
||||
props: IOrderSupplierInvoiceListProps,
|
||||
) {
|
||||
const { ...tableProps } = props;
|
||||
// 订单列表列定义
|
||||
const orderColumns = [
|
||||
{
|
||||
title: '采购单',
|
||||
dataIndex: 'orderVO',
|
||||
key: 'orderId',
|
||||
render: (orderVO: BusinessAPI.OrderVO) => {
|
||||
return (
|
||||
orderVO && (
|
||||
<OrderList
|
||||
ghost={true}
|
||||
mode={'detail'}
|
||||
orderId={orderVO.orderId}
|
||||
trigger={() => (
|
||||
<Space>
|
||||
<a>
|
||||
{`${orderVO.orderVehicle?.dealerName} - 第 ${orderVO.orderVehicle?.vehicleNo || '暂无'} 车 - ${orderVO.orderSn || '暂无'}`}
|
||||
</a>
|
||||
</Space>
|
||||
)}
|
||||
/>
|
||||
)
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '瓜农名称',
|
||||
key: 'name',
|
||||
render: (orderSupplierVO: BusinessAPI.OrderSupplierVO) => {
|
||||
return (
|
||||
orderSupplierVO && (
|
||||
<SupplierFarmerList
|
||||
ghost={true}
|
||||
mode={'detail'}
|
||||
supplierId={orderSupplierVO.supplierId}
|
||||
trigger={() => <a>{orderSupplierVO.name}</a>}
|
||||
/>
|
||||
)
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '货款金额(元)',
|
||||
dataIndex: 'invoiceAmount',
|
||||
key: 'invoiceAmount',
|
||||
valueType: 'money',
|
||||
},
|
||||
{
|
||||
title: '定金金额(元)',
|
||||
dataIndex: 'depositAmount',
|
||||
key: 'depositAmount',
|
||||
valueType: 'money',
|
||||
},
|
||||
{
|
||||
title: '应付金额(元)',
|
||||
key: 'remainingAmount',
|
||||
valueType: 'money',
|
||||
search: false,
|
||||
render: (record: BusinessAPI.OrderSupplierVO) => {
|
||||
return record.invoiceAmount - record.depositAmount || 0;
|
||||
},
|
||||
},
|
||||
...(tableProps.columns || []),
|
||||
];
|
||||
|
||||
return (
|
||||
<Table
|
||||
{...tableProps}
|
||||
rowKey="orderSupplierId"
|
||||
columns={orderColumns}
|
||||
pagination={false}
|
||||
size="small"
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -0,0 +1,459 @@
|
||||
import {
|
||||
BizEditor,
|
||||
ButtonAccess,
|
||||
InsertPosition,
|
||||
OrderSupplierInvoiceList,
|
||||
} from '@/components';
|
||||
import OrderSupplierModal from '@/components/Order/OrderSupplierModal';
|
||||
import { business } from '@/services';
|
||||
import { formatCurrency } from '@/utils/format';
|
||||
import { formLayout } from '@/utils/formLayout';
|
||||
import { useIntl } from '@@/exports';
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import {
|
||||
DrawerForm,
|
||||
ProCard,
|
||||
ProFormDependency,
|
||||
ProFormItem,
|
||||
ProFormSelect,
|
||||
ProFormText,
|
||||
RouteContext,
|
||||
RouteContextType,
|
||||
} from '@ant-design/pro-components';
|
||||
import { Button, Col, Image, message, Row, Table, Tag } from 'antd';
|
||||
import { useState } from 'react';
|
||||
|
||||
export interface IPaymentTaskCreateProps {
|
||||
onFinish: () => void;
|
||||
insertPosition?: InsertPosition;
|
||||
}
|
||||
|
||||
export default function PaymentTaskCreate(props: IPaymentTaskCreateProps) {
|
||||
const { onFinish } = props;
|
||||
const intl = useIntl();
|
||||
const intlPrefix = 'paymentTask';
|
||||
const [selectedSupplier, setSelectedSupplier] =
|
||||
useState<BusinessAPI.SupplierVO | null>(null);
|
||||
const [selectedOrderSupplierList, setSelectedOrderSupplierList] = useState<
|
||||
BusinessAPI.OrderSupplierVO[]
|
||||
>([]);
|
||||
const [orderSupplierModalOpen, setOrderSupplierModalOpen] = useState(false);
|
||||
|
||||
// 计算总金额和订单数量
|
||||
const totalAmount = selectedOrderSupplierList.reduce(
|
||||
(sum, order) =>
|
||||
sum + (order.invoiceAmount || 0) - (order.depositAmount || 0),
|
||||
0,
|
||||
);
|
||||
const orderCount = selectedOrderSupplierList.length;
|
||||
|
||||
const handleReset = () => {
|
||||
setSelectedSupplier(null);
|
||||
setSelectedOrderSupplierList([]);
|
||||
};
|
||||
console.log(selectedOrderSupplierList);
|
||||
|
||||
const handleSubmit = async (formData: any) => {
|
||||
if (!selectedSupplier) {
|
||||
message.error('请选择付款瓜农');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (selectedOrderSupplierList.length === 0) {
|
||||
message.error('请选择付款车次');
|
||||
return false;
|
||||
}
|
||||
|
||||
// 构建付款任务数据
|
||||
const paymentTaskData: BusinessAPI.PaymentTaskCreateCmd = {
|
||||
taskName: formData.taskName,
|
||||
taskType: 'MELON_FARMER', // 瓜农付款任务
|
||||
paymentCode: `PAY-${Date.now()}`, // 生成付款编码
|
||||
targetId: selectedSupplier.supplierId,
|
||||
totalAmount: totalAmount,
|
||||
paidAmount: 0,
|
||||
state: 'PENDING', // 待付款任务
|
||||
orderCount: orderCount,
|
||||
remark: formData.remark,
|
||||
orderSupplierVOList: selectedOrderSupplierList,
|
||||
};
|
||||
|
||||
const { success } =
|
||||
await business.paymentTask.createPaymentTask(paymentTaskData);
|
||||
|
||||
if (success) {
|
||||
message.success(
|
||||
intl.formatMessage({
|
||||
id: intlPrefix + '.modal.create.success',
|
||||
}),
|
||||
);
|
||||
handleReset();
|
||||
onFinish();
|
||||
}
|
||||
|
||||
return success;
|
||||
};
|
||||
|
||||
// 获取瓜农列表
|
||||
const loadSupplierList = async () => {
|
||||
const { data } = await business.supplier.listSupplier({
|
||||
supplierListQry: {
|
||||
type: 'FARMER',
|
||||
status: true,
|
||||
},
|
||||
});
|
||||
return (data || []).map((supplier: BusinessAPI.SupplierVO) => ({
|
||||
label: supplier.name,
|
||||
value: supplier.supplierId,
|
||||
...supplier,
|
||||
}));
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<RouteContext.Consumer>
|
||||
{(value: RouteContextType) => {
|
||||
const { isMobile } = value;
|
||||
return (
|
||||
<DrawerForm<any>
|
||||
title={intl.formatMessage({
|
||||
id: intlPrefix + '.modal.create.title',
|
||||
})}
|
||||
{...formLayout(isMobile)}
|
||||
width={isMobile ? '100%' : '85%'}
|
||||
drawerProps={{
|
||||
destroyOnHidden: true,
|
||||
onClose: handleReset,
|
||||
}}
|
||||
trigger={
|
||||
<ButtonAccess
|
||||
key={'createPaymentTask'}
|
||||
permission={'operation-paymentTask-create'}
|
||||
type={'primary'}
|
||||
size={'middle'}
|
||||
icon={<PlusOutlined />}
|
||||
>
|
||||
{intl.formatMessage({
|
||||
id: intlPrefix + '.modal.create.button',
|
||||
})}
|
||||
</ButtonAccess>
|
||||
}
|
||||
onFinish={handleSubmit}
|
||||
>
|
||||
{/* 选择瓜农 */}
|
||||
<ProFormSelect
|
||||
name="supplierId"
|
||||
label={intl.formatMessage({
|
||||
id: intlPrefix + '.form.supplier.label',
|
||||
})}
|
||||
placeholder={intl.formatMessage({
|
||||
id: intlPrefix + '.form.supplier.placeholder',
|
||||
})}
|
||||
required={true}
|
||||
showSearch={true}
|
||||
request={loadSupplierList}
|
||||
fieldProps={{
|
||||
labelInValue: true,
|
||||
}}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: intl.formatMessage({
|
||||
id: intlPrefix + '.form.supplier.required',
|
||||
}),
|
||||
},
|
||||
]}
|
||||
onChange={(value: any) => {
|
||||
setSelectedSupplier(value);
|
||||
// 切换瓜农时清空已选订单
|
||||
setSelectedOrderSupplierList([]);
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* 显示瓜农信息 */}
|
||||
{selectedSupplier && (
|
||||
<ProFormItem
|
||||
label={'瓜农信息'}
|
||||
style={{
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<ProCard bordered style={{ marginBottom: 16 }}>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={6}>
|
||||
<div>
|
||||
<div style={{ color: '#999', marginBottom: 4 }}>
|
||||
姓名
|
||||
</div>
|
||||
<div style={{ fontWeight: 'bold' }}>
|
||||
{selectedSupplier.name}
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<div>
|
||||
<div style={{ color: '#999', marginBottom: 4 }}>
|
||||
手机号
|
||||
</div>
|
||||
<div style={{ fontWeight: 'bold' }}>
|
||||
{selectedSupplier.phone}
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<div>
|
||||
<div style={{ color: '#999', marginBottom: 4 }}>
|
||||
银行卡号
|
||||
</div>
|
||||
<div style={{ fontWeight: 'bold' }}>
|
||||
{selectedSupplier.bankCard}
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<div>
|
||||
<div style={{ color: '#999', marginBottom: 4 }}>
|
||||
微信收款码
|
||||
</div>
|
||||
<div style={{ fontWeight: 'bold' }}>
|
||||
{selectedSupplier.wechatQr ? (
|
||||
<Image
|
||||
width={80}
|
||||
alt={'暂无'}
|
||||
src={selectedSupplier.wechatQr}
|
||||
/>
|
||||
) : (
|
||||
<div>暂无</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</ProCard>
|
||||
</ProFormItem>
|
||||
)}
|
||||
|
||||
{/* 选择车次 */}
|
||||
{selectedSupplier && (
|
||||
<ProFormItem
|
||||
label={'付款车次'}
|
||||
style={{
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<ProCard
|
||||
bordered
|
||||
title="选择需要付款的车次"
|
||||
extra={
|
||||
<Button
|
||||
type="primary"
|
||||
size="middle"
|
||||
onClick={() => setOrderSupplierModalOpen(true)}
|
||||
>
|
||||
添加车次
|
||||
</Button>
|
||||
}
|
||||
style={{ marginBottom: 16 }}
|
||||
>
|
||||
{selectedOrderSupplierList.length > 0 ? (
|
||||
<OrderSupplierInvoiceList
|
||||
rowKey="orderSupplierId"
|
||||
dataSource={selectedOrderSupplierList}
|
||||
columns={[
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
render: (
|
||||
_: any,
|
||||
record: BusinessAPI.OrderSupplierVO,
|
||||
) => (
|
||||
<Button
|
||||
type="link"
|
||||
danger
|
||||
onClick={() => {
|
||||
setSelectedOrderSupplierList(
|
||||
selectedOrderSupplierList.filter(
|
||||
(item) =>
|
||||
item.orderSupplierId !==
|
||||
record.orderSupplierId,
|
||||
),
|
||||
);
|
||||
}}
|
||||
>
|
||||
移除
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
]}
|
||||
pagination={false}
|
||||
size="small"
|
||||
summary={(pageData) => {
|
||||
let totalAmount = 0;
|
||||
pageData.forEach(
|
||||
({ invoiceAmount, depositAmount }) => {
|
||||
totalAmount +=
|
||||
(invoiceAmount || 0) - (depositAmount || 0);
|
||||
},
|
||||
);
|
||||
return (
|
||||
<Table.Summary fixed>
|
||||
<Table.Summary.Row>
|
||||
<Table.Summary.Cell index={0} colSpan={4}>
|
||||
<strong>合计</strong>
|
||||
</Table.Summary.Cell>
|
||||
<Table.Summary.Cell index={1}>
|
||||
<strong style={{ color: '#ff4d4f' }}>
|
||||
{formatCurrency(totalAmount)}
|
||||
</strong>
|
||||
</Table.Summary.Cell>
|
||||
<Table.Summary.Cell index={2} />
|
||||
</Table.Summary.Row>
|
||||
</Table.Summary>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
padding: '40px 0',
|
||||
color: '#999',
|
||||
}}
|
||||
>
|
||||
暂无数据,请点击「添加车次」按钮添加
|
||||
</div>
|
||||
)}
|
||||
</ProCard>
|
||||
</ProFormItem>
|
||||
)}
|
||||
|
||||
{/* 任务信息 */}
|
||||
{selectedOrderSupplierList.length > 0 && (
|
||||
<>
|
||||
<ProFormItem label={'任务摘要'} style={{ width: '100%' }}>
|
||||
{/* 任务摘要 */}
|
||||
<ProCard bordered style={{ marginBottom: 16 }}>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={6}>
|
||||
<div>
|
||||
<div style={{ color: '#999', marginBottom: 4 }}>
|
||||
付款瓜农
|
||||
</div>
|
||||
<div style={{ fontWeight: 'bold' }}>
|
||||
{selectedSupplier?.name}
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<div>
|
||||
<div style={{ color: '#999', marginBottom: 4 }}>
|
||||
车次数量
|
||||
</div>
|
||||
<div style={{ fontWeight: 'bold' }}>
|
||||
{orderCount} 车
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<div>
|
||||
<div style={{ color: '#999', marginBottom: 4 }}>
|
||||
付款总额
|
||||
</div>
|
||||
<div
|
||||
style={{ fontWeight: 'bold', color: '#ff4d4f' }}
|
||||
>
|
||||
{formatCurrency(totalAmount)}
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<div>
|
||||
<div style={{ color: '#999', marginBottom: 4 }}>
|
||||
付款状态
|
||||
</div>
|
||||
<div>
|
||||
<Tag color="orange">待付款</Tag>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</ProCard>
|
||||
</ProFormItem>
|
||||
|
||||
{/* 任务名称和备注 */}
|
||||
<ProFormText
|
||||
name="taskName"
|
||||
label={intl.formatMessage({
|
||||
id: intlPrefix + '.form.taskName.label',
|
||||
})}
|
||||
placeholder={intl.formatMessage({
|
||||
id: intlPrefix + '.form.taskName.placeholder',
|
||||
})}
|
||||
required={true}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: intl.formatMessage({
|
||||
id: intlPrefix + '.form.taskName.required',
|
||||
}),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<ProFormDependency key={'remark'} name={['remark']}>
|
||||
{({ remark }, form) => {
|
||||
return (
|
||||
<BizEditor
|
||||
key={'remark'}
|
||||
value={remark}
|
||||
onChange={(value) => {
|
||||
form.setFieldValue('remark', value);
|
||||
}}
|
||||
label={intl.formatMessage({
|
||||
id: intlPrefix + '.form.remark.label',
|
||||
})}
|
||||
name={'remark'}
|
||||
placeholder={intl.formatMessage({
|
||||
id: intlPrefix + '.form.remark.placeholder',
|
||||
})}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
</ProFormDependency>
|
||||
</>
|
||||
)}
|
||||
</DrawerForm>
|
||||
);
|
||||
}}
|
||||
</RouteContext.Consumer>
|
||||
|
||||
{/* 选择车次模态框 */}
|
||||
<OrderSupplierModal
|
||||
open={orderSupplierModalOpen}
|
||||
title="选择需要付款的车次"
|
||||
type="checkbox"
|
||||
selectedList={selectedOrderSupplierList}
|
||||
onFinish={(orderSupplierList) => {
|
||||
// 过滤掉已经选择的订单
|
||||
const newOrders = orderSupplierList.filter(
|
||||
(item) =>
|
||||
!selectedOrderSupplierList.some(
|
||||
(selected) => selected.orderSupplierId === item.orderSupplierId,
|
||||
),
|
||||
);
|
||||
setSelectedOrderSupplierList([
|
||||
...selectedOrderSupplierList,
|
||||
...newOrders,
|
||||
]);
|
||||
setOrderSupplierModalOpen(false);
|
||||
}}
|
||||
onCancel={() => setOrderSupplierModalOpen(false)}
|
||||
params={{
|
||||
type: 'FARMER',
|
||||
isPaid: false,
|
||||
}}
|
||||
tips="请选择该瓜农未付款的车次"
|
||||
num={999}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@ -0,0 +1,505 @@
|
||||
import {
|
||||
BizContainer,
|
||||
BizValueType,
|
||||
InvoicerStatisticCard,
|
||||
ModeType,
|
||||
OrderSupplierInvoiceList,
|
||||
PaymentTaskCreate,
|
||||
} from '@/components';
|
||||
import { business } from '@/services';
|
||||
import { calculateOrderSupplierStatistics } from '@/utils/calculateOrderSupplierStatistics';
|
||||
import { formatCurrency } from '@/utils/format';
|
||||
import { useIntl } from '@@/exports';
|
||||
import {
|
||||
ActionType,
|
||||
ProColumns,
|
||||
StatisticCard,
|
||||
} from '@ant-design/pro-components';
|
||||
import { ProDescriptionsItemProps } from '@ant-design/pro-descriptions';
|
||||
import { Image } from 'antd';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
|
||||
interface IPaymentTaskListProps {
|
||||
ghost?: boolean;
|
||||
paymentTaskId?: BusinessAPI.PaymentTaskVO['paymentTaskId'];
|
||||
search?: boolean;
|
||||
onValueChange?: () => void;
|
||||
mode?: ModeType;
|
||||
trigger?: () => React.ReactNode;
|
||||
}
|
||||
|
||||
export default function PaymentTaskList(props: IPaymentTaskListProps) {
|
||||
const {
|
||||
ghost = false,
|
||||
paymentTaskId,
|
||||
search = true,
|
||||
mode = 'page',
|
||||
trigger,
|
||||
onValueChange,
|
||||
} = props;
|
||||
const intl = useIntl();
|
||||
const intlPrefix = 'paymentTask';
|
||||
const actionRef = useRef<ActionType>();
|
||||
|
||||
const [activeKey, setActiveKey] = useState<string>('PENDING');
|
||||
const [statisticsPaymentTask, setStatisticsPaymentTask] =
|
||||
useState<BusinessAPI.PaymentTaskStatisticsVO>();
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
const initStatistic = async () => {
|
||||
const { data } = await business.paymentTask.statisticsPaymentTask({
|
||||
statisticsQry: {},
|
||||
});
|
||||
setStatisticsPaymentTask(data);
|
||||
setLoading(false);
|
||||
};
|
||||
useEffect(() => {
|
||||
initStatistic().then();
|
||||
}, []);
|
||||
|
||||
/** 状态文本映射 */
|
||||
const stateMap: Record<string, { text: string; color: string }> = {
|
||||
PENDING: {
|
||||
text: intl.formatMessage({ id: intlPrefix + '.state.pending' }),
|
||||
color: 'orange',
|
||||
},
|
||||
PARTIAL: {
|
||||
text: intl.formatMessage({ id: intlPrefix + '.state.partial' }),
|
||||
color: 'blue',
|
||||
},
|
||||
COMPLETED: {
|
||||
text: intl.formatMessage({ id: intlPrefix + '.state.completed' }),
|
||||
color: 'green',
|
||||
},
|
||||
CANCELLED: {
|
||||
text: intl.formatMessage({ id: intlPrefix + '.state.cancelled' }),
|
||||
color: 'red',
|
||||
},
|
||||
};
|
||||
|
||||
const columns: ProColumns<BusinessAPI.PaymentTaskVO, BizValueType>[] = [
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.paymentCode' }),
|
||||
dataIndex: 'paymentCode',
|
||||
key: 'paymentCode',
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.taskName' }),
|
||||
dataIndex: 'taskName',
|
||||
key: 'taskName',
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.supplier' }),
|
||||
dataIndex: 'supplierVO',
|
||||
key: 'supplier',
|
||||
valueType: 'supplier',
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.totalAmount' }),
|
||||
dataIndex: 'totalAmount',
|
||||
key: 'totalAmount',
|
||||
valueType: 'money',
|
||||
search: false,
|
||||
renderText: (value: number) => formatCurrency(value),
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.paidAmount' }),
|
||||
dataIndex: 'paidAmount',
|
||||
key: 'paidAmount',
|
||||
valueType: 'money',
|
||||
search: false,
|
||||
renderText: (value: number) => formatCurrency(value),
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.unpaidAmount' }),
|
||||
key: 'unpaidAmount',
|
||||
search: false,
|
||||
render: (_, record) => {
|
||||
const unpaid = (record.totalAmount || 0) - (record.paidAmount || 0);
|
||||
return <span>{formatCurrency(unpaid)}</span>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.orderCount' }),
|
||||
dataIndex: 'orderCount',
|
||||
key: 'orderCount',
|
||||
search: false,
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.state' }),
|
||||
dataIndex: 'state',
|
||||
key: 'state',
|
||||
valueType: 'select',
|
||||
valueEnum: {
|
||||
PENDING: { text: stateMap.PENDING.text, status: 'Warning' },
|
||||
PARTIAL: { text: stateMap.PARTIAL.text, status: 'Processing' },
|
||||
COMPLETED: { text: stateMap.COMPLETED.text, status: 'Success' },
|
||||
CANCELLED: { text: stateMap.CANCELLED.text, status: 'Error' },
|
||||
},
|
||||
search: false,
|
||||
render: (_, record) => {
|
||||
const stateInfo = stateMap[record.state] || stateMap.PENDING;
|
||||
return <span style={{ color: stateInfo.color }}>{stateInfo.text}</span>;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const detailColumns: ProDescriptionsItemProps<
|
||||
BusinessAPI.PaymentTaskVO,
|
||||
BizValueType
|
||||
>[] = columns as ProDescriptionsItemProps<
|
||||
BusinessAPI.PaymentTaskVO,
|
||||
BizValueType
|
||||
>[];
|
||||
|
||||
const detailContext = (paymentTaskVO: BusinessAPI.PaymentTaskVO) => {
|
||||
// 统计车次数据
|
||||
const statistics = calculateOrderSupplierStatistics(
|
||||
paymentTaskVO.orderSupplierVOList,
|
||||
);
|
||||
|
||||
return [
|
||||
// 统计卡片 Tab
|
||||
{
|
||||
label: intl.formatMessage({
|
||||
id: intlPrefix + '.detail.tab.statistics',
|
||||
}),
|
||||
key: 'statistics',
|
||||
children: (
|
||||
<div
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(3, 1fr)',
|
||||
gap: 12,
|
||||
marginBottom: 16,
|
||||
}}
|
||||
>
|
||||
<InvoicerStatisticCard
|
||||
title={intl.formatMessage({
|
||||
id: intlPrefix + '.detail.invoiceType.selfInvoice',
|
||||
})}
|
||||
count={statistics.selfInvoiceCount}
|
||||
amount={statistics.selfInvoiceAmount}
|
||||
color={'#52c41a'}
|
||||
/>
|
||||
<InvoicerStatisticCard
|
||||
title={intl.formatMessage({
|
||||
id: intlPrefix + '.detail.invoiceType.proxyInvoice',
|
||||
})}
|
||||
count={statistics.proxyInvoiceCount}
|
||||
amount={statistics.proxyInvoiceAmount}
|
||||
color={'#1890ff'}
|
||||
/>
|
||||
<InvoicerStatisticCard
|
||||
title={intl.formatMessage({
|
||||
id: intlPrefix + '.detail.invoiceType.noInvoice',
|
||||
})}
|
||||
count={statistics.noInvoiceCount}
|
||||
amount={statistics.noInvoiceAmount}
|
||||
color={'#ff4d4f'}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
// 开票方统计 Tab
|
||||
...(statistics.invoicerStatistics.length > 0
|
||||
? [
|
||||
{
|
||||
label: intl.formatMessage({
|
||||
id: intlPrefix + '.detail.tab.invoicerStatistics',
|
||||
}),
|
||||
key: 'invoicerStatistics',
|
||||
children: (
|
||||
<div
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns:
|
||||
'repeat(auto-fill, minmax(250px, 1fr))',
|
||||
gap: 12,
|
||||
}}
|
||||
>
|
||||
{statistics.invoicerStatistics.map((stat, index) => (
|
||||
<InvoicerStatisticCard
|
||||
key={index}
|
||||
title={stat.supplierName}
|
||||
count={stat.count}
|
||||
amount={stat.amount}
|
||||
color={'#722ed1'}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
// 自开车次列表 Tab
|
||||
...(statistics.selfInvoiceList.length > 0
|
||||
? [
|
||||
{
|
||||
label: intl.formatMessage(
|
||||
{ id: intlPrefix + '.detail.tab.selfInvoiceList' },
|
||||
{ count: statistics.selfInvoiceCount },
|
||||
),
|
||||
key: 'selfInvoiceList',
|
||||
subTitle: intl.formatMessage(
|
||||
{ id: intlPrefix + '.detail.tab.selfInvoiceList.subTitle' },
|
||||
{ count: statistics.selfInvoiceCount },
|
||||
),
|
||||
children: (
|
||||
<OrderSupplierInvoiceList
|
||||
rowKey="orderSupplierId"
|
||||
dataSource={statistics.selfInvoiceList}
|
||||
columns={[
|
||||
{
|
||||
title: '开票瓜农',
|
||||
dataIndex: ['supplierInvoiceVO', 'supplierName'],
|
||||
key: 'supplierName',
|
||||
},
|
||||
{
|
||||
title: '发票编码',
|
||||
dataIndex: 'supplierInvoiceVO',
|
||||
key: 'invoiceSn',
|
||||
render: (
|
||||
supplierInvoiceVO: BusinessAPI.SupplierInvoiceVO,
|
||||
) => {
|
||||
return <a>{supplierInvoiceVO.invoiceSn}</a>;
|
||||
},
|
||||
},
|
||||
]}
|
||||
pagination={false}
|
||||
size="small"
|
||||
/>
|
||||
),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
// 代开车次列表 Tab
|
||||
...(statistics.proxyInvoiceList.length > 0
|
||||
? [
|
||||
{
|
||||
label: intl.formatMessage(
|
||||
{ id: intlPrefix + '.detail.tab.proxyInvoiceList' },
|
||||
{ count: statistics.proxyInvoiceCount },
|
||||
),
|
||||
key: 'proxyInvoiceList',
|
||||
subTitle: intl.formatMessage(
|
||||
{ id: intlPrefix + '.detail.tab.proxyInvoiceList.subTitle' },
|
||||
{ count: statistics.proxyInvoiceCount },
|
||||
),
|
||||
children: (
|
||||
<OrderSupplierInvoiceList
|
||||
rowKey="orderSupplierId"
|
||||
dataSource={statistics.proxyInvoiceList}
|
||||
columns={[
|
||||
{
|
||||
title: '开票瓜农',
|
||||
dataIndex: ['supplierInvoiceVO', 'supplierName'],
|
||||
key: 'supplierName',
|
||||
},
|
||||
{
|
||||
title: '发票编码',
|
||||
dataIndex: ['supplierInvoiceVO', 'invoiceNo'],
|
||||
key: 'invoiceNo',
|
||||
},
|
||||
]}
|
||||
pagination={false}
|
||||
size="small"
|
||||
/>
|
||||
),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
// 无发票车次列表 Tab
|
||||
...(statistics.noInvoiceList.length > 0
|
||||
? [
|
||||
{
|
||||
label: intl.formatMessage(
|
||||
{ id: intlPrefix + '.detail.tab.noInvoiceList' },
|
||||
{ count: statistics.noInvoiceCount },
|
||||
),
|
||||
key: 'noInvoiceList',
|
||||
subTitle: intl.formatMessage(
|
||||
{ id: intlPrefix + '.detail.tab.noInvoiceList.subTitle' },
|
||||
{ count: statistics.noInvoiceCount },
|
||||
),
|
||||
children: (
|
||||
<OrderSupplierInvoiceList
|
||||
rowKey="orderSupplierId"
|
||||
columns={[
|
||||
{
|
||||
title: '瓜农收款码',
|
||||
dataIndex: 'wechatQr',
|
||||
key: 'wechatQr',
|
||||
render: (wechatQr: string) => {
|
||||
if (!wechatQr) {
|
||||
return '暂无微信收款码';
|
||||
}
|
||||
return (
|
||||
<Image
|
||||
src={wechatQr}
|
||||
alt="微信收款码"
|
||||
style={{ width: 40, height: 40 }}
|
||||
/>
|
||||
);
|
||||
},
|
||||
},
|
||||
]}
|
||||
dataSource={statistics.noInvoiceList}
|
||||
pagination={false}
|
||||
size="small"
|
||||
/>
|
||||
),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
];
|
||||
};
|
||||
|
||||
return (
|
||||
<BizContainer<
|
||||
typeof business.paymentTask,
|
||||
BusinessAPI.PaymentTaskVO,
|
||||
BusinessAPI.PaymentTaskPageQry,
|
||||
BusinessAPI.PaymentTaskCreateCmd,
|
||||
BusinessAPI.PaymentTaskUpdateCmd
|
||||
>
|
||||
rowKey={'paymentTaskId'}
|
||||
permission={'operation-payment-task'}
|
||||
func={business.paymentTask}
|
||||
method={'paymentTask'}
|
||||
methodUpper={'PaymentTask'}
|
||||
intlPrefix={intlPrefix}
|
||||
modeType={mode}
|
||||
onValueChange={onValueChange}
|
||||
container={{
|
||||
fieldProps: {
|
||||
ghost,
|
||||
loading,
|
||||
},
|
||||
}}
|
||||
remark={{
|
||||
mode: 'editor',
|
||||
}}
|
||||
page={{
|
||||
fieldProps: {
|
||||
bordered: true,
|
||||
...(!ghost && {
|
||||
tableExtraRender: () => (
|
||||
<StatisticCard.Group className={'statistics'}>
|
||||
<StatisticCard
|
||||
statistic={{
|
||||
title: '全部',
|
||||
value: statisticsPaymentTask?.totalCount || 0,
|
||||
}}
|
||||
/>
|
||||
<StatisticCard.Operation>=</StatisticCard.Operation>
|
||||
<StatisticCard
|
||||
statistic={{
|
||||
title: '待付款数量',
|
||||
value: statisticsPaymentTask?.pendingCount || 0,
|
||||
}}
|
||||
/>
|
||||
<StatisticCard.Operation>+</StatisticCard.Operation>
|
||||
<StatisticCard
|
||||
statistic={{
|
||||
title: '部分付款数量',
|
||||
value: statisticsPaymentTask?.partialCount || 0,
|
||||
}}
|
||||
/>
|
||||
<StatisticCard.Operation>+</StatisticCard.Operation>
|
||||
<StatisticCard
|
||||
statistic={{
|
||||
title: '已完成数量',
|
||||
value: statisticsPaymentTask?.completedCount || 0,
|
||||
}}
|
||||
/>
|
||||
<StatisticCard.Operation>+</StatisticCard.Operation>
|
||||
<StatisticCard
|
||||
statistic={{
|
||||
title: '已取消数量',
|
||||
value: statisticsPaymentTask?.cancelledCount || 0,
|
||||
}}
|
||||
/>
|
||||
</StatisticCard.Group>
|
||||
),
|
||||
}),
|
||||
ghost,
|
||||
//@ts-ignore
|
||||
search,
|
||||
params: {
|
||||
...(activeKey !== 'ALL' && {
|
||||
state: activeKey as BusinessAPI.PaymentTaskVO['state'],
|
||||
}),
|
||||
taskType: 'MELON_FARMER',
|
||||
},
|
||||
toolbar: {
|
||||
menu: {
|
||||
type: 'tab',
|
||||
activeKey: activeKey,
|
||||
items: [
|
||||
{
|
||||
key: 'ALL',
|
||||
label: intl.formatMessage({
|
||||
id: intlPrefix + '.tab.all',
|
||||
}),
|
||||
},
|
||||
{
|
||||
key: 'PENDING',
|
||||
label: intl.formatMessage({
|
||||
id: intlPrefix + '.tab.pending',
|
||||
}),
|
||||
},
|
||||
{
|
||||
key: 'PARTIAL',
|
||||
label: intl.formatMessage({
|
||||
id: intlPrefix + '.tab.partial',
|
||||
}),
|
||||
},
|
||||
{
|
||||
key: 'COMPLETED',
|
||||
label: intl.formatMessage({
|
||||
id: intlPrefix + '.tab.completed',
|
||||
}),
|
||||
},
|
||||
{
|
||||
key: 'CANCELLED',
|
||||
label: intl.formatMessage({
|
||||
id: intlPrefix + '.tab.cancelled',
|
||||
}),
|
||||
},
|
||||
],
|
||||
onChange: (key) => {
|
||||
setActiveKey(key as string);
|
||||
},
|
||||
},
|
||||
actions: [
|
||||
<PaymentTaskCreate
|
||||
key={'create'}
|
||||
onFinish={() => {
|
||||
actionRef.current?.reload();
|
||||
onValueChange?.();
|
||||
}}
|
||||
/>,
|
||||
],
|
||||
},
|
||||
},
|
||||
columns,
|
||||
actionRef: actionRef,
|
||||
}}
|
||||
create={false}
|
||||
update={{
|
||||
formType: 'drawer',
|
||||
formContext: [],
|
||||
}}
|
||||
destroy={{}}
|
||||
detail={{
|
||||
rowId: paymentTaskId,
|
||||
formType: 'drawer',
|
||||
columns: detailColumns,
|
||||
formContext: detailContext,
|
||||
formContextMode: 'flat',
|
||||
trigger,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
export { default as InvoicerStatisticCard } from './InvoicerStatisticCard';
|
||||
export { default as OrderSupplierInvoiceList } from './OrderSupplierInvoiceList';
|
||||
export { default as PaymentTaskCreate } from './PaymentTaskCreate';
|
||||
export { default as PaymentTaskList } from './PaymentTaskList';
|
||||
@ -18,7 +18,7 @@ import { ProDescriptionsItemProps } from '@ant-design/pro-descriptions';
|
||||
import { ProFormUploadMaterial } from '@chageable/components';
|
||||
import React, { useRef, useState } from 'react';
|
||||
|
||||
interface IMelonFarmerListProps {
|
||||
interface ISupplierFarmerListProps {
|
||||
ghost?: boolean;
|
||||
supplierId?: BusinessAPI.SupplierVO['supplierId'];
|
||||
search?: boolean;
|
||||
@ -27,7 +27,7 @@ interface IMelonFarmerListProps {
|
||||
trigger?: () => React.ReactNode;
|
||||
}
|
||||
|
||||
export default function MelonFarmerList(props: IMelonFarmerListProps) {
|
||||
export default function SupplierFarmerList(props: ISupplierFarmerListProps) {
|
||||
const {
|
||||
ghost = false,
|
||||
supplierId,
|
||||
@ -37,7 +37,7 @@ export default function MelonFarmerList(props: IMelonFarmerListProps) {
|
||||
onValueChange,
|
||||
} = props;
|
||||
const intl = useIntl();
|
||||
const intlPrefix = 'melonFarmer';
|
||||
const intlPrefix = 'supplierFarmer';
|
||||
const actionRef = useRef<ActionType>();
|
||||
|
||||
const [showIdCard, setShowIdCard] = useState<Record<string, boolean>>({});
|
||||
@ -60,7 +60,7 @@ export default function MelonFarmerList(props: IMelonFarmerListProps) {
|
||||
render: (_, record) => (
|
||||
<div className="flex items-center">
|
||||
<span>
|
||||
{formatIdCard(record.idCard, showIdCard[record.supplierId])}
|
||||
{formatIdCard(record.idCard!, showIdCard[record.supplierId])}
|
||||
</span>
|
||||
<span
|
||||
className="ml-2 cursor-pointer"
|
||||
@ -105,6 +105,12 @@ export default function MelonFarmerList(props: IMelonFarmerListProps) {
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.bankName' }),
|
||||
dataIndex: 'bankName',
|
||||
key: 'bankName',
|
||||
search: false,
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.bankCard' }),
|
||||
dataIndex: 'bankCard',
|
||||
@ -201,6 +207,23 @@ export default function MelonFarmerList(props: IMelonFarmerListProps) {
|
||||
},
|
||||
]}
|
||||
/>,
|
||||
<ProFormText
|
||||
key={'bankName'}
|
||||
name={'bankName'}
|
||||
label={intl.formatMessage({ id: intlPrefix + '.form.bankName.label' })}
|
||||
required={true}
|
||||
placeholder={intl.formatMessage({
|
||||
id: intlPrefix + '.form.bankName.placeholder',
|
||||
})}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: intl.formatMessage({
|
||||
id: intlPrefix + '.form.bankName.required',
|
||||
}),
|
||||
},
|
||||
]}
|
||||
/>,
|
||||
<ProFormText
|
||||
key={'bankCard'}
|
||||
name={'bankCard'}
|
||||
@ -286,7 +309,9 @@ export default function MelonFarmerList(props: IMelonFarmerListProps) {
|
||||
intlPrefix={intlPrefix}
|
||||
modeType={mode}
|
||||
onValueChange={onValueChange}
|
||||
container={{}}
|
||||
container={{
|
||||
ghost,
|
||||
}}
|
||||
remark={{
|
||||
mode: 'editor',
|
||||
}}
|
||||
@ -0,0 +1,309 @@
|
||||
import {
|
||||
BizContainer,
|
||||
BizValueType,
|
||||
MaterialList,
|
||||
ModeType,
|
||||
} from '@/components';
|
||||
import { business } from '@/services';
|
||||
import { formatBankCard, formatPhone } from '@/utils/format';
|
||||
import { formatParam } from '@/utils/formatParam';
|
||||
import { useIntl } from '@@/exports';
|
||||
import { EyeInvisibleOutlined, EyeTwoTone } from '@ant-design/icons';
|
||||
import {
|
||||
ActionType,
|
||||
ProColumns,
|
||||
ProFormText,
|
||||
} from '@ant-design/pro-components';
|
||||
import { ProDescriptionsItemProps } from '@ant-design/pro-descriptions';
|
||||
import { ProFormUploadMaterial } from '@chageable/components';
|
||||
import React, { useRef, useState } from 'react';
|
||||
|
||||
interface ISupplierStallListProps {
|
||||
ghost?: boolean;
|
||||
supplierId?: BusinessAPI.SupplierVO['supplierId'];
|
||||
search?: boolean;
|
||||
onValueChange?: () => void;
|
||||
mode?: ModeType;
|
||||
trigger?: () => React.ReactNode;
|
||||
}
|
||||
|
||||
export default function SupplierStallList(props: ISupplierStallListProps) {
|
||||
const {
|
||||
ghost = false,
|
||||
supplierId,
|
||||
search = true,
|
||||
mode = 'page',
|
||||
trigger,
|
||||
onValueChange,
|
||||
} = props;
|
||||
const intl = useIntl();
|
||||
const intlPrefix = 'supplierStall';
|
||||
const actionRef = useRef<ActionType>();
|
||||
|
||||
const [showBankCard, setShowBankCard] = useState<Record<string, boolean>>({});
|
||||
const [showPhone, setShowPhone] = useState<Record<string, boolean>>({});
|
||||
|
||||
const columns: ProColumns<BusinessAPI.SupplierVO, BizValueType>[] = [
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.name' }),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
renderText: (text: string) => <span className="font-medium">{text}</span>,
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.payeeName' }),
|
||||
dataIndex: 'payeeName',
|
||||
key: 'payeeName',
|
||||
search: false,
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.phone' }),
|
||||
dataIndex: 'phone',
|
||||
key: 'phone',
|
||||
render: (_, record) => (
|
||||
<div className="flex items-center">
|
||||
<span>{formatPhone(record.phone, showPhone[record.supplierId])}</span>
|
||||
<span
|
||||
className="ml-2 cursor-pointer"
|
||||
onClick={() => {
|
||||
setShowPhone((prev) => ({
|
||||
...prev,
|
||||
[record.supplierId]: !prev[record.supplierId],
|
||||
}));
|
||||
}}
|
||||
>
|
||||
{showPhone[record.supplierId] ? (
|
||||
<EyeTwoTone />
|
||||
) : (
|
||||
<EyeInvisibleOutlined />
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.bankName' }),
|
||||
dataIndex: 'bankName',
|
||||
key: 'bankName',
|
||||
search: false,
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.bankCard' }),
|
||||
dataIndex: 'bankCard',
|
||||
key: 'bankCard',
|
||||
render: (_, record) => (
|
||||
<div className="flex items-center">
|
||||
<span>
|
||||
{formatBankCard(record.bankCard, showBankCard[record.supplierId])}
|
||||
</span>
|
||||
<span
|
||||
className="ml-2 cursor-pointer"
|
||||
onClick={() => {
|
||||
setShowBankCard((prev) => ({
|
||||
...prev,
|
||||
[record.supplierId]: !prev[record.supplierId],
|
||||
}));
|
||||
}}
|
||||
>
|
||||
{showBankCard[record.supplierId] ? (
|
||||
<EyeTwoTone />
|
||||
) : (
|
||||
<EyeInvisibleOutlined />
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.wechatQr' }),
|
||||
dataIndex: 'wechatQr',
|
||||
valueType: 'image',
|
||||
key: 'wechatQr',
|
||||
search: false,
|
||||
},
|
||||
];
|
||||
|
||||
const formContext = [
|
||||
<ProFormText key={'type'} name={'type'} hidden={true} />,
|
||||
<ProFormText key={'payeeName'} name={'payeeName'} hidden={true} />,
|
||||
<ProFormText
|
||||
key={'name'}
|
||||
name={'name'}
|
||||
label={intl.formatMessage({ id: intlPrefix + '.form.name.label' })}
|
||||
required={true}
|
||||
placeholder={intl.formatMessage({
|
||||
id: intlPrefix + '.form.name.placeholder',
|
||||
})}
|
||||
transform={(value) => {
|
||||
return {
|
||||
name: value,
|
||||
payeeName: value,
|
||||
};
|
||||
}}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: intl.formatMessage({
|
||||
id: intlPrefix + '.form.name.required',
|
||||
}),
|
||||
},
|
||||
]}
|
||||
/>,
|
||||
<ProFormText
|
||||
key={'phone'}
|
||||
name={'phone'}
|
||||
label={intl.formatMessage({ id: intlPrefix + '.form.phone.label' })}
|
||||
required={true}
|
||||
placeholder={intl.formatMessage({
|
||||
id: intlPrefix + '.form.phone.placeholder',
|
||||
})}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: intl.formatMessage({
|
||||
id: intlPrefix + '.form.phone.required',
|
||||
}),
|
||||
},
|
||||
]}
|
||||
/>,
|
||||
<ProFormText
|
||||
key={'bankName'}
|
||||
name={'bankName'}
|
||||
label={intl.formatMessage({ id: intlPrefix + '.form.bankName.label' })}
|
||||
required={true}
|
||||
placeholder={intl.formatMessage({
|
||||
id: intlPrefix + '.form.bankName.placeholder',
|
||||
})}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: intl.formatMessage({
|
||||
id: intlPrefix + '.form.bankName.required',
|
||||
}),
|
||||
},
|
||||
]}
|
||||
/>,
|
||||
<ProFormText
|
||||
key={'bankCard'}
|
||||
name={'bankCard'}
|
||||
label={intl.formatMessage({ id: intlPrefix + '.form.bankCard.label' })}
|
||||
required={true}
|
||||
placeholder={intl.formatMessage({
|
||||
id: intlPrefix + '.form.bankCard.placeholder',
|
||||
})}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: intl.formatMessage({
|
||||
id: intlPrefix + '.form.bankCard.required',
|
||||
}),
|
||||
},
|
||||
]}
|
||||
/>,
|
||||
<ProFormUploadMaterial
|
||||
key={'wechatQr'}
|
||||
label={intl.formatMessage({
|
||||
id: intlPrefix + '.form.wechatQr.label',
|
||||
})}
|
||||
name={'wechatQrList'}
|
||||
transform={(value) => {
|
||||
return {
|
||||
wechatQrList: value,
|
||||
wechatQr: value[0],
|
||||
};
|
||||
}}
|
||||
fieldProps={{
|
||||
maxCount: 1,
|
||||
actionRef: actionRef,
|
||||
toolBarRender: () => [
|
||||
<MaterialList
|
||||
key={'create'}
|
||||
ghost={true}
|
||||
mode={'create'}
|
||||
search={false}
|
||||
onValueChange={() => actionRef.current?.reload()}
|
||||
/>,
|
||||
],
|
||||
request: async (params, sorter, filter) => {
|
||||
const { data, success, totalCount } =
|
||||
await business.material.pageMaterial({
|
||||
materialPageQry: formatParam<typeof params>(
|
||||
params,
|
||||
sorter,
|
||||
filter,
|
||||
),
|
||||
});
|
||||
|
||||
return {
|
||||
data: data || [],
|
||||
total: totalCount,
|
||||
success,
|
||||
};
|
||||
},
|
||||
}}
|
||||
/>,
|
||||
];
|
||||
|
||||
const detailColumns: ProDescriptionsItemProps<
|
||||
BusinessAPI.SupplierVO,
|
||||
BizValueType
|
||||
>[] = columns as ProDescriptionsItemProps<
|
||||
BusinessAPI.SupplierVO,
|
||||
BizValueType
|
||||
>[];
|
||||
|
||||
return (
|
||||
<BizContainer<
|
||||
typeof business.supplier,
|
||||
BusinessAPI.SupplierVO,
|
||||
BusinessAPI.SupplierPageQry,
|
||||
BusinessAPI.SupplierCreateCmd,
|
||||
BusinessAPI.SupplierUpdateCmd
|
||||
>
|
||||
rowKey={'supplierId'}
|
||||
permission={'operation-supplier'}
|
||||
func={business.supplier}
|
||||
method={'supplier'}
|
||||
methodUpper={'Supplier'}
|
||||
intlPrefix={intlPrefix}
|
||||
modeType={mode}
|
||||
onValueChange={onValueChange}
|
||||
container={{}}
|
||||
remark={{
|
||||
mode: 'editor',
|
||||
}}
|
||||
status
|
||||
page={{
|
||||
fieldProps: {
|
||||
bordered: true,
|
||||
ghost,
|
||||
//@ts-ignore
|
||||
search,
|
||||
params: {
|
||||
type: 'OTHER_STALL',
|
||||
},
|
||||
},
|
||||
columns,
|
||||
}}
|
||||
create={{
|
||||
formType: 'drawer',
|
||||
formContext,
|
||||
initValues: {
|
||||
status: true,
|
||||
type: 'OTHER_STALL',
|
||||
},
|
||||
}}
|
||||
update={{
|
||||
formType: 'drawer',
|
||||
formContext,
|
||||
}}
|
||||
destroy={{}}
|
||||
detail={{
|
||||
rowId: supplierId,
|
||||
formType: 'drawer',
|
||||
columns: detailColumns,
|
||||
trigger,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
2
packages/app-operation/src/components/Supplier/index.ts
Normal file
2
packages/app-operation/src/components/Supplier/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export { default as SupplierFarmerList } from './SupplierFarmerList';
|
||||
export { default as SupplierStallList } from './SupplierStallList';
|
||||
@ -8,16 +8,18 @@ export * from './Dealer';
|
||||
export * from './Delivery';
|
||||
export * from './Editor';
|
||||
export * from './Employee';
|
||||
export * from './Expense';
|
||||
export { default as IconFont } from './Iconfont';
|
||||
export { default as IconPicker } from './Iconfont/IconPicker';
|
||||
export * from './Material';
|
||||
export * from './Menu';
|
||||
export * from './Order';
|
||||
export * from './PaymentTask';
|
||||
export * from './Permission';
|
||||
export { default as PhoneContainer } from './PhoneContainer';
|
||||
export * from './Platform';
|
||||
export * from './Order';
|
||||
export * from './Remark';
|
||||
export * from './Role';
|
||||
export * from './Setting';
|
||||
export * from './Supplier';
|
||||
export * from './User';
|
||||
export * from './Expense';
|
||||
|
||||
@ -1209,96 +1209,6 @@ export default {
|
||||
},
|
||||
},
|
||||
},
|
||||
melonFarmer: {
|
||||
column: {
|
||||
name: '瓜农姓名',
|
||||
idCard: '身份证号',
|
||||
phone: '手机号',
|
||||
bankCard: '银行卡号',
|
||||
wechatQr: '微信收款码',
|
||||
remark: '备注',
|
||||
status: '状态',
|
||||
'status.enum.enabled': '正常',
|
||||
'status.enum.disabled': '禁用',
|
||||
'status.placeholder': '请选择状态',
|
||||
createdAt: '创建时间',
|
||||
option: '操作',
|
||||
},
|
||||
form: {
|
||||
name: {
|
||||
label: '姓名',
|
||||
placeholder: '请输入姓名',
|
||||
required: '姓名为必填项',
|
||||
},
|
||||
idCard: {
|
||||
label: '身份证号',
|
||||
placeholder: '请输入身份证号',
|
||||
required: '身份证号为必填项',
|
||||
},
|
||||
phone: {
|
||||
label: '手机号',
|
||||
placeholder: '请输入手机号',
|
||||
required: '手机号为必填项',
|
||||
},
|
||||
bankCard: {
|
||||
label: '银行卡号',
|
||||
placeholder: '请输入银行卡号',
|
||||
required: '银行卡号为必填项',
|
||||
},
|
||||
wechatQr: {
|
||||
label: '微信收款码',
|
||||
placeholder: '请输入微信收款码',
|
||||
required: '微信收款码为必填项',
|
||||
},
|
||||
remark: {
|
||||
label: '备注',
|
||||
placeholder: '请输入备注',
|
||||
},
|
||||
status: {
|
||||
label: '状态',
|
||||
placeholder: '请选择状态',
|
||||
required: '状态为必填项',
|
||||
enum: {
|
||||
enabled: '正常',
|
||||
disabled: '禁用',
|
||||
},
|
||||
},
|
||||
},
|
||||
modal: {
|
||||
create: {
|
||||
title: '新增瓜农',
|
||||
button: '新增瓜农',
|
||||
success: '新增瓜农成功',
|
||||
},
|
||||
update: {
|
||||
title: '更新瓜农',
|
||||
button: '编辑',
|
||||
success: '更新瓜农成功',
|
||||
status: {
|
||||
success: '修改状态成功',
|
||||
},
|
||||
},
|
||||
delete: {
|
||||
success: '删除瓜农成功',
|
||||
button: '删除',
|
||||
confirm: {
|
||||
title: '确认删除',
|
||||
content: '您确定要删除该瓜农吗?',
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
},
|
||||
},
|
||||
import: {
|
||||
title: '导入瓜农',
|
||||
button: '导入',
|
||||
success: '导入瓜农成功',
|
||||
},
|
||||
view: {
|
||||
title: '查看瓜农',
|
||||
button: '查看',
|
||||
},
|
||||
},
|
||||
},
|
||||
boxSpec: {
|
||||
column: {
|
||||
name: '规格名称',
|
||||
@ -2541,6 +2451,289 @@ export default {
|
||||
},
|
||||
},
|
||||
|
||||
supplierFarmer: {
|
||||
column: {
|
||||
name: '瓜农姓名',
|
||||
idCard: '身份证号',
|
||||
phone: '手机号',
|
||||
bankName: '银行名称',
|
||||
bankCard: '银行卡号',
|
||||
wechatQr: '微信收款码',
|
||||
remark: '备注',
|
||||
status: '状态',
|
||||
'status.enum.enabled': '正常',
|
||||
'status.enum.disabled': '禁用',
|
||||
'status.placeholder': '请选择状态',
|
||||
createdAt: '创建时间',
|
||||
option: '操作',
|
||||
},
|
||||
form: {
|
||||
name: {
|
||||
label: '姓名',
|
||||
placeholder: '请输入姓名',
|
||||
required: '姓名为必填项',
|
||||
},
|
||||
idCard: {
|
||||
label: '身份证号',
|
||||
placeholder: '请输入身份证号',
|
||||
required: '身份证号为必填项',
|
||||
},
|
||||
phone: {
|
||||
label: '手机号',
|
||||
placeholder: '请输入手机号',
|
||||
required: '手机号为必填项',
|
||||
},
|
||||
bankName: {
|
||||
label: '银行名称',
|
||||
placeholder: '请输入银行名称',
|
||||
required: '银行名为必填项',
|
||||
},
|
||||
bankCard: {
|
||||
label: '银行卡号',
|
||||
placeholder: '请输入银行卡号',
|
||||
required: '银行卡号为必填项',
|
||||
},
|
||||
wechatQr: {
|
||||
label: '微信收款码',
|
||||
placeholder: '请输入微信收款码',
|
||||
required: '微信收款码为必填项',
|
||||
},
|
||||
remark: {
|
||||
label: '备注',
|
||||
placeholder: '请输入备注',
|
||||
},
|
||||
status: {
|
||||
label: '状态',
|
||||
placeholder: '请选择状态',
|
||||
required: '状态为必填项',
|
||||
enum: {
|
||||
enabled: '正常',
|
||||
disabled: '禁用',
|
||||
},
|
||||
},
|
||||
},
|
||||
modal: {
|
||||
create: {
|
||||
title: '新增瓜农',
|
||||
button: '新增瓜农',
|
||||
success: '新增瓜农成功',
|
||||
},
|
||||
update: {
|
||||
title: '更新瓜农',
|
||||
button: '编辑',
|
||||
success: '更新瓜农成功',
|
||||
status: {
|
||||
success: '修改状态成功',
|
||||
},
|
||||
},
|
||||
delete: {
|
||||
success: '删除瓜农成功',
|
||||
button: '删除',
|
||||
confirm: {
|
||||
title: '确认删除',
|
||||
content: '您确定要删除该瓜农吗?',
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
},
|
||||
},
|
||||
import: {
|
||||
title: '导入瓜农',
|
||||
button: '导入',
|
||||
success: '导入瓜农成功',
|
||||
},
|
||||
view: {
|
||||
title: '查看瓜农',
|
||||
button: '查看',
|
||||
},
|
||||
},
|
||||
},
|
||||
paymentTask: {
|
||||
column: {
|
||||
taskName: '任务名称',
|
||||
paymentCode: '付款编码',
|
||||
supplier: '瓜农信息',
|
||||
totalAmount: '付款总金额',
|
||||
paidAmount: '已付金额',
|
||||
unpaidAmount: '未付金额',
|
||||
orderCount: '订单数量',
|
||||
state: '付款状态',
|
||||
createdAt: '创建时间',
|
||||
remark: '备注',
|
||||
option: '操作',
|
||||
},
|
||||
detail: {
|
||||
tab: {
|
||||
statistics: '瓜农车次统计',
|
||||
invoicerStatistics: '开票方统计',
|
||||
selfInvoiceList: '自开车次列表',
|
||||
'selfInvoiceList.subTitle': '(实际瓜农=收款人,建议银行转账)',
|
||||
proxyInvoiceList: '代开车次列表',
|
||||
'proxyInvoiceList.subTitle':
|
||||
'(实际瓜农≠开票方,注意核实收款人)',
|
||||
noInvoiceList: '无发票车次列表',
|
||||
'noInvoiceList.subTitle': '(需微信个人支付,必须上传截图)',
|
||||
},
|
||||
invoiceType: {
|
||||
selfInvoice: '自开票',
|
||||
proxyInvoice: '代开票',
|
||||
noInvoice: '无发票',
|
||||
},
|
||||
},
|
||||
tab: {
|
||||
all: '全部',
|
||||
pending: '待付款',
|
||||
partial: '部分付款',
|
||||
completed: '已完成',
|
||||
cancelled: '已取消',
|
||||
},
|
||||
state: {
|
||||
all: '全部',
|
||||
pending: '待付款任务',
|
||||
partial: '部分付款任务',
|
||||
completed: '已完成任务',
|
||||
cancelled: '已取消任务',
|
||||
},
|
||||
form: {
|
||||
supplier: {
|
||||
label: '付款瓜农',
|
||||
placeholder: '请选择付款瓜农',
|
||||
required: '请选择付款瓜农',
|
||||
},
|
||||
taskName: {
|
||||
label: '任务名称',
|
||||
placeholder: '请输入任务名称',
|
||||
required: '任务名称为必填项',
|
||||
},
|
||||
remark: {
|
||||
label: '任务备注',
|
||||
placeholder: '请输入任务备注',
|
||||
},
|
||||
},
|
||||
modal: {
|
||||
create: {
|
||||
title: '创建付款任务',
|
||||
button: '创建付款任务',
|
||||
success: '创建付款任务成功',
|
||||
},
|
||||
update: {
|
||||
title: '更新付款任务',
|
||||
button: '编辑',
|
||||
success: '更新付款任务成功',
|
||||
},
|
||||
delete: {
|
||||
success: '删除付款任务成功',
|
||||
button: '删除',
|
||||
confirm: {
|
||||
title: '确认删除',
|
||||
content: '您确定要删除该付款任务吗?',
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
},
|
||||
},
|
||||
view: {
|
||||
title: '查看付款任务',
|
||||
button: '详情',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
supplierStall: {
|
||||
column: {
|
||||
name: '其他家档口姓名',
|
||||
payeeName: '收款方名称',
|
||||
phone: '手机号',
|
||||
bankName: '银行名称',
|
||||
bankCard: '银行卡号',
|
||||
wechatQr: '微信收款码',
|
||||
remark: '备注',
|
||||
status: '状态',
|
||||
'status.enum.enabled': '正常',
|
||||
'status.enum.disabled': '禁用',
|
||||
'status.placeholder': '请选择状态',
|
||||
createdAt: '创建时间',
|
||||
option: '操作',
|
||||
},
|
||||
form: {
|
||||
name: {
|
||||
label: '姓名',
|
||||
placeholder: '请输入姓名',
|
||||
required: '姓名为必填项',
|
||||
},
|
||||
payeeName: {
|
||||
label: '收款方名称',
|
||||
placeholder: '请输入收款方名称',
|
||||
required: '收款方名称为必填项',
|
||||
},
|
||||
phone: {
|
||||
label: '手机号',
|
||||
placeholder: '请输入手机号',
|
||||
required: '手机号为必填项',
|
||||
},
|
||||
bankName: {
|
||||
label: '银行名称',
|
||||
placeholder: '请输入银行名称',
|
||||
required: '银行名称为必填项',
|
||||
},
|
||||
bankCard: {
|
||||
label: '银行卡号',
|
||||
placeholder: '请输入银行卡号',
|
||||
required: '银行卡号为必填项',
|
||||
},
|
||||
wechatQr: {
|
||||
label: '微信收款码',
|
||||
placeholder: '请输入微信收款码',
|
||||
required: '微信收款码为必填项',
|
||||
},
|
||||
remark: {
|
||||
label: '备注',
|
||||
placeholder: '请输入备注',
|
||||
},
|
||||
status: {
|
||||
label: '状态',
|
||||
placeholder: '请选择状态',
|
||||
required: '状态为必填项',
|
||||
enum: {
|
||||
enabled: '正常',
|
||||
disabled: '禁用',
|
||||
},
|
||||
},
|
||||
},
|
||||
modal: {
|
||||
create: {
|
||||
title: '新增其他家档口',
|
||||
button: '新增其他家档口',
|
||||
success: '新增其他家档口成功',
|
||||
},
|
||||
update: {
|
||||
title: '更新其他家档口',
|
||||
button: '编辑',
|
||||
success: '更新其他家档口成功',
|
||||
status: {
|
||||
success: '修改状态成功',
|
||||
},
|
||||
},
|
||||
delete: {
|
||||
success: '删除其他家档口成功',
|
||||
button: '删除',
|
||||
confirm: {
|
||||
title: '确认删除',
|
||||
content: '您确定要删除该其他家档口吗?',
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
},
|
||||
},
|
||||
import: {
|
||||
title: '导入其他家档口',
|
||||
button: '导入',
|
||||
success: '导入其他家档口成功',
|
||||
},
|
||||
view: {
|
||||
title: '查看其他家档口',
|
||||
button: '查看',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
form: {
|
||||
orderId: {
|
||||
label: '采购单',
|
||||
|
||||
5
packages/app-operation/src/pages/FarmerPaymentTask.tsx
Normal file
5
packages/app-operation/src/pages/FarmerPaymentTask.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import { PaymentTaskList } from '@/components';
|
||||
|
||||
export default function FarmerPaymentTask() {
|
||||
return <PaymentTaskList />;
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
import { MelonFarmerList } from '@/components';
|
||||
|
||||
export default function Page() {
|
||||
return <MelonFarmerList />;
|
||||
}
|
||||
5
packages/app-operation/src/pages/SupplierFarmer.tsx
Normal file
5
packages/app-operation/src/pages/SupplierFarmer.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import { SupplierFarmerList } from '@/components';
|
||||
|
||||
export default function Page() {
|
||||
return <SupplierFarmerList />;
|
||||
}
|
||||
5
packages/app-operation/src/pages/SupplierStall.tsx
Normal file
5
packages/app-operation/src/pages/SupplierStall.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import { SupplierStallList } from '@/components';
|
||||
|
||||
export default function Page() {
|
||||
return <SupplierStallList />;
|
||||
}
|
||||
@ -29,19 +29,23 @@ import * as orderCost from './orderCost';
|
||||
import * as orderRebate from './orderRebate';
|
||||
import * as orderShip from './orderShip';
|
||||
import * as orderSupplier from './orderSupplier';
|
||||
import * as paymentTask from './paymentTask';
|
||||
import * as permission from './permission';
|
||||
import * as platform from './platform';
|
||||
import * as product from './product';
|
||||
import * as role from './role';
|
||||
import * as setting from './setting';
|
||||
import * as supplier from './supplier';
|
||||
import * as supplierInvoice from './supplierInvoice';
|
||||
import * as user from './user';
|
||||
export default {
|
||||
user,
|
||||
supplier,
|
||||
supplierInvoice,
|
||||
setting,
|
||||
product,
|
||||
platform,
|
||||
paymentTask,
|
||||
order,
|
||||
orderSupplier,
|
||||
orderShip,
|
||||
|
||||
@ -2,21 +2,6 @@
|
||||
/* eslint-disable */
|
||||
import request from '../request';
|
||||
|
||||
/** 批量上传供应商发票 POST /operation/batchUploadInvoice */
|
||||
export async function batchUploadInvoice(
|
||||
body: BusinessAPI.OrderSupplierBatchInvoiceUploadCmd,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<BusinessAPI.Response>('/operation/batchUploadInvoice', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 订单供应商列表 GET /operation/pageOrderSupplier */
|
||||
export async function pageOrderSupplier(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
|
||||
152
packages/app-operation/src/services/business/paymentTask.ts
Normal file
152
packages/app-operation/src/services/business/paymentTask.ts
Normal file
@ -0,0 +1,152 @@
|
||||
// @ts-ignore
|
||||
/* eslint-disable */
|
||||
import request from '../request';
|
||||
|
||||
/** 创建付款任务 POST /operation/createPaymentTask */
|
||||
export async function createPaymentTask(
|
||||
body: BusinessAPI.PaymentTaskCreateCmd,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<BusinessAPI.SingleResponsePaymentTaskVO>(
|
||||
'/operation/createPaymentTask',
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/** 付款任务删除 DELETE /operation/destroyPaymentTask */
|
||||
export async function destroyPaymentTask(
|
||||
body: BusinessAPI.PaymentTaskDestroyCmd,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<BusinessAPI.Response>('/operation/destroyPaymentTask', {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 付款任务列表 GET /operation/listPaymentTask */
|
||||
export async function listPaymentTask(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: BusinessAPI.listPaymentTaskParams,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<BusinessAPI.MultiResponsePaymentTaskVO>(
|
||||
'/operation/listPaymentTask',
|
||||
{
|
||||
method: 'GET',
|
||||
params: {
|
||||
...params,
|
||||
paymentTaskListQry: undefined,
|
||||
...params['paymentTaskListQry'],
|
||||
},
|
||||
...(options || {}),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/** 付款任务列表 GET /operation/pagePaymentTask */
|
||||
export async function pagePaymentTask(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: BusinessAPI.pagePaymentTaskParams,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<BusinessAPI.PageResponsePaymentTaskVO>(
|
||||
'/operation/pagePaymentTask',
|
||||
{
|
||||
method: 'GET',
|
||||
params: {
|
||||
...params,
|
||||
paymentTaskPageQry: undefined,
|
||||
...params['paymentTaskPageQry'],
|
||||
},
|
||||
...(options || {}),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/** 付款任务详情 GET /operation/showPaymentTask */
|
||||
export async function showPaymentTask(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: BusinessAPI.showPaymentTaskParams,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<BusinessAPI.SingleResponsePaymentTaskVO>(
|
||||
'/operation/showPaymentTask',
|
||||
{
|
||||
method: 'GET',
|
||||
params: {
|
||||
...params,
|
||||
paymentTaskShowQry: undefined,
|
||||
...params['paymentTaskShowQry'],
|
||||
},
|
||||
...(options || {}),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/** 付款任务统计 GET /operation/statisticsPaymentTask */
|
||||
export async function statisticsPaymentTask(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: BusinessAPI.statisticsPaymentTaskParams,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<BusinessAPI.SingleResponsePaymentTaskStatisticsVO>(
|
||||
'/operation/statisticsPaymentTask',
|
||||
{
|
||||
method: 'GET',
|
||||
params: {
|
||||
...params,
|
||||
statisticsQry: undefined,
|
||||
...params['statisticsQry'],
|
||||
},
|
||||
...(options || {}),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/** 付款任务更新 PUT /operation/updatePaymentTask */
|
||||
export async function updatePaymentTask(
|
||||
body: BusinessAPI.PaymentTaskUpdateCmd,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<BusinessAPI.SingleResponsePaymentTaskVO>(
|
||||
'/operation/updatePaymentTask',
|
||||
{
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/** 付款任务更新 PATCH /operation/updatePaymentTask */
|
||||
export async function updatePaymentTask1(
|
||||
body: BusinessAPI.PaymentTaskUpdateCmd,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<BusinessAPI.SingleResponsePaymentTaskVO>(
|
||||
'/operation/updatePaymentTask',
|
||||
{
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
},
|
||||
);
|
||||
}
|
||||
132
packages/app-operation/src/services/business/supplierInvoice.ts
Normal file
132
packages/app-operation/src/services/business/supplierInvoice.ts
Normal file
@ -0,0 +1,132 @@
|
||||
// @ts-ignore
|
||||
/* eslint-disable */
|
||||
import request from '../request';
|
||||
|
||||
/** 创建发票 POST /operation/createSupplierInvoice */
|
||||
export async function createSupplierInvoice(
|
||||
body: BusinessAPI.SupplierInvoiceCreateCmd,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<BusinessAPI.SingleResponseSupplierInvoiceVO>(
|
||||
'/operation/createSupplierInvoice',
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/** 瓜农发票删除 DELETE /operation/destroySupplierInvoice */
|
||||
export async function destroySupplierInvoice(
|
||||
body: BusinessAPI.SupplierInvoiceDestroyCmd,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<BusinessAPI.Response>('/operation/destroySupplierInvoice', {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 瓜农发票列表 GET /operation/listSupplierInvoice */
|
||||
export async function listSupplierInvoice(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: BusinessAPI.listSupplierInvoiceParams,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<BusinessAPI.MultiResponseSupplierInvoiceVO>(
|
||||
'/operation/listSupplierInvoice',
|
||||
{
|
||||
method: 'GET',
|
||||
params: {
|
||||
...params,
|
||||
supplierInvoiceListQry: undefined,
|
||||
...params['supplierInvoiceListQry'],
|
||||
},
|
||||
...(options || {}),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/** 瓜农发票列表 GET /operation/pageSupplierInvoice */
|
||||
export async function pageSupplierInvoice(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: BusinessAPI.pageSupplierInvoiceParams,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<BusinessAPI.PageResponseSupplierInvoiceVO>(
|
||||
'/operation/pageSupplierInvoice',
|
||||
{
|
||||
method: 'GET',
|
||||
params: {
|
||||
...params,
|
||||
supplierInvoicePageQry: undefined,
|
||||
...params['supplierInvoicePageQry'],
|
||||
},
|
||||
...(options || {}),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/** 瓜农发票详情 GET /operation/showSupplierInvoice */
|
||||
export async function showSupplierInvoice(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: BusinessAPI.showSupplierInvoiceParams,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<BusinessAPI.SingleResponseSupplierInvoiceVO>(
|
||||
'/operation/showSupplierInvoice',
|
||||
{
|
||||
method: 'GET',
|
||||
params: {
|
||||
...params,
|
||||
supplierInvoiceShowQry: undefined,
|
||||
...params['supplierInvoiceShowQry'],
|
||||
},
|
||||
...(options || {}),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/** 瓜农发票更新 PUT /operation/updateSupplierInvoice */
|
||||
export async function updateSupplierInvoice(
|
||||
body: BusinessAPI.SupplierInvoiceUpdateCmd,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<BusinessAPI.SingleResponseSupplierInvoiceVO>(
|
||||
'/operation/updateSupplierInvoice',
|
||||
{
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/** 瓜农发票更新 PATCH /operation/updateSupplierInvoice */
|
||||
export async function updateSupplierInvoice1(
|
||||
body: BusinessAPI.SupplierInvoiceUpdateCmd,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<BusinessAPI.SingleResponseSupplierInvoiceVO>(
|
||||
'/operation/updateSupplierInvoice',
|
||||
{
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
},
|
||||
);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,135 @@
|
||||
/** 订单供应商车次统计接口 */
|
||||
interface IOrderSupplierStatistics {
|
||||
/** 自开车次列表 */
|
||||
selfInvoiceList: BusinessAPI.OrderSupplierVO[];
|
||||
/** 代开车次列表 */
|
||||
proxyInvoiceList: BusinessAPI.OrderSupplierVO[];
|
||||
/** 无发票车次列表 */
|
||||
noInvoiceList: BusinessAPI.OrderSupplierVO[];
|
||||
/** 自开车次数量 */
|
||||
selfInvoiceCount: number;
|
||||
/** 代开车次数量 */
|
||||
proxyInvoiceCount: number;
|
||||
/** 无发票车次数量 */
|
||||
noInvoiceCount: number;
|
||||
/** 自开车次金额 */
|
||||
selfInvoiceAmount: number;
|
||||
/** 代开车次金额 */
|
||||
proxyInvoiceAmount: number;
|
||||
/** 无发票金额 */
|
||||
noInvoiceAmount: number;
|
||||
/** 开票方统计 */
|
||||
invoicerStatistics: {
|
||||
supplierName: string;
|
||||
supplierId: string;
|
||||
count: number;
|
||||
amount: number;
|
||||
}[];
|
||||
}
|
||||
|
||||
/** 统计车次数据 */
|
||||
const calculateOrderSupplierStatistics = (
|
||||
orderSupplierList?: BusinessAPI.OrderSupplierVO[],
|
||||
): IOrderSupplierStatistics => {
|
||||
if (!orderSupplierList || orderSupplierList.length === 0) {
|
||||
return {
|
||||
selfInvoiceList: [],
|
||||
proxyInvoiceList: [],
|
||||
noInvoiceList: [],
|
||||
selfInvoiceCount: 0,
|
||||
proxyInvoiceCount: 0,
|
||||
noInvoiceCount: 0,
|
||||
selfInvoiceAmount: 0,
|
||||
proxyInvoiceAmount: 0,
|
||||
noInvoiceAmount: 0,
|
||||
invoicerStatistics: [],
|
||||
};
|
||||
}
|
||||
|
||||
const selfInvoiceList: BusinessAPI.OrderSupplierVO[] = [];
|
||||
const proxyInvoiceList: BusinessAPI.OrderSupplierVO[] = [];
|
||||
const noInvoiceList: BusinessAPI.OrderSupplierVO[] = [];
|
||||
const invoicerMap = new Map<
|
||||
string,
|
||||
{ count: number; amount: number; supplierName: string }
|
||||
>();
|
||||
|
||||
for (const orderSupplier of orderSupplierList) {
|
||||
const hasInvoice = !!orderSupplier.invoiceId;
|
||||
const supplierInvoiceVO = orderSupplier.supplierInvoiceVO;
|
||||
|
||||
if (!hasInvoice) {
|
||||
// 无发票车次
|
||||
noInvoiceList.push(orderSupplier);
|
||||
} else if (
|
||||
supplierInvoiceVO &&
|
||||
orderSupplier.supplierId === supplierInvoiceVO.supplierId
|
||||
) {
|
||||
// 自开车次
|
||||
selfInvoiceList.push(orderSupplier);
|
||||
// 统计开票方 - 使用 supplierId 作为分组键
|
||||
const key = supplierInvoiceVO.supplierId;
|
||||
const existing = invoicerMap.get(key) || {
|
||||
count: 0,
|
||||
amount: 0,
|
||||
supplierName: supplierInvoiceVO.supplierName,
|
||||
};
|
||||
invoicerMap.set(key, {
|
||||
count: existing.count + 1,
|
||||
amount: existing.amount + (orderSupplier.invoiceAmount || 0),
|
||||
supplierName: supplierInvoiceVO.supplierName,
|
||||
});
|
||||
} else {
|
||||
// 代开车次
|
||||
proxyInvoiceList.push(orderSupplier);
|
||||
// 代开也统计开票方 - 使用 supplierId 作为分组键
|
||||
if (supplierInvoiceVO) {
|
||||
const key = supplierInvoiceVO.supplierId;
|
||||
const existing = invoicerMap.get(key) || {
|
||||
count: 0,
|
||||
amount: 0,
|
||||
supplierName: supplierInvoiceVO.supplierName,
|
||||
};
|
||||
invoicerMap.set(key, {
|
||||
count: existing.count + 1,
|
||||
amount:
|
||||
existing.amount + (orderSupplier.invoiceAmount || 0),
|
||||
supplierName: supplierInvoiceVO.supplierName,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const invoicerStatistics = Array.from(invoicerMap.entries()).map(
|
||||
([supplierId, data]) => ({
|
||||
supplierId,
|
||||
supplierName: data.supplierName,
|
||||
count: data.count,
|
||||
amount: data.amount,
|
||||
}),
|
||||
);
|
||||
|
||||
return {
|
||||
selfInvoiceList,
|
||||
proxyInvoiceList,
|
||||
noInvoiceList,
|
||||
selfInvoiceCount: selfInvoiceList.length,
|
||||
proxyInvoiceCount: proxyInvoiceList.length,
|
||||
noInvoiceCount: noInvoiceList.length,
|
||||
selfInvoiceAmount: selfInvoiceList.reduce(
|
||||
(sum, item) => sum + (item.invoiceAmount || 0),
|
||||
0,
|
||||
),
|
||||
proxyInvoiceAmount: proxyInvoiceList.reduce(
|
||||
(sum, item) => sum + (item.invoiceAmount || 0),
|
||||
0,
|
||||
),
|
||||
noInvoiceAmount: noInvoiceList.reduce(
|
||||
(sum, item) => sum + (item.invoiceAmount || 0),
|
||||
0,
|
||||
),
|
||||
invoicerStatistics,
|
||||
};
|
||||
};
|
||||
|
||||
export { calculateOrderSupplierStatistics };
|
||||
32107
pnpm-lock.yaml
32107
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user