Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
J
jinfa-platform
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
XieZhiXiong
jinfa-platform
Commits
8a6f7658
Commit
8a6f7658
authored
Dec 22, 2021
by
XieZhiXiong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 添加 AsAddressCard 售后收发货地址展示及处理组件
parent
84f75ebf
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
541 additions
and
9 deletions
+541
-9
afterService.ts
src/constants/afterService.ts
+17
-7
index.less
...omponents/AsAddressCard/components/AddressInfo/index.less
+13
-0
index.tsx
...components/AsAddressCard/components/AddressInfo/index.tsx
+43
-0
index.less
src/pages/afterService/components/AsAddressCard/index.less
+10
-0
index.tsx
src/pages/afterService/components/AsAddressCard/index.tsx
+383
-0
reducer.ts
src/pages/afterService/components/AsAddressCard/reducer.ts
+61
-0
utils.ts
src/pages/afterService/utils.ts
+14
-2
No files found.
src/constants/afterService.ts
View file @
8a6f7658
...
...
@@ -578,12 +578,21 @@ export const RETURN_OUTER_STATUS = {
[
RETURN_OUTER_STATUS_FINISHED
]:
'售后完成'
,
}
/**
* 物流
*/
export
const
DELIVERY_TYPE_EXPRESS
=
1
;
/**
* 自提
*/
export
const
DELIVERY_TYPE_SELF_LIFTING
=
2
;
/**
* 无需配送
*/
export
const
DELIVERY_TYPE_NO_DISTRIBUTION
=
3
;
export
const
DELIVERY_TYPE_ENUM
=
[
{
label
:
intl
.
formatMessage
({
id
:
'afterService.constants.DELIVERY_TYPE_ENUM_1'
},
{
default
:
'物流'
}),
value
:
1
},
{
label
:
intl
.
formatMessage
({
id
:
'afterService.constants.DELIVERY_TYPE_ENUM_2'
},
{
default
:
'自提'
}),
value
:
2
},
{
label
:
intl
.
formatMessage
({
id
:
'afterService.constants.DELIVERY_TYPE_ENUM_3'
},
{
default
:
'无需配送'
}),
value
:
3
},
]
{
label
:
intl
.
formatMessage
({
id
:
'afterService.constants.DELIVERY_TYPE_ENUM_1'
},
{
default
:
'物流'
}),
value
:
DELIVERY_TYPE_EXPRESS
},
{
label
:
intl
.
formatMessage
({
id
:
'afterService.constants.DELIVERY_TYPE_ENUM_2'
},
{
default
:
'自提'
}),
value
:
DELIVERY_TYPE_SELF_LIFTING
},
{
label
:
intl
.
formatMessage
({
id
:
'afterService.constants.DELIVERY_TYPE_ENUM_3'
},
{
default
:
'无需配送'
}),
value
:
DELIVERY_TYPE_NO_DISTRIBUTION
},
];
\ No newline at end of file
src/pages/afterService/components/AsAddressCard/components/AddressInfo/index.less
0 → 100644
View file @
8a6f7658
@import '~antd/es/style/themes/default.less';
.addressInfo {
&-head {
margin-bottom: @margin-xss;
line-height: @height-base;
}
&-foot {
margin-bottom: 0;
}
}
\ No newline at end of file
src/pages/afterService/components/AsAddressCard/components/AddressInfo/index.tsx
0 → 100644
View file @
8a6f7658
/**
* @Description: 地址卡片组件
*/
import
React
from
'react'
;
import
styles
from
'./index.less'
;
export
type
AsAddressType
=
{
/**
* 地址id
*/
id
:
number
,
/**
* 姓名
*/
name
:
string
,
/**
* 联系电话
*/
phone
:
string
,
/**
* 详细地址
*/
detailed
:
string
,
};
interface
AddressInfoProps
{
/**
* 数据
*/
data
:
AsAddressType
,
}
const
AddressInfo
:
React
.
FC
<
AddressInfoProps
>
=
(
props
:
AddressInfoProps
)
=>
{
const
{
data
}
=
props
;
return
(
<
div
className=
{
styles
.
addressInfo
}
>
<
p
className=
{
styles
[
'addressInfo-head'
]
}
>
{
data
?.
name
||
''
}
/
{
data
?.
phone
||
''
}
</
p
>
<
p
className=
{
styles
[
'addressInfo-foot'
]
}
>
{
data
?.
detailed
||
''
}
</
p
>
</
div
>
);
};
export
default
AddressInfo
;
src/pages/afterService/components/AsAddressCard/index.less
0 → 100644
View file @
8a6f7658
@import '~antd/es/style/themes/default.less';
.as-address-card {
:global {
.ant-form-item {
margin-bottom: @card-head-padding;
}
}
}
\ No newline at end of file
src/pages/afterService/components/AsAddressCard/index.tsx
0 → 100644
View file @
8a6f7658
/**
* @Description: 地址卡片组件
*/
import
React
,
{
useImperativeHandle
,
useReducer
}
from
'react'
;
import
{
Row
,
Col
,
message
}
from
'antd'
;
import
{
createFormActions
,
Form
,
FormEffectHooks
,
FormItem
,
ISchemaFormActions
,
}
from
'@formily/antd'
;
import
{
useIntl
,
getIntl
}
from
'umi'
;
import
{
Radio
}
from
'@formily/antd-components'
;
import
{
DELIVERY_TYPE_EXPRESS
,
DELIVERY_TYPE_SELF_LIFTING
,
DELIVERY_TYPE_NO_DISTRIBUTION
,
DELIVERY_TYPE_ENUM
,
}
from
'@/constants/afterService'
;
import
MellowCard
from
'@/components/MellowCard'
;
import
{
AddressSelectProps
}
from
'@/components/AddressSelect'
;
import
CustomAddressSelect
from
'@/components/NiceForm/components/CustomAddressSelect'
;
import
{
AsType
,
AsAddressRole
}
from
'../../utils'
;
import
{
reducer
,
initialState
,
AsAddressType
,
AsAddressValue
}
from
'./reducer'
;
import
AddressInfo
from
'./components/AddressInfo'
;
import
styles
from
'./index.less'
;
const
formActions
=
createFormActions
();
const
{
onFieldValueChange$
,
}
=
FormEffectHooks
;
const
intlIns
=
getIntl
();
interface
AsAddressCardProps
{
/**
* 售后类型,需要注意的是 换货流程其实是包含退货流程的
* 售后换货:2 售后退货: 3 售后维修:4
*/
asType
:
AsType
,
/**
* 角色
* 寄件人 'sender' 收件人 'receiver'
*/
addressRole
?:
AsAddressRole
,
/**
* 配送方式
*/
deliveryType
:
number
|
undefined
,
/**
* 发货地址
*/
deliveryAddress
:
AsAddressType
,
/**
* 收货地址
*/
shippingAddress
:
AsAddressType
,
/**
* 是否可编辑的,默认 false
*/
ediabled
?:
boolean
,
}
export
type
AsAddressSubmitValue
=
{
/**
* 收货地址
*/
shippingAddress
:
{
/**
* 收货地址id
*/
receiveId
:
number
,
/**
* 收货地址
*/
receiveAddress
:
string
,
/**
* 收货者名称
*/
receiveUserName
:
string
,
/**
* 收货者电话
*/
receiveUserTel
:
string
,
},
/**
* 发货地址
*/
deliveryAddress
:
{
/**
* 配送方式
*/
deliveryType
:
number
,
/**
* 发货地址id
*/
sendId
:
number
,
/**
* 发货地址
*/
sendAddress
:
string
,
/**
* 发货者名称
*/
sendUserName
:
string
,
/**
* 发货者电话
*/
sendUserTel
:
string
,
},
}
export
interface
AsAddressRefHandle
{
submit
:
()
=>
Promise
<
AsAddressSubmitValue
>
,
}
// 卡片标题
const
CARD_TITLE_MAP
:
{
[
key
in
AsType
]:
string
}
=
{
2
:
intlIns
.
formatMessage
({
id
:
'afterService.components.ExchangeAddressInfo.title'
},
{
default
:
'换货收货地址'
}),
3
:
intlIns
.
formatMessage
({
id
:
'afterService.components.ReturnAddressInfo.title'
},
{
default
:
'退货收货地址'
}),
4
:
intlIns
.
formatMessage
({
id
:
'afterService.components.RepairAddressInfo.title'
},
{
default
:
'维修地址'
}),
};
// 发货信息标题
const
DELIVERY_ADDRESS_TITLE_MAP
:
{
[
key
in
AsType
]:
string
}
=
{
2
:
intlIns
.
formatMessage
({
id
:
'afterService.components.ExchangeAddressInfo.deliveryAddress'
},
{
default
:
'换货发货地址'
}),
3
:
intlIns
.
formatMessage
({
id
:
'afterService.components.ReturnAddressInfo.deliveryAddress'
},
{
default
:
'退货发货地址'
}),
4
:
intlIns
.
formatMessage
({
id
:
'afterService.components.RepairAddressInfo.title'
},
{
default
:
'维修地址'
}),
};
// 收货信息标题
const
SHIPPIND_ADDRESS_TITLE_MAP
:
{
[
key
in
AsType
]:
string
}
=
{
2
:
intlIns
.
formatMessage
({
id
:
'afterService.components.ExchangeAddressInfo.shippingAddress'
},
{
default
:
'换货收货地址'
}),
3
:
intlIns
.
formatMessage
({
id
:
'afterService.components.ReturnAddressInfo.shippingAddress'
},
{
default
:
'退货收货地址'
}),
4
:
''
,
};
// 自提信息标题
const
SELF_LIFTING_TITLE_MAP
:
{
[
key
in
AsType
]:
string
}
=
{
2
:
intlIns
.
formatMessage
({
id
:
'afterService.components.ExchangeAddressInfo.pickupAddress'
},
{
default
:
'换货自提地址'
}),
3
:
intlIns
.
formatMessage
({
id
:
'afterService.components.ReturnAddressInfo.pickupAddress'
},
{
default
:
'退货自提地址'
}),
4
:
''
,
};
const
AsAddressCardProps
:
React
.
ForwardRefRenderFunction
<
AsAddressRefHandle
,
AsAddressCardProps
>
=
(
props
:
AsAddressCardProps
,
ref
)
=>
{
const
{
asType
,
addressRole
,
deliveryType
,
deliveryAddress
,
shippingAddress
,
ediabled
=
false
,
}
=
props
;
const
[
innerValue
,
innerValueDispatch
]
=
useReducer
(
reducer
,
initialState
);
const
intl
=
useIntl
();
const
handleShippingAddressChange
=
(
next
:
AddressSelectProps
[
'value'
])
=>
{
innerValueDispatch
({
type
:
'setAsAddress'
,
payload
:
{
shippingAddress
:
{
id
:
next
.
id
,
name
:
next
.
name
,
phone
:
next
.
phone
,
detailed
:
next
.
fullAddress
,
},
},
});
};
const
handleDeliveryAddressChange
=
(
next
:
AddressSelectProps
[
'value'
])
=>
{
innerValueDispatch
({
type
:
'setAsAddress'
,
payload
:
{
deliveryAddress
:
{
id
:
next
.
id
,
name
:
next
.
name
,
phone
:
next
.
phone
,
detailed
:
next
.
fullAddress
,
},
},
});
};
const
handleDeliveryTypeChange
=
(
next
:
number
)
=>
{
innerValueDispatch
({
type
:
'setAsAddress'
,
payload
:
{
deliveryType
:
next
,
},
});
};
const
handleSubmit
:
()
=>
Promise
<
AsAddressSubmitValue
>
=
()
=>
(
new
Promise
(
async
(
resolve
,
reject
)
=>
{
try
{
await
formActions
.
validate
(
'*'
);
resolve
({
shippingAddress
:
{
receiveId
:
innerValue
.
shippingAddress
?.
id
,
receiveAddress
:
innerValue
.
shippingAddress
?.
detailed
,
receiveUserName
:
innerValue
.
shippingAddress
?.
name
,
receiveUserTel
:
innerValue
.
shippingAddress
?.
phone
,
},
deliveryAddress
:
{
deliveryType
:
innerValue
.
deliveryType
,
sendId
:
innerValue
.
deliveryAddress
?.
id
,
sendAddress
:
innerValue
.
deliveryAddress
?.
detailed
,
sendUserName
:
innerValue
.
deliveryAddress
?.
name
,
sendUserTel
:
innerValue
.
deliveryAddress
?.
phone
,
},
})
}
catch
(
error
)
{
if
(
error
.
errors
?.
length
)
{
message
.
warning
(
error
.
errors
[
0
].
messages
[
0
]);
reject
(
error
);
}
}
})
);
const
renderDeliveryBlock
=
()
=>
(
<
Col
span=
{
12
}
>
{
ediabled
&&
asType
===
2
?
(
<
FormItem
type=
"string"
title=
{
DELIVERY_ADDRESS_TITLE_MAP
[
asType
]
}
name=
"deliveryAddress"
component=
{
CustomAddressSelect
}
onChange=
{
handleDeliveryAddressChange
}
rules=
{
[
{
required
:
true
,
message
:
`${intl.formatMessage({ id: 'afterService.components.ReturnAddressInfo.shippingAddress.placeholder' }, { default: '请选择' })}${DELIVERY_ADDRESS_TITLE_MAP[asType]}`
,
},
]
}
addressType=
{
2
}
isDefaultAddress
/>
)
:
(
<
FormItem
type=
"string"
title=
{
DELIVERY_ADDRESS_TITLE_MAP
[
asType
]
}
name=
"deliveryAddress"
valueName=
"data"
component=
{
AddressInfo
}
/>
)
}
</
Col
>
);
// 这里不能直接调用 Form 的 submit,因为还没有返回值
// 所以只能手动 监听onChang,并内部维护表单状态
useImperativeHandle
(
ref
,
()
=>
({
submit
:
()
=>
handleSubmit
(),
}));
return
(
<
div
className=
{
styles
[
'as-address-card'
]
}
>
<
MellowCard
title=
{
CARD_TITLE_MAP
[
asType
]
}
bodyStyle=
{
{
paddingBottom
:
0
,
}
}
>
<
Form
value=
{
{
deliveryType
:
deliveryType
,
deliveryAddress
,
shippingAddress
,
}
}
actions=
{
formActions
}
effects=
{
(
$
,
actions
:
ISchemaFormActions
)
=>
{
const
{
setFieldState
}
=
actions
;
onFieldValueChange$
(
'deliveryType'
).
subscribe
((
fieldState
)
=>
{
const
{
value
}
=
fieldState
;
switch
(
value
)
{
// 物流
case
DELIVERY_TYPE_EXPRESS
:
{
setFieldState
(
'*(deliveryAddress,shippingAddress)'
,
(
state
)
=>
{
state
.
visible
=
true
;
});
setFieldState
(
'deliveryAddress'
,
(
state
)
=>
{
state
.
props
.
title
=
DELIVERY_ADDRESS_TITLE_MAP
[
asType
];
});
break
;
};
// 自提
case
DELIVERY_TYPE_SELF_LIFTING
:
{
setFieldState
(
'*(deliveryAddress,shippingAddress)'
,
(
state
)
=>
{
state
.
visible
=
true
;
});
setFieldState
(
'deliveryAddress'
,
(
state
)
=>
{
state
.
props
.
title
=
SELF_LIFTING_TITLE_MAP
[
asType
];
});
break
;
};
// 无需物流
case
DELIVERY_TYPE_NO_DISTRIBUTION
:
{
setFieldState
(
'*(deliveryAddress,shippingAddress)'
,
(
state
)
=>
{
state
.
visible
=
false
;
});
break
;
};
default
:
break
};
});
}
}
labelAlign=
"left"
labelCol=
{
6
}
wrapperCol=
{
18
}
previewPlaceholder=
" "
editable=
{
ediabled
}
colon=
{
false
}
>
<
Row
gutter=
{
128
}
>
{
asType
!==
4
&&
(
<
Col
span=
{
12
}
>
<
FormItem
type=
"string"
title=
{
intl
.
formatMessage
({
id
:
'afterService.components.ReturnAddressInfo.deliveryType'
},
{
default
:
'配送方式'
})
}
name=
"deliveryType"
dataSource=
{
DELIVERY_TYPE_ENUM
}
component=
{
Radio
.
Group
}
optionType=
"button"
onChange=
{
handleDeliveryTypeChange
}
rules=
{
[
{
required
:
true
,
message
:
intl
.
formatMessage
({
id
:
'afterService.components.ExchangeAddressInfo.deliveryType.required'
},
{
default
:
'请选择配送方式'
}),
},
]
}
editable=
{
ediabled
&&
asType
===
2
}
/>
</
Col
>
)
}
{
ediabled
?
renderDeliveryBlock
()
:
(<
Col
span=
{
12
}
/>)
}
{
asType
!==
4
&&
(
<
Col
span=
{
12
}
>
{
ediabled
&&
asType
===
3
?
(
<
FormItem
type=
"string"
title=
{
SHIPPIND_ADDRESS_TITLE_MAP
[
asType
]
}
name=
"shippingAddress"
component=
{
CustomAddressSelect
}
onChange=
{
handleShippingAddressChange
}
rules=
{
[
{
required
:
true
,
message
:
`${intl.formatMessage({ id: 'afterService.components.ReturnAddressInfo.shippingAddress.placeholder' }, { default: '请选择' })}${SHIPPIND_ADDRESS_TITLE_MAP[asType]}`
,
},
]
}
addressType=
{
1
}
isDefaultAddress
/>
)
:
(
<
FormItem
type=
"string"
title=
{
SHIPPIND_ADDRESS_TITLE_MAP
[
asType
]
}
name=
"shippingAddress"
valueName=
"data"
component=
{
AddressInfo
}
/>
)
}
</
Col
>
)
}
{
!
ediabled
?
renderDeliveryBlock
()
:
null
}
</
Row
>
</
Form
>
</
MellowCard
>
</
div
>
);
};
const
AsAddressCardPropsForWard
=
React
.
forwardRef
<
AsAddressRefHandle
,
AsAddressCardProps
>
(
AsAddressCardProps
);
export
default
AsAddressCardPropsForWard
;
\ No newline at end of file
src/pages/afterService/components/AsAddressCard/reducer.ts
0 → 100644
View file @
8a6f7658
import
{
Reducer
}
from
'react'
;
export
type
AsAddressType
=
{
/**
* 地址id
*/
id
:
number
,
/**
* 姓名
*/
name
:
string
,
/**
* 联系电话
*/
phone
:
string
,
/**
* 详细地址
*/
detailed
:
string
,
}
export
type
AsAddressValue
=
{
/**
* 配送方式
*/
deliveryType
:
number
,
/**
* 发货地址
*/
deliveryAddress
:
AsAddressType
|
null
,
/**
* 收货地址
*/
shippingAddress
:
AsAddressType
|
null
,
}
export
const
initialState
:
AsAddressValue
=
{
deliveryType
:
undefined
,
deliveryAddress
:
null
,
shippingAddress
:
null
,
}
type
ReducerActionType
=
{
/**
* 类型
*/
type
:
string
,
/**
* 额外的参数
*/
payload
:
Partial
<
AsAddressValue
>
,
}
export
const
reducer
:
Reducer
<
AsAddressValue
,
ReducerActionType
>
=
(
state
:
AsAddressValue
,
action
:
ReducerActionType
)
=>
{
switch
(
action
.
type
)
{
case
'setAsAddress'
:
return
{
...
state
,
...
action
.
payload
};
default
:
throw
new
Error
();
}
}
src/pages/afterService/utils.ts
View file @
8a6f7658
...
...
@@ -20,4 +20,16 @@ export const isMaterialOrder = (orderType: number) => {
||
orderType
===
ORDER_TYPE_TENDER_CONTRACT
||
orderType
===
ORDER_TYPE_REQUISITION
)
};
\ No newline at end of file
};
/**
* 售后类型
* 售后换货:2 售后退货: 3 售后维修:4
*/
export
type
AsType
=
2
|
3
|
4
;
/**
* 售后地址角色
* 寄件人 'sender' 收件人 'receiver'
*/
export
type
AsAddressRole
=
'sender'
|
'receiver'
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment