Commit dcb5e192 authored by XieZhiXiong's avatar XieZhiXiong

feat: 添加新增单据逻辑

parent f33af2fd
......@@ -2,12 +2,17 @@
* @Author: XieZhiXiong
* @Date: 2021-08-04 11:33:33
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-08-04 17:55:28
* @LastEditTime: 2021-08-12 17:52:48
* @Description: 单据表单组件,提供基础的表单内容,单据明细相关由外部传入控制
*/
import React, { useEffect, useState } from 'react';
import { Button, Spin } from 'antd';
import { createFormActions, FormEffectHooks, ISchemaFormActions, ISchemaFormAsyncActions } from '@formily/antd';
import {
createFormActions,
IFormExtendsEffectSelector,
ISchemaFormActions,
ISchemaFormAsyncActions,
} from '@formily/antd';
import { Radio, ArrayTable } from '@formily/antd-components';
import {
DOC_TYPE_PURCHASE_RECEIPT,
......@@ -21,12 +26,17 @@ import {
DOC_TYPE_EXCHANGE_INVOICE,
DOC_TYPE_EXCHANGE_RECEIPT,
} from '@/constants/commodity';
import { DELIVERY_TYPE } from '@/constants/order';
import AnchorPage from '@/layouts/AnchorPage';
import NiceForm from '@/components/NiceForm';
import createSchema, { BillDetailSchemaType, BILL_DETAIL_KEY } from './schema';
import createSchema from './schema';
import { createEffects } from './effects';
import { RelatedInfoDataType, RelatedInfoType, BillSubmitValuesType } from './interface';
import { normalizeBillDetails } from './utils';
import EllipsisText from '../EllipsisText';
export * from './interface';
const TITLE_MAP = {
[DOC_TYPE_PURCHASE_RECEIPT]: '采购入库单',
[DOC_TYPE_SALES_INVOICE]: '销售发货单',
......@@ -41,30 +51,6 @@ const TITLE_MAP = {
};
const formActions = createFormActions();
const {
onFieldValueChange$,
onFieldInputChange$,
onFormInputChange$,
} = FormEffectHooks;
export type RelatedInfoType = {
/**
* 关联单据编号
*/
relatedNo: string,
/**
* 会员名称
*/
memberName: string,
/**
* 收货地址 或 发货地址
*/
address: string,
/**
* 物流方式名称
*/
logisticsTypeName: string,
}
interface IProps {
/**
......@@ -78,7 +64,19 @@ interface IProps {
/**
* 获取对应单据详情
*/
fetchRelatedInfo: () => Promise<RelatedInfoType>,
fetchRelatedInfo: () => Promise<RelatedInfoDataType>,
/**
* submit loading
*/
submitLoading: boolean,
/**
* 点击保存触发事件
*/
onSubmit: (values: BillSubmitValuesType) => void,
/**
* 自定义的 effects事件
*/
customEffects?: (context?: IFormExtendsEffectSelector, action?: ISchemaFormActions | ISchemaFormAsyncActions) => void,
}
const BillsFormPage: React.FC<IProps> = (props: IProps) => {
......@@ -86,15 +84,25 @@ const BillsFormPage: React.FC<IProps> = (props: IProps) => {
billType,
editable = true,
fetchRelatedInfo,
submitLoading,
onSubmit,
customEffects,
} = props;
const [relatedInfo, setRelatedInfo] = useState<RelatedInfoType | null>(null);
const [relatedLoading, setRelatedLoading] = useState(false);
const [unsaved, setUnsaved] = useState(false);
const getRelatedInfo = () => {
if (fetchRelatedInfo) {
setRelatedLoading(true);
fetchRelatedInfo().then((res) => {
console.log('res', res)
if (res) {
setRelatedInfo({
...res,
logisticsTypeName: DELIVERY_TYPE[res.logisticsType],
billDetails: normalizeBillDetails(res.billDetails),
});
}
}).finally(() => {
setRelatedLoading(false);
});
......@@ -116,24 +124,30 @@ const BillsFormPage: React.FC<IProps> = (props: IProps) => {
},
];
const handleSubmit = (values: any) => {
const handleSubmit = (values: BillSubmitValuesType) => {
onSubmit?.(values);
};
return (
<Spin spinning={relatedLoading}>
<AnchorPage
title={TITLE_MAP[1]}
title={`新增${TITLE_MAP[billType]}`}
anchors={anchorsArr}
extra={(
<Button type="primary">保存</Button>
<Button
type="primary"
loading={submitLoading}
onClick={() => formActions.submit()}
>
保存
</Button>
)}
>
<NiceForm
previewPlaceholder=" "
onSubmit={handleSubmit}
actions={formActions}
initialValues={{}}
initialValues={relatedInfo}
components={{
RadioGroup: Radio.Group,
ArrayTable,
......@@ -143,11 +157,7 @@ const BillsFormPage: React.FC<IProps> = (props: IProps) => {
createEffects($, actions);
onFormInputChange$().subscribe(() => {
if (!unsaved) {
setUnsaved(true);
}
});
customEffects?.($, actions);
}}
schema={createSchema(billType)}
editable={!!editable}
......
/*
* @Author: XieZhiXiong
* @Date: 2021-08-12 16:39:50
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-08-12 17:49:41
* @Description:
*/
export type BillDetailsItemType = {
/**
* 订单编号
*/
orderNo: string,
/**
* 商品id
*/
productId: string,
/**
* 商品名称
*/
productName: string,
/**
* 商品品类
*/
category: string,
/**
* 商品单位
*/
unit: string,
/**
* 商品品牌
*/
brand: string,
/**
* 商品单价
*/
price: string | number,
/**
* 关联的数量,eg:退货发货单则表示 退货数量(申请数)
*/
relatedCount: string | number,
}
export type BillDetailsItemValueType = BillDetailsItemType & {
/**
* 单据数量
*/
count: number,
/**
* 单据金额
*/
amount: number,
}
export type RelatedInfoDataType = {
/**
* 关联单据编号
*/
relatedNo: string,
/**
* 会员名称
*/
memberName: string,
/**
* 收货地址 或 发货地址
*/
address: string,
/**
* 物流方式
*/
logisticsType: number,
/**
* 单据明细数据
*/
billDetails: BillDetailsItemType[],
}
export type RelatedInfoType = Omit<RelatedInfoDataType, 'billDetails'> & {
/**
* 物流方式名称
*/
logisticsTypeName: string,
/**
* 单据明细数据
*/
billDetails: BillDetailsItemValueType[],
}
export type BillSubmitValuesType = RelatedInfoType & {
/**
* 对应仓库id
*/
inventoryId: number,
/**
* 申请摘要
*/
digest: string,
/**
* 单据时间
*/
createTime: string,
/**
* 仓库人员
*/
inventoryRole: string,
/**
* 对应仓库名称
*/
inventoryName: string,
/**
* 对应单据
*/
relatedBillType: number,
/**
* 关联对应单据编号
*/
relatedNo: string,
/**
* 关联对应单据会员名称
*/
memberName: string,
}
\ No newline at end of file
......@@ -32,8 +32,6 @@ export type BillDetailSchemaType = {
[key: string]: ISchema,
};
export const BILL_DETAIL_KEY = 'billDetail';
// 单据类型 换 关联单据类型
const RELATED_BILL_TYPE_MAP = {
[DOC_TYPE_PURCHASE_RECEIPT]: DEPENDENT_DOC_ORDER,
......@@ -125,20 +123,30 @@ const createSchema = (billType: number): ISchema => ({
title: '对应仓库',
type: 'string',
enum: [],
required: true,
'x-component-props': {
allowClear: false,
},
'x-rules': [
{
required: true,
message: '请选择对应仓库',
},
],
},
invoicesAbstract: {
digest: {
title: '单据摘要',
type: 'string',
required: true,
'x-component-props': {
allowClear: false,
},
'x-rules': [
{
required: true,
message: '请输入单据摘要',
},
],
},
transactionTime: {
createTime: {
type: 'date',
title: '单据时间',
'x-component-props': {
......@@ -151,7 +159,17 @@ const createSchema = (billType: number): ISchema => ({
inventoryRole: {
type: 'string',
title: '仓库人员',
'x-rules': [
{
required: true,
message: '请输入仓库人员',
},
],
},
// 收集值用
inventoryName: {
type: 'string',
display: false,
},
},
},
......@@ -241,7 +259,7 @@ const createSchema = (billType: number): ISchema => ({
},
},
properties: {
[BILL_DETAIL_KEY]: {
billDetails: {
type: 'array',
'x-component': 'ArrayTable',
'x-component-props': {
......
/*
* @Author: XieZhiXiong
* @Date: 2021-08-12 16:41:18
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-08-12 16:41:18
* @Description:
*/
import { BillDetailsItemType, BillDetailsItemValueType } from './interface';
// 格式化初始单据详情数据,计算初始单据数量,单据金额
export function normalizeBillDetails(data: BillDetailsItemType[]): BillDetailsItemValueType[] {
const ret: BillDetailsItemValueType[] = [];
data.forEach((item) => {
const atom: BillDetailsItemValueType = {
...item,
count: +item.relatedCount,
amount: +(+item.relatedCount * +item.price).toFixed(2),
};
ret.push(atom)
});
return ret;
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment