feat(reconciliation): 新增对账记录创建功能
- 添加 ReconciliationRecordCreate 组件实现对账单创建流程 - 更新 DealerAccountRecordList 组件中 dealerAccountRecordId 字段为可选 - 修改 DealerModal 中显示经销商名称格式 - 调整 LeftMenu 样式中的 margin 属性 - 重构 PaymentTask 和 Reconciliation 组件中的渲染逻辑 - 简化 ReconciliationSummary 组件的参数传递方式 - 更新国际化配置文件增加对账相关翻译 - 替换 ReconciliationCreate 页面使用新的创建组件
This commit is contained in:
parent
9001490da1
commit
65b5d42985
@ -624,3 +624,289 @@ operation-<资源>-<操作>
|
||||
1. 确认 `dataIndex` 使用的是 `orderVO` 而不是 `orderId`
|
||||
2. 确认 `key` 使用的是 `orderId`
|
||||
3. 检查 BizContainer 配置中 `detail` 是否正确启用
|
||||
|
||||
## 高级配置:Toolbar 和状态管理
|
||||
|
||||
### Toolbar Tab 配置
|
||||
|
||||
对于需要按状态筛选的列表页面,可以添加 Tab 类型的 toolbar:
|
||||
|
||||
**完整示例(参考 PaymentTaskList):**
|
||||
```tsx
|
||||
import React, { useState } from 'react';
|
||||
|
||||
export default function ComponentNameList(props: IComponentNameListProps) {
|
||||
const intl = useIntl();
|
||||
const intlPrefix = 'componentName';
|
||||
|
||||
// 1. 添加 activeKey 状态管理
|
||||
const [activeKey, setActiveKey] = useState<string>('PENDING');
|
||||
|
||||
return (
|
||||
<BizContainer
|
||||
// ... 其他配置
|
||||
page={{
|
||||
fieldProps: {
|
||||
// 2. 将 activeKey 传递给 params 作为筛选条件
|
||||
params: {
|
||||
...(activeKey !== 'ALL' && {
|
||||
state: activeKey as BusinessAPI.XXXVO['state'],
|
||||
}),
|
||||
},
|
||||
// 3. 配置 toolbar
|
||||
toolbar: {
|
||||
menu: {
|
||||
type: 'tab',
|
||||
activeKey: activeKey,
|
||||
items: [
|
||||
{
|
||||
key: 'ALL',
|
||||
label: intl.formatMessage({
|
||||
id: intlPrefix + '.tab.all',
|
||||
}),
|
||||
},
|
||||
// ... 其他状态 tab
|
||||
],
|
||||
onChange: (key) => {
|
||||
setActiveKey(key as string);
|
||||
},
|
||||
},
|
||||
// 4. 可选:添加操作按钮
|
||||
actions: [
|
||||
<ComponentCreate
|
||||
key={'create'}
|
||||
onFinish={() => {
|
||||
actionRef.current?.reload();
|
||||
onValueChange?.();
|
||||
}}
|
||||
/>,
|
||||
],
|
||||
},
|
||||
},
|
||||
columns,
|
||||
options: () => [],
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
**关键点:**
|
||||
1. **useState**: 使用 `useState` 管理当前选中的 tab
|
||||
2. **params 筛选**: 当 `activeKey !== 'ALL'` 时,将状态传递给 API 查询参数
|
||||
3. **toolbar.menu.type**: 设置为 `'tab'` 启用 tab 菜单
|
||||
4. **onChange**: tab 切换时更新 `activeKey`
|
||||
5. **actions**: 可选,在 toolbar 右侧添加操作按钮
|
||||
|
||||
**参考文件:** `components/PaymentTask/PaymentTaskList.tsx:538-587`
|
||||
|
||||
### 状态枚举映射(stateMap)
|
||||
|
||||
为状态字段创建枚举映射,统一管理状态显示文本和颜色:
|
||||
|
||||
**定义模式:**
|
||||
```tsx
|
||||
// 状态枚举映射
|
||||
const stateMap: Record<string, { label: string; color: string }> = {
|
||||
PENDING: {
|
||||
label: intl.formatMessage({
|
||||
id: intlPrefix + '.state.pending',
|
||||
}),
|
||||
color: 'default', // default | processing | success | warning | error
|
||||
},
|
||||
COMPLETED: {
|
||||
label: intl.formatMessage({
|
||||
id: intlPrefix + '.state.completed',
|
||||
}),
|
||||
color: 'success',
|
||||
},
|
||||
CANCELLED: {
|
||||
label: intl.formatMessage({
|
||||
id: intlPrefix + '.state.cancelled',
|
||||
}),
|
||||
color: 'error',
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
**在列配置中使用 stateMap:**
|
||||
```tsx
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.state' }),
|
||||
dataIndex: 'state',
|
||||
key: 'state',
|
||||
valueType: 'select',
|
||||
valueEnum: Object.entries(stateMap).reduce(
|
||||
(acc, [key, value]) => ({
|
||||
...acc,
|
||||
[key]: { text: value.label, status: value.color as any },
|
||||
}),
|
||||
{},
|
||||
),
|
||||
search: false, // 状态通常通过 tab 筛选,不需要在搜索表单中显示
|
||||
render: (_, record) => {
|
||||
const stateInfo = stateMap[record.state as string];
|
||||
return stateInfo ? (
|
||||
<span style={{ color: stateInfo.color === 'default' ? undefined : stateInfo.color }}>
|
||||
{stateInfo.label}
|
||||
</span>
|
||||
) : (
|
||||
<span>{record.state}</span>
|
||||
);
|
||||
},
|
||||
},
|
||||
```
|
||||
|
||||
**颜色映射规则:**
|
||||
| 状态类型 | color 值 | ProTable status | 适用场景 |
|
||||
|---------|----------|----------------|----------|
|
||||
| 默认/待处理 | `default` | `Default` | 待处理、初始状态 |
|
||||
| 进行中 | `processing` | `Processing` | 处理中、部分完成 |
|
||||
| 成功/完成 | `success` | `Success` | 已完成、已通过 |
|
||||
| 警告/注意 | `warning` | `Warning` | 部分完成、需注意 |
|
||||
| 错误/取消 | `error` | `Error` | 已取消、已拒绝 |
|
||||
|
||||
**国际化翻译配置:**
|
||||
```typescript
|
||||
componentName: {
|
||||
state: {
|
||||
pending: '待处理',
|
||||
completed: '已完成',
|
||||
cancelled: '已取消',
|
||||
},
|
||||
tab: {
|
||||
all: '全部',
|
||||
pending: '待处理',
|
||||
completed: '已完成',
|
||||
cancelled: '已取消',
|
||||
},
|
||||
},
|
||||
```
|
||||
|
||||
**最佳实践:**
|
||||
1. **stateMap 和 tab items 保持一致**: 状态枚举值应与 tab 的 key 完全匹配
|
||||
2. **使用国际化的 key**: stateMap 中的 key 使用后端枚举值(如 `PENDING`),label 使用国际化
|
||||
3. **颜色语义化**: 根据状态含义选择合适的颜色
|
||||
4. **添加 ALL tab**: 除了具体状态外,通常需要"全部"选项用于显示所有数据
|
||||
|
||||
**参考文件:** `components/Reconciliation/ReconciliationRecordList.tsx:32-72`
|
||||
|
||||
### 完整示例:带 Tab 筛选的列表组件
|
||||
|
||||
```tsx
|
||||
import { BizContainer, BizValueType, ModeType } from '@/components';
|
||||
import { business } from '@/services';
|
||||
import { useIntl } from '@@/exports';
|
||||
import { ProColumns } from '@ant-design/pro-components';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
export default function ReconciliationRecordList(
|
||||
props: IReconciliationRecordListProps,
|
||||
) {
|
||||
const { ghost = false, search = true, mode = 'page' } = props;
|
||||
const intl = useIntl();
|
||||
const intlPrefix = 'reconciliationRecord';
|
||||
|
||||
const [activeKey, setActiveKey] = useState<string>('PENDING');
|
||||
|
||||
// 状态枚举映射
|
||||
const stateMap: Record<string, { label: string; color: string }> = {
|
||||
PENDING: {
|
||||
label: intl.formatMessage({ id: intlPrefix + '.state.pending' }),
|
||||
color: 'default',
|
||||
},
|
||||
RECONCILED: {
|
||||
label: intl.formatMessage({ id: intlPrefix + '.state.reconciled' }),
|
||||
color: 'processing',
|
||||
},
|
||||
PARTIAL_INVOICE: {
|
||||
label: intl.formatMessage({ id: intlPrefix + '.state.partialInvoice' }),
|
||||
color: 'warning',
|
||||
},
|
||||
INVOICED: {
|
||||
label: intl.formatMessage({ id: intlPrefix + '.state.invoiced' }),
|
||||
color: 'success',
|
||||
},
|
||||
PARTIAL_PAYMENT: {
|
||||
label: intl.formatMessage({ id: intlPrefix + '.state.partialPayment' }),
|
||||
color: 'warning',
|
||||
},
|
||||
PAID: {
|
||||
label: intl.formatMessage({ id: intlPrefix + '.state.paid' }),
|
||||
color: 'success',
|
||||
},
|
||||
};
|
||||
|
||||
const columns: ProColumns<BusinessAPI.ReconciliationVO, BizValueType>[] = [
|
||||
// ... 列配置
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.state' }),
|
||||
dataIndex: 'state',
|
||||
key: 'state',
|
||||
valueType: 'select',
|
||||
valueEnum: Object.entries(stateMap).reduce(
|
||||
(acc, [key, value]) => ({
|
||||
...acc,
|
||||
[key]: { text: value.label, status: value.color as any },
|
||||
}),
|
||||
{},
|
||||
),
|
||||
search: false,
|
||||
render: (_, record) => {
|
||||
const stateInfo = stateMap[record.state as string];
|
||||
return stateInfo ? (
|
||||
<span className={`text-${stateInfo.color}-600`}>
|
||||
{stateInfo.label}
|
||||
</span>
|
||||
) : (
|
||||
<span>{record.state}</span>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<BizContainer>
|
||||
page={{
|
||||
fieldProps: {
|
||||
params: {
|
||||
...(activeKey !== 'ALL' && {
|
||||
state: activeKey as BusinessAPI.ReconciliationVO['state'],
|
||||
}),
|
||||
},
|
||||
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: 'RECONCILED',
|
||||
label: intl.formatMessage({ id: intlPrefix + '.tab.reconciled' }),
|
||||
},
|
||||
// ... 其他状态 tab
|
||||
],
|
||||
onChange: (key) => {
|
||||
setActiveKey(key as string);
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
columns,
|
||||
options: () => [],
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
**参考文件:**
|
||||
- `components/PaymentTask/PaymentTaskList.tsx` - 完整的 Tab 筛选示例
|
||||
- `components/Reconciliation/ReconciliationRecordList.tsx` - 对账记录 Tab 筛选
|
||||
|
||||
@ -12,7 +12,7 @@ interface IDealerAccountRecordListProps {
|
||||
ghost?: boolean;
|
||||
dealerVO?: BusinessAPI.DealerVO;
|
||||
orderVO?: BusinessAPI.OrderVO;
|
||||
dealerAccountRecordId: BusinessAPI.DealerAccountRecordVO['dealerAccountRecordId'];
|
||||
dealerAccountRecordId?: BusinessAPI.DealerAccountRecordVO['dealerAccountRecordId'];
|
||||
search?: boolean;
|
||||
onValueChange?: () => void;
|
||||
mode?: ModeType;
|
||||
|
||||
@ -2,6 +2,7 @@ import { DealerList, SelectModal } from '@/components';
|
||||
import { business } from '@/services';
|
||||
import { formatParam } from '@/utils/formatParam';
|
||||
import { pagination } from '@/utils/pagination';
|
||||
import { useIntl } from '@@/exports';
|
||||
import {
|
||||
ActionType,
|
||||
LightFilter,
|
||||
@ -9,7 +10,6 @@ import {
|
||||
} from '@ant-design/pro-components';
|
||||
import { Alert, ModalProps, Row, Space, Tag } from 'antd';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { useIntl } from '@@/exports';
|
||||
|
||||
export interface IDealerModalProps extends ModalProps {
|
||||
title: string;
|
||||
@ -207,7 +207,7 @@ export default function DealerModal(props: IDealerModalProps) {
|
||||
}}
|
||||
key={item.dealerId}
|
||||
>
|
||||
({item.shortName}) {item.fullName}
|
||||
{item.shortName}
|
||||
</Tag>
|
||||
);
|
||||
})}
|
||||
|
||||
@ -32,7 +32,7 @@ const useButtonStyle = () => {
|
||||
subMenu: {
|
||||
width: '140px !important',
|
||||
backgroundColor: '#fff !important',
|
||||
margin: '8px 0 !important',
|
||||
margin: '8px 0 0 0 !important',
|
||||
overflow: 'scroll',
|
||||
scrollbarWidth: 'none',
|
||||
},
|
||||
|
||||
@ -248,10 +248,12 @@ export default function PaymentTaskCreate(props: IPaymentTaskCreateProps) {
|
||||
{
|
||||
title: '开票瓜农',
|
||||
dataIndex: 'supplierInvoiceVO',
|
||||
key: 'supplierName',
|
||||
render: (
|
||||
supplierInvoiceVO: BusinessAPI.SupplierInvoiceVO,
|
||||
_,
|
||||
orderSupplierVO: BusinessAPI.OrderSupplierVO,
|
||||
) => {
|
||||
const supplierInvoiceVO =
|
||||
orderSupplierVO.supplierInvoiceVO;
|
||||
return (
|
||||
supplierInvoiceVO && (
|
||||
<SupplierFarmerList
|
||||
@ -269,11 +271,14 @@ export default function PaymentTaskCreate(props: IPaymentTaskCreateProps) {
|
||||
{
|
||||
title: '发票编码',
|
||||
dataIndex: 'supplierInvoiceVO',
|
||||
key: 'invoiceSn',
|
||||
render: (
|
||||
supplierInvoiceVO: BusinessAPI.SupplierInvoiceVO,
|
||||
_,
|
||||
orderSupplierVO: BusinessAPI.OrderSupplierVO,
|
||||
) => {
|
||||
const supplierInvoiceVO =
|
||||
orderSupplierVO.supplierInvoiceVO;
|
||||
return (
|
||||
supplierInvoiceVO && (
|
||||
<SupplierInvoiceList
|
||||
ghost={true}
|
||||
mode={'detail'}
|
||||
@ -286,6 +291,7 @@ export default function PaymentTaskCreate(props: IPaymentTaskCreateProps) {
|
||||
</Space>
|
||||
)}
|
||||
/>
|
||||
)
|
||||
);
|
||||
},
|
||||
},
|
||||
@ -293,18 +299,24 @@ export default function PaymentTaskCreate(props: IPaymentTaskCreateProps) {
|
||||
{
|
||||
title: '开票状态',
|
||||
key: 'invoiceStatus',
|
||||
render: (record: BusinessAPI.OrderSupplierVO) => {
|
||||
render: (
|
||||
_,
|
||||
orderSupplierVO: BusinessAPI.OrderSupplierVO,
|
||||
) => {
|
||||
let invoiceStatus = 'NOT_INVOICE';
|
||||
if (record.invoiceUpload && record.invoiceId) {
|
||||
if (
|
||||
record.supplierId ===
|
||||
record.supplierInvoiceVO?.supplierId
|
||||
orderSupplierVO.invoiceUpload &&
|
||||
orderSupplierVO.invoiceId
|
||||
) {
|
||||
if (
|
||||
orderSupplierVO.supplierId ===
|
||||
orderSupplierVO.supplierInvoiceVO?.supplierId
|
||||
) {
|
||||
invoiceStatus = 'SELF';
|
||||
}
|
||||
if (
|
||||
record.supplierId !==
|
||||
record.supplierInvoiceVO?.supplierId
|
||||
orderSupplierVO.supplierId !==
|
||||
orderSupplierVO.supplierInvoiceVO?.supplierId
|
||||
) {
|
||||
invoiceStatus = 'AGENT';
|
||||
}
|
||||
@ -327,7 +339,10 @@ export default function PaymentTaskCreate(props: IPaymentTaskCreateProps) {
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
fixed: 'right',
|
||||
render: (record: BusinessAPI.OrderSupplierVO) => (
|
||||
render: (
|
||||
_,
|
||||
orderSupplierVO: BusinessAPI.OrderSupplierVO,
|
||||
) => (
|
||||
<Button
|
||||
type="link"
|
||||
danger
|
||||
@ -336,7 +351,7 @@ export default function PaymentTaskCreate(props: IPaymentTaskCreateProps) {
|
||||
selectedOrderSupplierList.filter(
|
||||
(item) =>
|
||||
item.orderSupplierId !==
|
||||
record.orderSupplierId,
|
||||
orderSupplierVO.orderSupplierId,
|
||||
),
|
||||
);
|
||||
}}
|
||||
|
||||
@ -259,8 +259,11 @@ export default function PaymentTaskList(props: IPaymentTaskListProps) {
|
||||
title: '开票瓜农',
|
||||
dataIndex: 'supplierInvoiceVO',
|
||||
render: (
|
||||
supplierInvoiceVO: BusinessAPI.SupplierInvoiceVO,
|
||||
_,
|
||||
orderSupplierVO: BusinessAPI.OrderSupplierVO,
|
||||
) => {
|
||||
const supplierInvoiceVO =
|
||||
orderSupplierVO.supplierInvoiceVO;
|
||||
return (
|
||||
supplierInvoiceVO && (
|
||||
<SupplierFarmerList
|
||||
@ -280,9 +283,13 @@ export default function PaymentTaskList(props: IPaymentTaskListProps) {
|
||||
dataIndex: 'supplierInvoiceVO',
|
||||
key: 'invoiceSn',
|
||||
render: (
|
||||
supplierInvoiceVO: BusinessAPI.SupplierInvoiceVO,
|
||||
_,
|
||||
orderSupplierVO: BusinessAPI.OrderSupplierVO,
|
||||
) => {
|
||||
const supplierInvoiceVO =
|
||||
orderSupplierVO.supplierInvoiceVO;
|
||||
return (
|
||||
supplierInvoiceVO && (
|
||||
<SupplierInvoiceList
|
||||
ghost={true}
|
||||
mode={'detail'}
|
||||
@ -295,6 +302,7 @@ export default function PaymentTaskList(props: IPaymentTaskListProps) {
|
||||
</Space>
|
||||
)}
|
||||
/>
|
||||
)
|
||||
);
|
||||
},
|
||||
},
|
||||
@ -328,8 +336,11 @@ export default function PaymentTaskList(props: IPaymentTaskListProps) {
|
||||
title: '开票瓜农',
|
||||
dataIndex: 'supplierInvoiceVO',
|
||||
render: (
|
||||
supplierInvoiceVO: BusinessAPI.SupplierInvoiceVO,
|
||||
_,
|
||||
orderSupplierVO: BusinessAPI.OrderSupplierVO,
|
||||
) => {
|
||||
const supplierInvoiceVO =
|
||||
orderSupplierVO.supplierInvoiceVO;
|
||||
return (
|
||||
supplierInvoiceVO && (
|
||||
<SupplierFarmerList
|
||||
@ -349,9 +360,13 @@ export default function PaymentTaskList(props: IPaymentTaskListProps) {
|
||||
dataIndex: 'supplierInvoiceVO',
|
||||
key: 'invoiceSn',
|
||||
render: (
|
||||
supplierInvoiceVO: BusinessAPI.SupplierInvoiceVO,
|
||||
_,
|
||||
orderSupplierVO: BusinessAPI.OrderSupplierVO,
|
||||
) => {
|
||||
const supplierInvoiceVO =
|
||||
orderSupplierVO.supplierInvoiceVO;
|
||||
return (
|
||||
supplierInvoiceVO && (
|
||||
<SupplierInvoiceList
|
||||
ghost={true}
|
||||
mode={'detail'}
|
||||
@ -364,6 +379,7 @@ export default function PaymentTaskList(props: IPaymentTaskListProps) {
|
||||
</Space>
|
||||
)}
|
||||
/>
|
||||
)
|
||||
);
|
||||
},
|
||||
},
|
||||
@ -396,7 +412,11 @@ export default function PaymentTaskList(props: IPaymentTaskListProps) {
|
||||
title: '瓜农收款码',
|
||||
dataIndex: 'wechatQr',
|
||||
key: 'wechatQr',
|
||||
render: (wechatQr: string) => {
|
||||
render: (
|
||||
_,
|
||||
orderSupplierVO: BusinessAPI.OrderSupplierVO,
|
||||
) => {
|
||||
const wechatQr = orderSupplierVO.wechatQr;
|
||||
if (!wechatQr) {
|
||||
return '暂无微信收款码';
|
||||
}
|
||||
|
||||
@ -0,0 +1,695 @@
|
||||
import {
|
||||
BizEditor,
|
||||
ButtonAccess,
|
||||
OrderShipSelectList,
|
||||
PageContainer,
|
||||
ReconciliationAdjustment,
|
||||
ReconciliationSummary,
|
||||
} from '@/components';
|
||||
import DealerModal from '@/components/Dealer/DealerModal';
|
||||
import OrderShipModal from '@/components/Order/OrderShipModal';
|
||||
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,
|
||||
FooterToolbar,
|
||||
ProCard,
|
||||
ProForm,
|
||||
ProFormDependency,
|
||||
ProFormSelect,
|
||||
RouteContext,
|
||||
RouteContextType,
|
||||
} from '@ant-design/pro-components';
|
||||
import { Button, Col, message, Row, Space, Steps, Table, Tag } from 'antd';
|
||||
import { useState } from 'react';
|
||||
|
||||
interface IReconciliationRecordCreateProps {
|
||||
mode: 'page' | 'drawer';
|
||||
onFinish?: () => void;
|
||||
}
|
||||
|
||||
export default function ReconciliationRecordCreate(
|
||||
props: IReconciliationRecordCreateProps,
|
||||
) {
|
||||
const { mode, onFinish } = props;
|
||||
const intl = useIntl();
|
||||
const intlPrefix = 'reconciliationRecord';
|
||||
const [current, setCurrent] = useState(0);
|
||||
const [submitLoading, setSubmitLoading] = useState(false);
|
||||
|
||||
const [selectedDealer, setSelectedDealer] =
|
||||
useState<BusinessAPI.DealerVO | null>(null);
|
||||
const [dealerModalOpen, setDealerModalOpen] = useState(false);
|
||||
const [selectedShipOrderList, setSelectedShipOrderList] = useState<
|
||||
BusinessAPI.OrderShipVO[]
|
||||
>([]);
|
||||
const [orderShipModalOpen, setOrderShipModalOpen] = useState(false);
|
||||
|
||||
// 调整项状态 Map<发货单ID, 调整项数组>
|
||||
const [adjustmentsMap, setAdjustmentsMap] = useState<
|
||||
Record<string, ReconciliationAdjustment[]>
|
||||
>({});
|
||||
|
||||
// 抹零状态
|
||||
const [roundOff, setRoundOff] = useState<{
|
||||
roundOffEnabled?: boolean;
|
||||
roundOffAmount?: number;
|
||||
roundOffRemark?: string;
|
||||
}>({});
|
||||
|
||||
// 备注状态
|
||||
const [remark, setRemark] = useState('');
|
||||
|
||||
const [companyId, setCompanyId] =
|
||||
useState<BusinessAPI.CompanyVO['companyId']>();
|
||||
|
||||
// // 添加调整项
|
||||
// const handleAddAdjustment = useCallback((shipOrderId: string) => {
|
||||
// const newAdjustment: ReconciliationAdjustment = {
|
||||
// id: `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`,
|
||||
// type: 'LOSS',
|
||||
// quantity: 0,
|
||||
// unitPrice: 0,
|
||||
// amount: 0,
|
||||
// remark: '',
|
||||
// };
|
||||
// setAdjustmentsMap((prev) => ({
|
||||
// ...prev,
|
||||
// [shipOrderId]: [...(prev[shipOrderId] || []), newAdjustment],
|
||||
// }));
|
||||
// }, []);
|
||||
//
|
||||
// // 删除调整项
|
||||
// const handleRemoveAdjustment = useCallback(
|
||||
// (shipOrderId: string, adjustmentId: string) => {
|
||||
// setAdjustmentsMap((prev) => ({
|
||||
// ...prev,
|
||||
// [shipOrderId]: (prev[shipOrderId] || []).filter(
|
||||
// (adj) => adj.id !== adjustmentId,
|
||||
// ),
|
||||
// }));
|
||||
// },
|
||||
// [],
|
||||
// );
|
||||
|
||||
let receivableAmount =
|
||||
selectedShipOrderList?.reduce(
|
||||
(sum, item) => sum + (item.receivableAmount || 0),
|
||||
0,
|
||||
) || 0;
|
||||
let adjustedAmount =
|
||||
selectedShipOrderList?.reduce(
|
||||
(sum, item) => sum + (item.adjustedAmount || 0),
|
||||
0,
|
||||
) || 0;
|
||||
|
||||
// 计算调整总额
|
||||
const adjustmentTotal = Object.values(adjustmentsMap)
|
||||
.flat()
|
||||
.reduce((sum, adj) => sum + (adj.amount || 0), 0);
|
||||
|
||||
// 计算原对账金额(应收金额 - 已调整金额)
|
||||
const originalAmount = receivableAmount - adjustedAmount;
|
||||
|
||||
// 计算实际对账金额(含抹零)
|
||||
const roundingAmount = roundOff.roundOffEnabled
|
||||
? roundOff.roundOffAmount || 0
|
||||
: 0;
|
||||
const reconciliationAmount =
|
||||
originalAmount - adjustmentTotal + roundingAmount;
|
||||
|
||||
// 提交对账单处理函数
|
||||
const handleSubmit = async () => {
|
||||
if (!selectedDealer) {
|
||||
message.warning('请选择经销商');
|
||||
return;
|
||||
}
|
||||
if (selectedShipOrderList.length === 0) {
|
||||
message.warning('请选择发货车次');
|
||||
return;
|
||||
}
|
||||
|
||||
setSubmitLoading(true);
|
||||
try {
|
||||
const result = await business.reconciliation.createReconciliation({
|
||||
dealerId: selectedDealer.dealerId!,
|
||||
originalAmount,
|
||||
isRounding: roundOff.roundOffEnabled || false,
|
||||
roundingAmount,
|
||||
roundingRemark: roundOff.roundOffRemark || '',
|
||||
reconciliationAmount,
|
||||
remark,
|
||||
companyId: companyId!,
|
||||
orderShipVOList: selectedShipOrderList,
|
||||
});
|
||||
|
||||
if (result.success) {
|
||||
message.success('对账单创建成功');
|
||||
onFinish?.();
|
||||
} else {
|
||||
message.error(result.errMessage || '对账单创建失败');
|
||||
}
|
||||
} catch (error) {
|
||||
message.error('对账单创建失败,请稍后重试');
|
||||
console.error('提交对账单失败:', error);
|
||||
} finally {
|
||||
setSubmitLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const orderCount = selectedShipOrderList.length;
|
||||
|
||||
const renderForm = () => {
|
||||
{
|
||||
/* 对账单表单 */
|
||||
}
|
||||
return (
|
||||
<ProCard
|
||||
title={'创建对账单'}
|
||||
headerBordered
|
||||
subTitle={
|
||||
<Space>
|
||||
<Tag color="blue">步骤 {current + 1}</Tag>
|
||||
{current === 0 && '选择经销商'}
|
||||
{current === 1 && '选择发货车次'}
|
||||
{current === 2 && '核对并录入调整项'}
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
{/* 步骤1:选择经销商 */}
|
||||
{(current === 0 || current === 1) && (
|
||||
<>
|
||||
{/* 选择经销商 */}
|
||||
<ProCard
|
||||
title={'经销商信息'}
|
||||
style={{ marginTop: 16 }}
|
||||
bordered
|
||||
extra={
|
||||
current === 0 && (
|
||||
<Button
|
||||
type="primary"
|
||||
size="middle"
|
||||
onClick={() => setDealerModalOpen(true)}
|
||||
>
|
||||
选择经销商
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
>
|
||||
{selectedDealer ? (
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={8}>
|
||||
<div>
|
||||
<div style={{ color: '#999', marginBottom: 4 }}>
|
||||
经销商简称
|
||||
</div>
|
||||
<div style={{ fontWeight: 'bold' }}>
|
||||
{selectedDealer.shortName || '-'}
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<div>
|
||||
<div style={{ color: '#999', marginBottom: 4 }}>
|
||||
经销商类型
|
||||
</div>
|
||||
<div style={{ fontWeight: 'bold' }}>
|
||||
{selectedDealer.dealerType === 'MARKET'
|
||||
? '市场'
|
||||
: '超市'}
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<div>
|
||||
<div style={{ color: '#999', marginBottom: 4 }}>
|
||||
应收金额
|
||||
</div>
|
||||
<div style={{ fontWeight: 'bold' }}>
|
||||
¥{selectedDealer.receivable || '-'}
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
padding: '40px 0',
|
||||
color: '#999',
|
||||
}}
|
||||
>
|
||||
暂无选择,请点击「选择经销商」按钮选择
|
||||
</div>
|
||||
)}
|
||||
</ProCard>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* 步骤2:选择发货车次 */}
|
||||
{current === 1 && selectedDealer && (
|
||||
<>
|
||||
{/* 选择车次 */}
|
||||
<ProCard
|
||||
title={'选择车次'}
|
||||
style={{ marginTop: 16 }}
|
||||
bordered
|
||||
extra={
|
||||
<Button
|
||||
type="primary"
|
||||
size="middle"
|
||||
onClick={() => setOrderShipModalOpen(true)}
|
||||
>
|
||||
添加车次
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
{selectedShipOrderList.length > 0 ? (
|
||||
<OrderShipSelectList
|
||||
dataSource={selectedShipOrderList}
|
||||
columns={[
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
fixed: 'right',
|
||||
width: 80,
|
||||
render: (_: any, record: BusinessAPI.OrderShipVO) => (
|
||||
<Button
|
||||
type="link"
|
||||
danger
|
||||
onClick={() => {
|
||||
setSelectedShipOrderList(
|
||||
selectedShipOrderList.filter(
|
||||
(item) =>
|
||||
item.orderShipId !== record.orderShipId,
|
||||
),
|
||||
);
|
||||
// 同时清除该车次的调整项
|
||||
setAdjustmentsMap((prev) => {
|
||||
const newMap = { ...prev };
|
||||
delete newMap[record.orderShipId];
|
||||
return newMap;
|
||||
});
|
||||
}}
|
||||
>
|
||||
移除
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
]}
|
||||
pagination={false}
|
||||
size="small"
|
||||
summary={(pageData) => {
|
||||
let receivableAmount =
|
||||
pageData?.reduce(
|
||||
(sum, item) => sum + (item.receivableAmount || 0),
|
||||
0,
|
||||
) || 0;
|
||||
let adjustedAmount =
|
||||
pageData?.reduce(
|
||||
(sum, item) => sum + (item.adjustedAmount || 0),
|
||||
0,
|
||||
) || 0;
|
||||
return (
|
||||
<Table.Summary fixed>
|
||||
<Table.Summary.Row>
|
||||
<Table.Summary.Cell index={0} colSpan={9}>
|
||||
<strong>合计</strong>
|
||||
</Table.Summary.Cell>
|
||||
<Table.Summary.Cell index={1}>
|
||||
<strong className="text-blue-600 font-medium">
|
||||
¥{formatCurrency(receivableAmount)}
|
||||
</strong>
|
||||
</Table.Summary.Cell>
|
||||
<Table.Summary.Cell index={1}>
|
||||
<strong
|
||||
className={
|
||||
adjustedAmount >= 0
|
||||
? 'text-green-600'
|
||||
: 'text-red-600'
|
||||
}
|
||||
>
|
||||
¥{formatCurrency(adjustedAmount)}
|
||||
</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>
|
||||
|
||||
{/* 任务摘要 */}
|
||||
{selectedShipOrderList.length > 0 && (
|
||||
<ProCard title={'对账摘要'} style={{ marginTop: 16 }} bordered>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={6}>
|
||||
<div>
|
||||
<div style={{ color: '#999', marginBottom: 4 }}>
|
||||
对账经销商
|
||||
</div>
|
||||
<div style={{ fontWeight: 'bold' }}>
|
||||
{selectedDealer?.fullName || selectedDealer?.shortName}
|
||||
</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(receivableAmount - adjustedAmount)}
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<div>
|
||||
<div style={{ color: '#999', marginBottom: 4 }}>
|
||||
对账状态
|
||||
</div>
|
||||
<div>
|
||||
<Tag color="orange">待对账</Tag>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</ProCard>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* 步骤3:核对并录入调整项 */}
|
||||
{current === 2 && (
|
||||
<>
|
||||
{/* 对账车次清单 */}
|
||||
{/*<ProCard title={'对账车次清单'} style={{ marginTop: 16 }} bordered>*/}
|
||||
{/* {selectedShipOrderList.map((shipOrder) => (*/}
|
||||
{/* <ReconciliationShipCard*/}
|
||||
{/* key={shipOrder.orderShipId}*/}
|
||||
{/* shipOrder={shipOrder}*/}
|
||||
{/* adjustments={adjustmentsMap[shipOrder.orderShipId] || []}*/}
|
||||
{/* onAddAdjustment={handleAddAdjustment}*/}
|
||||
{/* onRemoveAdjustment={handleRemoveAdjustment}*/}
|
||||
{/* />*/}
|
||||
{/* ))}*/}
|
||||
{/*</ProCard>*/}
|
||||
|
||||
{/* 对账汇总 */}
|
||||
<ProCard title={'对账汇总'} style={{ marginTop: 16 }} bordered>
|
||||
<ProFormDependency name={['roundOffAmount']}>
|
||||
{({ roundOffAmount }) => {
|
||||
return (
|
||||
<ReconciliationSummary
|
||||
shipOrders={selectedShipOrderList}
|
||||
adjustmentsMap={adjustmentsMap}
|
||||
roundOffAmount={roundOffAmount}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
</ProFormDependency>
|
||||
</ProCard>
|
||||
|
||||
{/* 备注信息 */}
|
||||
<ProCard title={'备注信息'} style={{ marginTop: 16 }} bordered>
|
||||
<ProFormSelect
|
||||
label={'入账公司'}
|
||||
name={'companyId'}
|
||||
placeholder={'请选择入账公司'}
|
||||
request={async (params) => {
|
||||
const { data } = await business.company.listCompany({
|
||||
companyListQry: {
|
||||
...params,
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
data?.map((item) => {
|
||||
return {
|
||||
label: item.fullName,
|
||||
value: item.companyId,
|
||||
};
|
||||
}) || []
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<ProFormDependency key={'remark'} name={['remark']}>
|
||||
{({}, form) => {
|
||||
return (
|
||||
<BizEditor
|
||||
key={'remark'}
|
||||
value={remark}
|
||||
onChange={(value) => {
|
||||
setRemark(value);
|
||||
form.setFieldValue('remark', value);
|
||||
}}
|
||||
label={'对账备注'}
|
||||
name={'remark'}
|
||||
placeholder={'请输入对账备注信息'}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
</ProFormDependency>
|
||||
</ProCard>
|
||||
</>
|
||||
)}
|
||||
</ProCard>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<RouteContext.Consumer>
|
||||
{(value: RouteContextType) => {
|
||||
const { isMobile } = value;
|
||||
if (mode === 'page') {
|
||||
return (
|
||||
<PageContainer
|
||||
permission={''}
|
||||
fieldProps={{
|
||||
content: (
|
||||
<Steps
|
||||
current={current}
|
||||
style={{ padding: '16px 0' }}
|
||||
items={[
|
||||
{
|
||||
title: '选择经销商',
|
||||
},
|
||||
{
|
||||
title: '选择发货车次',
|
||||
},
|
||||
{
|
||||
title: '核对并录入调整项',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
>
|
||||
<ProForm
|
||||
{...formLayout(isMobile)}
|
||||
submitter={{
|
||||
render: () => (
|
||||
<FooterToolbar
|
||||
style={{
|
||||
width: 'calc(100% - 248px)',
|
||||
}}
|
||||
>
|
||||
<Space>
|
||||
{current === 1 && (
|
||||
<Button onClick={() => setCurrent(0)}>
|
||||
上一步
|
||||
</Button>
|
||||
)}
|
||||
{current === 2 && (
|
||||
<Button onClick={() => setCurrent(1)}>
|
||||
上一步
|
||||
</Button>
|
||||
)}
|
||||
{current === 0 && (
|
||||
<Button
|
||||
type="primary"
|
||||
disabled={!selectedDealer}
|
||||
onClick={() => setCurrent(1)}
|
||||
>
|
||||
下一步:选择发货车次
|
||||
</Button>
|
||||
)}
|
||||
{current === 1 && (
|
||||
<Button
|
||||
type="primary"
|
||||
disabled={selectedShipOrderList.length === 0}
|
||||
onClick={() => setCurrent(2)}
|
||||
>
|
||||
下一步:核对并录入调整项
|
||||
</Button>
|
||||
)}
|
||||
{current === 2 && (
|
||||
<Button
|
||||
type="primary"
|
||||
loading={submitLoading}
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
提交对账单
|
||||
</Button>
|
||||
)}
|
||||
</Space>
|
||||
</FooterToolbar>
|
||||
),
|
||||
}}
|
||||
onValuesChange={(formData) => {
|
||||
setRoundOff({
|
||||
roundOffEnabled: formData.roundOffEnabled || false,
|
||||
roundOffAmount: formData.roundOffAmount || 0,
|
||||
roundOffRemark: formData.roundOffRemark || '',
|
||||
});
|
||||
|
||||
setRemark(formData.remark || '');
|
||||
setCompanyId(formData.companyId || '');
|
||||
}}
|
||||
>
|
||||
{renderForm()}
|
||||
</ProForm>
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
|
||||
if (mode === 'drawer') {
|
||||
return (
|
||||
<DrawerForm<any>
|
||||
title={intl.formatMessage({
|
||||
id: intlPrefix + '.modal.create.title',
|
||||
})}
|
||||
{...formLayout(isMobile)}
|
||||
width={isMobile ? '100%' : '85%'}
|
||||
drawerProps={{
|
||||
destroyOnHidden: true,
|
||||
}}
|
||||
trigger={
|
||||
<ButtonAccess
|
||||
key={'createPaymentTask'}
|
||||
permission={'operation-paymentTask-create'}
|
||||
type={'primary'}
|
||||
size={'middle'}
|
||||
icon={<PlusOutlined />}
|
||||
>
|
||||
{intl.formatMessage({
|
||||
id: intlPrefix + '.modal.create.button',
|
||||
})}
|
||||
</ButtonAccess>
|
||||
}
|
||||
submitter={{
|
||||
render: () => (
|
||||
<Space>
|
||||
{current === 1 && (
|
||||
<Button onClick={() => setCurrent(0)}>上一步</Button>
|
||||
)}
|
||||
{current === 2 && (
|
||||
<Button onClick={() => setCurrent(1)}>上一步</Button>
|
||||
)}
|
||||
{current === 0 && (
|
||||
<Button
|
||||
type="primary"
|
||||
disabled={!selectedDealer}
|
||||
onClick={() => setCurrent(1)}
|
||||
>
|
||||
下一步:选择发货车次
|
||||
</Button>
|
||||
)}
|
||||
{current === 1 && (
|
||||
<Button
|
||||
type="primary"
|
||||
disabled={selectedShipOrderList.length === 0}
|
||||
onClick={() => setCurrent(2)}
|
||||
>
|
||||
下一步:核对并录入调整项
|
||||
</Button>
|
||||
)}
|
||||
{current === 2 && (
|
||||
<Button
|
||||
type="primary"
|
||||
loading={submitLoading}
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
提交对账单
|
||||
</Button>
|
||||
)}
|
||||
</Space>
|
||||
),
|
||||
}}
|
||||
onFinish={handleSubmit}
|
||||
>
|
||||
{renderForm()}
|
||||
</DrawerForm>
|
||||
);
|
||||
}
|
||||
}}
|
||||
</RouteContext.Consumer>
|
||||
|
||||
{/* 选择经销商模态框 */}
|
||||
<DealerModal
|
||||
open={dealerModalOpen}
|
||||
title="选择经销商"
|
||||
type="radio"
|
||||
selectedList={selectedDealer ? [selectedDealer] : []}
|
||||
onFinish={(dealerVOList) => {
|
||||
setSelectedDealer(dealerVOList[0]);
|
||||
// 切换经销商时清空已选车次和调整项
|
||||
setSelectedShipOrderList([]);
|
||||
setAdjustmentsMap({});
|
||||
setDealerModalOpen(false);
|
||||
}}
|
||||
onCancel={() => setDealerModalOpen(false)}
|
||||
tips="请选择对账的经销商"
|
||||
num={1}
|
||||
/>
|
||||
{/* 选择发货单模态框 */}
|
||||
<OrderShipModal
|
||||
open={orderShipModalOpen}
|
||||
title="选择需要对账的发货单"
|
||||
type="checkbox"
|
||||
selectedList={selectedShipOrderList}
|
||||
onFinish={(orderShipList) => {
|
||||
// 过滤掉已经选择的发货单
|
||||
const newOrders = orderShipList.filter(
|
||||
(item) =>
|
||||
!selectedShipOrderList.some(
|
||||
(selected) => selected.orderShipId === item.orderShipId,
|
||||
),
|
||||
);
|
||||
setSelectedShipOrderList([...selectedShipOrderList, ...newOrders]);
|
||||
setOrderShipModalOpen(false);
|
||||
}}
|
||||
onCancel={() => setOrderShipModalOpen(false)}
|
||||
params={{
|
||||
dealerId: selectedDealer?.dealerId,
|
||||
}}
|
||||
tips="请选择该经销商未对账的发货单"
|
||||
num={999}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@ -0,0 +1,293 @@
|
||||
import {
|
||||
BizContainer,
|
||||
BizValueType,
|
||||
ModeType,
|
||||
ReconciliationRecordCreate,
|
||||
} from '@/components';
|
||||
import { business } from '@/services';
|
||||
import { formatCurrency } from '@/utils/format';
|
||||
import { useIntl } from '@@/exports';
|
||||
import { ActionType, ProColumns } from '@ant-design/pro-components';
|
||||
import { ProDescriptionsItemProps } from '@ant-design/pro-descriptions';
|
||||
import React, { useRef, useState } from 'react';
|
||||
|
||||
interface IReconciliationRecordListProps {
|
||||
ghost?: boolean;
|
||||
reconciliationId?: BusinessAPI.ReconciliationVO['reconciliationId'];
|
||||
search?: boolean;
|
||||
onValueChange?: () => void;
|
||||
mode?: ModeType;
|
||||
trigger?: () => React.ReactNode;
|
||||
}
|
||||
|
||||
export default function ReconciliationRecordList(
|
||||
props: IReconciliationRecordListProps,
|
||||
) {
|
||||
const {
|
||||
ghost = false,
|
||||
reconciliationId,
|
||||
search = true,
|
||||
mode = 'page',
|
||||
trigger,
|
||||
onValueChange,
|
||||
} = props;
|
||||
const intl = useIntl();
|
||||
const intlPrefix = 'reconciliationRecord';
|
||||
|
||||
const [activeKey, setActiveKey] = useState<string>('PENDING');
|
||||
|
||||
// 对账状态映射
|
||||
const stateMap: Record<string, { label: string; color: string }> = {
|
||||
PENDING: {
|
||||
label: intl.formatMessage({
|
||||
id: intlPrefix + '.state.pending',
|
||||
}),
|
||||
color: 'default',
|
||||
},
|
||||
RECONCILED: {
|
||||
label: intl.formatMessage({
|
||||
id: intlPrefix + '.state.reconciled',
|
||||
}),
|
||||
color: 'processing',
|
||||
},
|
||||
PARTIAL_INVOICE: {
|
||||
label: intl.formatMessage({
|
||||
id: intlPrefix + '.state.partialInvoice',
|
||||
}),
|
||||
color: 'warning',
|
||||
},
|
||||
INVOICED: {
|
||||
label: intl.formatMessage({
|
||||
id: intlPrefix + '.state.invoiced',
|
||||
}),
|
||||
color: 'success',
|
||||
},
|
||||
PARTIAL_PAYMENT: {
|
||||
label: intl.formatMessage({
|
||||
id: intlPrefix + '.state.partialPayment',
|
||||
}),
|
||||
color: 'warning',
|
||||
},
|
||||
PAID: {
|
||||
label: intl.formatMessage({
|
||||
id: intlPrefix + '.state.paid',
|
||||
}),
|
||||
color: 'success',
|
||||
},
|
||||
};
|
||||
|
||||
const columns: ProColumns<BusinessAPI.ReconciliationVO, BizValueType>[] = [
|
||||
{
|
||||
title: intl.formatMessage({
|
||||
id: intlPrefix + '.column.reconciliationSn',
|
||||
}),
|
||||
dataIndex: 'reconciliationSn',
|
||||
key: 'reconciliationSn',
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({
|
||||
id: intlPrefix + '.column.dealer',
|
||||
}),
|
||||
dataIndex: 'dealerVO',
|
||||
key: 'dealerId',
|
||||
valueType: 'dealer',
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({
|
||||
id: intlPrefix + '.column.company',
|
||||
}),
|
||||
dataIndex: 'companyVO',
|
||||
key: 'companyId',
|
||||
valueType: 'company',
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.originalAmount' }),
|
||||
dataIndex: 'originalAmount',
|
||||
key: 'originalAmount',
|
||||
valueType: 'money',
|
||||
search: false,
|
||||
render: (_, record) => (
|
||||
<span className="text-gray-600">
|
||||
¥{formatCurrency(record.originalAmount)}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.roundingAmount' }),
|
||||
dataIndex: 'roundingAmount',
|
||||
key: 'roundingAmount',
|
||||
valueType: 'money',
|
||||
search: false,
|
||||
render: (_, record) => (
|
||||
<span
|
||||
className={record.roundingAmount ? 'text-blue-600' : 'text-gray-400'}
|
||||
>
|
||||
{record.roundingAmount
|
||||
? `¥${formatCurrency(record.roundingAmount)}`
|
||||
: '-'}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({
|
||||
id: intlPrefix + '.column.reconciliationAmount',
|
||||
}),
|
||||
dataIndex: 'reconciliationAmount',
|
||||
key: 'reconciliationAmount',
|
||||
valueType: 'money',
|
||||
search: false,
|
||||
render: (_, record) => (
|
||||
<span className="text-green-600 font-medium">
|
||||
¥{formatCurrency(record.reconciliationAmount)}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: intl.formatMessage({ id: intlPrefix + '.column.state' }),
|
||||
dataIndex: 'state',
|
||||
key: 'state',
|
||||
valueType: 'select',
|
||||
valueEnum: Object.entries(stateMap).reduce(
|
||||
(acc, [key, value]) => ({
|
||||
...acc,
|
||||
[key]: { text: value.label, status: value.color as any },
|
||||
}),
|
||||
{},
|
||||
),
|
||||
search: false,
|
||||
render: (_, record) => {
|
||||
const stateInfo = stateMap[record.state as string];
|
||||
return stateInfo ? (
|
||||
<span className={`text-${stateInfo.color}-600`}>
|
||||
{stateInfo.label}
|
||||
</span>
|
||||
) : (
|
||||
<span>{record.state}</span>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const detailColumns: ProDescriptionsItemProps<
|
||||
BusinessAPI.ReconciliationVO,
|
||||
BizValueType
|
||||
>[] = columns as ProDescriptionsItemProps<
|
||||
BusinessAPI.ReconciliationVO,
|
||||
BizValueType
|
||||
>[];
|
||||
|
||||
const actionRef = useRef<ActionType>();
|
||||
|
||||
return (
|
||||
<BizContainer<
|
||||
typeof business.reconciliation,
|
||||
BusinessAPI.ReconciliationVO,
|
||||
BusinessAPI.ReconciliationPageQry
|
||||
>
|
||||
rowKey={'reconciliationId'}
|
||||
permission={'operation-reconciliation-record'}
|
||||
func={business.reconciliation}
|
||||
method={'reconciliation'}
|
||||
methodUpper={'Reconciliation'}
|
||||
intlPrefix={intlPrefix}
|
||||
modeType={mode}
|
||||
onValueChange={onValueChange}
|
||||
container={{
|
||||
ghost,
|
||||
}}
|
||||
remark={{
|
||||
mode: 'editor',
|
||||
}}
|
||||
status={false}
|
||||
page={{
|
||||
fieldProps: {
|
||||
actionRef: actionRef,
|
||||
bordered: true,
|
||||
ghost,
|
||||
//@ts-ignore
|
||||
search,
|
||||
params: {
|
||||
...(reconciliationId && { reconciliationId }),
|
||||
...(activeKey !== 'ALL' && {
|
||||
state: activeKey as BusinessAPI.ReconciliationVO['state'],
|
||||
}),
|
||||
},
|
||||
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: 'RECONCILED',
|
||||
label: intl.formatMessage({
|
||||
id: intlPrefix + '.tab.reconciled',
|
||||
}),
|
||||
},
|
||||
{
|
||||
key: 'PARTIAL_INVOICE',
|
||||
label: intl.formatMessage({
|
||||
id: intlPrefix + '.tab.partialInvoice',
|
||||
}),
|
||||
},
|
||||
{
|
||||
key: 'INVOICED',
|
||||
label: intl.formatMessage({
|
||||
id: intlPrefix + '.tab.invoiced',
|
||||
}),
|
||||
},
|
||||
{
|
||||
key: 'PARTIAL_PAYMENT',
|
||||
label: intl.formatMessage({
|
||||
id: intlPrefix + '.tab.partialPayment',
|
||||
}),
|
||||
},
|
||||
{
|
||||
key: 'PAID',
|
||||
label: intl.formatMessage({
|
||||
id: intlPrefix + '.tab.paid',
|
||||
}),
|
||||
},
|
||||
],
|
||||
onChange: (key) => {
|
||||
setActiveKey(key as string);
|
||||
},
|
||||
},
|
||||
actions: [
|
||||
<ReconciliationRecordCreate
|
||||
mode={'drawer'}
|
||||
key={'create'}
|
||||
onFinish={() => {
|
||||
actionRef.current?.reload();
|
||||
onValueChange?.();
|
||||
}}
|
||||
/>,
|
||||
],
|
||||
},
|
||||
},
|
||||
columns,
|
||||
options: () => [],
|
||||
}}
|
||||
create={false}
|
||||
update={false}
|
||||
destroy={false}
|
||||
detail={{
|
||||
rowId: reconciliationId,
|
||||
formType: 'drawer',
|
||||
columns: detailColumns,
|
||||
trigger,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
import { ReconciliationSummaryProps } from '@/components';
|
||||
import { formatCurrency } from '@/utils/format';
|
||||
import {
|
||||
ProForm,
|
||||
ProFormDependency,
|
||||
ProFormMoney,
|
||||
ProFormSwitch,
|
||||
@ -25,8 +24,7 @@ const ADJUSTMENT_TYPE_LABELS: Record<string, string> = {
|
||||
export default function ReconciliationSummary({
|
||||
shipOrders,
|
||||
adjustmentsMap,
|
||||
roundOff,
|
||||
onFinish,
|
||||
roundOffAmount = 0,
|
||||
}: ReconciliationSummaryProps) {
|
||||
const intl = useIntl();
|
||||
const intlPrefix = 'reconciliation';
|
||||
@ -60,7 +58,7 @@ export default function ReconciliationSummary({
|
||||
|
||||
// 计算实际应收总额(包含抹零金额)
|
||||
const actualTotalAmount =
|
||||
originalTotalAmount - adjustmentTotal + (roundOff?.roundOffAmount || 0);
|
||||
originalTotalAmount - adjustmentTotal - roundOffAmount;
|
||||
|
||||
return (
|
||||
<div
|
||||
@ -108,20 +106,6 @@ export default function ReconciliationSummary({
|
||||
marginBottom: '10px',
|
||||
backgroundColor: '#f8f9fa',
|
||||
}}
|
||||
>
|
||||
<ProForm
|
||||
submitter={false}
|
||||
request={async () => {
|
||||
return Promise.resolve({
|
||||
roundOffEnabled: roundOff?.roundOffEnabled || false,
|
||||
roundOffAmount: roundOff?.roundOffAmount || 0,
|
||||
roundOffRemark: roundOff?.roundOffRemark || '',
|
||||
});
|
||||
}}
|
||||
onValuesChange={(_, formData) => {
|
||||
onFinish?.(formData);
|
||||
}}
|
||||
layout="horizontal"
|
||||
>
|
||||
<ProFormSwitch
|
||||
label={intl.formatMessage({
|
||||
@ -165,7 +149,6 @@ export default function ReconciliationSummary({
|
||||
)
|
||||
}
|
||||
</ProFormDependency>
|
||||
</ProForm>
|
||||
</div>
|
||||
|
||||
{/*/!* 调整总额 *!/*/}
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
export { default as ReconciliationRecordCreate } from './ReconciliationRecordCreate';
|
||||
export { default as ReconciliationRecordList } from './ReconciliationRecordList';
|
||||
export { default as ReconciliationShipCard } from './ReconciliationShipCard';
|
||||
export { default as ReconciliationSummary } from './ReconciliationSummary';
|
||||
export type {
|
||||
|
||||
@ -24,24 +24,12 @@ export interface ReconciliationShipCardProps {
|
||||
onExpandChange?: (expanded: boolean) => void;
|
||||
}
|
||||
|
||||
/** 抹零数据 */
|
||||
export interface RoundOff {
|
||||
/** 是否抹零 */
|
||||
roundOffEnabled?: boolean;
|
||||
/** 抹零金额 */
|
||||
roundOffAmount?: number;
|
||||
/** 抹零备注 */
|
||||
roundOffRemark?: string;
|
||||
}
|
||||
|
||||
/** 对账汇总Props */
|
||||
export interface ReconciliationSummaryProps {
|
||||
/** 发货单列表 */
|
||||
shipOrders: BusinessAPI.OrderShipVO[];
|
||||
/** 调整项数据 Map<发货单ID, 调整项数组> */
|
||||
adjustmentsMap: Record<string, ReconciliationAdjustment[]>;
|
||||
/** 抹零数据 */
|
||||
roundOff?: RoundOff;
|
||||
/** 抹零注变化回调 */
|
||||
onFinish?: (roundOff: RoundOff) => void;
|
||||
/** 抹零金额 */
|
||||
roundOffAmount: number;
|
||||
}
|
||||
|
||||
@ -3083,4 +3083,61 @@ export default {
|
||||
roundOffRemarkPlaceholder: '请输入抹零备注信息',
|
||||
},
|
||||
},
|
||||
reconciliationRecord: {
|
||||
column: {
|
||||
reconciliationSn: '对账编码',
|
||||
dealer: '经销商',
|
||||
company: '入账公司',
|
||||
originalAmount: '原对账金额',
|
||||
roundingAmount: '抹零金额',
|
||||
reconciliationAmount: '对账金额',
|
||||
state: '状态',
|
||||
createdAt: '创建时间',
|
||||
remark: '备注',
|
||||
option: '操作',
|
||||
},
|
||||
state: {
|
||||
pending: '待对账',
|
||||
reconciled: '已对账',
|
||||
partialInvoice: '部分开票',
|
||||
invoiced: '已开票',
|
||||
partialPayment: '部分回款',
|
||||
paid: '已回款',
|
||||
},
|
||||
tab: {
|
||||
all: '全部',
|
||||
pending: '待对账',
|
||||
reconciled: '已对账',
|
||||
partialInvoice: '部分开票',
|
||||
invoiced: '已开票',
|
||||
partialPayment: '部分回款',
|
||||
paid: '已回款',
|
||||
},
|
||||
modal: {
|
||||
create: {
|
||||
title: '新增对账单',
|
||||
button: '新增对账单',
|
||||
success: '新增对账单成功',
|
||||
},
|
||||
view: {
|
||||
title: '对账详情',
|
||||
button: '详情',
|
||||
},
|
||||
update: {
|
||||
title: '更新对账单',
|
||||
button: '编辑',
|
||||
success: '更新对账单成功',
|
||||
},
|
||||
delete: {
|
||||
success: '删除对账单成功',
|
||||
button: '删除',
|
||||
confirm: {
|
||||
title: '确认删除',
|
||||
content: '您确定要删除该对账单吗?',
|
||||
okText: '确定',
|
||||
cancelText: '取消',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@ -1,465 +1,13 @@
|
||||
import {
|
||||
OrderShipSelectList,
|
||||
PageContainer,
|
||||
ReconciliationAdjustment,
|
||||
ReconciliationSummary,
|
||||
ReconciliationSummaryProps,
|
||||
} from '@/components';
|
||||
import DealerModal from '@/components/Dealer/DealerModal';
|
||||
import OrderShipModal from '@/components/Order/OrderShipModal';
|
||||
import { formatCurrency } from '@/utils/format';
|
||||
import { ProCard, ProFormTextArea } from '@ant-design/pro-components';
|
||||
import { Button, Col, Row, Space, Steps, Table, Tag } from 'antd';
|
||||
import { useState } from 'react';
|
||||
import { ReconciliationRecordCreate } from '@/components';
|
||||
import { useNavigate } from 'umi';
|
||||
|
||||
export default function Page() {
|
||||
const [current, setCurrent] = useState(0);
|
||||
|
||||
const [selectedDealer, setSelectedDealer] =
|
||||
useState<BusinessAPI.DealerVO | null>(null);
|
||||
const [dealerModalOpen, setDealerModalOpen] = useState(false);
|
||||
const [selectedShipOrderList, setSelectedShipOrderList] = useState<
|
||||
BusinessAPI.OrderShipVO[]
|
||||
>([]);
|
||||
const [orderShipModalOpen, setOrderShipModalOpen] = useState(false);
|
||||
|
||||
// 调整项状态 Map<发货单ID, 调整项数组>
|
||||
const [adjustmentsMap, setAdjustmentsMap] = useState<
|
||||
Record<string, ReconciliationAdjustment[]>
|
||||
>({});
|
||||
|
||||
// 抹零状态
|
||||
const [roundOffEnabled, setRoundOffEnabled] = useState(false);
|
||||
const [roundOffAmount, setRoundOffAmount] = useState<number | undefined>(
|
||||
undefined,
|
||||
);
|
||||
const [roundOffRemark, setRoundOffRemark] = useState('');
|
||||
|
||||
// // 添加调整项
|
||||
// const handleAddAdjustment = useCallback((shipOrderId: string) => {
|
||||
// const newAdjustment: ReconciliationAdjustment = {
|
||||
// id: `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`,
|
||||
// type: 'LOSS',
|
||||
// quantity: 0,
|
||||
// unitPrice: 0,
|
||||
// amount: 0,
|
||||
// remark: '',
|
||||
// };
|
||||
// setAdjustmentsMap((prev) => ({
|
||||
// ...prev,
|
||||
// [shipOrderId]: [...(prev[shipOrderId] || []), newAdjustment],
|
||||
// }));
|
||||
// }, []);
|
||||
//
|
||||
// // 删除调整项
|
||||
// const handleRemoveAdjustment = useCallback(
|
||||
// (shipOrderId: string, adjustmentId: string) => {
|
||||
// setAdjustmentsMap((prev) => ({
|
||||
// ...prev,
|
||||
// [shipOrderId]: (prev[shipOrderId] || []).filter(
|
||||
// (adj) => adj.id !== adjustmentId,
|
||||
// ),
|
||||
// }));
|
||||
// },
|
||||
// [],
|
||||
// );
|
||||
|
||||
let receivableAmount =
|
||||
selectedShipOrderList?.reduce(
|
||||
(sum, item) => sum + (item.receivableAmount || 0),
|
||||
0,
|
||||
) || 0;
|
||||
let adjustedAmount =
|
||||
selectedShipOrderList?.reduce(
|
||||
(sum, item) => sum + (item.adjustedAmount || 0),
|
||||
0,
|
||||
) || 0;
|
||||
// 计算总金额
|
||||
|
||||
const orderCount = selectedShipOrderList.length;
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<PageContainer
|
||||
permission={''}
|
||||
fieldProps={{
|
||||
content: (
|
||||
<Steps
|
||||
current={current}
|
||||
style={{ padding: '16px 0' }}
|
||||
items={[
|
||||
{
|
||||
title: '选择经销商',
|
||||
},
|
||||
{
|
||||
title: '选择发货车次',
|
||||
},
|
||||
{
|
||||
title: '核对并录入调整项',
|
||||
},
|
||||
]}
|
||||
<ReconciliationRecordCreate
|
||||
mode={'page'}
|
||||
onFinish={() => navigate('/operation/financial/reconciliation/records')}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
>
|
||||
{/* 对账单表单 */}
|
||||
<ProCard
|
||||
title={'创建对账单'}
|
||||
headerBordered
|
||||
subTitle={
|
||||
<Space>
|
||||
<Tag color="blue">步骤 {current + 1}</Tag>
|
||||
{current === 0 && '选择经销商'}
|
||||
{current === 1 && '选择发货车次'}
|
||||
{current === 2 && '核对并录入调整项'}
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
{/* 步骤1:选择经销商 */}
|
||||
{(current === 0 || current === 1) && (
|
||||
<>
|
||||
{/* 选择经销商 */}
|
||||
<ProCard
|
||||
title={'经销商信息'}
|
||||
style={{ marginTop: 16 }}
|
||||
bordered
|
||||
extra={
|
||||
current === 0 && (
|
||||
<Button
|
||||
type="primary"
|
||||
size="middle"
|
||||
onClick={() => setDealerModalOpen(true)}
|
||||
>
|
||||
选择经销商
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
>
|
||||
{selectedDealer ? (
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={8}>
|
||||
<div>
|
||||
<div style={{ color: '#999', marginBottom: 4 }}>
|
||||
经销商简称
|
||||
</div>
|
||||
<div style={{ fontWeight: 'bold' }}>
|
||||
{selectedDealer.shortName || '-'}
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<div>
|
||||
<div style={{ color: '#999', marginBottom: 4 }}>
|
||||
经销商类型
|
||||
</div>
|
||||
<div style={{ fontWeight: 'bold' }}>
|
||||
{selectedDealer.dealerType === 'MARKET'
|
||||
? '市场'
|
||||
: '超市'}
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<div>
|
||||
<div style={{ color: '#999', marginBottom: 4 }}>
|
||||
应收金额
|
||||
</div>
|
||||
<div style={{ fontWeight: 'bold' }}>
|
||||
¥{selectedDealer.receivable || '-'}
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
) : (
|
||||
<div
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
padding: '40px 0',
|
||||
color: '#999',
|
||||
}}
|
||||
>
|
||||
暂无选择,请点击「选择经销商」按钮选择
|
||||
</div>
|
||||
)}
|
||||
</ProCard>
|
||||
|
||||
{/* 下一步按钮 */}
|
||||
{current === 0 && (
|
||||
<div style={{ marginTop: 16, textAlign: 'right' }}>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
setCurrent(1);
|
||||
}}
|
||||
disabled={!selectedDealer}
|
||||
>
|
||||
下一步:选择发货车次
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* 步骤2:选择发货车次 */}
|
||||
{current === 1 && selectedDealer && (
|
||||
<>
|
||||
{/* 选择车次 */}
|
||||
<ProCard
|
||||
title={'选择车次'}
|
||||
style={{ marginTop: 16 }}
|
||||
bordered
|
||||
extra={
|
||||
<Button
|
||||
type="primary"
|
||||
size="middle"
|
||||
onClick={() => setOrderShipModalOpen(true)}
|
||||
>
|
||||
添加车次
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
{selectedShipOrderList.length > 0 ? (
|
||||
<OrderShipSelectList
|
||||
dataSource={selectedShipOrderList}
|
||||
columns={[
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
fixed: 'right',
|
||||
width: 80,
|
||||
render: (_: any, record: BusinessAPI.OrderShipVO) => (
|
||||
<Button
|
||||
type="link"
|
||||
danger
|
||||
onClick={() => {
|
||||
setSelectedShipOrderList(
|
||||
selectedShipOrderList.filter(
|
||||
(item) =>
|
||||
item.orderShipId !== record.orderShipId,
|
||||
),
|
||||
);
|
||||
// 同时清除该车次的调整项
|
||||
setAdjustmentsMap((prev) => {
|
||||
const newMap = { ...prev };
|
||||
delete newMap[record.orderShipId];
|
||||
return newMap;
|
||||
});
|
||||
}}
|
||||
>
|
||||
移除
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
]}
|
||||
pagination={false}
|
||||
size="small"
|
||||
summary={(pageData) => {
|
||||
let receivableAmount =
|
||||
pageData?.reduce(
|
||||
(sum, item) => sum + (item.receivableAmount || 0),
|
||||
0,
|
||||
) || 0;
|
||||
let adjustedAmount =
|
||||
pageData?.reduce(
|
||||
(sum, item) => sum + (item.adjustedAmount || 0),
|
||||
0,
|
||||
) || 0;
|
||||
return (
|
||||
<Table.Summary fixed>
|
||||
<Table.Summary.Row>
|
||||
<Table.Summary.Cell index={0} colSpan={9}>
|
||||
<strong>合计</strong>
|
||||
</Table.Summary.Cell>
|
||||
<Table.Summary.Cell index={1}>
|
||||
<strong className="text-blue-600 font-medium">
|
||||
¥{formatCurrency(receivableAmount)}
|
||||
</strong>
|
||||
</Table.Summary.Cell>
|
||||
<Table.Summary.Cell index={1}>
|
||||
<strong
|
||||
className={
|
||||
adjustedAmount >= 0
|
||||
? 'text-green-600'
|
||||
: 'text-red-600'
|
||||
}
|
||||
>
|
||||
¥{formatCurrency(adjustedAmount)}
|
||||
</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>
|
||||
|
||||
{/* 任务摘要 */}
|
||||
{selectedShipOrderList.length > 0 && (
|
||||
<ProCard title={'对账摘要'} style={{ marginTop: 16 }} bordered>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={6}>
|
||||
<div>
|
||||
<div style={{ color: '#999', marginBottom: 4 }}>
|
||||
对账经销商
|
||||
</div>
|
||||
<div style={{ fontWeight: 'bold' }}>
|
||||
{selectedDealer?.fullName || selectedDealer?.shortName}
|
||||
</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(receivableAmount - adjustedAmount)}
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<div>
|
||||
<div style={{ color: '#999', marginBottom: 4 }}>
|
||||
对账状态
|
||||
</div>
|
||||
<div>
|
||||
<Tag color="orange">待对账</Tag>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</ProCard>
|
||||
)}
|
||||
|
||||
{/* 上一步和下一步按钮 */}
|
||||
<div style={{ marginTop: 16, textAlign: 'right' }}>
|
||||
<Space>
|
||||
<Button onClick={() => setCurrent(0)}>上一步</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
disabled={selectedShipOrderList.length === 0}
|
||||
onClick={() => {
|
||||
setCurrent(2);
|
||||
}}
|
||||
>
|
||||
下一步:核对并录入调整项
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* 步骤3:核对并录入调整项 */}
|
||||
{current === 2 && (
|
||||
<>
|
||||
{/* 对账车次清单 */}
|
||||
{/*<ProCard title={'对账车次清单'} style={{ marginTop: 16 }} bordered>*/}
|
||||
{/* {selectedShipOrderList.map((shipOrder) => (*/}
|
||||
{/* <ReconciliationShipCard*/}
|
||||
{/* key={shipOrder.orderShipId}*/}
|
||||
{/* shipOrder={shipOrder}*/}
|
||||
{/* adjustments={adjustmentsMap[shipOrder.orderShipId] || []}*/}
|
||||
{/* onAddAdjustment={handleAddAdjustment}*/}
|
||||
{/* onRemoveAdjustment={handleRemoveAdjustment}*/}
|
||||
{/* />*/}
|
||||
{/* ))}*/}
|
||||
{/*</ProCard>*/}
|
||||
|
||||
{/* 对账汇总 */}
|
||||
<ProCard title={'对账汇总'} style={{ marginTop: 16 }} bordered>
|
||||
<ReconciliationSummary
|
||||
shipOrders={selectedShipOrderList}
|
||||
adjustmentsMap={adjustmentsMap}
|
||||
roundOff={{
|
||||
roundOffEnabled: roundOffEnabled,
|
||||
roundOffAmount: roundOffAmount,
|
||||
roundOffRemark: roundOffRemark,
|
||||
}}
|
||||
onFinish={(
|
||||
roundOff: ReconciliationSummaryProps['roundOff'],
|
||||
) => {
|
||||
setRoundOffEnabled(roundOff?.roundOffEnabled || false);
|
||||
setRoundOffAmount(roundOff?.roundOffAmount);
|
||||
setRoundOffRemark(roundOff?.roundOffRemark || '');
|
||||
}}
|
||||
/>
|
||||
</ProCard>
|
||||
|
||||
{/* 备注信息 */}
|
||||
<ProCard title={'备注信息'} style={{ marginTop: 16 }} bordered>
|
||||
<ProFormTextArea name="remark" placeholder="请输入备注信息" />
|
||||
</ProCard>
|
||||
|
||||
{/* 提交按钮 */}
|
||||
<Row justify="end" style={{ marginTop: 16 }}>
|
||||
<Space>
|
||||
<Button onClick={() => setCurrent(1)}>上一步</Button>
|
||||
<Button type="primary">提交对账单</Button>
|
||||
</Space>
|
||||
</Row>
|
||||
</>
|
||||
)}
|
||||
</ProCard>
|
||||
{/* 选择经销商模态框 */}
|
||||
<DealerModal
|
||||
open={dealerModalOpen}
|
||||
title="选择经销商"
|
||||
type="radio"
|
||||
selectedList={selectedDealer ? [selectedDealer] : []}
|
||||
onFinish={(dealerVOList) => {
|
||||
setSelectedDealer(dealerVOList[0]);
|
||||
// 切换经销商时清空已选车次和调整项
|
||||
setSelectedShipOrderList([]);
|
||||
setAdjustmentsMap({});
|
||||
setDealerModalOpen(false);
|
||||
}}
|
||||
onCancel={() => setDealerModalOpen(false)}
|
||||
tips="请选择对账的经销商"
|
||||
num={1}
|
||||
/>
|
||||
{/* 选择发货单模态框 */}
|
||||
<OrderShipModal
|
||||
open={orderShipModalOpen}
|
||||
title="选择需要对账的发货单"
|
||||
type="checkbox"
|
||||
selectedList={selectedShipOrderList}
|
||||
onFinish={(orderShipList) => {
|
||||
// 过滤掉已经选择的发货单
|
||||
const newOrders = orderShipList.filter(
|
||||
(item) =>
|
||||
!selectedShipOrderList.some(
|
||||
(selected) => selected.orderShipId === item.orderShipId,
|
||||
),
|
||||
);
|
||||
setSelectedShipOrderList([...selectedShipOrderList, ...newOrders]);
|
||||
setOrderShipModalOpen(false);
|
||||
}}
|
||||
onCancel={() => setOrderShipModalOpen(false)}
|
||||
params={{
|
||||
dealerId: selectedDealer?.dealerId,
|
||||
}}
|
||||
tips="请选择该经销商未对账的发货单"
|
||||
num={999}
|
||||
/>
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { PageContainer } from '@/components';
|
||||
import { ReconciliationRecordList } from '@/components';
|
||||
|
||||
export default function Page() {
|
||||
return <PageContainer permission={''}></PageContainer>;
|
||||
return <ReconciliationRecordList />;
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@ declare namespace AuthAPI {
|
||||
/** 用户ID */
|
||||
userId: string;
|
||||
/** 角色ID */
|
||||
roleIdList: string[];
|
||||
roleIdList: number[];
|
||||
/** 角色信息 */
|
||||
userRoleList?: UserRoleVO[];
|
||||
};
|
||||
@ -195,7 +195,7 @@ declare namespace AuthAPI {
|
||||
|
||||
type RoleMenuTreeQry = {
|
||||
/** 角色权限 */
|
||||
roleId?: string[];
|
||||
roleId?: number[];
|
||||
/** 平台ID */
|
||||
platformId: string;
|
||||
};
|
||||
@ -329,7 +329,7 @@ declare namespace AuthAPI {
|
||||
/** 备注 */
|
||||
remark?: string;
|
||||
/** 客户标签 */
|
||||
labelId?: string[];
|
||||
labelId?: number[];
|
||||
/** 用户ID */
|
||||
userId: string;
|
||||
};
|
||||
|
||||
@ -35,6 +35,7 @@ import * as paymentTask from './paymentTask';
|
||||
import * as permission from './permission';
|
||||
import * as platform from './platform';
|
||||
import * as product from './product';
|
||||
import * as reconciliation from './reconciliation';
|
||||
import * as role from './role';
|
||||
import * as setting from './setting';
|
||||
import * as supplier from './supplier';
|
||||
@ -46,6 +47,7 @@ export default {
|
||||
supplier,
|
||||
supplierInvoice,
|
||||
setting,
|
||||
reconciliation,
|
||||
product,
|
||||
platform,
|
||||
paymentTask,
|
||||
|
||||
132
packages/app-operation/src/services/business/reconciliation.ts
Normal file
132
packages/app-operation/src/services/business/reconciliation.ts
Normal file
@ -0,0 +1,132 @@
|
||||
// @ts-ignore
|
||||
/* eslint-disable */
|
||||
import request from '../request';
|
||||
|
||||
/** 创建对账 POST /operation/createReconciliation */
|
||||
export async function createReconciliation(
|
||||
body: BusinessAPI.ReconciliationCreateCmd,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<BusinessAPI.SingleResponseReconciliationVO>(
|
||||
'/operation/createReconciliation',
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/** 对账删除 DELETE /operation/destroyReconciliation */
|
||||
export async function destroyReconciliation(
|
||||
body: BusinessAPI.ReconciliationDestroyCmd,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<BusinessAPI.Response>('/operation/destroyReconciliation', {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** 对账列表 GET /operation/listReconciliation */
|
||||
export async function listReconciliation(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: BusinessAPI.listReconciliationParams,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<BusinessAPI.MultiResponseReconciliationVO>(
|
||||
'/operation/listReconciliation',
|
||||
{
|
||||
method: 'GET',
|
||||
params: {
|
||||
...params,
|
||||
reconciliationListQry: undefined,
|
||||
...params['reconciliationListQry'],
|
||||
},
|
||||
...(options || {}),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/** 对账列表 GET /operation/pageReconciliation */
|
||||
export async function pageReconciliation(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: BusinessAPI.pageReconciliationParams,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<BusinessAPI.PageResponseReconciliationVO>(
|
||||
'/operation/pageReconciliation',
|
||||
{
|
||||
method: 'GET',
|
||||
params: {
|
||||
...params,
|
||||
reconciliationPageQry: undefined,
|
||||
...params['reconciliationPageQry'],
|
||||
},
|
||||
...(options || {}),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/** 对账详情 GET /operation/showReconciliation */
|
||||
export async function showReconciliation(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: BusinessAPI.showReconciliationParams,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<BusinessAPI.SingleResponseReconciliationVO>(
|
||||
'/operation/showReconciliation',
|
||||
{
|
||||
method: 'GET',
|
||||
params: {
|
||||
...params,
|
||||
reconciliationShowQry: undefined,
|
||||
...params['reconciliationShowQry'],
|
||||
},
|
||||
...(options || {}),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/** 对账更新 PUT /operation/updateReconciliation */
|
||||
export async function updateReconciliation(
|
||||
body: BusinessAPI.ReconciliationUpdateCmd,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<BusinessAPI.SingleResponseReconciliationVO>(
|
||||
'/operation/updateReconciliation',
|
||||
{
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/** 对账更新 PATCH /operation/updateReconciliation */
|
||||
export async function updateReconciliation1(
|
||||
body: BusinessAPI.ReconciliationUpdateCmd,
|
||||
options?: { [key: string]: any },
|
||||
) {
|
||||
return request<BusinessAPI.SingleResponseReconciliationVO>(
|
||||
'/operation/updateReconciliation',
|
||||
{
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: body,
|
||||
...(options || {}),
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -208,7 +208,7 @@ declare namespace BusinessAPI {
|
||||
/** 品牌图片URL */
|
||||
image?: string;
|
||||
/** 纸箱规格ID */
|
||||
specIds?: string[];
|
||||
specIds?: number[];
|
||||
/** 备注 */
|
||||
remark?: string;
|
||||
/** 状态:1_启用;0_禁用 */
|
||||
@ -279,7 +279,7 @@ declare namespace BusinessAPI {
|
||||
/** 品牌图片URL */
|
||||
image?: string;
|
||||
/** 纸箱规格ID */
|
||||
specIds?: string[];
|
||||
specIds?: number[];
|
||||
/** 备注 */
|
||||
remark?: string;
|
||||
/** 状态:1_启用;0_禁用 */
|
||||
@ -296,7 +296,7 @@ declare namespace BusinessAPI {
|
||||
/** 品牌图片URL */
|
||||
image?: string;
|
||||
/** 纸箱规格ID */
|
||||
specIds?: string[];
|
||||
specIds?: number[];
|
||||
/** 备注 */
|
||||
remark?: string;
|
||||
/** 状态:1_启用;0_禁用 */
|
||||
@ -1021,7 +1021,7 @@ declare namespace BusinessAPI {
|
||||
/** 状态:1_启用;0_禁用 */
|
||||
status: boolean;
|
||||
/** 成本项ID */
|
||||
costItemIds?: string[];
|
||||
costItemIds?: number[];
|
||||
};
|
||||
|
||||
type CostDestroyCmd = {
|
||||
@ -1249,7 +1249,7 @@ declare namespace BusinessAPI {
|
||||
/** 状态:1_启用;0_禁用 */
|
||||
status: boolean;
|
||||
/** 成本项ID */
|
||||
costItemIds?: string[];
|
||||
costItemIds?: number[];
|
||||
};
|
||||
|
||||
type CostVO = {
|
||||
@ -1280,7 +1280,7 @@ declare namespace BusinessAPI {
|
||||
/** 状态:1_启用;0_禁用 */
|
||||
status: boolean;
|
||||
/** 项目id集合 */
|
||||
costItemIds?: string[];
|
||||
costItemIds?: number[];
|
||||
/** 创建时间 */
|
||||
createdAt?: string;
|
||||
/** 项目列表 */
|
||||
@ -2099,7 +2099,7 @@ declare namespace BusinessAPI {
|
||||
/** 登录密码 */
|
||||
password: string;
|
||||
/** 角色ID */
|
||||
roleId: string[];
|
||||
roleId: number[];
|
||||
};
|
||||
|
||||
type EmployeeDestroyCmd = {
|
||||
@ -2192,7 +2192,7 @@ declare namespace BusinessAPI {
|
||||
/** 用户ID */
|
||||
userId: string;
|
||||
/** 角色ID */
|
||||
roleIdList: string[];
|
||||
roleIdList: number[];
|
||||
/** 角色信息 */
|
||||
userRoleList?: UserRoleVO[];
|
||||
};
|
||||
@ -2497,6 +2497,10 @@ declare namespace BusinessAPI {
|
||||
productListQry: ProductListQry;
|
||||
};
|
||||
|
||||
type listReconciliationParams = {
|
||||
reconciliationListQry: ReconciliationListQry;
|
||||
};
|
||||
|
||||
type listRoleParams = {
|
||||
roleListQry: RoleListQry;
|
||||
};
|
||||
@ -2629,7 +2633,7 @@ declare namespace BusinessAPI {
|
||||
/** 平台id */
|
||||
platformId: string;
|
||||
/** 角色Id */
|
||||
roleId?: string[];
|
||||
roleId?: number[];
|
||||
/** 是否隐藏 */
|
||||
hideInMenu?: boolean;
|
||||
/** 权限Id */
|
||||
@ -2702,7 +2706,7 @@ declare namespace BusinessAPI {
|
||||
/** 平台id */
|
||||
platformId: string;
|
||||
/** 角色Id */
|
||||
roleId?: string[];
|
||||
roleId?: number[];
|
||||
/** 是否隐藏 */
|
||||
hideInMenu?: boolean;
|
||||
/** 权限Id */
|
||||
@ -2984,6 +2988,15 @@ declare namespace BusinessAPI {
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type MultiResponseReconciliationVO = {
|
||||
success?: boolean;
|
||||
errCode?: string;
|
||||
errMessage?: string;
|
||||
data?: ReconciliationVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type MultiResponseRoleVO = {
|
||||
success?: boolean;
|
||||
errCode?: string;
|
||||
@ -3129,7 +3142,7 @@ declare namespace BusinessAPI {
|
||||
| 'LOGISTICS_TYPE'
|
||||
| 'EXPENSE_TYPE';
|
||||
/** 关联项目id */
|
||||
costItemIds?: string[];
|
||||
costItemIds?: number[];
|
||||
/** 是否选中 */
|
||||
selected: boolean;
|
||||
/** 是否已付款 */
|
||||
@ -3166,7 +3179,7 @@ declare namespace BusinessAPI {
|
||||
| 'LOGISTICS_TYPE'
|
||||
| 'EXPENSE_TYPE';
|
||||
/** 关联项目id */
|
||||
costItemIds?: string[];
|
||||
costItemIds?: number[];
|
||||
/** 是否付款 */
|
||||
isPaid?: boolean;
|
||||
};
|
||||
@ -3299,7 +3312,7 @@ declare namespace BusinessAPI {
|
||||
| 'LOGISTICS_TYPE'
|
||||
| 'EXPENSE_TYPE';
|
||||
/** 关联项目id */
|
||||
costItemIds?: string[];
|
||||
costItemIds?: number[];
|
||||
/** 创建时间 */
|
||||
createdAt: string;
|
||||
/** 采购订单状态: 0_草稿;1_审核中;2_已完成;3_已关闭; */
|
||||
@ -3808,6 +3821,8 @@ declare namespace BusinessAPI {
|
||||
supplierName?: string;
|
||||
/** 经销商ID */
|
||||
dealerId?: string;
|
||||
/** 发货时间 */
|
||||
shippingDate?: string;
|
||||
offset?: number;
|
||||
};
|
||||
|
||||
@ -4037,7 +4052,7 @@ declare namespace BusinessAPI {
|
||||
/** 产品名称 */
|
||||
productName?: string;
|
||||
/** 关联费用id */
|
||||
costIds?: string[];
|
||||
costIds?: number[];
|
||||
/** 成本模板 */
|
||||
costTemplate?: string;
|
||||
/** 是否已付定金 */
|
||||
@ -4466,6 +4481,10 @@ declare namespace BusinessAPI {
|
||||
productPageQry: ProductPageQry;
|
||||
};
|
||||
|
||||
type pageReconciliationParams = {
|
||||
reconciliationPageQry: ReconciliationPageQry;
|
||||
};
|
||||
|
||||
type PageResponseAgreementVO = {
|
||||
success?: boolean;
|
||||
errCode?: string;
|
||||
@ -4475,8 +4494,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: AgreementVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseAuditVO = {
|
||||
@ -4488,8 +4507,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: AuditVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseBoxBrandVO = {
|
||||
@ -4501,8 +4520,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: BoxBrandVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseBoxProductVO = {
|
||||
@ -4514,8 +4533,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: BoxProductVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseBoxSpecVO = {
|
||||
@ -4527,8 +4546,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: BoxSpecVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseChannelVO = {
|
||||
@ -4540,8 +4559,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: ChannelVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseCompanyPaymentAccountVO = {
|
||||
@ -4553,8 +4572,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: CompanyPaymentAccountVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseCompanyVO = {
|
||||
@ -4566,8 +4585,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: CompanyVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseCostItemVO = {
|
||||
@ -4579,8 +4598,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: CostItemVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseCostVO = {
|
||||
@ -4592,8 +4611,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: CostVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseDealerAccountRecordVO = {
|
||||
@ -4605,8 +4624,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: DealerAccountRecordVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseDealerPaymentAccountVO = {
|
||||
@ -4618,8 +4637,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: DealerPaymentAccountVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseDealerRebateCustomerVO = {
|
||||
@ -4631,8 +4650,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: DealerRebateCustomerVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseDealerVO = {
|
||||
@ -4644,8 +4663,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: DealerVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseDealerWarehouseVO = {
|
||||
@ -4657,8 +4676,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: DealerWarehouseVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseDictionaryVO = {
|
||||
@ -4670,8 +4689,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: DictionaryVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseEmployeeVO = {
|
||||
@ -4683,8 +4702,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: EmployeeVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseGiftBoxVO = {
|
||||
@ -4696,8 +4715,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: GiftBoxVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseMaterialVO = {
|
||||
@ -4709,8 +4728,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: MaterialVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseOrderCostVO = {
|
||||
@ -4722,8 +4741,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: OrderCostVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseOrderRebateVO = {
|
||||
@ -4735,8 +4754,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: OrderRebateVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseOrderShipVO = {
|
||||
@ -4748,8 +4767,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: OrderShipVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseOrderSupplierVO = {
|
||||
@ -4761,8 +4780,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: OrderSupplierVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseOrderVO = {
|
||||
@ -4774,8 +4793,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: OrderVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponsePaymentRecordVO = {
|
||||
@ -4787,8 +4806,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: PaymentRecordVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponsePaymentTaskVO = {
|
||||
@ -4800,8 +4819,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: PaymentTaskVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponsePermissionVO = {
|
||||
@ -4813,8 +4832,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: PermissionVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponsePlatformVO = {
|
||||
@ -4826,8 +4845,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: PlatformVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseProductVO = {
|
||||
@ -4839,8 +4858,21 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: ProductVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseReconciliationVO = {
|
||||
success?: boolean;
|
||||
errCode?: string;
|
||||
errMessage?: string;
|
||||
totalCount?: number;
|
||||
pageSize?: number;
|
||||
pageIndex?: number;
|
||||
data?: ReconciliationVO[];
|
||||
empty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseRoleVO = {
|
||||
@ -4852,8 +4884,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: RoleVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseSupplierInvoiceVO = {
|
||||
@ -4865,8 +4897,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: SupplierInvoiceVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseSupplierVO = {
|
||||
@ -4878,8 +4910,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: SupplierVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type PageResponseUserVO = {
|
||||
@ -4891,8 +4923,8 @@ declare namespace BusinessAPI {
|
||||
pageIndex?: number;
|
||||
data?: UserVO[];
|
||||
empty?: boolean;
|
||||
notEmpty?: boolean;
|
||||
totalPages?: number;
|
||||
notEmpty?: boolean;
|
||||
};
|
||||
|
||||
type pageRoleParams = {
|
||||
@ -5368,7 +5400,7 @@ declare namespace BusinessAPI {
|
||||
/** 产品名称 */
|
||||
name: string;
|
||||
/** 关联成本费用id */
|
||||
costIds?: string[];
|
||||
costIds?: number[];
|
||||
/** 成本模板 */
|
||||
costTemplate?: string;
|
||||
/** 备注 */
|
||||
@ -5435,7 +5467,7 @@ declare namespace BusinessAPI {
|
||||
/** 产品名称 */
|
||||
name: string;
|
||||
/** 关联成本费用id */
|
||||
costIds?: string[];
|
||||
costIds?: number[];
|
||||
/** 成本模板 */
|
||||
costTemplate?: string;
|
||||
/** 备注 */
|
||||
@ -5460,7 +5492,7 @@ declare namespace BusinessAPI {
|
||||
/** 状态:1_启用;0_禁用 */
|
||||
status: boolean;
|
||||
/** 成本ID集合 */
|
||||
costIds?: string[];
|
||||
costIds?: number[];
|
||||
/** 成本费用 */
|
||||
costVOList?: CostVO[];
|
||||
/** 成本模板 */
|
||||
@ -5469,6 +5501,130 @@ declare namespace BusinessAPI {
|
||||
createdAt?: string;
|
||||
};
|
||||
|
||||
type ReconciliationCreateCmd = {
|
||||
/** 经销商ID */
|
||||
dealerId: string;
|
||||
/** 原对账金额 */
|
||||
originalAmount: number;
|
||||
/** 是否抹零 1是0否 */
|
||||
isRounding: boolean;
|
||||
companyId: string;
|
||||
/** 抹零金额 */
|
||||
roundingAmount: number;
|
||||
/** 抹零备注 */
|
||||
roundingRemark: string;
|
||||
/** 对账金额 */
|
||||
reconciliationAmount: number;
|
||||
/** 备注 */
|
||||
remark?: string;
|
||||
/** 对账发货单 */
|
||||
orderShipVOList?: OrderShipVO[];
|
||||
};
|
||||
|
||||
type ReconciliationDestroyCmd = {
|
||||
/** 对账ID */
|
||||
reconciliationId: string;
|
||||
};
|
||||
|
||||
type ReconciliationListQry = {
|
||||
/** 状态:1_启用;0_禁用; */
|
||||
status?: boolean;
|
||||
/** 对账ID */
|
||||
reconciliationId?: string;
|
||||
};
|
||||
|
||||
type ReconciliationPageQry = {
|
||||
pageSize?: number;
|
||||
pageIndex?: number;
|
||||
orderBy?: string;
|
||||
orderDirection?: string;
|
||||
groupBy?: string;
|
||||
needTotalCount?: boolean;
|
||||
/** 自定义字段key */
|
||||
customFieldKey?: string;
|
||||
/** 自定义字段value */
|
||||
customFieldValue?: string;
|
||||
/** 备注 */
|
||||
remark?: string;
|
||||
/** 状态:1_启用;0_禁用; */
|
||||
status?: boolean;
|
||||
/** 对账ID */
|
||||
reconciliationId?: string;
|
||||
offset?: number;
|
||||
};
|
||||
|
||||
type ReconciliationShowQry = {
|
||||
/** 状态:1_启用;0_禁用; */
|
||||
status?: boolean;
|
||||
/** 对账ID */
|
||||
reconciliationId?: string;
|
||||
};
|
||||
|
||||
type ReconciliationUpdateCmd = {
|
||||
/** 对账ID */
|
||||
reconciliationId: string;
|
||||
/** 对账编码 */
|
||||
reconciliationSn: string;
|
||||
/** 经销商ID */
|
||||
dealerId: string;
|
||||
/** 原对账金额 */
|
||||
originalAmount: number;
|
||||
/** 是否抹零 1是0否 */
|
||||
isRounding: boolean;
|
||||
/** 抹零金额 */
|
||||
roundingAmount: number;
|
||||
/** 抹零备注 */
|
||||
roundingRemark: string;
|
||||
/** 对账金额 */
|
||||
reconciliationAmount: number;
|
||||
/** 状态: 0-待对账, 1-已对账, 2-部分开票, 3-已开票, 4-部分回款, 5-已回款 */
|
||||
state:
|
||||
| 'PENDING'
|
||||
| 'RECONCILED'
|
||||
| 'PARTIAL_INVOICE'
|
||||
| 'INVOICED'
|
||||
| 'PARTIAL_PAYMENT'
|
||||
| 'PAID';
|
||||
/** 备注 */
|
||||
remark?: string;
|
||||
/** 对账发货单 */
|
||||
orderShipVOList?: OrderShipVO[];
|
||||
};
|
||||
|
||||
type ReconciliationVO = {
|
||||
/** 对账ID */
|
||||
reconciliationId: string;
|
||||
/** 对账编码 */
|
||||
reconciliationSn: string;
|
||||
/** 经销商ID */
|
||||
dealerId: string;
|
||||
/** 原对账金额 */
|
||||
originalAmount: number;
|
||||
companyId: number;
|
||||
/** 是否抹零 1是0否 */
|
||||
isRounding: boolean;
|
||||
/** 抹零金额 */
|
||||
roundingAmount: number;
|
||||
/** 抹零备注 */
|
||||
roundingRemark: string;
|
||||
/** 对账金额 */
|
||||
reconciliationAmount: number;
|
||||
/** 状态: 0-待对账, 1-已对账, 2-部分开票, 3-已开票, 4-部分回款, 5-已回款 */
|
||||
state:
|
||||
| 'PENDING'
|
||||
| 'RECONCILED'
|
||||
| 'PARTIAL_INVOICE'
|
||||
| 'INVOICED'
|
||||
| 'PARTIAL_PAYMENT'
|
||||
| 'PAID';
|
||||
/** 备注 */
|
||||
remark?: string;
|
||||
/** 创建时间 */
|
||||
createdAt?: string;
|
||||
/** 对账发货单 */
|
||||
orderShipVOList?: OrderShipVO[];
|
||||
};
|
||||
|
||||
type Response = {
|
||||
success?: boolean;
|
||||
errCode?: string;
|
||||
@ -5487,7 +5643,7 @@ declare namespace BusinessAPI {
|
||||
/** 角色详情 */
|
||||
description?: string;
|
||||
/** 角色id */
|
||||
menuId: string[];
|
||||
menuId: number[];
|
||||
};
|
||||
|
||||
type RoleDestroyCmd = {
|
||||
@ -5509,7 +5665,7 @@ declare namespace BusinessAPI {
|
||||
/** 角色编号 */
|
||||
roleId?: string;
|
||||
/** 应用角色Id */
|
||||
roleIdList?: string[];
|
||||
roleIdList?: number[];
|
||||
/** 平台Id */
|
||||
platformId?: string;
|
||||
/** 平台Id */
|
||||
@ -5556,7 +5712,7 @@ declare namespace BusinessAPI {
|
||||
/** 角色详情 */
|
||||
description?: string;
|
||||
/** 角色id */
|
||||
menuId: string[];
|
||||
menuId: number[];
|
||||
/** 角色ID */
|
||||
roleId: string;
|
||||
};
|
||||
@ -5577,9 +5733,9 @@ declare namespace BusinessAPI {
|
||||
/** 平台 */
|
||||
platformVO?: PlatformVO;
|
||||
/** 权限列表 */
|
||||
permissionId: string[];
|
||||
permissionId: number[];
|
||||
/** 菜单列表 */
|
||||
menuId: string[];
|
||||
menuId: number[];
|
||||
/** 创建时间 */
|
||||
createdAt: string;
|
||||
};
|
||||
@ -5807,6 +5963,10 @@ declare namespace BusinessAPI {
|
||||
productShowQry: ProductShowQry;
|
||||
};
|
||||
|
||||
type showReconciliationParams = {
|
||||
reconciliationShowQry: ReconciliationShowQry;
|
||||
};
|
||||
|
||||
type showRoleParams = {
|
||||
roleShowQry: RoleShowQry;
|
||||
};
|
||||
@ -6065,6 +6225,13 @@ declare namespace BusinessAPI {
|
||||
data?: ProductVO;
|
||||
};
|
||||
|
||||
type SingleResponseReconciliationVO = {
|
||||
success?: boolean;
|
||||
errCode?: string;
|
||||
errMessage?: string;
|
||||
data?: ReconciliationVO;
|
||||
};
|
||||
|
||||
type SingleResponseRoleVO = {
|
||||
success?: boolean;
|
||||
errCode?: string;
|
||||
@ -6464,7 +6631,7 @@ declare namespace BusinessAPI {
|
||||
/** 备注 */
|
||||
remark?: string;
|
||||
/** 客户标签 */
|
||||
labelId?: string[];
|
||||
labelId?: number[];
|
||||
};
|
||||
|
||||
type UserDestroyCmd = {
|
||||
@ -6486,7 +6653,7 @@ declare namespace BusinessAPI {
|
||||
/** 状态:1_启用;0_禁用; */
|
||||
status?: boolean;
|
||||
/** 用户ID */
|
||||
userIdList?: string[];
|
||||
userIdList?: number[];
|
||||
/** 用户名 */
|
||||
name?: string;
|
||||
};
|
||||
@ -6529,9 +6696,9 @@ declare namespace BusinessAPI {
|
||||
/** 是否是管理员 */
|
||||
isAdmin?: boolean;
|
||||
/** 会员id列表 */
|
||||
userIdList?: string[];
|
||||
userIdList?: number[];
|
||||
/** 排除的用户id列表 */
|
||||
excludeUserIdList?: string[];
|
||||
excludeUserIdList?: number[];
|
||||
/** 小区id */
|
||||
communityId?: number;
|
||||
offset?: number;
|
||||
@ -6541,7 +6708,7 @@ declare namespace BusinessAPI {
|
||||
/** 用户ID */
|
||||
userId: string;
|
||||
/** 角色ID */
|
||||
roleIdList?: string[];
|
||||
roleIdList?: number[];
|
||||
/** 是否覆盖 */
|
||||
cover: boolean;
|
||||
};
|
||||
@ -6586,7 +6753,7 @@ declare namespace BusinessAPI {
|
||||
/** 备注 */
|
||||
remark?: string;
|
||||
/** 客户标签 */
|
||||
labelId?: string[];
|
||||
labelId?: number[];
|
||||
/** 用户ID */
|
||||
userId: string;
|
||||
};
|
||||
|
||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user