feat(reconciliation): 新增对账记录创建功能

- 添加 ReconciliationRecordCreate 组件实现对账单创建流程
- 更新 DealerAccountRecordList 组件中 dealerAccountRecordId 字段为可选
- 修改 DealerModal 中显示经销商名称格式
- 调整 LeftMenu 样式中的 margin 属性
- 重构 PaymentTask 和 Reconciliation 组件中的渲染逻辑
- 简化 ReconciliationSummary 组件的参数传递方式
- 更新国际化配置文件增加对账相关翻译
- 替换 ReconciliationCreate 页面使用新的创建组件
This commit is contained in:
shenyifei 2026-01-12 18:14:04 +08:00
parent 9001490da1
commit 65b5d42985
19 changed files with 1882 additions and 694 deletions

View File

@ -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 筛选

View File

@ -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;

View File

@ -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>
);
})}

View File

@ -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',
},

View File

@ -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,
),
);
}}

View File

@ -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 '暂无微信收款码';
}

View File

@ -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}
/>
</>
);
}

View File

@ -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,
}}
/>
);
}

View File

@ -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>
{/*/!* 调整总额 *!/*/}

View File

@ -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 {

View File

@ -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;
}

View File

@ -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: '取消',
},
},
},
},
};

View File

@ -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>
);
}

View File

@ -1,5 +1,5 @@
import { PageContainer } from '@/components';
import { ReconciliationRecordList } from '@/components';
export default function Page() {
return <PageContainer permission={''}></PageContainer>;
return <ReconciliationRecordList />;
}

View File

@ -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;
};

View File

@ -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,

View 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 || {}),
},
);
}

View File

@ -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