Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
merchant-manage-ui
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
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
ui
merchant-manage-ui
Commits
cd6b961e
Commit
cd6b961e
authored
Oct 28, 2022
by
李腾
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 完善售后取消订单逻辑
parent
7534953c
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
562 additions
and
105 deletions
+562
-105
index.jsx
src/components/FormSearch/index.jsx
+21
-5
index.jsx
src/components/MessageReminder/Complex/index.jsx
+45
-19
index.jsx
src/components/MessageReminder/Simple/index.jsx
+2
-2
index.less
src/components/MessageReminder/Simple/index.less
+1
-0
BasicLayout.jsx
src/layouts/BasicLayout.jsx
+16
-16
CancelAuditModal.jsx
src/pages/AfterSaleManage/components/CancelAuditModal.jsx
+113
-0
CancelDetailTable.jsx
src/pages/AfterSaleManage/components/CancelDetailTable.jsx
+35
-0
CancelRejectModal.jsx
src/pages/AfterSaleManage/components/CancelRejectModal.jsx
+61
-0
data.js
src/pages/AfterSaleManage/data.js
+58
-17
index.jsx
src/pages/AfterSaleManage/index.jsx
+76
-11
services.js
src/pages/AfterSaleManage/services.js
+23
-1
index.jsx
src/pages/orderManage/pendingDeliveryOrder/index.jsx
+89
-20
index.less
src/pages/orderManage/pendingDeliveryOrder/index.less
+6
-0
websocket.js
src/utils/websocket.js
+16
-14
No files found.
src/components/FormSearch/index.jsx
View file @
cd6b961e
import
React
from
'
react
'
;
import
React
,
{
useState
}
from
'
react
'
;
import
{
Form
,
Input
,
Select
,
DatePicker
,
Button
,
Space
}
from
'
antd
'
;
import
{
moment
,
Moment
}
from
'
moment
'
;
import
moment
from
'
moment
'
;
import
style
from
'
./index.less
'
;
const
{
Option
}
=
Select
;
...
...
@@ -82,11 +82,27 @@ const FormSearch = props => {
// 选择日期范围类型
const
FormItemRangePicker
=
config
=>
{
const
{
originOptions
=
{}
}
=
config
;
const
{
originOptions
=
{}
,
bindKey
,
rangeNum
,
rangeUnit
}
=
config
;
const
attrs
=
{
placeholder
:
[
'
开始日期
'
,
'
结束日期
'
],
...
originOptions
};
// 自动截取日期限制的范围
const
onOpenChange
=
open
=>
{
if
(
!
open
)
{
const
[
date1
,
date2
]
=
form
.
getFieldValue
(
bindKey
);
const
diffNum
=
date2
.
diff
(
date1
,
'
months
'
);
if
(
diffNum
>=
3
)
{
setTimeout
(()
=>
{
form
.
setFieldsValue
({
[
bindKey
]:
[
moment
(
date1
),
moment
(
date1
).
add
(
3
,
'
month
'
)],
});
});
}
}
};
return
(
<
FormItemBox
{
...
config
}
>
<
RangePicker
className=
{
style
[
'
form-item-tag
'
]
}
{
...
attrs
}
/>
<
RangePicker
className=
{
style
[
'
form-item-tag
'
]
}
onOpenChange=
{
onOpenChange
}
{
...
attrs
}
/>
</
FormItemBox
>
);
};
...
...
@@ -107,7 +123,7 @@ const FormSearch = props => {
// 输入框类型
const
FormItemInput
=
config
=>
{
const
{
originOptions
=
{}
}
=
config
;
const
attrs
=
{
placeholder
:
'
请输入
'
,
...
originOptions
};
const
attrs
=
{
placeholder
:
'
请输入
'
,
allowClear
:
true
,
...
originOptions
};
return
(
<
FormItemBox
{
...
config
}
>
<
Input
className=
{
style
[
'
form-item-tag
'
]
}
{
...
attrs
}
/>
...
...
src/components/MessageReminder/Complex/index.jsx
View file @
cd6b961e
import
React
,
{
useState
,
useEffect
,
forwardRef
,
useImperativeHandle
}
from
'
react
'
;
import
{
useHistory
}
from
'
react-router-dom
'
;
import
{
Modal
,
Tabs
,
Pagination
,
Spin
,
notification
,
Checkbox
,
Badge
}
from
'
antd
'
;
import
{
apiGetBussinessMsgList
,
apiGetBusinessMsgUnReadCount
}
from
'
@/services/messageReminder
'
;
import
{
connect
}
from
'
dva
'
;
...
...
@@ -16,7 +17,7 @@ const INIT_QUERY_PARAMS = {
};
const
MessageItem
=
props
=>
{
const
{
item
,
onMark
}
=
props
;
const
{
item
,
onMark
,
viewDetail
}
=
props
;
/**
* type: 0订单消息,1售后消息
* readStatus: 0未读,1已读
...
...
@@ -28,11 +29,18 @@ const MessageItem = props => {
}
catch
(
e
)
{
console
.
error
(
'
消息数据格式错误
'
);
}
const
goodList
=
message
.
items
.
map
(
good
=>
(
<
div
className=
{
styles
.
good
}
>
<
span
className=
{
styles
.
good__name
}
>
{
good
.
skuName
}
</
span
>
<
span
className=
{
styles
.
good__count
}
>
x
{
good
.
quantity
}
</
span
>
</
div
>
));
return
(
<
div
className=
{
styles
[
'
complex-list__item
'
]
}
>
<
div
className=
{
styles
[
'
complex-list__item--header
'
]
}
>
<
span
className=
{
styles
[
'
order-number
'
]
}
>
订单编号:
{
message
.
orderNo
}
</
span
>
<
span
className=
{
styles
.
time
}
>
订单时间:
{
message
.
createdAt
}
</
span
>
<
span
className=
{
styles
.
time
}
>
订单时间:
{
message
.
time
}
</
span
>
{
readStatus
===
0
?
(
<
a
className=
{
styles
[
'
read-status
'
]
}
onClick=
{
()
=>
onMark
([
item
.
id
])
}
>
标记为已读
...
...
@@ -41,15 +49,12 @@ const MessageItem = props => {
<
span
className=
{
styles
[
'
read-status--read
'
]
}
>
已读
</
span
>
)
}
</
div
>
<
div
className=
{
styles
[
'
complex-list__item--body
'
]
}
>
<
div
className=
{
styles
.
good
}
>
<
span
className=
{
styles
.
good__name
}
>
商品名称商品名称商品名称商品名称
</
span
>
<
span
className=
{
styles
.
good__count
}
>
x10
</
span
>
</
div
>
</
div
>
<
div
className=
{
styles
[
'
complex-list__item--body
'
]
}
>
{
goodList
}
</
div
>
<
div
className=
{
styles
[
'
complex-list__item--footer
'
]
}
>
<
div
className=
{
styles
.
actions
}
>
<
a
className=
{
styles
.
notice
}
>
新的xxx订单,请查看
</
a
>
<
a
onClick=
{
()
=>
viewDetail
(
message
)
}
className=
{
styles
.
notice
}
>
{
message
.
title
}
,请查看
</
a
>
</
div
>
</
div
>
</
div
>
...
...
@@ -58,6 +63,7 @@ const MessageItem = props => {
const
Complex
=
props
=>
{
const
{
dispatch
,
refInstance
}
=
props
;
const
history
=
useHistory
();
const
[
visible
,
setVisible
]
=
useState
(
false
);
const
[
dataTotal
,
setDataTotal
]
=
useState
(
10
);
const
[
loading
,
setLoading
]
=
useState
(
false
);
...
...
@@ -133,6 +139,33 @@ const Complex = props => {
});
};
const
open
=
()
=>
{
setVisible
(
true
);
getMsgReadCount
();
};
const
close
=
()
=>
{
setVisible
(
false
);
};
// 跳转到详情
const
viewDetail
=
message
=>
{
console
.
log
(
message
);
const
{
orderNo
}
=
message
;
// 待发货
history
.
push
({
pathname
:
'
/orderManage/pendingDeliveryOrder
'
,
query
:
{
orderNo
},
});
// 已发货
// /orderManage/deliveryOrder
// 售后
close
();
};
// 切换消息类型
const
onTabChange
=
index
=>
{
setQueryParams
({
...
...
@@ -161,15 +194,6 @@ const Complex = props => {
});
};
const
open
=
()
=>
{
setVisible
(
true
);
getMsgReadCount
();
};
const
close
=
()
=>
{
setVisible
(
false
);
};
// 展开初始化
useEffect
(()
=>
{
if
(
visible
)
{
...
...
@@ -261,7 +285,9 @@ const Complex = props => {
<
FilterRender
/>
<
div
className=
{
styles
[
'
complex-list
'
]
}
>
{
messageData
.
length
?
(
messageData
.
map
(
item
=>
<
MessageItem
key=
{
item
.
id
}
item=
{
item
}
onMark=
{
onMark
}
/>)
messageData
.
map
(
item
=>
(
<
MessageItem
key=
{
item
.
id
}
item=
{
item
}
onMark=
{
onMark
}
viewDetail=
{
viewDetail
}
/>
))
)
:
(
<
Empty
text=
"暂无数据"
/>
)
}
...
...
src/components/MessageReminder/Simple/index.jsx
View file @
cd6b961e
...
...
@@ -31,6 +31,7 @@ const Message = props => {
}
catch
(
e
)
{
console
.
error
(
'
消息数据格式错误
'
);
}
return
(
<
div
className=
{
styles
.
item
}
>
<
div
className=
{
styles
.
info
}
>
...
...
@@ -43,7 +44,7 @@ const Message = props => {
<
span
>
{
message
.
createdAt
}
</
span
>
</
div
>
<
div
className=
{
styles
.
notice
}
>
<
a
>
您有新的xxxxx订单
,请查看
</
a
>
<
a
>
{
message
.
title
}
,请查看
</
a
>
</
div
>
</
div
>
);
...
...
@@ -125,7 +126,6 @@ const Simple = props => {
notification
.
error
(
res
.
msg
);
return
;
}
console
.
log
(
res
);
const
{
content
}
=
res
.
data
;
setVisible
(
!!
content
.
length
);
dispatch
({
...
...
src/components/MessageReminder/Simple/index.less
View file @
cd6b961e
...
...
@@ -2,6 +2,7 @@
position: fixed;
right: 30px;
bottom: 10px;
z-index: 19;
// width: 112px;
// height: 50px;
color: #fff;
...
...
src/layouts/BasicLayout.jsx
View file @
cd6b961e
...
...
@@ -53,28 +53,28 @@ const BasicLayout = props => {
const
[
siderCollapsed
,
setSiderCollapsed
]
=
useState
(
false
);
const
messageReminderComplexRef
=
useRef
();
/**
* constructor
*/
// const audioRef = useRef()
useEffect
(()
=>
{
const
token
=
window
.
localStorage
.
getItem
(
'
token
'
);
const
channelId
=
100001
;
const
socket
=
new
Socket
({
url
:
getSocketUrl
({
token
,
channelId
}),
});
socket
.
connection
();
const
token
=
window
.
localStorage
.
getItem
(
'
token
'
);
const
channelId
=
100001
;
const
socket
=
new
Socket
({
url
:
getSocketUrl
({
token
,
channelId
}),
});
socket
.
connection
();
socket
.
event
.
on
(
'
open
'
,
()
=>
{
console
.
log
(
'
连接成功3
'
);
});
socket
.
event
.
on
(
'
open
'
,
()
=>
{
console
.
log
(
'
连接成功3
'
);
});
useEffect
(()
=>
{
socket
.
event
.
on
(
'
message
'
,
msg
=>
{
console
.
log
(
msg
);
// audioRef.current.click()
dispatch
({
type
:
'
messageReminder/setUnReadData
'
,
payload
:
[
JSON
.
parse
(
msg
.
data
)],
});
// socket.play()
});
// let a = 100000000000;
// setInterval(() => {
...
...
@@ -85,7 +85,7 @@ const BasicLayout = props => {
// channelId: 100001,
// bussinessId: 'self_40',
// type: 0,
// sendContent: `{"name":"商品21111", "orderNo":${a},"createdAt":"2022-10-13 12:12:12", "count":11}`,
// sendContent: `{"name":"商品21111",
"title":"商品21111",
"orderNo":${a},"createdAt":"2022-10-13 12:12:12", "count":11}`,
// readStatus: 0,
// createdAt: '2022-10-18 14:05:12',
// updatedAt: '2022-10-18 17:15:19',
...
...
@@ -226,7 +226,7 @@ const BasicLayout = props => {
<
MessageReminder
.
Simple
complexRef=
{
messageReminderComplexRef
}
/>
<
MessageReminder
.
Complex
ref=
{
messageReminderComplexRef
}
/>
{
/* <
audio id="myaudio" src="https://img.lkbang.net/10544.b57be67d.mp3" loop="loop" preload="preload" muted="muted" /
> */
}
{
/* <
Button ref={audioRef} onClick={() => { socket.play() }}>声音</Button
> */
}
</
ProLayout
>
);
};
...
...
src/pages/AfterSaleManage/components/CancelAuditModal.jsx
0 → 100644
View file @
cd6b961e
import
React
from
'
react
'
;
import
{
Form
}
from
'
@ant-design/compatible
'
;
import
'
@ant-design/compatible/assets/index.css
'
;
import
{
Modal
,
Input
,
Cascader
,
notification
}
from
'
antd
'
;
import
{
cancelShopAudit
}
from
'
../services
'
;
const
FormItem
=
Form
.
Item
;
const
{
TextArea
}
=
Input
;
const
AuditModal
=
props
=>
{
const
{
visible
,
onCancel
,
form
:
{
getFieldDecorator
,
getFieldValue
,
validateFields
,
resetFields
},
formData
=
{},
}
=
props
;
const
handleCancel
=
isSuccess
=>
{
resetFields
();
onCancel
(
isSuccess
);
};
const
treeData
=
[
{
label
:
'
同意
'
,
value
:
true
,
},
{
label
:
'
不同意
'
,
value
:
false
,
children
:
[
{
label
:
'
订单已发货
'
,
value
:
10
,
},
{
label
:
'
已与客户沟通继续发货
'
,
value
:
20
,
},
{
label
:
'
其他
'
,
value
:
30
,
},
],
},
];
const
handleOk
=
()
=>
{
validateFields
(
async
(
error
,
fieldsValue
)
=>
{
if
(
!
error
)
{
const
{
approve
}
=
fieldsValue
;
const
data
=
await
cancelShopAudit
({
...
fieldsValue
,
refuseReasonCode
:
approve
?.[
1
],
approve
:
approve
?.[
0
],
serviceNo
:
formData
?.
serviceNo
,
});
if
(
data
.
businessCode
===
'
0000
'
)
{
notification
.
success
({
message
:
approve
?.[
0
]
?
'
审核成功
'
:
'
审核拒绝提交成功
'
});
handleCancel
(
true
);
}
}
});
};
const
layout
=
{
labelCol
:
{
span
:
6
},
wrapperCol
:
{
span
:
16
},
};
const
approve
=
getFieldValue
(
'
approve
'
);
const
isRefuse
=
()
=>
approve
&&
approve
[
0
]
!==
1
;
return
(
<
Modal
title=
"售后操作确认"
visible=
{
visible
}
onOk=
{
()
=>
handleOk
()
}
onCancel=
{
()
=>
handleCancel
()
}
>
<
Form
{
...
layout
}
name=
"formData"
>
<
FormItem
label=
"审核结果"
>
{
getFieldDecorator
(
'
approve
'
)(
<
Cascader
allowClear
showSearch
style=
{
{
width
:
'
315px
'
}
}
dropdownStyle=
{
{
maxHeight
:
400
,
overflow
:
'
auto
'
}
}
options=
{
treeData
}
placeholder=
"请选择"
/>,
)
}
</
FormItem
>
{
isRefuse
()
&&
approve
[
1
]
===
30
&&
(
<
FormItem
label=
"拒绝原因"
>
{
getFieldDecorator
(
'
refuseReasonRemark
'
,
{
initialValue
:
formData
.
refuseDesc
,
rules
:
[
{
required
:
true
,
message
:
'
请填写拒绝原因!
'
,
},
],
})(
<
TextArea
placeholder=
"请填写拒绝原因"
allowClear
autoSize=
{
{
minRows
:
3
,
maxRows
:
6
}
}
/>,
)
}
</
FormItem
>
)
}
</
Form
>
</
Modal
>
);
};
export
default
Form
.
create
()(
AuditModal
);
src/pages/AfterSaleManage/components/CancelDetailTable.jsx
0 → 100644
View file @
cd6b961e
import
React
from
'
react
'
;
import
{
Modal
,
Table
}
from
'
antd
'
;
export
default
props
=>
{
const
{
visible
,
onCancel
,
dataSource
}
=
props
;
const
handleCancel
=
()
=>
{
onCancel
();
};
const
columns
=
[
{
title
:
'
商品名称
'
,
width
:
400
,
dataIndex
:
'
skuName
'
,
},
{
title
:
'
商品属性
'
,
dataIndex
:
'
skuAttr
'
,
},
{
title
:
'
商品件数
'
,
dataIndex
:
'
count
'
,
},
];
return
(
<
Modal
title=
"订单详情"
visible=
{
visible
}
onCancel=
{
handleCancel
}
footer=
{
null
}
width=
{
800
}
>
<
Table
dataSource=
{
dataSource
}
columns=
{
columns
}
key=
{
r
=>
r
.
orderId
}
pagination=
{
false
}
bordered
/>
</
Modal
>
);
};
src/pages/AfterSaleManage/components/CancelRejectModal.jsx
0 → 100644
View file @
cd6b961e
import
React
from
'
react
'
;
import
{
Form
}
from
'
@ant-design/compatible
'
;
import
'
@ant-design/compatible/assets/index.css
'
;
import
{
Modal
,
Input
,
notification
}
from
'
antd
'
;
import
{
shopCheck
}
from
'
../service
'
;
const
FormItem
=
Form
.
Item
;
const
{
TextArea
}
=
Input
;
const
RejectModal
=
props
=>
{
const
{
visible
,
onCancel
,
form
:
{
getFieldDecorator
,
validateFields
,
resetFields
},
serviceNo
=
null
,
}
=
props
;
const
handleCancel
=
isSuccess
=>
{
resetFields
();
onCancel
(
isSuccess
);
};
const
handleOk
=
()
=>
{
validateFields
(
async
(
error
,
fieldsValue
)
=>
{
if
(
!
error
)
{
const
data
=
await
shopCheck
({
...
fieldsValue
,
serviceNo
,
auditResult
:
2
,
});
if
(
data
.
code
===
'
0000
'
)
{
notification
.
success
({
message
:
'
操作成功
'
});
handleCancel
(
true
);
}
}
});
};
const
layout
=
{
labelCol
:
{
span
:
6
},
wrapperCol
:
{
span
:
16
},
};
return
(
<
Modal
title=
"驳回"
visible=
{
visible
}
onOk=
{
()
=>
handleOk
()
}
onCancel=
{
()
=>
handleCancel
()
}
>
<
Form
{
...
layout
}
name=
"formData"
>
<
FormItem
label=
"原因"
>
{
getFieldDecorator
(
'
refuseReasonRemark
'
,
{
rules
:
[
{
required
:
true
,
message
:
'
请填写原因!
'
,
},
],
})(
<
TextArea
placeholder=
"请填写原因"
allowClear
autoSize=
{
{
minRows
:
3
,
maxRows
:
6
}
}
/>,
)
}
</
FormItem
>
</
Form
>
</
Modal
>
);
};
export
default
Form
.
create
()(
RejectModal
);
src/pages/AfterSaleManage/data.js
View file @
cd6b961e
...
...
@@ -130,16 +130,14 @@ export const getFormConfig = (props = {}) => {
bindKey
:
'
receiverPhone
'
,
},
{
type
:
SEARCH_TYPE
.
DAT
E_PICKER
,
label
:
'
订单开始
日期
'
,
type
:
SEARCH_TYPE
.
RANG
E_PICKER
,
label
:
'
售后
日期
'
,
column
:
5
,
bindKey
:
'
startDate
'
,
},
{
type
:
SEARCH_TYPE
.
DATE_PICKER
,
label
:
'
订单结束日期
'
,
column
:
5
,
bindKey
:
'
endDate
'
,
bindKey
:
'
afterTime
'
,
originOptions
:
{
placeholder
:
[
'
开始日期
'
,
'
结束日期
'
],
allowClear
:
false
,
},
},
],
btnConfig
:
[
...
...
@@ -152,9 +150,10 @@ export const getFormConfig = (props = {}) => {
actionRef
.
current
.
reload
();
return
;
}
setTableParams
(
params
);
const
{
type
,
dealStatus
}
=
params
;
let
hasMatchingKey
=
''
;
console
.
log
(
111111
,
params
);
Object
.
keys
(
TAB_MAPPING_DATA
).
forEach
(
key
=>
{
const
item
=
TAB_MAPPING_DATA
[
key
];
if
(
type
===
item
.
type
&&
dealStatus
===
item
.
dealStatus
)
{
...
...
@@ -162,14 +161,17 @@ export const getFormConfig = (props = {}) => {
}
});
setCurrentTab
(
hasMatchingKey
);
setTableParams
(
params
);
},
},
{
label
:
'
重置
'
,
type
:
''
,
clickType
:
'
reset
'
,
onClick
:
()
=>
{
setTableParams
({});
onClick
:
({
params
})
=>
{
// setTableParams({});
actionRef
.
current
.
reload
();
setCurrentTab
(
''
);
},
},
],
...
...
@@ -193,6 +195,8 @@ export const getColumns = props => {
refund
,
reject
,
canEditable
,
openCancelAudit
,
viewCancelDetail
,
}
=
props
;
return
[
{
...
...
@@ -222,10 +226,18 @@ export const getColumns = props => {
title
:
'
售后类型
'
,
dataIndex
:
'
serviceType
'
,
hideInSearch
:
true
,
width
:
1
2
0
,
width
:
1
4
0
,
render
:
serviceType
=>
{
if
(
+
serviceType
===
0
)
{
return
<
span
style
=
{{
color
:
'
#ff1616
'
}}
>
仅退款
(
未发货
)
<
/span>
;
}
if
(
+
serviceType
===
1
)
{
return
<
span
style
=
{{
color
:
'
#ff1616
'
}}
>
仅退款
<
/span>
;
return
(
<
span
style
=
{{
color
:
'
#ff1616
'
}}
>
{
/* {AFTER_TYPE.find(item=> item.value === serviceType)} */
}
仅退款
<
/span
>
);
}
return
<
span
>
退货退款
<
/span>
;
},
...
...
@@ -386,10 +398,11 @@ export const getColumns = props => {
key
:
'
pop
'
,
};
/** @name applyTpye=1 */
// 允许退款/已退款按钮
const
refundBtn
=
(
<
Popconfirm
{...
refundBtnProps
}
onConfirm
=
{()
=>
refund
(
record
)}
disabled
=
{
!
showRefund
}
>
<
Button
key
=
"
link1
"
disabled
=
{
!
showRefund
}
>
<
Button
key
=
"
link1
"
{...
btnProps
}
disabled
=
{
!
showRefund
}
>
{
showRefunded
?
'
已退款
'
:
'
允许退款
'
}
<
/Button
>
<
/Popconfirm
>
...
...
@@ -400,6 +413,7 @@ export const getColumns = props => {
审核
<
/Button
>
);
// 驳回按钮
let
refuseBtn
=
(
<
Button
key
=
"
link3
"
onClick
=
{()
=>
reject
(
record
)}
{...
btnProps
}
disabled
=
{
!
showRefuse
}
>
...
...
@@ -445,14 +459,28 @@ export const getColumns = props => {
<
/Button
>
);
const
cancelAuditBtn
=
(
<
Button
key
=
"
cancellink1
"
onClick
=
{()
=>
openCancelAudit
(
record
)}
{...
btnProps
}
>
审核
<
/Button
>
);
const
cancelDetailBtn
=
(
<
Button
key
=
"
cancellink2
"
onClick
=
{()
=>
viewCancelDetail
(
record
)}
{...
btnProps
}
>
订单详情
<
/Button
>
);
/** @name applyTpye=2 */
if
(
!
canEditable
)
{
auditBtn
=
''
;
refuseBtn
=
''
;
logisticsInterceptionBtn
=
''
;
}
// 服务商品
|| 实物商品-仅退款未发货 serviceType = 0
if
(
isServiceGoods
||
serviceType
===
0
)
{
// 服务商品
if
(
isServiceGoods
)
{
// 待商户审核14
if
([
14
].
includes
(
status
))
{
return
[
auditBtn
,
detailBtn
,
viewLogBtn
];
...
...
@@ -464,6 +492,19 @@ export const getColumns = props => {
}
}
// 实物商品-仅退款未发货 serviceType = 0
if
(
serviceType
===
0
)
{
// 待商户审核14 待审核0
if
([
14
,
0
].
includes
(
status
))
{
return
[
cancelAuditBtn
,
cancelDetailBtn
,
viewLogBtn
];
}
// 拒绝16, 处理成功70
if
([
16
,
70
].
includes
(
status
))
{
return
[
cancelDetailBtn
,
viewLogBtn
];
}
}
// 实物商品-仅退款 serviceType = 1
if
(
serviceType
===
1
)
{
// 待商户审核14
...
...
src/pages/AfterSaleManage/index.jsx
View file @
cd6b961e
...
...
@@ -13,6 +13,8 @@ import AppealDetail from '@/pages/afterSale/components/detail';
import
AfterLog
from
'
./components/AfterLog
'
;
import
RejectModal
from
'
./components/rejectModal
'
;
import
LogisticsCom
from
'
../orderManage/pendingDeliveryOrder/components/LogisticsCom
'
;
import
CancelAuditModal
from
'
./components/CancelAuditModal
'
;
import
CancelDetailTable
from
'
./components/CancelDetailTable
'
;
import
{
getColumns
,
getFormConfig
,
TAB_MAPPING_DATA
}
from
'
./data.js
'
;
import
{
getDetail
}
from
'
@/pages/afterSale/appeal/services
'
;
...
...
@@ -25,6 +27,7 @@ import {
trackInfo
,
shopCheck
,
getAfterPendingNum
,
cancelOrderDetail
,
}
from
'
./services
'
;
import
styles
from
'
./index.less
'
;
...
...
@@ -41,7 +44,13 @@ const AfterSale = props => {
const
[
currentTab
,
setCurrentTab
]
=
useState
(
''
);
const
[
appealDetailModal
,
setAppealDetailModal
]
=
useState
(
false
);
const
[
selectedRow
,
setSelectedRow
]
=
useState
({});
const
[
tabInfoData
,
setTabInfoData
]
=
useState
({});
const
[
tabInfoData
,
setTabInfoData
]
=
useState
({
cancelOrderPendingAuditNum
:
0
,
refundPendingAuditNum
:
0
,
returnPendingAuditNum
:
0
,
returnWaitAuditNum
:
0
,
afterSalseDoneNum
:
0
,
});
// 申诉
const
[
proofsData
,
setProofsData
]
=
useState
([]);
const
[
proofsVisible
,
setProofsVisible
]
=
useState
(
false
);
...
...
@@ -65,6 +74,14 @@ const AfterSale = props => {
const
[
serviceNoInfo
,
setServiceNoInfo
]
=
useState
({});
const
[
rejectVisible
,
setRejectVisible
]
=
useState
(
false
);
// 取消订单审核
const
[
cancelVisible
,
setCancelVisible
]
=
useState
(
false
);
const
[
cancelAuditInfo
,
setCancelAuditInfo
]
=
useState
({});
// 取消订单审核详情
const
[
cancelDetailVisible
,
setCancelDetailVisible
]
=
useState
(
false
);
const
[
cancelDetailInfo
,
setCancelDetailInfo
]
=
useState
({});
// 关闭modal
const
closeModal
=
isReload
=>
{
if
(
isReload
===
true
)
{
...
...
@@ -77,6 +94,8 @@ const AfterSale = props => {
setAppealDetailModal
(
false
);
setAfterVisible
(
false
);
setLogisticsComModalVisible
(
false
);
setCancelVisible
(
false
);
setCancelDetailVisible
(
false
);
};
// 查看申诉详情
...
...
@@ -187,6 +206,20 @@ const AfterSale = props => {
setRejectVisible
(
true
);
};
// 取消订单审核
const
openCancelAudit
=
async
({
serviceNo
})
=>
{
// const data = await auditInfoApi({ serviceNo });
setCancelAuditInfo
({
serviceNo
});
setCancelVisible
(
true
);
};
// 取消订单审核详情
const
viewCancelDetail
=
async
({
serviceNo
})
=>
{
const
data
=
await
cancelOrderDetail
({
serviceNo
});
setCancelDetailInfo
(
data
||
[]);
setCancelDetailVisible
(
true
);
};
const
[
form
]
=
Form
.
useForm
();
const
formConfig
=
getFormConfig
({
actionRef
,
...
...
@@ -194,9 +227,13 @@ const AfterSale = props => {
setTableParams
,
setCurrentTab
,
});
const
afterTime
=
[
moment
().
subtract
(
3
,
'
month
'
),
moment
()];
const
FormSearchProps
=
{
form
,
initialValues
:
{},
initialValues
:
{
afterTime
,
},
formOptions
:
{},
...
formConfig
,
};
...
...
@@ -205,11 +242,16 @@ const AfterSale = props => {
const
tabChange
=
tabIndex
=>
{
setCurrentTab
(
tabIndex
);
const
{
type
,
dealStatus
}
=
TAB_MAPPING_DATA
[
tabIndex
];
form
.
resetFields
();
form
.
setFieldsValue
({
...
tableParams
,
dealStatus
,
type
,
});
setTableParams
({
...
tableParams
,
dealStatus
,
type
});
// setTimeout(() => {
// form.submit()
// }, 0)
};
const
columns
=
getColumns
({
...
...
@@ -223,6 +265,8 @@ const AfterSale = props => {
refund
,
reject
,
canEditable
,
openCancelAudit
,
viewCancelDetail
,
});
// 表格属性
...
...
@@ -233,11 +277,10 @@ const AfterSale = props => {
scroll
:
{
x
:
'
100%
'
,
y
:
500
},
rowKey
:
r
=>
r
.
serviceNo
,
request
:
async
params
=>
{
console
.
log
(
params
);
console
.
log
(
'
搜索
'
,
params
);
const
[
start
,
end
]
=
params
.
afterTime
||
afterTime
;
const
{
current
:
page
,
pageSize
:
size
}
=
params
;
const
startDate
=
params
.
startDate
?
moment
(
params
.
startDate
).
format
(
'
YYYY-MM-DD
'
)
:
''
;
const
endDate
=
params
.
endDate
?
moment
(
params
.
endDate
).
format
(
'
YYYY-MM-DD
'
)
:
''
;
const
startDate
=
start
?
moment
(
start
).
format
(
'
YYYY-MM-DD
'
)
:
''
;
const
endDate
=
end
?
moment
(
end
).
format
(
'
YYYY-MM-DD
'
)
:
''
;
const
requestParams
=
{
page
,
size
,
...
...
@@ -245,8 +288,20 @@ const AfterSale = props => {
startDate
,
endDate
,
};
delete
requestParams
.
afterTime
;
delete
requestParams
.
current
;
delete
requestParams
.
pageSize
;
const
countRes
=
await
getAfterPendingNum
({
startDate
,
endDate
,
});
const
res
=
await
searchList
(
requestParams
);
const
{
records
=
[],
total
}
=
res
.
data
;
console
.
log
(
countRes
);
if
(
countRes
.
code
===
'
0000
'
)
{
setTabInfoData
(
countRes
.
data
);
}
return
{
data
:
records
,
total
,
...
...
@@ -278,11 +333,14 @@ const AfterSale = props => {
tabBarStyle=
{
{
padding
:
'
0 30px
'
}
}
>
<
TabPane
key=
""
tab=
"全部"
></
TabPane
>
<
TabPane
key=
"1"
tab=
"仅退款(未发货)待审核0"
></
TabPane
>
<
TabPane
key=
"2"
tab=
"仅退款待审核8"
></
TabPane
>
<
TabPane
key=
"3"
tab=
"退货退款待审核0"
></
TabPane
>
<
TabPane
key=
"4"
tab=
"退货入库待审核0"
></
TabPane
>
<
TabPane
key=
"5"
tab=
"已完成0"
></
TabPane
>
<
TabPane
key=
"1"
tab=
{
`仅退款(未发货)待审核${tabInfoData.cancelOrderPendingAuditNum}`
}
></
TabPane
>
<
TabPane
key=
"2"
tab=
{
`仅退款待审核${tabInfoData.refundPendingAuditNum}`
}
></
TabPane
>
<
TabPane
key=
"3"
tab=
{
`退货退款待审核${tabInfoData.returnPendingAuditNum}`
}
></
TabPane
>
<
TabPane
key=
"4"
tab=
{
`退货入库待审核${tabInfoData.returnWaitAuditNum}`
}
></
TabPane
>
<
TabPane
key=
"5"
tab=
{
`已完成${tabInfoData.afterSalseDoneNum}`
}
></
TabPane
>
</
Tabs
>
</
div
>
<
ProTable
...
...
@@ -310,6 +368,13 @@ const AfterSale = props => {
></
AppealDetail
>
<
AfterLog
visible=
{
afterVisible
}
onCancel=
{
closeModal
}
data=
{
afterList
}
/>
<
RejectModal
visible=
{
rejectVisible
}
onCancel=
{
closeModal
}
serviceNo=
{
serviceNoInfo
}
/>
<
CancelAuditModal
visible=
{
cancelVisible
}
onCancel=
{
closeModal
}
formData=
{
cancelAuditInfo
}
/>
<
CancelDetailTable
visible=
{
cancelDetailVisible
}
onCancel=
{
closeModal
}
dataSource=
{
cancelDetailInfo
}
/>
</
PageHeaderWrapper
>
);
};
...
...
src/pages/AfterSaleManage/services.js
View file @
cd6b961e
...
...
@@ -9,7 +9,7 @@ const { kdspApi } = config;
export
const
searchList
=
params
=>
request
.
post
(
'
/api/kdsp/op/afs/shop/list
'
,
{
prefix
:
kdspApi
,
data
:
stringify
(
_
.
omitBy
(
params
,
v
=>
!
v
)),
data
:
stringify
(
_
.
omitBy
(
params
,
v
=>
!
v
&&
v
!==
0
)),
headers
:
{
'
Content-Type
'
:
'
application/x-www-form-urlencoded
'
,
},
...
...
@@ -51,6 +51,19 @@ export function orderDetail(params) {
},
});
}
// 取消售后单详情
export
async
function
cancelOrderDetail
(
params
)
{
const
data
=
await
request
.
get
(
'
/cancel-order/sku
'
,
{
prefix
:
kdspApi
,
params
,
headers
:
{
'
Content-Type
'
:
'
application/x-www-form-urlencoded
'
,
},
});
return
data
.
data
||
[];
}
// 售后审核
export
async
function
shopAudit
(
params
)
{
return
request
.
post
(
'
/api/kdsp/op/afs/shop/audit
'
,
{
...
...
@@ -58,6 +71,15 @@ export async function shopAudit(params) {
prefix
:
kdspApi
,
});
}
// 取消订单审核
export
async
function
cancelShopAudit
(
params
)
{
return
request
.
post
(
'
/cancel-order/audit
'
,
{
data
:
params
,
prefix
:
kdspApi
,
});
}
// 查询审核信息
export
async
function
auditInfoApi
(
params
)
{
return
request
.
get
(
'
/api/kdsp/op/afs/back-info
'
,
{
...
...
src/pages/orderManage/pendingDeliveryOrder/index.jsx
View file @
cd6b961e
import
{
Button
,
notification
,
Modal
,
Popover
}
from
'
antd
'
;
import
React
,
{
useState
,
useEffect
,
useRef
}
from
'
react
'
;
import
{
PageHeaderWrapper
}
from
'
@ant-design/pro-layout
'
;
import
{
useLocation
}
from
'
react-router-dom
'
;
import
ProTable
from
'
@ant-design/pro-table
'
;
import
{
FormInstance
}
from
'
antd/lib/form
'
;
import
moment
from
'
moment
'
;
...
...
@@ -23,8 +24,10 @@ import {
const
{
confirm
}
=
Modal
;
const
TableList
=
props
=>
{
const
location
=
useLocation
();
const
dateFormat
=
'
YYYY-MM-DD
'
;
const
{
permissions
}
=
props
;
// 因待发货 和 已发货都使用当前组件,功能且相同,所以只要授权其中一个均可获得发货物流权限
const
canEditable
=
permissions
[
PENDING_DELIVERY_ORDER
.
EDITABLE
]
||
permissions
[
DELIVERY_ORDER
.
EDITABLE
];
...
...
@@ -44,6 +47,7 @@ const TableList = props => {
const
[
endTime
,
setEndTime
]
=
useState
(
moment
());
const
[
orderStatus
,
setorderStatus
]
=
useState
(
1
);
const
[
orderNo
,
setOrderNo
]
=
useState
(
''
);
const
[
endTimeStr
,
setEndTimeStr
]
=
useState
(
moment
().
format
(
dateFormat
));
const
[
visibleDelay
,
setVisibleDelay
]
=
useState
(
false
);
...
...
@@ -133,6 +137,15 @@ const TableList = props => {
return
''
;
};
const
PopoverNotice
=
noticeProps
=>
{
const
{
time
,
content
}
=
noticeProps
;
return
(
<
div
className=
{
style
[
'
popover-notice
'
]
}
>
{
time
}
:
{
content
}
</
div
>
);
};
const
columns
=
[
{
title
:
'
订单ID
'
,
...
...
@@ -141,14 +154,32 @@ const TableList = props => {
order
:
6
,
width
:
250
,
fixed
:
'
left
'
,
render
:
(
_
,
record
)
=>
(
<>
{
_
}
<
Popover
placement=
"top"
title=
"催发货"
content=
{
<>
111
</>
}
trigger=
"click"
>
<
span
className=
{
style
.
urge
}
>
催
</
span
>
</
Popover
>
</>
),
formItemProps
:
{
value
:
orderNo
,
onChange
(
e
)
{
console
.
log
(
e
.
target
.
value
);
setOrderNo
(
e
.
target
.
value
);
},
},
render
:
(
_
,
record
)
=>
{
const
{
urgeDeliverGoodsList
}
=
record
;
const
content
=
()
=>
urgeDeliverGoodsList
?.
map
(
item
=>
(
<
PopoverNotice
time=
{
item
.
time
}
content=
{
item
.
content
}
/>
));
return
(
<>
{
_
}
{
urgeDeliverGoodsList
?
(
<
Popover
placement=
"top"
title=
"催发货"
content=
{
<>
{
content
()
}
</>
}
trigger=
"hover"
>
<
span
className=
{
style
.
urge
}
>
催
</
span
>
</
Popover
>
)
:
(
''
)
}
</>
);
},
},
{
title
:
'
订单提醒
'
,
...
...
@@ -156,19 +187,43 @@ const TableList = props => {
key
:
'
orderNotice
'
,
width
:
150
,
render
:
(
_
,
record
)
=>
{
const
{
address
}
=
record
;
const
{
updateAddressList
,
platformRemark
}
=
record
;
let
addressData
;
if
(
updateAddressList
)
{
addressData
=
updateAddressList
.
pop
();
}
return
(
<
div
className=
{
style
[
'
notice-btn
'
]
}
>
<
Popover
placement=
"top"
title=
"收货地址变更"
content=
{
<>
111
</>
}
trigger=
"click"
>
<
Button
block
type=
"primary"
>
收货地址变更
</
Button
>
</
Popover
>
<
Popover
placement=
"top"
title=
"平台备注"
content=
{
<>
222
</>
}
trigger=
"click"
>
<
Button
block
type=
"warning"
>
平台备注
</
Button
>
</
Popover
>
{
updateAddressList
?
(
<
Popover
placement=
"top"
title=
"收货地址变更"
content=
{
<
PopoverNotice
time=
{
addressData
.
time
}
content=
{
addressData
.
content
}
/>
}
trigger=
"hover"
>
<
Button
block
type=
"primary"
>
收货地址变更
</
Button
>
</
Popover
>
)
:
(
''
)
}
{
platformRemark
?
(
<
Popover
placement=
"top"
title=
"平台备注"
content=
{
<
PopoverNotice
time=
{
platformRemark
.
time
}
content=
{
platformRemark
.
content
}
/>
}
trigger=
"hover"
>
<
Button
block
type=
"warning"
>
平台备注
</
Button
>
</
Popover
>
)
:
(
''
)
}
</
div
>
);
},
...
...
@@ -187,7 +242,7 @@ const TableList = props => {
hideInTable
:
true
,
formItemProps
:
{
// eslint-disable-next-line no-nested-ternary
value
:
orderStatus
?
(
orderStatus
===
1
?
'
是
'
:
'
否
'
)
:
''
,
value
:
orderStatus
?
(
orderStatus
===
1
?
'
是
'
:
'
否
'
)
:
null
,
onChange
(
status
)
{
setorderStatus
(
Number
(
status
));
},
...
...
@@ -395,6 +450,19 @@ const TableList = props => {
}
},
[]);
// 监听路由query参数变化重新发起请求
useEffect
(()
=>
{
if
(
location
?.
query
)
{
const
{
orderNo
:
orderNumber
}
=
location
?.
query
;
setOrderNo
(
orderNumber
);
if
(
actionRef
.
current
)
{
actionRef
.
current
.
reload
();
}
}
else
{
setOrderNo
(
''
);
}
},
[
location
]);
const
queryToSendFn
=
params
=>
{
const
transformedParam
=
{
...
params
,
...
...
@@ -402,6 +470,7 @@ const TableList = props => {
pageNo
:
params
.
current
,
pageSize
:
params
.
pageSize
||
20
,
timeOutType
:
orderStatus
||
''
,
orderNo
,
};
return
queryToSend
(
transformedParam
);
};
...
...
src/pages/orderManage/pendingDeliveryOrder/index.less
View file @
cd6b961e
...
...
@@ -88,9 +88,15 @@
display: inline-block;
width: 20px;
height: 20px;
margin-left: 5px;
color: #fff;
line-height: 20px;
text-align: center;
background-color: red;
border-radius: 50%;
cursor: pointer;
}
.popover-notice {
max-width: 300px;
}
src/utils/websocket.js
View file @
cd6b961e
import
EventEmitter
from
'
events
'
;
import
{
Modal
}
from
'
antd
'
;
class
Socket
extends
EventEmitter
{
event
=
new
EventEmitter
();
...
...
@@ -11,7 +12,7 @@ class Socket extends EventEmitter {
this
.
taskRemindInterval
=
null
;
this
.
connected
=
false
;
this
.
waitingSendData
=
[];
this
.
reconnectCount
=
0
;
return
this
;
}
...
...
@@ -73,20 +74,21 @@ class Socket extends EventEmitter {
// 根据后端返回的状态码做操作
// 我的项目是当前页面打开两个或者以上,就把当前以打开的socket关闭
// 否则就20秒重连一次,直到重连成功为止
if
(
e
.
code
===
'
4500
'
)
{
this
.
socket
.
close
();
}
else
{
const
reconnect
=
()
=>
{
clearTimeout
(
this
.
taskRemindInterval
);
this
.
taskRemindInterval
=
setTimeout
(()
=>
{
if
(
!
this
.
connected
)
{
this
.
connection
();
reconnect
();
}
},
5000
);
};
reconnect
();
if
(
this
.
reconnectCount
>
10
)
{
this
.
reconnectCount
=
0
;
return
;
}
const
reconnect
=
()
=>
{
clearTimeout
(
this
.
taskRemindInterval
);
this
.
taskRemindInterval
=
setTimeout
(()
=>
{
if
(
!
this
.
connected
)
{
this
.
reconnectCount
++
;
this
.
connection
();
reconnect
();
}
},
2000
);
};
reconnect
();
};
onerror
=
e
=>
{
...
...
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