Commit 8eaea579 authored by XieZhiXiong's avatar XieZhiXiong

feat: 抽离 单据页面 组件

parent e98d1f98
/*
* @Author: XieZhiXiong
* @Date: 2021-08-04 14:42:57
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-08-04 17:59:35
* @Description:
*/
import { FormPath, FormEffectHooks } from '@formily/antd';
import { useAsyncSelect } from '@/formSchema/effects/useAsyncSelect';
import { PublicApi } from '@/services/api';
import { useBusinessEffects } from './useBusinessEffects';
const {
onFieldMount$,
} = FormEffectHooks;
// 获取单据类型
const fetchInvoicesType = (): Promise<any[]> => {
return new Promise((resolve, reject) => {
PublicApi.getProductInvoicesTypeAll().then(res => {
if (res.code === 1000) {
resolve(res.data);
}
reject();
}).catch(() => {
reject();
});
});
};
// 获取仓库
const fetchInventory = (): Promise<any[]> => {
return new Promise((resolve, reject) => {
PublicApi.getProductWarehouseAll().then(res => {
if (res.code === 1000) {
resolve(res.data);
}
reject();
}).catch(() => {
reject();
});
});
};
export const createEffects = (context, actions) => {
const { setFieldState } = actions;
useBusinessEffects(context, actions);
useAsyncSelect('billType', fetchInvoicesType, ['name', 'id']);
useAsyncSelect('inventoryId', fetchInventory, ['name', 'id']);
};
\ No newline at end of file
/*
* @Author: XieZhiXiong
* @Date: 2021-08-04 14:43:14
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-08-04 18:00:12
* @Description:
*/
import { FormEffectHooks, FormPath, IFormActions } from '@formily/antd';
import { useLinkageUtils } from '@/utils/formEffectUtils';
const {
onFieldInputChange$,
onFieldValueChange$,
} = FormEffectHooks;
export const useBusinessEffects = (context, actions: IFormActions) => {
const { getFieldValue, setFieldState, setFieldValue, getFieldState } = actions;
const linkage = useLinkageUtils();
// 对应仓库改变
onFieldInputChange$('inventoryId').subscribe(fieldState => {
const current = fieldState.originAsyncData.find(item => item.id === fieldState.value);
if (current) {
linkage.value('inventoryRole', current.principal);
}
});
}
\ No newline at end of file
/*
* @Author: XieZhiXiong
* @Date: 2021-08-04 11:33:33
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-08-04 17:55:28
* @Description: 单据表单组件,提供基础的表单内容,单据明细相关由外部传入控制
*/
import React, { useEffect, useState } from 'react';
import { Button, Spin } from 'antd';
import { createFormActions, FormEffectHooks, ISchemaFormActions, ISchemaFormAsyncActions } from '@formily/antd';
import { Radio, ArrayTable } from '@formily/antd-components';
import {
DOC_TYPE_PURCHASE_RECEIPT,
DOC_TYPE_SALES_INVOICE,
DOC_TYPE_PROCESS_RECEIPT,
DOC_TYPE_PROCESS_INVOICE,
DOC_TYPE_RETURN_INVOICE,
DOC_TYPE_RETURN_RECEIPT,
DOC_TYPE_EXCHANGE_RETURN_INVOICE,
DOC_TYPE_EXCHANGE_RETURN_RECEIPT,
DOC_TYPE_EXCHANGE_INVOICE,
DOC_TYPE_EXCHANGE_RECEIPT,
} from '@/constants/commodity';
import AnchorPage from '@/layouts/AnchorPage';
import NiceForm from '@/components/NiceForm';
import createSchema, { BillDetailSchemaType, BILL_DETAIL_KEY } from './schema';
import { createEffects } from './effects';
import EllipsisText from '../EllipsisText';
const TITLE_MAP = {
[DOC_TYPE_PURCHASE_RECEIPT]: '采购入库单',
[DOC_TYPE_SALES_INVOICE]: '销售发货单',
[DOC_TYPE_PROCESS_RECEIPT]: '加工入库单',
[DOC_TYPE_PROCESS_INVOICE]: '加工发货单',
[DOC_TYPE_RETURN_INVOICE]: '退货发货单',
[DOC_TYPE_RETURN_RECEIPT]: '退货入库单',
[DOC_TYPE_EXCHANGE_RETURN_INVOICE]: '换货退货发货单',
[DOC_TYPE_EXCHANGE_RETURN_RECEIPT]: '换货退货入货单',
[DOC_TYPE_EXCHANGE_INVOICE]: '换货发货单',
[DOC_TYPE_EXCHANGE_RECEIPT]: '换货入库单',
};
const formActions = createFormActions();
const {
onFieldValueChange$,
onFieldInputChange$,
onFormInputChange$,
} = FormEffectHooks;
export type RelatedInfoType = {
/**
* 关联单据编号
*/
relatedNo: string,
/**
* 会员名称
*/
memberName: string,
/**
* 收货地址 或 发货地址
*/
address: string,
/**
* 物流方式名称
*/
logisticsTypeName: string,
}
interface IProps {
/**
* 单据类型
*/
billType: number,
/**
* 是否可编辑的
*/
editable?: boolean,
/**
* 获取对应单据详情
*/
fetchRelatedInfo: () => Promise<RelatedInfoType>,
}
const BillsFormPage: React.FC<IProps> = (props: IProps) => {
const {
billType,
editable = true,
fetchRelatedInfo,
} = props;
const [relatedLoading, setRelatedLoading] = useState(false);
const [unsaved, setUnsaved] = useState(false);
const getRelatedInfo = () => {
if (fetchRelatedInfo) {
setRelatedLoading(true);
fetchRelatedInfo().then((res) => {
console.log('res', res)
}).finally(() => {
setRelatedLoading(false);
});
}
};
useEffect(() => {
getRelatedInfo();
}, []);
const anchorsArr = [
{
key: 'basicInfo',
name: '基本信息',
},
{
key: 'billDetail',
name: '单据明细',
},
];
const handleSubmit = (values: any) => {
};
return (
<Spin spinning={relatedLoading}>
<AnchorPage
title={TITLE_MAP[1]}
anchors={anchorsArr}
extra={(
<Button type="primary">保存</Button>
)}
>
<NiceForm
previewPlaceholder=" "
onSubmit={handleSubmit}
actions={formActions}
initialValues={{}}
components={{
RadioGroup: Radio.Group,
ArrayTable,
Text: EllipsisText,
}}
effects={($, actions) => {
createEffects($, actions);
onFormInputChange$().subscribe(() => {
if (!unsaved) {
setUnsaved(true);
}
});
}}
schema={createSchema(billType)}
editable={!!editable}
/>
</AnchorPage>
</Spin>
);
};
export default BillsFormPage;
/*
* @Author: XieZhiXiong
* @Date: 2021-08-04 13:59:33
* @LastEditors: XieZhiXiong
* @LastEditTime: 2021-08-04 18:06:51
* @Description:
*/
import { ISchema } from '@formily/antd';
import moment from 'moment';
import themeConfig from '@/../config/lingxi.theme.config';
import { PATTERN_MAPS } from '@/constants/regExp';
import {
DOC_TYPE_PURCHASE_RECEIPT,
DOC_TYPE_SALES_INVOICE,
DOC_TYPE_PROCESS_RECEIPT,
DOC_TYPE_PROCESS_INVOICE,
DOC_TYPE_RETURN_INVOICE,
DOC_TYPE_RETURN_RECEIPT,
DOC_TYPE_EXCHANGE_RETURN_INVOICE,
DOC_TYPE_EXCHANGE_RETURN_RECEIPT,
DOC_TYPE_EXCHANGE_INVOICE,
DOC_TYPE_EXCHANGE_RECEIPT,
DEPENDENT_DOC_ORDER,
DEPENDENT_DOC_EXCHANGE,
DEPENDENT_DOC_RETURN,
DEPENDENT_DOC_PRODUCTION,
DEPENDENT_DOC_INTERNAL,
} from '@/constants/commodity';
export type BillDetailSchemaType = {
[key: string]: ISchema,
};
export const BILL_DETAIL_KEY = 'billDetail';
// 单据类型 换 关联单据类型
const RELATED_BILL_TYPE_MAP = {
[DOC_TYPE_PURCHASE_RECEIPT]: DEPENDENT_DOC_ORDER,
[DOC_TYPE_SALES_INVOICE]: DEPENDENT_DOC_ORDER,
[DOC_TYPE_PROCESS_RECEIPT]: DEPENDENT_DOC_PRODUCTION,
[DOC_TYPE_PROCESS_INVOICE]: DEPENDENT_DOC_PRODUCTION,
[DOC_TYPE_RETURN_INVOICE]: DEPENDENT_DOC_RETURN,
[DOC_TYPE_RETURN_RECEIPT]: DEPENDENT_DOC_RETURN,
[DOC_TYPE_EXCHANGE_RETURN_INVOICE]: DEPENDENT_DOC_EXCHANGE,
[DOC_TYPE_EXCHANGE_RETURN_RECEIPT]: DEPENDENT_DOC_EXCHANGE,
[DOC_TYPE_EXCHANGE_INVOICE]: DEPENDENT_DOC_EXCHANGE,
[DOC_TYPE_EXCHANGE_RECEIPT]: DEPENDENT_DOC_EXCHANGE,
};
// 单据类型 换 单据类型名称
const BILL_NAME_MAP = {
[DOC_TYPE_PURCHASE_RECEIPT]: '订单',
[DOC_TYPE_SALES_INVOICE]: '订单',
[DOC_TYPE_PROCESS_RECEIPT]: '加工',
[DOC_TYPE_PROCESS_INVOICE]: '加工',
[DOC_TYPE_RETURN_INVOICE]: '退货',
[DOC_TYPE_RETURN_RECEIPT]: '退货',
[DOC_TYPE_EXCHANGE_RETURN_INVOICE]: '换货',
[DOC_TYPE_EXCHANGE_RETURN_RECEIPT]: '换货',
[DOC_TYPE_EXCHANGE_INVOICE]: '换货',
[DOC_TYPE_EXCHANGE_RECEIPT]: '换货',
};
// 单据类型 换 单据方向名称
const BILL_DIRECTION_NAME_MAP = {
[DOC_TYPE_PURCHASE_RECEIPT]: '收货',
[DOC_TYPE_SALES_INVOICE]: '发货',
[DOC_TYPE_PROCESS_RECEIPT]: '入库',
[DOC_TYPE_PROCESS_INVOICE]: '发货',
[DOC_TYPE_RETURN_INVOICE]: '发货',
[DOC_TYPE_RETURN_RECEIPT]: '收货',
[DOC_TYPE_EXCHANGE_RETURN_INVOICE]: '发货',
[DOC_TYPE_EXCHANGE_RETURN_RECEIPT]: '收货',
[DOC_TYPE_EXCHANGE_INVOICE]: '发货',
[DOC_TYPE_EXCHANGE_RECEIPT]: '收货',
};
const createSchema = (billType: number): ISchema => ({
type: 'object',
properties: {
BASIC_INFO: {
type: 'object',
'x-component': 'MellowCardBox',
'x-component-props': {
title: '基本信息',
id: 'basicInfo',
style: {
marginBottom: themeConfig['@margin-md'],
},
},
properties: {
COlUMN_LAYOUT: {
type: 'object',
'x-component': 'ColumnLayout',
'x-component-props': {
column: 2,
gutter: 128,
},
properties: {
MEGA_LADYOUT_1: {
type: 'object',
'x-component': 'Mega-Layout',
'x-component-props': {
grid: true,
full: true,
columns: 1,
autoRow: true,
labelCol: 6,
labelAlign: 'left',
},
properties: {
billType: {
title: '单据类型',
type: 'string',
enum: [],
required: true,
'x-component-props': {
allowClear: false,
disabled: true,
},
default: billType,
},
inventoryId: {
title: '对应仓库',
type: 'string',
enum: [],
required: true,
'x-component-props': {
allowClear: false,
},
},
invoicesAbstract: {
title: '单据摘要',
type: 'string',
required: true,
'x-component-props': {
allowClear: false,
},
},
transactionTime: {
type: 'date',
title: '单据时间',
'x-component-props': {
format: 'YYYY-MM-DD HH:mm:ss',
showTime: true,
},
required: true,
default: moment().format('YYYY-MM-DD HH:mm:ss'),
},
inventoryRole: {
type: 'string',
title: '仓库人员',
required: true,
},
},
},
MEGA_LADYOUT_2: {
type: 'object',
'x-component': 'Mega-Layout',
'x-component-props': {
grid: true,
full: true,
columns: 1,
autoRow: true,
labelCol: 6,
labelAlign: 'left',
},
properties: {
relatedBillType: {
title: '对应单据',
type: 'string',
'x-rules': [
{
required: true,
message: '请选择对应单据',
},
],
enum: [
{
label: '订单',
value: DEPENDENT_DOC_ORDER,
},
{
label: '换货申请单',
value: DEPENDENT_DOC_EXCHANGE,
},
{
label: '退货申请单',
value: DEPENDENT_DOC_RETURN,
},
{
label: '生产通知单',
value: DEPENDENT_DOC_PRODUCTION,
},
{
label: '内部单据',
value: DEPENDENT_DOC_INTERNAL,
},
],
default: RELATED_BILL_TYPE_MAP[billType],
editable: false,
},
// 关联单据的编号,例如订单编号、售后编号、加工编号
relatedNo: {
title: '关联单据',
type: 'string',
required: true,
editable: false,
},
memberName: {
type: 'string',
title: '会员名称',
editable: false,
},
// 收货地址 或 发货地址
address: {
type: 'string',
title: '收货地址',
editable: false,
},
logisticsTypeName: {
type: 'string',
title: '物流方式',
editable: false,
},
},
},
},
},
},
},
BILL_DETAIL: {
type: 'object',
'x-component': 'MellowCardBox',
'x-component-props': {
title: '单据明细',
id: 'billDetail',
style: {
marginBottom: themeConfig['@margin-md'],
},
},
properties: {
[BILL_DETAIL_KEY]: {
type: 'array',
'x-component': 'ArrayTable',
'x-component-props': {
renderAddition: () => null,
},
'x-rules': [
{
required: true,
message: '请添加单据明细',
},
],
items: {
type: 'object',
properties: {
orderNo: {
title: '订单号',
type: 'string',
'x-component': 'Text',
'x-component-props': {
ellipsis: true,
},
},
productId: {
title: '商品ID',
type: 'string',
'x-component': 'Text',
'x-component-props': {
ellipsis: true,
},
},
productName: {
title: `${BILL_NAME_MAP[billType]}商品名称`,
type: 'string',
'x-component': 'Text',
'x-component-props': {
ellipsis: true,
},
},
// 商品品类
category: {
type: 'string',
title: '品类',
'x-component': 'Text',
'x-component-props': {
ellipsis: true,
},
},
// 商品品牌
brand: {
type: 'string',
title: '品牌',
'x-component': 'Text',
'x-component-props': {
ellipsis: true,
},
},
// 商品单位
unit: {
type: 'string',
title: '单位',
'x-component': 'Text',
'x-component-props': {
ellipsis: true,
},
},
// 商品单价
price: {
type: 'string',
title: '单价',
'x-component': 'Text',
'x-component-props': {
ellipsis: true,
},
},
// 关联单据商品数量
relatedCount: {
type: 'string',
title: `${BILL_NAME_MAP[billType]}数量`,
'x-component': 'Text',
'x-component-props': {
ellipsis: true,
},
},
// 单据数量
count: {
type: 'string',
title: `${BILL_NAME_MAP[billType]}${BILL_DIRECTION_NAME_MAP[billType]}数量`,
'x-component-props': {
allowClear: true,
},
'x-rules': [
{
required: true,
message: `请输入${BILL_NAME_MAP[billType]}${BILL_DIRECTION_NAME_MAP[billType]}数量`,
},
{
pattern: PATTERN_MAPS.weight,
message: '请输入正确的数量',
},
],
},
// 单据金额
amount: {
type: 'string',
title: `${BILL_NAME_MAP[billType]}${BILL_DIRECTION_NAME_MAP[billType]}金额`,
'x-component': 'Text',
'x-component-props': {
ellipsis: true,
},
},
},
}
},
},
},
},
});
export default createSchema;
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