Commit c2546718 authored by 前端-黄佳鑫's avatar 前端-黄佳鑫

feat: 物流能力地址修改成四级联动

parent 16adb735
......@@ -41,18 +41,21 @@ const {
onFormInit$,
} = FormEffectHooks;
const useFetchAreaEnumLinkageEffect = () => {
export const useFetchAreaEnumLinkageEffect = () => {
useValueLinkageEffect({
type: 'value:areaEnum',
resolve: async ({ origin, target }, { getFieldValue, setFieldState }) => {
resolve: async ({ origin, target }, { getFieldValue, setFieldState, getFieldState }) => {
const parentValue = getFieldValue(origin);
if (!parentValue) {
setFieldState(target, innerState => {
FormPath.setIn(innerState, 'value', undefined);
FormPath.setIn(innerState, 'props.enum', []);
});
return;
}
getFieldState(origin, (innerState) => {
if (innerState.modified) {
setFieldState(target, innerState => {
FormPath.setIn(innerState, 'value', undefined);
FormPath.setIn(innerState, 'props.enum', []);
});
return;
}
});
// loading start
setFieldState(
target,
......@@ -486,7 +489,7 @@ const AddressSelect: React.FC<IProps> = (props) => {
flag: visible,
};
});
// 先获取地区信息
formActions.setFieldState('provinceCode', targetState => {
FormPath.setIn(targetState, 'props.x-props.hasFeedback', true);
......@@ -607,7 +610,7 @@ const AddressSelect: React.FC<IProps> = (props) => {
<div>{full || (!isStr ? `${value?.name || ''} ${value?.fullAddress || ''} ${value?.phone || ''}` : value)}</div>
);
};
if (!editable) {
return renderAddressStr();
}
......
import React from 'react';
import { receiverAddress } from '../component/schema'
import AddressForm from '../component/addressForm';
import { postLogisticsReceiverAddressAdd } from '@/services/LogisticsV2Api';
import AddedAddressLayout from './form';
const ReceivingAddressAdded = () => {
return (
<AddressForm
title='收货地区'
schema={receiverAddress}
fetch={postLogisticsReceiverAddressAdd}
isEdit
/>
<AddedAddressLayout mode='add' />
)
}
export default ReceivingAddressAdded
import React from 'react';
import { history } from 'umi';
import { receiverAddress } from '../component/schema'
import AddressForm from '../component/addressForm';
import { getLogisticsReceiverAddressGet, postLogisticsReceiverAddressUpdate } from '@/services/LogisticsV2Api';
import AddedAddressLayout from './form';
const ReceivingAddressEdit = () => {
const {
......@@ -11,14 +9,7 @@ const ReceivingAddressEdit = () => {
},
} = history.location;
return (
<AddressForm
id={id}
title='收货地区'
schema={receiverAddress}
fetch={postLogisticsReceiverAddressUpdate}
detail={getLogisticsReceiverAddressGet}
isEdit
/>
<AddedAddressLayout mode='edit' id={id as any} />
)
}
export default ReceivingAddressEdit
import React, { useState, useEffect } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { history, Prompt } from 'umi';
import ReutrnEle from '@/components/ReturnEle';
import { Button, Card, Spin } from 'antd';
import NiceForm from '@/components/NiceForm';
import { useAsyncSelect } from '@/formSchema/effects/useAsyncSelect';
import { getManageAreaByPcode, GetManageAreaByPcodeRequest, getManageCountryAreaGetTelCode } from '@/services/ManageV2Api';
import { PATTERN_MAPS } from '@/constants/regExp';
import { createFormActions, FormEffectHooks } from '@formily/antd'
import { getLogisticsReceiverAddressGet, postLogisticsReceiverAddressAdd, postLogisticsReceiverAddressUpdate } from '@/services/LogisticsV2Api';
import { SaveOutlined } from '@ant-design/icons';
import { useFetchAreaEnumLinkageEffect } from '@/components/AddressSelect';
export interface AddressModalProps {
/** 类型 */
mode: 'add' | 'edit' | 'preview' | 'default',
/** id */
id?: string,
}
const addressSchemaAction = createFormActions()
const {
onFormInputChange$,
} = FormEffectHooks;
const AddedAddressLayout: React.FC<AddressModalProps> = (props) => {
const { mode, id } = props;
const [infoLoading, setInfoLoading] = useState<boolean>(false);
const [unsaved, setUnsaved] = useState<boolean>(false);
const [submitLoading, setSubmitLoading] = useState<boolean>(false);
const [selfInitValue, setSelfInitValue] = useState<any>({});
// 获取手机区号
const fetchTelCode = async () => {
const { data } = await getManageCountryAreaGetTelCode()
return data
}
const handleSubmit = async (value) => {
const provinceName = value?.provinceName ? value.provinceName : addressSchemaAction.getFieldState('provinceCode')['values'][1]['title']
const cityName = value?.cityName ? value.cityName : addressSchemaAction.getFieldState('cityCode')['values'][1]['title']
const districtName = value?.districtName ? value.districtName : addressSchemaAction.getFieldState('districtCode')['values'][1]['title']
const streetName = value?.streetName ? value.streetName : value['streetCode'] ? addressSchemaAction.getFieldState('streetCode')['values'][1]['title'] : null
const params = {
...value,
isDefault: Number(!!value.isDefault),
provinceName,
cityName,
districtName,
streetName
}
setSubmitLoading(true)
const fn = mode === 'edit' ? postLogisticsReceiverAddressUpdate : postLogisticsReceiverAddressAdd
await fn(params).then(res => {
if (res.code !== 1000) {
setSubmitLoading(false);
return
}
setUnsaved(false)
setSubmitLoading(false);
history.goBack();
})
}
const renderSelectOption = (key, ctx, params?: GetManageAreaByPcodeRequest) => {
getManageAreaByPcode({ ...params }).then(res => {
if (res.code === 1000) {
const { data } = res
ctx.setFieldState(key, targetState => {
targetState.originData = data
targetState.props.enum = data.map(v => ({
label: v.name,
value: v.code,
}))
})
}
})
}
useEffect(() => {
if (id) {
setInfoLoading(true)
new Promise((resolve) => {
getLogisticsReceiverAddressGet({ id }).then(res => {
if (res.code !== 1000) {
setInfoLoading(false);
return
}
setInfoLoading(false);
resolve(res.data)
})
}).then((res: any) => {
setSelfInitValue(res)
})
}
}, [mode === 'edit'])
const useChainEffects = ($, ctx) => {
// 初始省份选择
renderSelectOption('provinceCode', ctx)
}
return (
<Spin spinning={infoLoading}>
<PageHeaderWrapper
onBack={() => history.goBack()}
backIcon={<ReutrnEle description="返回" />}
extra={[
(mode !== 'preview' && <Button
key="1"
type="primary"
icon={<SaveOutlined />}
loading={submitLoading}
onClick={() => addressSchemaAction.submit()}
>
保存
</Button>)
]}
>
<Card>
<NiceForm
editable={mode !== 'preview'}
onSubmit={handleSubmit}
initialValues={selfInitValue}
actions={addressSchemaAction}
effects={($, ctx) => {
$('onFormMount').subscribe(() => {
// 四级联动
useChainEffects($, ctx)
})
useFetchAreaEnumLinkageEffect()
useAsyncSelect('areaCode', fetchTelCode)
$('onFieldChange', 'areaCode').subscribe(result => {
if (result.props.enum.length) {
ctx.setFieldValue('areaCode', '86')
}
})
onFormInputChange$().subscribe(() => {
if (!unsaved) {
setUnsaved(true);
}
});
}}
schema={{
type: 'object',
properties: {
NO_SUBMIT_LAYOUT_ADDRESS: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
labelCol: 4,
wrapperCol: 9,
labelAlign: 'left',
},
properties: {
shipperName: {
type: 'string',
title: '收货人',
"x-rules": [
{
required: true,
message: '请输入收货人',
},
{
limitByte: true,
maxByte: 20
}
]
},
NO_SUBMIT_LAYOUT_EFFECT: {
type: 'object',
"x-component": 'mega-layout',
"x-component-props": {
label: '收货地区',
wrapperCol: 24,
className: 'noMarbottom',
},
properties: {
MEGA_LAYOUT1_1: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
grid: true,
full: true,
columns: 4
},
properties: {
provinceCode: {
type: 'string',
enum: [],
required: true,
"x-component-props": {
placeholder: '-省份/直辖市-',
},
"x-mega-props": {
span: 1
},
'x-linkages': [
{
type: 'value:areaEnum',
condition: '{{!!$value}}',
origin: 'provinceCode',
target: 'cityCode',
},
],
},
cityCode: {
type: 'string',
enum: [],
required: true,
"x-component-props": {
placeholder: '-市-',
},
"x-mega-props": {
span: 1
},
'x-linkages': [
{
type: 'value:areaEnum',
condition: '{{!!$value}}',
origin: 'cityCode',
target: 'districtCode',
},
],
},
districtCode: {
type: 'string',
enum: [],
required: true,
"x-component-props": {
placeholder: '-区/县-',
},
"x-mega-props": {
span: 1
},
'x-linkages': [
{
type: 'value:areaEnum',
condition: '{{ !!$value }}', // $self.value 不生效不知道咋滴
origin: 'districtCode',
target: 'streetCode',
},
]
},
streetCode: {
type: 'string',
enum: [],
// required: true,
"x-component-props": {
placeholder: '-街道/乡/镇-',
},
"x-mega-props": {
span: 1
}
},
}
},
}
},
address: {
type: 'string',
"x-component": 'textarea',
"x-component-props": {
rows: 3,
placeholder: '',
},
title: '详细地址',
"x-rules": [
{
required: true,
message: '',
},
{
limitByte: true,
maxByte: 60
}
]
},
postalCode: {
type: 'string',
title: '邮编',
"x-rules": [
{
limitByte: true,
maxByte: 12
}
]
},
NO_SUBMIT_LAYOUT_PHONE: {
type: 'object',
"x-component": 'mega-layout',
"x-component-props": {
wrapperCol: 24,
label: '手机号码',
className: 'noMarbottom',
required: true,
},
properties: {
MEGA_LAYOUT2_1: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
grid: true,
full: true,
columns: 2
},
properties: {
areaCode: {
type: 'string',
enum: [],
'x-component-props': {
placeholder: '请选择',
},
},
phone: {
type: 'string',
required: true,
'x-mega-props': {
span: 3,
},
'x-component-props': {
placeholder: '请输入你的手机号码',
maxLength: 11,
},
'x-rules': [
{
pattern: PATTERN_MAPS.phone,
message: '请输入正确格式的手机号',
},
],
},
},
},
}
},
tel: {
title: '电话号码',
type: 'string'
},
isDefault: {
title: '是否默认',
type: 'boolean',
"x-mega-props": {
wrapperWidth: 36
}
}
}
}
}
}}
/>
</Card>
</PageHeaderWrapper>
<Prompt when={unsaved} message="您还有未保存的内容,是否确定要离开?" />
</Spin>
)
}
export default AddedAddressLayout
import React from 'react';
import { shipperAddress } from '../component/schema'
import AddressForm from '../component/addressForm';
import { postLogisticsShipperAddressAdd } from '@/services/LogisticsV2Api';
import AddedAddressLayout from './form';
const ShipperAddressAdded = () => {
return (
<AddressForm
title='发货地区'
schema={shipperAddress}
fetch={postLogisticsShipperAddressAdd}
isEdit
/>
<AddedAddressLayout mode='add' />
)
}
export default ShipperAddressAdded
import React from 'react';
import { history } from 'umi';
import { shipperAddress } from '../component/schema'
import AddressForm from '../component/addressForm';
import { getLogisticsShipperAddressGet, postLogisticsShipperAddressUpdate } from '@/services/LogisticsV2Api';
import AddedAddressLayout from './form';
const ShipperAddressEdit = () => {
const {
......@@ -10,15 +8,9 @@ const ShipperAddressEdit = () => {
id
},
} = history.location;
return (
<AddressForm
id={id}
title='发货地区'
schema={shipperAddress}
fetch={postLogisticsShipperAddressUpdate}
detail={getLogisticsShipperAddressGet}
isEdit
/>
<AddedAddressLayout mode='edit' id={id as any} />
)
}
export default ShipperAddressEdit
import React, { useState, useEffect } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { history, Prompt } from 'umi';
import ReutrnEle from '@/components/ReturnEle';
import { Button, Card, Spin } from 'antd';
import NiceForm from '@/components/NiceForm';
import { useAsyncSelect } from '@/formSchema/effects/useAsyncSelect';
import { getManageAreaByPcode, GetManageAreaByPcodeRequest, getManageCountryAreaGetTelCode } from '@/services/ManageV2Api';
import { PATTERN_MAPS } from '@/constants/regExp';
import { createFormActions, FormEffectHooks } from '@formily/antd'
import { getLogisticsShipperAddressGet, postLogisticsShipperAddressAdd, postLogisticsShipperAddressUpdate } from '@/services/LogisticsV2Api';
import { SaveOutlined } from '@ant-design/icons';
import { isEmpty } from 'lodash';
import { useFetchAreaEnumLinkageEffect } from '@/components/AddressSelect';
export interface AddressModalProps {
/** 类型 */
mode: 'add' | 'edit' | 'preview' | 'default',
/** id */
id?: string,
}
const addressSchemaAction = createFormActions()
const {
onFormInputChange$,
} = FormEffectHooks;
const AddedAddressLayout: React.FC<AddressModalProps> = (props) => {
const { mode, id } = props;
const [infoLoading, setInfoLoading] = useState<boolean>(false);
const [unsaved, setUnsaved] = useState<boolean>(false);
const [submitLoading, setSubmitLoading] = useState<boolean>(false);
const [selfInitValue, setSelfInitValue] = useState<any>({});
// 获取手机区号
const fetchTelCode = async () => {
const { data } = await getManageCountryAreaGetTelCode()
return data
}
const handleSubmit = async (value) => {
const provinceName = value?.provinceName ? value.provinceName : addressSchemaAction.getFieldState('provinceCode')['values'][1]['title']
const cityName = value?.cityName ? value.cityName : addressSchemaAction.getFieldState('cityCode')['values'][1]['title']
const districtName = value?.districtName ? value.districtName : addressSchemaAction.getFieldState('districtCode')['values'][1]['title']
const streetName = value?.streetName ? value.streetName : value['streetCode'] ? addressSchemaAction.getFieldState('streetCode')['values'][1]['title'] : null
const params = {
...value,
isDefault: Number(!!value.isDefault),
provinceName,
cityName,
districtName,
streetName
}
setSubmitLoading(true)
const fn = mode === 'edit' ? postLogisticsShipperAddressUpdate : postLogisticsShipperAddressAdd
await fn(params).then(res => {
if (res.code !== 1000) {
setSubmitLoading(false);
return
}
setUnsaved(false)
setSubmitLoading(false);
history.goBack();
})
}
const renderSelectOption = (key, ctx, params?: GetManageAreaByPcodeRequest) => {
getManageAreaByPcode({ ...params }).then(res => {
if (res.code === 1000) {
const { data } = res
ctx.setFieldState(key, targetState => {
targetState.originData = data
targetState.props.enum = data.map(v => ({
label: v.name,
value: v.code,
}))
})
}
})
}
useEffect(() => {
if (id) {
setInfoLoading(true)
new Promise((resolve) => {
getLogisticsShipperAddressGet({ id }).then(res => {
if (res.code !== 1000) {
setInfoLoading(false);
return
}
setInfoLoading(false);
resolve(res.data)
})
}).then((res: any) => {
setSelfInitValue(res)
})
}
}, [mode === 'edit'])
const useChainEffects = ($, ctx) => {
// 初始省份选择
renderSelectOption('provinceCode', ctx)
}
return (
<Spin spinning={infoLoading}>
<PageHeaderWrapper
onBack={() => history.goBack()}
backIcon={<ReutrnEle description="返回" />}
extra={[
(mode !== 'preview' && <Button
key="1"
type="primary"
icon={<SaveOutlined />}
loading={submitLoading}
onClick={() => addressSchemaAction.submit()}
>
保存
</Button>)
]}
>
<Card>
<NiceForm
editable={mode !== 'preview'}
onSubmit={handleSubmit}
initialValues={selfInitValue}
actions={addressSchemaAction}
effects={($, ctx) => {
$('onFormMount').subscribe(() => {
// 四级联动
useChainEffects($, ctx)
})
useFetchAreaEnumLinkageEffect()
useAsyncSelect('areaCode', fetchTelCode)
$('onFieldChange', 'areaCode').subscribe(result => {
if (result.props.enum.length) {
ctx.setFieldValue('areaCode', '86')
}
})
onFormInputChange$().subscribe(() => {
if (!unsaved) {
setUnsaved(true);
}
});
}}
schema={{
type: 'object',
properties: {
NO_SUBMIT_LAYOUT_ADDRESS: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
labelCol: 4,
wrapperCol: 9,
labelAlign: 'left',
},
properties: {
shipperName: {
type: 'string',
title: '发货人',
"x-rules": [
{
required: true,
message: '请输入发货人',
},
{
limitByte: true,
maxByte: 20
}
]
},
NO_SUBMIT_LAYOUT_EFFECT: {
type: 'object',
"x-component": 'mega-layout',
"x-component-props": {
label: '发货地区',
wrapperCol: 24,
className: 'noMarbottom',
},
properties: {
MEGA_LAYOUT1_1: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
grid: true,
full: true,
columns: 4
},
properties: {
provinceCode: {
type: 'string',
enum: [],
required: true,
"x-component-props": {
placeholder: '-省份/直辖市-',
},
"x-mega-props": {
span: 1
},
'x-linkages': [
{
type: 'value:areaEnum',
condition: '{{!!$value}}',
origin: 'provinceCode',
target: 'cityCode',
},
],
},
cityCode: {
type: 'string',
enum: [],
required: true,
"x-component-props": {
placeholder: '-市-',
},
"x-mega-props": {
span: 1
},
'x-linkages': [
{
type: 'value:areaEnum',
condition: '{{!!$value}}',
origin: 'cityCode',
target: 'districtCode',
},
],
},
districtCode: {
type: 'string',
enum: [],
required: true,
"x-component-props": {
placeholder: '-区/县-',
},
"x-mega-props": {
span: 1
},
'x-linkages': [
{
type: 'value:areaEnum',
condition: '{{ !!$value }}', // $self.value 不生效不知道咋滴
origin: 'districtCode',
target: 'streetCode',
},
]
},
streetCode: {
type: 'string',
enum: [],
// required: true,
"x-component-props": {
placeholder: '-街道/乡/镇-',
},
"x-mega-props": {
span: 1
}
},
}
},
}
},
address: {
type: 'string',
"x-component": 'textarea',
"x-component-props": {
rows: 3,
placeholder: '',
},
title: '详细地址',
"x-rules": [
{
required: true,
message: '',
},
{
limitByte: true,
maxByte: 60
}
]
},
postalCode: {
type: 'string',
title: '邮编',
"x-rules": [
{
limitByte: true,
maxByte: 12
}
]
},
NO_SUBMIT_LAYOUT_PHONE: {
type: 'object',
"x-component": 'mega-layout',
"x-component-props": {
wrapperCol: 24,
label: '手机号码',
className: 'noMarbottom',
required: true,
},
properties: {
MEGA_LAYOUT2_1: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
grid: true,
full: true,
columns: 2
},
properties: {
areaCode: {
type: 'string',
enum: [],
'x-component-props': {
placeholder: '请选择',
},
},
phone: {
type: 'string',
required: true,
'x-mega-props': {
span: 3,
},
'x-component-props': {
placeholder: '请输入你的手机号码',
maxLength: 11,
},
'x-rules': [
{
pattern: PATTERN_MAPS.phone,
message: '请输入正确格式的手机号',
},
],
},
},
},
}
},
tel: {
title: '电话号码',
type: 'string'
},
isDefault: {
title: '是否默认',
type: 'boolean',
"x-mega-props": {
wrapperWidth: 36
}
}
}
}
}
}}
/>
</Card>
</PageHeaderWrapper>
<Prompt when={unsaved} message="您还有未保存的内容,是否确定要离开?" />
</Spin>
)
}
export default AddedAddressLayout
......@@ -131,6 +131,7 @@ const AddressModal:React.FC<AddressModalProps> = (props) => {
effects={($, ctx) => {
$('onFormMount').subscribe(() => {
// 四级联动
console.log($, ctx, 1)
useChainEffects($, ctx)
})
......
......@@ -51,7 +51,7 @@ const addressSchema: ISchema = {
'x-linkages': [
{
type: 'value:linkage',
condition: '{{!!$value}}',
condition: '{{!!$value}}111',
origin: 'provinceCode',
target: 'cityCode',
},
......
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