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
7534953c
Commit
7534953c
authored
Oct 20, 2022
by
李腾
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 完成售后订单列表逻辑
parent
17b8b15c
Changes
29
Show whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
1684 additions
and
1091 deletions
+1684
-1091
config.js
config/config.js
+5
-5
index.jsx
src/components/MessageReminder/Complex/index.jsx
+254
-93
index.less
src/components/MessageReminder/Complex/index.less
+51
-12
index.jsx
src/components/MessageReminder/Simple/index.jsx
+31
-14
BasicLayout.jsx
src/layouts/BasicLayout.jsx
+21
-18
messageReminder.js
src/models/messageReminder.js
+9
-2
AfterLog.jsx
src/pages/AfterSaleManage/components/AfterLog.jsx
+1
-1
LogisticsRecordModal.jsx
...pages/AfterSaleManage/components/LogisticsRecordModal.jsx
+118
-0
auditModal.jsx
src/pages/AfterSaleManage/components/auditModal.jsx
+127
-118
proofsModal.jsx
src/pages/AfterSaleManage/components/proofsModal.jsx
+1
-1
data.js
src/pages/AfterSaleManage/data.js
+470
-150
index.jsx
src/pages/AfterSaleManage/index.jsx
+303
-14
index.less
src/pages/AfterSaleManage/index.less
+0
-0
services.js
src/pages/AfterSaleManage/services.js
+46
-23
data.js
src/pages/AfterSaleManageNew/data.js
+0
-377
index.jsx
src/pages/AfterSaleManageNew/index.jsx
+0
-220
index.jsx
src/pages/AfterSaleManageOld/PassAudit/index.jsx
+0
-0
index.jsx
src/pages/AfterSaleManageOld/Pending/index.jsx
+0
-0
AfterLog.jsx
src/pages/AfterSaleManageOld/components/AfterLog.jsx
+1
-1
auditModal.jsx
src/pages/AfterSaleManageOld/components/auditModal.jsx
+1
-1
detailTable.jsx
src/pages/AfterSaleManageOld/components/detailTable.jsx
+0
-0
proofsModal.jsx
src/pages/AfterSaleManageOld/components/proofsModal.jsx
+1
-1
rejectModal.jsx
src/pages/AfterSaleManageOld/components/rejectModal.jsx
+0
-0
data.js
src/pages/AfterSaleManageOld/data.js
+179
-0
index.jsx
src/pages/AfterSaleManageOld/index.jsx
+30
-0
services.js
src/pages/AfterSaleManageOld/services.js
+20
-29
styles.less
src/pages/AfterSaleManageOld/styles.less
+0
-0
messageReminder.js
src/services/messageReminder.js
+5
-4
websocket.js
src/utils/websocket.js
+10
-7
No files found.
config/config.js
View file @
7534953c
...
@@ -148,24 +148,24 @@ export default {
...
@@ -148,24 +148,24 @@ export default {
},
},
{
{
title
:
'
商户管理后台
'
,
title
:
'
商户管理后台
'
,
path
:
'
/afterSaleManage
New
'
,
path
:
'
/afterSaleManage
Old
'
,
name
:
'
afterSaleManage
New
'
,
name
:
'
afterSaleManage
Old
'
,
icon
:
'
smile
'
,
icon
:
'
smile
'
,
component
:
'
./AfterSaleManage
New
/index
'
,
component
:
'
./AfterSaleManage
Old
/index
'
,
},
},
{
{
title
:
'
商户管理后台
'
,
title
:
'
商户管理后台
'
,
path
:
'
/auditPending
'
,
path
:
'
/auditPending
'
,
name
:
'
auditPending
'
,
name
:
'
auditPending
'
,
icon
:
'
smile
'
,
icon
:
'
smile
'
,
component
:
'
./AfterSaleManage/Pending
'
,
component
:
'
./AfterSaleManage
Old
/Pending
'
,
},
},
{
{
title
:
'
商户管理后台
'
,
title
:
'
商户管理后台
'
,
path
:
'
/passAudit
'
,
path
:
'
/passAudit
'
,
name
:
'
passAudit
'
,
name
:
'
passAudit
'
,
icon
:
'
smile
'
,
icon
:
'
smile
'
,
component
:
'
./AfterSaleManage/PassAudit
'
,
component
:
'
./AfterSaleManage
Old
/PassAudit
'
,
},
},
{
{
title
:
'
商户管理后台
'
,
title
:
'
商户管理后台
'
,
...
...
src/components/MessageReminder/Complex/index.jsx
View file @
7534953c
import
React
,
{
useState
,
useEffect
,
forwardRef
,
useImperativeHandle
}
from
'
react
'
;
import
React
,
{
useState
,
useEffect
,
forwardRef
,
useImperativeHandle
}
from
'
react
'
;
import
{
Modal
,
Tabs
,
Pagination
}
from
'
antd
'
;
import
{
Modal
,
Tabs
,
Pagination
,
Spin
,
notification
,
Checkbox
,
Badge
}
from
'
antd
'
;
import
{
apiGetBussinessMsgList
,
apiGetBusinessMsgUnReadCount
}
from
'
@/services/messageReminder
'
;
import
{
connect
}
from
'
dva
'
;
import
Empty
from
'
../Empty
'
;
import
styles
from
'
./index.less
'
;
import
styles
from
'
./index.less
'
;
import
{
CHANNEL_ID
}
from
'
@/utils/constants
'
;
const
Complex
=
(
props
,
ref
)
=>
{
const
INIT_PAGINATION
=
{
pageSize
:
10
,
pageNo
:
1
,
};
const
INIT_QUERY_PARAMS
=
{
type
:
'
0
'
,
readStatus
:
''
,
};
const
MessageItem
=
props
=>
{
const
{
item
,
onMark
}
=
props
;
/**
* type: 0订单消息,1售后消息
* readStatus: 0未读,1已读
*/
const
{
readStatus
,
type
}
=
item
;
let
message
=
{};
try
{
message
=
JSON
.
parse
(
item
.
sendContent
||
'
{}
'
);
}
catch
(
e
)
{
console
.
error
(
'
消息数据格式错误
'
);
}
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
>
{
readStatus
===
0
?
(
<
a
className=
{
styles
[
'
read-status
'
]
}
onClick=
{
()
=>
onMark
([
item
.
id
])
}
>
标记为已读
</
a
>
)
:
(
<
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--footer
'
]
}
>
<
div
className=
{
styles
.
actions
}
>
<
a
className=
{
styles
.
notice
}
>
新的xxx订单,请查看
</
a
>
</
div
>
</
div
>
</
div
>
);
};
const
Complex
=
props
=>
{
const
{
dispatch
,
refInstance
}
=
props
;
const
[
visible
,
setVisible
]
=
useState
(
false
);
const
[
visible
,
setVisible
]
=
useState
(
false
);
const
[
dataTotal
,
setDataTotal
]
=
useState
(
10
);
const
[
dataTotal
,
setDataTotal
]
=
useState
(
10
);
const
[
pagination
,
setPagination
]
=
useState
({
const
[
loading
,
setLoading
]
=
useState
(
false
);
pageSize
:
20
,
const
[
messageData
,
setMessageData
]
=
useState
([]);
pageNo
:
1
,
// 未读消息
});
const
[
orderUnReadCount
,
setOrderUnReadCount
]
=
useState
(
0
);
const
[
afterUnReadCount
,
setAfterUnReadCount
]
=
useState
(
0
);
const
[
queryParams
,
setQueryParams
]
=
useState
({
...
INIT_QUERY_PARAMS
,
...
INIT_PAGINATION
});
const
userInfo
=
JSON
.
parse
(
localStorage
.
getItem
(
'
user
'
)
||
'
{}
'
);
// 获取信息列表
const
getMsgList
=
async
()
=>
{
const
params
=
{
pageSize
:
queryParams
.
pageSize
,
pageNo
:
queryParams
.
pageNo
,
};
const
data
=
{
channelId
:
CHANNEL_ID
,
bussinessId
:
userInfo
.
supplierCode
,
...
queryParams
,
};
delete
data
.
pageSize
;
delete
data
.
pageNo
;
setLoading
(
true
);
const
res
=
await
apiGetBussinessMsgList
(
data
,
params
);
setLoading
(
false
);
if
(
res
.
code
!==
'
0000
'
)
{
notification
.
error
(
res
.
msg
);
return
;
}
const
{
content
,
totalElements
}
=
res
.
data
;
setMessageData
(
content
);
setDataTotal
(
totalElements
);
};
// 获取未读数量
const
getMsgReadCount
=
async
()
=>
{
const
data
=
{
channelId
:
CHANNEL_ID
,
bussinessId
:
userInfo
.
supplierCode
,
};
const
res
=
await
apiGetBusinessMsgUnReadCount
(
data
);
if
(
res
.
code
!==
'
0000
'
)
{
notification
.
error
(
res
.
msg
);
return
;
}
const
{
afterSalesUnRead
,
orderUnRead
}
=
res
.
data
;
setOrderUnReadCount
(
orderUnRead
);
setAfterUnReadCount
(
afterSalesUnRead
);
};
// 分页操作
// 分页操作
const
onPageChange
=
(
page
,
size
)
=>
{
const
onPageChange
=
(
page
,
size
)
=>
{
const
current
=
pagination
.
pageSize
!==
size
?
1
:
page
;
const
current
=
queryParams
.
pageSize
!==
size
?
1
:
page
;
setPagination
({
setQueryParams
({
...
queryParams
,
pageNo
:
current
,
pageNo
:
current
,
pageSize
:
size
,
pageSize
:
size
,
});
});
};
};
useEffect
(()
=>
{},
[
pagination
]);
// 筛选未读/已读
const
onReadStatusChange
=
e
=>
{
let
{
value
}
=
e
.
target
;
if
(
queryParams
.
readStatus
===
e
.
target
.
value
)
{
value
=
''
;
}
setQueryParams
({
...
queryParams
,
readStatus
:
value
,
});
};
// 切换消息类型
const
onTabChange
=
index
=>
{
setQueryParams
({
...
queryParams
,
...
INIT_PAGINATION
,
type
:
index
,
});
};
// 标记已读
const
onMark
=
idList
=>
{
if
(
!
idList
.
length
)
{
return
;
}
const
payload
=
{
channelId
:
CHANNEL_ID
,
bussinessId
:
userInfo
.
supplierCode
,
idList
,
};
dispatch
({
type
:
'
messageReminder/setMarkRead
'
,
payload
,
options
:
{
setLoading
,
},
});
};
const
open
=
()
=>
{
const
open
=
()
=>
{
setVisible
(
true
);
setVisible
(
true
);
getMsgReadCount
();
};
};
const
close
=
()
=>
{
const
close
=
()
=>
{
setVisible
(
false
);
setVisible
(
false
);
};
};
useImperativeHandle
(
ref
,
()
=>
({
// 展开初始化
useEffect
(()
=>
{
if
(
visible
)
{
getMsgList
();
}
},
[
visible
,
queryParams
]);
useEffect
(()
=>
{
if
(
!
visible
)
{
setQueryParams
({
...
INIT_QUERY_PARAMS
,
...
INIT_PAGINATION
});
}
},
[
visible
]);
useImperativeHandle
(
refInstance
,
()
=>
({
open
,
open
,
}));
}));
const
modalProps
=
{
const
modalProps
=
{
bodyStyle
:
{
display
:
'
flex
'
,
flexWrap
:
'
wrap
'
,
padding
:
0
,
},
width
:
'
1000px
'
,
width
:
'
1000px
'
,
height
:
'
600px
'
,
height
:
'
600px
'
,
visible
,
visible
,
...
@@ -42,95 +201,97 @@ const Complex = (props, ref) => {
...
@@ -42,95 +201,97 @@ const Complex = (props, ref) => {
onCancel
:
close
,
onCancel
:
close
,
};
};
const
TabRender
=
tabProps
=>
{
const
{
title
,
count
=
0
}
=
tabProps
;
return
(
return
(
<
Modal
{
...
modalProps
}
>
<
Tabs
tabPosition=
"left"
>
<
Tabs
.
TabPane
tab=
{
<
span
>
<
span
>
1111
<
span
style=
{
{
background
:
'
red
'
}
}
>
abc
</
span
>
{
title
}
<
Badge
size=
"small"
overflowCount=
{
999
}
count=
{
count
}
/>
</
span
>
</
span
>
}
);
key=
"1"
};
>
<
div
className=
{
styles
[
'
complex-list
'
]
}
>
<
div
className=
{
styles
[
'
complex-list__item
'
]
}
>
<
div
className=
{
styles
[
'
complex-list__item--header
'
]
}
>
<
span
className=
{
styles
.
notice
}
>
新的xxx订单,请查看
</
span
>
<
span
className=
{
styles
.
orderNumber
}
>
订单编号:1562742258351251456
</
span
>
<
span
className=
{
styles
.
time
}
>
2022-10-13 12:22:03
</
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
className=
{
styles
.
good
}
>
<
span
className=
{
styles
.
good__name
}
>
商品名称商品名称商品名称商品名称
</
span
>
<
span
className=
{
styles
.
good__count
}
>
x10
</
span
>
</
div
>
<
div
className=
{
styles
.
good
}
>
const
FilterRender
=
filterProps
=>
{
<
span
className=
{
styles
.
good__name
}
>
商品名称商品名称商品名称商品名称
</
span
>
console
.
log
(
filterProps
);
<
span
className=
{
styles
.
good__count
}
>
x10
</
span
>
return
(
</
div
>
<
div
className=
{
styles
[
'
filter-box
'
]
}
>
</
div
>
<
div
className=
{
styles
[
'
filter-box__content
'
]
}
>
<
div
className=
{
styles
[
'
complex-list__item--footer
'
]
}
>
<
Checkbox
<
div
className=
{
styles
.
actions
}
>
checked=
{
queryParams
.
readStatus
===
'
0
'
}
<
a
>
标记为已读
</
a
>
value=
"0"
<
a
>
立即查看
</
a
>
onChange=
{
onReadStatusChange
}
</
div
>
>
</
div
>
未读
</
Checkbox
>
<
Checkbox
checked=
{
queryParams
.
readStatus
===
'
1
'
}
value=
"1"
onChange=
{
onReadStatusChange
}
>
已读读
</
Checkbox
>
</
div
>
</
div
>
<
div
className=
{
styles
[
'
filter-box__actions
'
]
}
>
<
div
className=
{
styles
[
'
complex-list__item
'
]
}
>
<
a
<
div
className=
{
styles
[
'
complex-list__item--header
'
]
}
>
onClick=
{
()
=>
<
span
className=
{
styles
.
notice
}
>
新的xxx订单,请查看
</
span
>
onMark
(
messageData
.
filter
(
message
=>
message
.
readStatus
===
0
).
map
(
item
=>
item
.
id
))
<
span
className=
{
styles
.
orderNumber
}
>
订单编号:1562742258351251456
</
span
>
}
<
span
className=
{
styles
.
time
}
>
2022-10-13 12:22:03
</
span
>
>
全部标记为已读
</
a
>
</
div
>
</
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
.
good
}
>
return
(
<
span
className=
{
styles
.
good__name
}
>
商品名称商品名称商品名称商品名称
</
span
>
<
Modal
{
...
modalProps
}
>
<
span
className=
{
styles
.
good__count
}
>
x10
</
span
>
<
Tabs
</
div
>
className=
{
styles
.
tabs
}
activeKey=
{
queryParams
.
type
}
tabPosition=
"left"
onChange=
{
onTabChange
}
>
<
Tabs
.
TabPane
tab=
{
<
TabRender
title=
"订单消息"
count=
{
orderUnReadCount
}
/>
}
key=
"0"
/>
<
Tabs
.
TabPane
tab=
{
<
TabRender
title=
"售后消息"
count=
{
afterUnReadCount
}
/>
}
key=
"1"
/>
</
Tabs
>
<
div
className=
{
styles
.
good
}
>
<
div
className=
{
styles
[
'
tab-pane
'
]
}
>
<
span
className=
{
styles
.
good__name
}
>
商品名称商品名称商品名称商品名称
</
span
>
<
Spin
spinning=
{
loading
}
>
<
span
className=
{
styles
.
good__count
}
>
x10
</
span
>
<
FilterRender
/>
</
div
>
<
div
className=
{
styles
[
'
complex-list
'
]
}
>
</
div
>
{
messageData
.
length
?
(
<
div
className=
{
styles
[
'
complex-list__item--footer
'
]
}
>
messageData
.
map
(
item
=>
<
MessageItem
key=
{
item
.
id
}
item=
{
item
}
onMark=
{
onMark
}
/>)
<
div
className=
{
styles
.
actions
}
>
)
:
(
<
a
>
标记为已读
</
a
>
<
Empty
text=
"暂无数据"
/>
<
a
>
立即查看
</
a
>
)
}
</
div
>
</
div
>
</
div
>
</
div
>
</
Spin
>
</
div
>
</
div
>
</
Tabs
.
TabPane
>
<
Tabs
.
TabPane
tab=
"售后消息"
key=
"2"
>
<
div
className=
{
styles
[
'
complex-list
'
]
}
></
div
>
</
Tabs
.
TabPane
>
</
Tabs
>
{
dataTotal
>
0
?
(
<
div
className=
{
styles
.
pagination
}
>
<
div
className=
{
styles
.
pagination
}
>
<
Pagination
<
Pagination
onChange=
{
onPageChange
}
onChange=
{
onPageChange
}
total=
{
dataTotal
}
total=
{
dataTotal
}
showTotal=
{
(
total
,
range
)
=>
`第${range[0]}-${range[1]}条 /总共${total}条`
}
showTotal=
{
(
total
,
range
)
=>
`第${range[0]}-${range[1]}条 /总共${total}条`
}
pageSize=
{
pagination
.
pageSize
}
showSizeChanger
current=
{
pagination
.
pageNo
}
pageSize=
{
queryParams
.
pageSize
}
current=
{
queryParams
.
pageNo
}
/>
/>
</
div
>
</
div
>
)
:
(
''
)
}
</
Modal
>
</
Modal
>
);
);
};
};
export
default
forwardRef
(
Complex
);
const
MiddleComponent
=
connect
(({
messageReminder
})
=>
({
unReadCount
:
messageReminder
.
unReadCount
,
unReadData
:
messageReminder
.
unReadData
,
}))(
Complex
);
// 注意:这里不要在Component上使用ref;换个属性名字比如refInstance;不然会导致覆盖
export
default
forwardRef
((
props
,
ref
)
=>
<
MiddleComponent
{
...
props
}
refInstance=
{
ref
}
/>);
src/components/MessageReminder/Complex/index.less
View file @
7534953c
.tab-pane {
flex: 1;
}
.filter-box {
display: flex;
margin-top: 15px;
padding-right: 25px;
&__content {
flex: 1;
}
// &__actions{
// }
}
.complex-list {
.complex-list {
height: 500px;
height: 500px;
margin-top: 20px;
padding-right: 25px;
overflow-y: auto;
overflow-y: auto;
border: 1px solid #efefef;
& :first-child {
& :first-child {
margin: 0;
margin: 0;
}
}
&__item {
&__item {
margin-top: 15px;
margin-top: 15px;
border: 1px solid #efefef;
&--header {
&--header {
display: flex;
display: flex;
width: 100%;
width: 100%;
height: 40px;
height: 40px;
padding: 0
20
px;
padding: 0
15
px;
line-height: 40px;
line-height: 40px;
background: #f8f8f8;
background: #fff;
.orderNumber {
border-bottom: 1px solid #efefef;
.order-number,
.time {
flex: 1;
flex: 1;
padding: 0 20px;
padding-right: 20px;
color: #999;
}
.read-status {
&--read {
color: #999;
}
}
.notice {
color: green;
}
}
}
}
&--body {
&--body {
...
@@ -37,16 +60,30 @@
...
@@ -37,16 +60,30 @@
&--footer {
&--footer {
display: flex;
display: flex;
justify-content: end;
padding: 0 15px;
border-top: 1px solid #efefef;
border-top: 1px solid #efefef;
border-bottom: 1px solid #efefef;
.actions {
.actions {
display: flex;
display: flex;
width: 100%;
margin-left: 10px;
margin-left: 10px;
line-height: 40px;
line-height: 40px;
a {
a {
margin-left: 15px;
position: relative;
display: block;
flex: 1;
color: #ff1515;
font-weight: 400;
&::after {
position: absolute;
top: 50%;
right: 10px;
display: block;
width: 0;
height: 0;
margin-top: -3px;
border: 6px solid transparent;
border-left: 8px solid #999;
content: '';
}
}
}
}
}
}
}
...
@@ -54,5 +91,7 @@
...
@@ -54,5 +91,7 @@
}
}
.pagination {
.pagination {
width: 100%;
padding: 25px;
text-align: right;
text-align: right;
}
}
src/components/MessageReminder/Simple/index.jsx
View file @
7534953c
import
React
,
{
useState
,
useEffect
}
from
'
react
'
;
import
React
,
{
useState
,
useEffect
}
from
'
react
'
;
import
{
Badge
,
notification
}
from
'
antd
'
;
import
{
Badge
,
notification
,
Spin
}
from
'
antd
'
;
import
{
CloseOutlined
}
from
'
@ant-design/icons
'
;
import
{
CloseOutlined
}
from
'
@ant-design/icons
'
;
import
classNames
from
'
classnames
'
;
import
classNames
from
'
classnames
'
;
import
{
connect
}
from
'
dva
'
;
import
{
connect
}
from
'
dva
'
;
...
@@ -21,21 +21,26 @@ const Horn = props => {
...
@@ -21,21 +21,26 @@ const Horn = props => {
};
};
const
Message
=
props
=>
{
const
Message
=
props
=>
{
const
{
toggle
,
animationClass
,
messageData
,
openComplex
,
onMark
}
=
props
;
const
{
toggle
,
animationClass
,
messageData
,
openComplex
,
onMark
,
loading
}
=
props
;
const
ReminderItem
=
args
=>
{
const
ReminderItem
=
args
=>
{
const
{
item
}
=
args
;
const
{
item
}
=
args
;
const
{
orderNo
,
createdAt
}
=
JSON
.
parse
(
item
.
sendContent
||
'
{}
'
);
let
message
=
{};
try
{
message
=
JSON
.
parse
(
item
.
sendContent
||
'
{}
'
);
}
catch
(
e
)
{
console
.
error
(
'
消息数据格式错误
'
);
}
return
(
return
(
<
div
className=
{
styles
.
item
}
>
<
div
className=
{
styles
.
item
}
>
<
div
className=
{
styles
.
info
}
>
<
div
className=
{
styles
.
info
}
>
<
span
className=
{
styles
[
'
order-number
'
]
}
>
{
orderNo
}
</
span
>
<
span
className=
{
styles
[
'
order-number
'
]
}
>
{
message
.
orderNo
}
</
span
>
<
span
className=
{
styles
[
'
mark-read
'
]
}
onClick=
{
()
=>
onMark
([
item
.
id
])
}
>
<
span
className=
{
styles
[
'
mark-read
'
]
}
onClick=
{
()
=>
onMark
([
item
.
id
])
}
>
标记为已读
标记为已读
</
span
>
</
span
>
</
div
>
</
div
>
<
div
className=
{
styles
.
time
}
>
<
div
className=
{
styles
.
time
}
>
<
span
>
{
createdAt
}
</
span
>
<
span
>
{
message
.
createdAt
}
</
span
>
</
div
>
</
div
>
<
div
className=
{
styles
.
notice
}
>
<
div
className=
{
styles
.
notice
}
>
<
a
>
您有新的xxxxx订单,请查看
</
a
>
<
a
>
您有新的xxxxx订单,请查看
</
a
>
...
@@ -55,6 +60,7 @@ const Message = props => {
...
@@ -55,6 +60,7 @@ const Message = props => {
</
div
>
</
div
>
</
div
>
</
div
>
<
div
className=
{
styles
[
'
message-reminder__body
'
]
}
>
<
div
className=
{
styles
[
'
message-reminder__body
'
]
}
>
<
Spin
spinning=
{
loading
}
>
<
div
className=
{
styles
[
'
message-reminder__body--list
'
]
}
>
<
div
className=
{
styles
[
'
message-reminder__body--list
'
]
}
>
{
messageData
.
length
?
(
{
messageData
.
length
?
(
messageData
messageData
...
@@ -64,6 +70,7 @@ const Message = props => {
...
@@ -64,6 +70,7 @@ const Message = props => {
<
Empty
text=
"暂无数据"
/>
<
Empty
text=
"暂无数据"
/>
)
}
)
}
</
div
>
</
div
>
</
Spin
>
</
div
>
</
div
>
<
div
className=
{
styles
[
'
message-reminder__footer
'
]
}
>
<
div
className=
{
styles
[
'
message-reminder__footer
'
]
}
>
<
div
className=
{
styles
[
'
message-reminder__footer--actions
'
]
}
>
<
div
className=
{
styles
[
'
message-reminder__footer--actions
'
]
}
>
...
@@ -87,6 +94,7 @@ const Message = props => {
...
@@ -87,6 +94,7 @@ const Message = props => {
const
Simple
=
props
=>
{
const
Simple
=
props
=>
{
const
{
dispatch
,
unReadCount
,
complexRef
,
unReadData
}
=
props
;
const
{
dispatch
,
unReadCount
,
complexRef
,
unReadData
}
=
props
;
const
[
visible
,
setVisible
]
=
useState
(
false
);
const
[
visible
,
setVisible
]
=
useState
(
false
);
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
count
,
setCount
]
=
useState
(
0
);
const
[
count
,
setCount
]
=
useState
(
0
);
const
[
hornClass
,
setHornClass
]
=
useState
(
''
);
const
[
hornClass
,
setHornClass
]
=
useState
(
''
);
const
[
messageClass
,
setMessageClass
]
=
useState
(
''
);
const
[
messageClass
,
setMessageClass
]
=
useState
(
''
);
...
@@ -110,7 +118,9 @@ const Simple = props => {
...
@@ -110,7 +118,9 @@ const Simple = props => {
bussinessId
:
userInfo
.
supplierCode
,
bussinessId
:
userInfo
.
supplierCode
,
readStatus
:
0
,
readStatus
:
0
,
};
};
setLoading
(
true
);
const
res
=
await
apiGetBussinessMsgList
(
data
,
params
);
const
res
=
await
apiGetBussinessMsgList
(
data
,
params
);
setLoading
(
false
);
if
(
res
.
code
!==
'
0000
'
)
{
if
(
res
.
code
!==
'
0000
'
)
{
notification
.
error
(
res
.
msg
);
notification
.
error
(
res
.
msg
);
return
;
return
;
...
@@ -135,6 +145,9 @@ const Simple = props => {
...
@@ -135,6 +145,9 @@ const Simple = props => {
// 标记已读信息
// 标记已读信息
const
onMark
=
idList
=>
{
const
onMark
=
idList
=>
{
if
(
!
idList
.
length
)
{
return
;
}
const
payload
=
{
const
payload
=
{
channelId
:
CHANNEL_ID
,
channelId
:
CHANNEL_ID
,
bussinessId
:
userInfo
.
supplierCode
,
bussinessId
:
userInfo
.
supplierCode
,
...
@@ -143,6 +156,9 @@ const Simple = props => {
...
@@ -143,6 +156,9 @@ const Simple = props => {
dispatch
({
dispatch
({
type
:
'
messageReminder/setMarkRead
'
,
type
:
'
messageReminder/setMarkRead
'
,
payload
,
payload
,
options
:
{
setLoading
,
},
});
});
};
};
...
@@ -175,6 +191,7 @@ const Simple = props => {
...
@@ -175,6 +191,7 @@ const Simple = props => {
messageData
,
messageData
,
openComplex
,
openComplex
,
onMark
,
onMark
,
loading
,
};
};
// 隐藏消息提醒
// 隐藏消息提醒
...
...
src/layouts/BasicLayout.jsx
View file @
7534953c
...
@@ -14,6 +14,7 @@ import Authorized from '@/utils/Authorized';
...
@@ -14,6 +14,7 @@ import Authorized from '@/utils/Authorized';
import
RightContent
from
'
@/components/GlobalHeader/RightContent
'
;
import
RightContent
from
'
@/components/GlobalHeader/RightContent
'
;
import
MessageReminder
from
'
@/components/MessageReminder
'
;
import
MessageReminder
from
'
@/components/MessageReminder
'
;
import
{
getAuthorityFromRouter
}
from
'
@/utils/utils
'
;
import
{
getAuthorityFromRouter
}
from
'
@/utils/utils
'
;
import
{
getSocketUrl
}
from
'
@/services/messageReminder
'
;
import
logo
from
'
../assets/logo.png
'
;
import
logo
from
'
../assets/logo.png
'
;
import
style
from
'
./BasicLayout.less
'
;
import
style
from
'
./BasicLayout.less
'
;
...
@@ -60,7 +61,7 @@ const BasicLayout = props => {
...
@@ -60,7 +61,7 @@ const BasicLayout = props => {
const
token
=
window
.
localStorage
.
getItem
(
'
token
'
);
const
token
=
window
.
localStorage
.
getItem
(
'
token
'
);
const
channelId
=
100001
;
const
channelId
=
100001
;
const
socket
=
new
Socket
({
const
socket
=
new
Socket
({
url
:
`ws://ws-sc.liangkebang.net/ws?token=
${
token
}
&channelId=
${
channelId
}
`
,
url
:
getSocketUrl
({
token
,
channelId
})
,
});
});
socket
.
connection
();
socket
.
connection
();
...
@@ -69,27 +70,28 @@ const BasicLayout = props => {
...
@@ -69,27 +70,28 @@ const BasicLayout = props => {
});
});
socket
.
event
.
on
(
'
message
'
,
msg
=>
{
socket
.
event
.
on
(
'
message
'
,
msg
=>
{
console
.
log
(
msg
);
dispatch
({
dispatch
({
type
:
'
messageReminder/setUnReadData
'
,
type
:
'
messageReminder/setUnReadData
'
,
payload
:
JSON
.
parse
(
msg
.
data
)
,
payload
:
[
JSON
.
parse
(
msg
.
data
)]
,
});
});
});
});
let
a
=
100000000000
;
//
let a = 100000000000;
setInterval
(()
=>
{
//
setInterval(() => {
a
++
;
//
a++;
socket
.
sendMessage
([
// socket.sendMessage(
{
//
{
id
:
a
,
//
id: a,
channelId
:
100001
,
//
channelId: 100001,
bussinessId
:
'
self_40
'
,
//
bussinessId: 'self_40',
type
:
0
,
//
type: 0,
sendContent
:
`{"name":"商品21111", "orderNo":
${
a
}
,"createdAt":"2022-10-13 12:12:12", "count":11}`
,
//
sendContent: `{"name":"商品21111", "orderNo":${a},"createdAt":"2022-10-13 12:12:12", "count":11}`,
readStatus
:
0
,
//
readStatus: 0,
createdAt
:
'
2022-10-18 14:05:12
'
,
//
createdAt: '2022-10-18 14:05:12',
updatedAt
:
'
2022-10-18 17:15:19
'
,
//
updatedAt: '2022-10-18 17:15:19',
},
//
},
]
);
//
);
},
5000
);
//
}, 5000);
if
(
dispatch
)
{
if
(
dispatch
)
{
dispatch
({
dispatch
({
type
:
'
settings/getSetting
'
,
type
:
'
settings/getSetting
'
,
...
@@ -224,6 +226,7 @@ const BasicLayout = props => {
...
@@ -224,6 +226,7 @@ const BasicLayout = props => {
<
MessageReminder
.
Simple
complexRef=
{
messageReminderComplexRef
}
/>
<
MessageReminder
.
Simple
complexRef=
{
messageReminderComplexRef
}
/>
<
MessageReminder
.
Complex
ref=
{
messageReminderComplexRef
}
/>
<
MessageReminder
.
Complex
ref=
{
messageReminderComplexRef
}
/>
{
/* <audio id="myaudio" src="https://img.lkbang.net/10544.b57be67d.mp3" loop="loop" preload="preload" muted="muted" /> */
}
</
ProLayout
>
</
ProLayout
>
);
);
};
};
...
...
src/models/messageReminder.js
View file @
7534953c
...
@@ -16,9 +16,16 @@ const MessageReminderModel = {
...
@@ -16,9 +16,16 @@ const MessageReminderModel = {
});
});
});
});
},
},
*
setMarkRead
({
payload
,
options
},
{
put
,
call
})
{
*
setMarkRead
({
payload
,
options
=
{}
},
{
put
,
call
})
{
// const res = yield call(apiUpdageBusinessMsgStatus, payload)
const
{
setLoading
}
=
options
;
if
(
setLoading
)
{
setLoading
(
true
);
}
const
res
=
yield
call
(
apiUpdageBusinessMsgStatus
,
payload
);
// console.log(res)
// console.log(res)
if
(
setLoading
)
{
setLoading
(
false
);
}
yield
put
({
yield
put
({
type
:
'
updateUnReadData
'
,
type
:
'
updateUnReadData
'
,
payload
,
payload
,
...
...
src/pages/AfterSaleManage/components/AfterLog.jsx
View file @
7534953c
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
/* eslint-disable guard-for-in */
/* eslint-disable guard-for-in */
import
React
,
{
useState
,
useEffect
}
from
'
react
'
;
import
React
,
{
useState
,
useEffect
}
from
'
react
'
;
import
{
Modal
,
Timeline
,
Button
}
from
'
antd
'
;
import
{
Modal
,
Timeline
,
Button
}
from
'
antd
'
;
import
styles
from
'
../
styles
.less
'
;
import
styles
from
'
../
index
.less
'
;
const
LogisticsCom
=
props
=>
{
const
LogisticsCom
=
props
=>
{
const
{
visible
,
onCancel
,
data
}
=
props
;
const
{
visible
,
onCancel
,
data
}
=
props
;
...
...
src/pages/AfterSaleManage/components/LogisticsRecordModal.jsx
0 → 100644
View file @
7534953c
import
React
,
{
useState
,
forwardRef
,
useImperativeHandle
,
useEffect
}
from
'
react
'
;
import
{
Modal
,
Timeline
,
notification
,
Spin
}
from
'
antd
'
;
import
{
getLogisticsRecord
}
from
'
../services
'
;
const
LogisticsRecordModal
=
(
props
,
ref
)
=>
{
// const { } = props;
const
[
visible
,
setVisible
]
=
useState
(
false
);
const
[
result
,
setResult
]
=
useState
({});
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
getRecordList
=
async
orderNo
=>
{
const
tempObj
=
{
detailList
:
[],
key
:
Date
.
now
(),
};
setLoading
(
true
);
const
res
=
await
getLogisticsRecord
({
orderNo
});
setLoading
(
false
);
if
(
!
res
)
{
notification
.
info
({
message
:
'
暂无物流信息
'
});
return
;
}
const
{
logisticsName
,
logisticsBillNo
,
logisticsList
=
[]
}
=
res
.
data
;
tempObj
.
expressCompanyName
=
logisticsName
;
tempObj
.
deliveryNo
=
logisticsBillNo
;
logisticsList
.
forEach
(
v
=>
{
tempObj
.
detailList
=
[...
tempObj
.
detailList
,
...
v
.
detailList
];
});
setResult
(
tempObj
);
};
const
open
=
orderNo
=>
{
setVisible
(
true
);
getRecordList
(
orderNo
);
};
const
onCancel
=
()
=>
{
setVisible
(
false
);
setResult
([]);
};
useImperativeHandle
(
ref
,
()
=>
({
open
,
}));
const
modalProps
=
{
title
:
'
查看物流
'
,
visible
,
onCancel
,
destroyOnClose
:
true
,
bodyStyle
:
{
maxHeight
:
'
600px
'
,
minHeight
:
'
200px
'
,
overflow
:
'
auto
'
},
footer
:
null
,
};
const
emptyStyle
=
{
textAlign
:
'
center
'
,
padding
:
'
30px 0
'
,
color
:
'
#999
'
,
};
return
(
<
Modal
{
...
modalProps
}
>
<
Spin
spinning=
{
loading
}
>
{
result
.
detailList
?.
length
?
(
<
Timeline
>
{
result
?.
detailList
?.
map
((
item
,
index
)
=>
(
<
Timeline
.
Item
color=
{
index
>
0
?
'
gray
'
:
'
blue
'
}
key=
{
index
.
toString
()
}
>
<
p
>
{
item
.
desc
}
</
p
>
<
p
>
{
item
.
logisticsTime
}
</
p
>
</
Timeline
.
Item
>
))
}
</
Timeline
>
)
:
(
<
div
style=
{
emptyStyle
}
>
暂无物流信息
</
div
>
)
}
</
Spin
>
</
Modal
>
);
};
export
default
forwardRef
(
LogisticsRecordModal
);
const
LogisticsCom
=
props
=>
{
const
{
modalVisible
,
onCancel
}
=
props
;
const
[
result
,
setResult
]
=
useState
({});
useEffect
(()
=>
{
setResult
(
props
.
value
);
});
return
(
<
Modal
destroyOnClose
title=
{
`${
result?.expressCompanyName
? `
$
{
result
?.
expressCompanyName
}
-
$
{
result
?.
deliveryNo
}
`
: '物流信息'
}`
}
visible=
{
modalVisible
}
onCancel=
{
()
=>
onCancel
()
}
onOk=
{
()
=>
onCancel
()
}
afterClose=
{
()
=>
setResult
({})
}
bodyStyle=
{
{
maxHeight
:
'
600px
'
,
minHeight
:
'
200px
'
,
overflow
:
'
auto
'
}
}
footer=
{
[]
}
>
{
result
?.
detailList
?.
length
?
(
<
Timeline
>
{
result
?.
detailList
?.
map
((
item
,
index
)
=>
(
// eslint-disable-next-line react/no-array-index-key
<
Timeline
.
Item
color=
{
index
>
0
?
'
gray
'
:
'
blue
'
}
key=
{
index
}
>
<
p
>
{
item
.
desc
}
</
p
>
<
p
>
{
item
.
logisticsTime
}
</
p
>
</
Timeline
.
Item
>
))
}
</
Timeline
>
)
:
(
'
暂无物流信息
'
)
}
</
Modal
>
);
};
src/pages/AfterSaleManage/components/auditModal.jsx
View file @
7534953c
import
React
from
'
react
'
;
import
React
,
{
useRef
}
from
'
react
'
;
import
{
Form
}
from
'
@ant-design/compatible
'
;
import
{
Form
}
from
'
@ant-design/compatible
'
;
import
'
@ant-design/compatible/assets/index.css
'
;
import
'
@ant-design/compatible/assets/index.css
'
;
import
{
Modal
,
Input
,
Cascader
,
notification
,
InputNumber
}
from
'
antd
'
;
import
{
Modal
,
Input
,
Cascader
,
notification
,
InputNumber
}
from
'
antd
'
;
import
{
shopAudit
}
from
'
../services
'
;
import
{
shopAudit
}
from
'
../services
'
;
import
styles
from
'
../styles.less
'
;
import
styles
from
'
../index.less
'
;
import
LogisticsRecordModal
from
'
./LogisticsRecordModal
'
;
const
FormItem
=
Form
.
Item
;
const
FormItem
=
Form
.
Item
;
const
{
TextArea
}
=
Input
;
const
{
TextArea
}
=
Input
;
...
@@ -15,7 +17,7 @@ const AuditModal = props => {
...
@@ -15,7 +17,7 @@ const AuditModal = props => {
form
:
{
getFieldDecorator
,
getFieldValue
,
validateFields
,
resetFields
},
form
:
{
getFieldDecorator
,
getFieldValue
,
validateFields
,
resetFields
},
formData
=
{},
formData
=
{},
}
=
props
;
}
=
props
;
const
logisticsRecordModalRef
=
useRef
();
const
handleCancel
=
isSuccess
=>
{
const
handleCancel
=
isSuccess
=>
{
resetFields
();
resetFields
();
onCancel
(
isSuccess
);
onCancel
(
isSuccess
);
...
@@ -102,6 +104,10 @@ const AuditModal = props => {
...
@@ -102,6 +104,10 @@ const AuditModal = props => {
});
});
};
};
const
openLogisticsRecord
=
()
=>
{
logisticsRecordModalRef
.
current
.
open
(
formData
.
orderNo
);
};
const
layout
=
{
const
layout
=
{
labelCol
:
{
span
:
6
},
labelCol
:
{
span
:
6
},
wrapperCol
:
{
span
:
16
},
wrapperCol
:
{
span
:
16
},
...
@@ -110,6 +116,7 @@ const AuditModal = props => {
...
@@ -110,6 +116,7 @@ const AuditModal = props => {
const
isAgree
=
()
=>
auditResult
?.[
0
]
===
1
;
const
isAgree
=
()
=>
auditResult
?.[
0
]
===
1
;
const
isRefuse
=
()
=>
auditResult
&&
auditResult
[
0
]
!==
1
;
const
isRefuse
=
()
=>
auditResult
&&
auditResult
[
0
]
!==
1
;
return
(
return
(
<>
<
Modal
<
Modal
title=
"售后操作确认"
title=
"售后操作确认"
visible=
{
visible
}
visible=
{
visible
}
...
@@ -120,7 +127,7 @@ const AuditModal = props => {
...
@@ -120,7 +127,7 @@ const AuditModal = props => {
<
div
className=
{
styles
.
redTip
}
>
<
div
className=
{
styles
.
redTip
}
>
温馨提示:当前售后类型为用户未收到产品,申请
温馨提示:当前售后类型为用户未收到产品,申请
<
span
className=
{
styles
.
redTipBold
}
>
仅退款
</
span
>
<
span
className=
{
styles
.
redTipBold
}
>
仅退款
</
span
>
,请务必检查此单物流状态后审核。
,请务必检查此单物流状态后审核。
<
a
onClick=
{
openLogisticsRecord
}
>
查看物流
</
a
>
</
div
>
</
div
>
)
}
)
}
<
Form
{
...
layout
}
name=
"formData"
>
<
Form
{
...
layout
}
name=
"formData"
>
...
@@ -237,6 +244,8 @@ const AuditModal = props => {
...
@@ -237,6 +244,8 @@ const AuditModal = props => {
)
}
)
}
</
Form
>
</
Form
>
</
Modal
>
</
Modal
>
<
LogisticsRecordModal
ref=
{
logisticsRecordModalRef
}
/>
</>
);
);
};
};
...
...
src/pages/AfterSaleManage/components/proofsModal.jsx
View file @
7534953c
import
React
,
{
useState
}
from
'
react
'
;
import
React
,
{
useState
}
from
'
react
'
;
import
{
Modal
}
from
'
antd
'
;
import
{
Modal
}
from
'
antd
'
;
import
style
from
'
../
styles
.less
'
;
import
style
from
'
../
index
.less
'
;
export
default
props
=>
{
export
default
props
=>
{
const
{
visible
,
onCancel
,
data
}
=
props
;
const
{
visible
,
onCancel
,
data
}
=
props
;
...
...
src/pages/AfterSaleManage/data.js
View file @
7534953c
import
{
Tag
,
Badge
}
from
'
antd
'
;
import
{
Tag
,
Badge
,
Statistic
,
Button
,
Popconfirm
}
from
'
antd
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
moment
from
'
moment
'
;
import
{
SEARCH_TYPE
}
from
'
@/components/FormSearch
'
;
const
{
Countdown
}
=
Statistic
;
export
const
TAB_MAPPING_DATA
=
{
''
:
{},
1
:
{
label
:
'
仅退款(未发货)待审核
'
,
type
:
0
,
dealStatus
:
14
,
},
2
:
{
label
:
'
仅退款待审核
'
,
type
:
1
,
dealStatus
:
14
,
},
3
:
{
label
:
'
退货退款待审核
'
,
type
:
2
,
dealStatus
:
14
,
},
4
:
{
label
:
'
退货入库待审核
'
,
dealStatus
:
40
,
},
5
:
{
label
:
'
已完成
'
,
dealStatus
:
70
,
},
};
// 售后类型
const
AFTER_TYPE
=
[
{
value
:
0
,
name
:
'
仅退款(未发货)
'
,
},
{
value
:
1
,
name
:
'
仅退款
'
,
},
{
value
:
2
,
name
:
'
退货退款
'
,
},
];
// 售后状态
const
AFTER_STATUS
=
[
{
value
:
14
,
name
:
'
商户审核中
'
,
},
{
value
:
16
,
name
:
'
商户审核拒绝
'
,
},
{
value
:
30
,
name
:
'
待填写退货物流信息
'
,
},
{
value
:
40
,
name
:
'
待退货入库
'
,
},
{
value
:
50
,
name
:
'
退货拒收
'
,
},
{
value
:
70
,
name
:
'
退款成功
'
,
},
{
value
:
99
,
name
:
'
用户撤销
'
,
},
];
export
const
getFormConfig
=
(
props
=
{})
=>
{
const
{
setTableParams
,
setCurrentTab
,
tableParams
,
actionRef
}
=
props
;
return
{
formConfig
:
[
{
type
:
SEARCH_TYPE
.
INPUT
,
label
:
'
订单ID
'
,
bindKey
:
'
orderNo
'
,
column
:
5
,
},
{
type
:
SEARCH_TYPE
.
INPUT
,
label
:
'
售后单ID
'
,
bindKey
:
'
serviceNo
'
,
column
:
5
,
},
{
type
:
SEARCH_TYPE
.
SELECT
,
label
:
'
售后状态
'
,
column
:
5
,
bindKey
:
'
dealStatus
'
,
options
:
AFTER_STATUS
,
originOptions
:
{
allowClear
:
true
,
},
},
{
type
:
SEARCH_TYPE
.
SELECT
,
label
:
'
售后类型
'
,
column
:
5
,
bindKey
:
'
type
'
,
options
:
AFTER_TYPE
,
originOptions
:
{
allowClear
:
true
,
},
},
{
type
:
SEARCH_TYPE
.
INPUT
,
label
:
'
收货人姓名
'
,
column
:
5
,
bindKey
:
'
receiverName
'
,
},
{
type
:
SEARCH_TYPE
.
INPUT
,
label
:
'
收货人手机号
'
,
column
:
5
,
bindKey
:
'
receiverPhone
'
,
},
{
type
:
SEARCH_TYPE
.
DATE_PICKER
,
label
:
'
订单开始日期
'
,
column
:
5
,
bindKey
:
'
startDate
'
,
},
{
type
:
SEARCH_TYPE
.
DATE_PICKER
,
label
:
'
订单结束日期
'
,
column
:
5
,
bindKey
:
'
endDate
'
,
},
],
btnConfig
:
[
{
label
:
'
筛选
'
,
clickType
:
'
submit
'
,
onClick
:
({
params
})
=>
{
// 参数相同,直接执行刷新
if
(
JSON
.
stringify
(
params
)
===
JSON
.
stringify
(
tableParams
))
{
actionRef
.
current
.
reload
();
return
;
}
setTableParams
(
params
);
const
{
type
,
dealStatus
}
=
params
;
let
hasMatchingKey
=
''
;
Object
.
keys
(
TAB_MAPPING_DATA
).
forEach
(
key
=>
{
const
item
=
TAB_MAPPING_DATA
[
key
];
if
(
type
===
item
.
type
&&
dealStatus
===
item
.
dealStatus
)
{
hasMatchingKey
=
key
;
}
});
setCurrentTab
(
hasMatchingKey
);
},
},
{
label
:
'
重置
'
,
type
:
''
,
clickType
:
'
reset
'
,
onClick
:
()
=>
{
setTableParams
({});
},
},
],
};
};
export
const
appealType
=
{
export
const
appealType
=
{
1
:
'
已申诉
'
,
1
:
'
已申诉
'
,
0
:
'
未申诉
'
,
0
:
'
未申诉
'
,
};
};
export
const
columnSticData
=
[
export
const
getColumns
=
props
=>
{
const
{
openAudit
,
viewAppeal
,
viewProofs
,
openLogistics
,
viewDetail
,
viewLog
,
handleCom
,
refund
,
reject
,
canEditable
,
}
=
props
;
return
[
{
title
:
'
审核倒计时
'
,
dataIndex
:
'
serviceTime
'
,
key
:
'
serviceTime
'
,
hideInSearch
:
true
,
width
:
150
,
render
:
(
val
,
record
)
=>
{
const
serviceTime
=
moment
(
record
.
approvalEndTime
).
valueOf
();
return
(
<
Countdown
format
=
"
HH时mm分ss秒
"
value
=
{
serviceTime
}
valueStyle
=
{{
color
:
'
red
'
,
fontSize
:
'
14px
'
}}
/
>
);
},
},
{
title
:
'
售后状态
'
,
dataIndex
:
'
serviceStatus
'
,
hideInSearch
:
true
,
width
:
120
,
},
{
{
title
:
'
售后类型
'
,
title
:
'
售后类型
'
,
dataIndex
:
'
serviceType
'
,
dataIndex
:
'
serviceType
'
,
...
@@ -18,12 +230,6 @@ export const columnSticData = [
...
@@ -18,12 +230,6 @@ export const columnSticData = [
return
<
span
>
退货退款
<
/span>
;
return
<
span
>
退货退款
<
/span>
;
},
},
},
},
{
title
:
'
订单ID
'
,
dataIndex
:
'
orderNo
'
,
hideInTable
:
true
,
width
:
200
,
},
{
{
title
:
'
售后单ID
'
,
title
:
'
售后单ID
'
,
dataIndex
:
'
serviceNo
'
,
dataIndex
:
'
serviceNo
'
,
...
@@ -42,56 +248,19 @@ export const columnSticData = [
...
@@ -42,56 +248,19 @@ export const columnSticData = [
width
:
300
,
width
:
300
,
},
},
{
{
title
:
'
售后状态
'
,
title
:
'
收货人信息
'
,
dataIndex
:
'
dealStatus
'
,
hideInTable
:
true
,
valueEnum
:
{
0
:
'
待审核
'
,
10
:
'
三方审核中
'
,
11
:
'
三方审核通过
'
,
12
:
'
三方审核拒绝
'
,
13
:
'
客服审核通过
'
,
14
:
'
商户审核中
'
,
15
:
'
商户审核通过
'
,
16
:
'
商户审核拒绝
'
,
20
:
'
审核拒绝
'
,
21
:
'
申诉中
'
,
30
:
'
待填写退货物流信息
'
,
40
:
'
待退货入库
'
,
50
:
'
退货拒收
'
,
60
:
'
待退款
'
,
61
:
'
退货处理中
'
,
70
:
'
售后成功
'
,
99
:
'
用户取消
'
,
},
width
:
100
,
},
{
title
:
'
售后类型
'
,
dataIndex
:
'
type
'
,
hideInTable
:
true
,
width
:
120
,
valueEnum
:
{
1
:
'
仅退款
'
,
2
:
'
退货退款
'
,
},
},
{
title
:
'
收货人姓名
'
,
dataIndex
:
'
receiverName
'
,
dataIndex
:
'
receiverName
'
,
width
:
200
,
width
:
200
,
render
:
(
_
,
record
)
=>
{
const
{
receiverPhone
,
receiveAddress
}
=
record
;
return
(
<>
<
p
>
{
_
}
<
/p
>
<
p
>
{
receiverPhone
}
<
/p
>
<
p
>
{
receiveAddress
}
<
/p
>
<
/
>
);
},
},
{
title
:
'
收货人手机号
'
,
dataIndex
:
'
receiverPhone
'
,
width
:
200
,
},
{
title
:
'
收货人地址
'
,
dataIndex
:
'
receiveAddress
'
,
width
:
200
,
hideInSearch
:
true
,
},
},
{
{
title
:
'
订单开始时间
'
,
title
:
'
订单开始时间
'
,
...
@@ -149,31 +318,182 @@ export const columnSticData = [
...
@@ -149,31 +318,182 @@ export const columnSticData = [
hideInSearch
:
true
,
hideInSearch
:
true
,
width
:
200
,
width
:
200
,
},
},
];
export
const
columnPassAudit
=
[
...
columnSticData
,
{
{
title
:
'
商家退货地址
'
,
title
:
'
商家退货信息
'
,
dataIndex
:
'
merchantAddress
'
,
dataIndex
:
'
merchantAddress
'
,
hideInSearch
:
true
,
hideInSearch
:
true
,
width
:
200
,
width
:
200
,
render
:
(
_
,
record
)
=>
{
const
{
expressCompanyName
,
deliveryNo
}
=
record
;
return
(
<>
<
p
>
{
_
}
<
/p
>
<
p
>
{
expressCompanyName
}
<
/p
>
<
p
>
{
deliveryNo
}
<
/p
>
<
/
>
);
},
},
},
{
{
title
:
'
退回物流
'
,
title
:
'
售后凭证
'
,
dataIndex
:
'
expressCompanyName
'
,
dataIndex
:
'
proofs
'
,
hideInSearch
:
true
,
hideInSearch
:
true
,
width
:
150
,
width
:
100
,
render
:
(
val
,
r
)
=>
<
a
onClick
=
{()
=>
viewProofs
(
r
.
proofs
)}
>
查看凭证
<
/a>
,
},
},
{
{
title
:
'
退回物流单号
'
,
title
:
'
售后申诉
'
,
dataIndex
:
'
deliveryNo
'
,
dataIndex
:
'
appealFlag
'
,
valueEnum
:
appealType
,
hideInSearch
:
true
,
hideInSearch
:
true
,
width
:
200
,
width
:
120
,
render
:
(
appealFlag
,
r
)
=>
{
if
(
appealFlag
)
{
return
<
a
onClick
=
{()
=>
viewAppeal
(
r
)}
>
已申诉
<
/a>
;
}
return
<
div
>
未申诉
<
/div>
;
},
},
},
{
{
title
:
'
售后状态
'
,
title
:
'
操作
'
,
dataIndex
:
'
serviceStatus
'
,
hideInSearch
:
true
,
hideInSearch
:
true
,
width
:
120
,
dataIndex
:
'
action
'
,
width
:
250
,
fixed
:
'
right
'
,
render
:
(
val
,
record
)
=>
{
const
{
status
,
supplierType
,
serviceType
,
intercept
,
showRefuse
,
showRefund
,
showLogistics
,
showRefunded
,
}
=
record
;
// 是否是服务类商品
const
isServiceGoods
=
!
[
'
vip
'
,
'
self
'
].
includes
(
supplierType
);
// 按钮通用属性
const
btnProps
=
{
className
:
'
mr10 mt10
'
,
type
:
'
primary
'
,
};
const
refundBtnProps
=
{
title
:
'
确定允许退款?
'
,
okText
:
'
确认
'
,
cancelText
:
'
取消
'
,
key
:
'
pop
'
,
};
// 允许退款/已退款按钮
const
refundBtn
=
(
<
Popconfirm
{...
refundBtnProps
}
onConfirm
=
{()
=>
refund
(
record
)}
disabled
=
{
!
showRefund
}
>
<
Button
key
=
"
link1
"
disabled
=
{
!
showRefund
}
>
{
showRefunded
?
'
已退款
'
:
'
允许退款
'
}
<
/Button
>
<
/Popconfirm
>
);
// 审核按钮
let
auditBtn
=
(
<
Button
key
=
"
link2
"
onClick
=
{()
=>
openAudit
(
record
)}
{...
btnProps
}
>
审核
<
/Button
>
);
// 驳回按钮
let
refuseBtn
=
(
<
Button
key
=
"
link3
"
onClick
=
{()
=>
reject
(
record
)}
{...
btnProps
}
disabled
=
{
!
showRefuse
}
>
{
'
'
}
驳回
{
'
'
}
<
/Button
>
);
// 物流拦截按钮
let
logisticsInterceptionBtn
=
(
<
Button
key
=
"
link7
"
onClick
=
{()
=>
openLogistics
(
record
)}
{...
btnProps
}
disabled
=
{
serviceType
!==
1
||
(
serviceType
===
1
&&
intercept
)}
>
{
'
'
}
物流拦截
{
'
'
}
<
/Button
>
);
// 订单详情
const
detailBtn
=
(
<
Button
key
=
"
link4
"
onClick
=
{()
=>
viewDetail
(
record
)}
{...
btnProps
}
>
订单详情
<
/Button
>
);
// 查看物流
const
viewLogisticsBtn
=
(
<
Button
key
=
"
link5
"
onClick
=
{()
=>
handleCom
(
record
)}
{...
btnProps
}
disabled
=
{
!
showLogistics
}
>
{
'
'
}
退货物流
{
'
'
}
<
/Button
>
);
// 查看记录
const
viewLogBtn
=
(
<
Button
key
=
"
link6
"
onClick
=
{()
=>
viewLog
(
record
)}
{...
btnProps
}
>
{
'
'
}
查看记录
{
'
'
}
<
/Button
>
);
if
(
!
canEditable
)
{
auditBtn
=
''
;
refuseBtn
=
''
;
logisticsInterceptionBtn
=
''
;
}
// 服务商品 || 实物商品-仅退款未发货 serviceType = 0
if
(
isServiceGoods
||
serviceType
===
0
)
{
// 待商户审核14
if
([
14
].
includes
(
status
))
{
return
[
auditBtn
,
detailBtn
,
viewLogBtn
];
}
// 拒绝16, 处理成功70
if
([
16
,
70
].
includes
(
status
))
{
return
[
detailBtn
,
viewLogBtn
];
}
}
// 实物商品-仅退款 serviceType = 1
if
(
serviceType
===
1
)
{
// 待商户审核14
if
([
14
].
includes
(
status
))
{
return
[
auditBtn
,
detailBtn
,
viewLogBtn
,
logisticsInterceptionBtn
];
}
// 拒绝16/处理成功70
if
([
16
,
70
].
includes
(
status
))
{
return
[
detailBtn
,
viewLogBtn
];
}
}
// 实物商品-退货退款 serviceType = 2
if
(
serviceType
===
2
)
{
// 待商户审核14
if
([
14
].
includes
(
status
))
{
return
[
auditBtn
,
detailBtn
,
viewLogBtn
];
}
// 待退货入库40
if
([
40
].
includes
(
status
))
{
return
[
refundBtn
,
refuseBtn
,
viewLogisticsBtn
,
detailBtn
,
viewLogBtn
];
}
// 拒绝16/待填写退货物流信息30/处理成功70
if
([
16
,
30
,
70
].
includes
(
status
))
{
return
[
viewLogisticsBtn
,
detailBtn
,
viewLogBtn
];
}
}
return
[
detailBtn
,
viewLogBtn
];
},
},
];
},
];
};
src/pages/AfterSaleManage/index.jsx
View file @
7534953c
import
{
Tabs
}
from
'
antd
'
;
import
React
,
{
useRef
,
useState
,
useEffect
}
from
'
react
'
;
import
React
from
'
react
'
;
import
{
Tabs
,
notification
,
Form
,
Modal
}
from
'
antd
'
;
import
{
PageHeaderWrapper
}
from
'
@ant-design/pro-layout
'
;
import
{
PageHeaderWrapper
}
from
'
@ant-design/pro-layout
'
;
import
ProTable
from
'
@ant-design/pro-table
'
;
import
{
AFTER_SALE_ORDER
}
from
'
@/../config/permission.config
'
;
import
{
AFTER_SALE_ORDER
}
from
'
@/../config/permission.config
'
;
import
{
connect
}
from
'
dva
'
;
import
{
connect
}
from
'
dva
'
;
import
Pending
from
'
./Pending
'
;
import
{
FormSearch
}
from
'
@/components/FormSearch
'
;
import
PassAudit
from
'
./PassAudit
'
;
import
moment
from
'
moment
'
;
import
AuditModal
from
'
./components/auditModal
'
;
import
DetailTable
from
'
./components/detailTable
'
;
import
ProofsModal
from
'
./components/proofsModal
'
;
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
{
getColumns
,
getFormConfig
,
TAB_MAPPING_DATA
}
from
'
./data.js
'
;
import
{
getDetail
}
from
'
@/pages/afterSale/appeal/services
'
;
import
{
searchList
,
logisticsIntercept
,
orderDetail
,
getOpLog
,
auditInfoApi
,
trackInfo
,
shopCheck
,
getAfterPendingNum
,
}
from
'
./services
'
;
import
styles
from
'
./index.less
'
;
const
{
TabPane
}
=
Tabs
;
const
{
TabPane
}
=
Tabs
;
const
{
confirm
}
=
Modal
;
function
AfterSale
(
props
)
{
const
AfterSale
=
props
=>
{
const
{
permissions
}
=
props
;
const
{
permissions
}
=
props
;
const
canEditable
=
permissions
[
AFTER_SALE_ORDER
.
EDITABLE
];
const
canEditable
=
permissions
[
AFTER_SALE_ORDER
.
EDITABLE
];
const
actionRef
=
useRef
();
const
formRef
=
useRef
();
const
[
tableParams
,
setTableParams
]
=
useState
({});
const
[
currentTab
,
setCurrentTab
]
=
useState
(
''
);
const
[
appealDetailModal
,
setAppealDetailModal
]
=
useState
(
false
);
const
[
selectedRow
,
setSelectedRow
]
=
useState
({});
const
[
tabInfoData
,
setTabInfoData
]
=
useState
({});
// 申诉
const
[
proofsData
,
setProofsData
]
=
useState
([]);
const
[
proofsVisible
,
setProofsVisible
]
=
useState
(
false
);
// 详情
const
[
detailVisible
,
setDetailVisible
]
=
useState
(
false
);
const
[
detailInfo
,
setDetailInfo
]
=
useState
([]);
// 售后操作记录
const
[
afterVisible
,
setAfterVisible
]
=
useState
(
false
);
const
[
afterList
,
setAfterList
]
=
useState
([]);
// 审核
const
[
visible
,
setVisible
]
=
useState
(
false
);
const
[
auditInfo
,
setAuditInfo
]
=
useState
({});
// 查看物流
const
[
LogisticsComList
,
setLogisticsComList
]
=
useState
({});
const
[
logisticsComModalVisible
,
setLogisticsComModalVisible
]
=
useState
(
false
);
// 驳回
const
[
serviceNoInfo
,
setServiceNoInfo
]
=
useState
({});
const
[
rejectVisible
,
setRejectVisible
]
=
useState
(
false
);
// 关闭modal
const
closeModal
=
isReload
=>
{
if
(
isReload
===
true
)
{
// eslint-disable-next-line no-unused-expressions
actionRef
.
current
?.
reload
?.();
}
setVisible
(
false
);
setDetailVisible
(
false
);
setProofsVisible
(
false
);
setAppealDetailModal
(
false
);
setAfterVisible
(
false
);
setLogisticsComModalVisible
(
false
);
};
// 查看申诉详情
const
viewAppeal
=
async
r
=>
{
const
detailData
=
await
getDetail
({
appealNo
:
r
.
appealNo
});
setAppealDetailModal
(
true
);
setSelectedRow
(
detailData
);
};
// 查看凭证
const
viewProofs
=
proofs
=>
{
if
(
!
proofs
)
{
notification
.
warning
({
message
:
'
该订单没有凭证
'
});
return
;
}
const
list
=
proofs
.
replace
(
/
(\u
ff1b|
\u
ff0c|
\u
003b
)
/g
,
'
,
'
).
split
(
'
,
'
);
setProofsData
(
list
);
setProofsVisible
(
true
);
};
// 审核
const
openAudit
=
async
({
serviceNo
,
serviceType
,
orderNo
})
=>
{
const
data
=
await
auditInfoApi
({
serviceNo
});
setAuditInfo
({
...
data
?.
data
,
serviceNo
,
serviceType
,
orderNo
});
setVisible
(
true
);
};
// 查看物流
const
handleCom
=
async
({
expressCompanyCode
,
deliveryNo
})
=>
{
const
tempObj
=
{
detailList
:
[],
key
:
Date
.
now
(),
};
const
data
=
await
trackInfo
({
expressCompanyCode
,
logisticsNo
:
deliveryNo
});
if
(
!
data
)
{
notification
.
info
({
message
:
'
暂无物流信息
'
});
return
;
}
tempObj
.
expressCompanyName
=
data
.
logisticsName
;
tempObj
.
deliveryNo
=
data
.
logisticsBillNo
;
if
(
data
.
logisticsList
?.
length
)
{
data
.
logisticsList
.
forEach
(
v
=>
{
tempObj
.
detailList
=
[...
tempObj
.
detailList
,
...
v
.
detailList
];
});
}
setLogisticsComModalVisible
(
true
);
setLogisticsComList
(
tempObj
);
};
// 物流拦截
const
openLogistics
=
r
=>
{
confirm
({
title
:
'
温馨提示
'
,
okText
:
'
确认拦截
'
,
cancelText
:
'
取消拦截
'
,
content
:
(
<
div
>
请48小时内自行联系物流公司进行物流拦截,系统监测拦截成功后
<
span
className=
{
styles
.
redTipBold
}
>
自动同意
</
span
>
退款
</
div
>
),
async
onOk
()
{
const
data
=
await
logisticsIntercept
({
serviceNo
:
r
.
serviceNo
});
if
(
data
.
businessCode
===
'
0000
'
)
{
notification
.
success
({
message
:
'
拦截成功
'
});
actionRef
.
current
.
reload
();
}
else
{
notification
.
error
({
message
:
data
.
msg
||
'
拦截失败
'
});
}
},
onCancel
()
{
console
.
log
(
'
Cancel
'
);
},
});
};
// 查看
const
viewDetail
=
async
({
serviceNo
})
=>
{
const
res
=
await
orderDetail
({
serviceNo
});
const
data
=
res
.
data
||
[];
setDetailInfo
(
data
);
setDetailVisible
(
true
);
};
// 查看售后操作日志
const
viewLog
=
async
r
=>
{
const
data
=
await
getOpLog
(
r
.
serviceNo
);
if
(
data
?.
data
?.
length
)
{
setAfterList
(
data
.
data
);
setAfterVisible
(
true
);
}
};
// 已退款/允许退款
const
refund
=
async
({
serviceNo
})
=>
{
const
data
=
await
shopCheck
({
serviceNo
,
auditResult
:
1
,
});
if
(
data
.
businessCode
===
'
0000
'
)
{
notification
.
success
({
message
:
'
操作成功
'
});
closeModal
(
true
);
}
};
// 驳回
const
reject
=
async
({
serviceNo
})
=>
{
setServiceNoInfo
(
serviceNo
);
setRejectVisible
(
true
);
};
const
[
form
]
=
Form
.
useForm
();
const
formConfig
=
getFormConfig
({
actionRef
,
tableParams
,
setTableParams
,
setCurrentTab
,
});
const
FormSearchProps
=
{
form
,
initialValues
:
{},
formOptions
:
{},
...
formConfig
,
};
// tab选项框回调
const
tabChange
=
tabIndex
=>
{
setCurrentTab
(
tabIndex
);
const
{
type
,
dealStatus
}
=
TAB_MAPPING_DATA
[
tabIndex
];
form
.
setFieldsValue
({
dealStatus
,
type
,
});
setTableParams
({
...
tableParams
,
dealStatus
,
type
});
};
const
columns
=
getColumns
({
openAudit
,
viewAppeal
,
viewProofs
,
openLogistics
,
viewDetail
,
viewLog
,
handleCom
,
refund
,
reject
,
canEditable
,
});
// 表格属性
const
tableProps
=
{
columns
,
params
:
tableParams
,
bordered
:
true
,
scroll
:
{
x
:
'
100%
'
,
y
:
500
},
rowKey
:
r
=>
r
.
serviceNo
,
request
:
async
params
=>
{
console
.
log
(
params
);
console
.
log
(
'
搜索
'
,
params
);
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
requestParams
=
{
page
,
size
,
...
params
,
startDate
,
endDate
,
};
const
res
=
await
searchList
(
requestParams
);
const
{
records
=
[],
total
}
=
res
.
data
;
return
{
data
:
records
,
total
,
};
},
toolBarRender
:
null
,
};
const
getPendingNum
=
async
()
=>
{
const
params
=
{
startDate
:
new
Date
(
'
2020/01/01 00:00:00
'
),
endDate
:
new
Date
(),
};
const
res
=
await
getAfterPendingNum
(
params
);
console
.
log
(
res
);
};
useEffect
(()
=>
{
getPendingNum
();
},
[]);
return
(
return
(
<
PageHeaderWrapper
>
<
PageHeaderWrapper
>
<
Tabs
defaultActiveKey=
"1"
>
<
FormSearch
{
...
FormSearchProps
}
/>
<
TabPane
tab=
"未审核"
key=
"1"
>
<
div
className=
{
styles
[
'
tab-box
'
]
}
>
<
Pending
canEditable=
{
canEditable
}
/>
<
Tabs
</
TabPane
>
activeKey=
{
currentTab
}
<
TabPane
tab=
"已审核"
key=
"2"
>
onChange=
{
tabChange
}
<
PassAudit
canEditable=
{
canEditable
}
/>
size=
"large"
</
TabPane
>
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
>
</
Tabs
>
</
Tabs
>
</
div
>
<
ProTable
{
...
tableProps
}
actionRef=
{
actionRef
}
formRef=
{
formRef
}
search=
{
false
}
// toolBarRender={false}
/>
<
AuditModal
visible=
{
visible
}
onCancel=
{
closeModal
}
formData=
{
auditInfo
}
/>
<
DetailTable
visible=
{
detailVisible
}
onCancel=
{
closeModal
}
dataSource=
{
detailInfo
}
/>
<
ProofsModal
visible=
{
proofsVisible
}
onCancel=
{
closeModal
}
data=
{
proofsData
}
/>
<
LogisticsCom
onSubmit=
{
closeModal
}
onCancel=
{
closeModal
}
modalVisible=
{
logisticsComModalVisible
}
value=
{
LogisticsComList
}
key=
{
LogisticsComList
.
key
}
/>
<
AppealDetail
data=
{
selectedRow
}
modalVisible=
{
appealDetailModal
}
onCancel=
{
closeModal
}
></
AppealDetail
>
<
AfterLog
visible=
{
afterVisible
}
onCancel=
{
closeModal
}
data=
{
afterList
}
/>
<
RejectModal
visible=
{
rejectVisible
}
onCancel=
{
closeModal
}
serviceNo=
{
serviceNoInfo
}
/>
</
PageHeaderWrapper
>
</
PageHeaderWrapper
>
);
);
}
}
;
export
default
connect
(({
menu
})
=>
({
export
default
connect
(({
menu
})
=>
({
permissions
:
menu
.
permissions
,
permissions
:
menu
.
permissions
,
...
...
src/pages/AfterSaleManage
New
/index.less
→
src/pages/AfterSaleManage/index.less
View file @
7534953c
File moved
src/pages/AfterSaleManage/services.js
View file @
7534953c
...
@@ -6,42 +6,50 @@ import _ from 'lodash';
...
@@ -6,42 +6,50 @@ import _ from 'lodash';
const
{
kdspApi
}
=
config
;
const
{
kdspApi
}
=
config
;
// 分页查询所有数据
// 分页查询所有数据
export
async
function
searchList
(
params
,
queryStatus
)
{
export
const
searchList
=
params
=>
const
param
=
{
request
.
post
(
'
/api/kdsp/op/afs/shop/list
'
,
{
...
params
,
pageNo
:
params
.
current
,
pageSize
:
params
.
pageSize
||
20
,
queryStatus
,
};
const
data
=
await
request
.
post
(
'
/api/kdsp/op/afs/shop/list
'
,
{
prefix
:
kdspApi
,
prefix
:
kdspApi
,
data
:
stringify
(
_
.
omitBy
(
param
,
v
=>
!
v
)),
data
:
stringify
(
_
.
omitBy
(
param
s
,
v
=>
!
v
)),
headers
:
{
headers
:
{
'
Content-Type
'
:
'
application/x-www-form-urlencoded
'
,
'
Content-Type
'
:
'
application/x-www-form-urlencoded
'
,
},
},
});
});
if
(
data
.
data
)
{
return
{
// export async function searchList(params, queryStatus) {
total
:
data
.
data
.
total
,
// const param = {
data
:
data
.
data
.
records
,
// ...params,
};
// pageNo: params.current,
}
// pageSize: params.pageSize || 20,
return
{
// queryStatus,
total
:
0
,
// };
data
:
[],
// const data = await request.post('/api/kdsp/op/afs/shop/list', {
};
// prefix: kdspApi,
}
// data: stringify(_.omitBy(param, v => !v)),
// headers: {
// 'Content-Type': 'application/x-www-form-urlencoded',
// },
// });
// if (data.data) {
// return {
// total: data.data.total,
// data: data.data.records,
// };
// }
// return {
// total: 0,
// data: [],
// };
// }
// 售后单详情
// 售后单详情
export
async
function
orderDetail
(
params
)
{
export
function
orderDetail
(
params
)
{
const
data
=
await
request
.
get
(
'
/api/kdsp/op/afs/sku
'
,
{
return
request
.
get
(
'
/api/kdsp/op/afs/sku
'
,
{
prefix
:
kdspApi
,
prefix
:
kdspApi
,
params
,
params
,
headers
:
{
headers
:
{
'
Content-Type
'
:
'
application/x-www-form-urlencoded
'
,
'
Content-Type
'
:
'
application/x-www-form-urlencoded
'
,
},
},
});
});
return
data
.
data
||
[];
}
}
// 售后审核
// 售后审核
export
async
function
shopAudit
(
params
)
{
export
async
function
shopAudit
(
params
)
{
...
@@ -93,3 +101,18 @@ export async function getOpLog(params) {
...
@@ -93,3 +101,18 @@ export async function getOpLog(params) {
prefix
:
kdspApi
,
prefix
:
kdspApi
,
});
});
}
}
// 查询物流记录信息
export
async
function
getLogisticsRecord
(
params
)
{
return
request
.
get
(
`/api/kdsp/op/logistics/kd100/track-list?orderNo=
${
params
.
orderNo
}
`
,
{
prefix
:
kdspApi
,
});
}
// 查询售后待办数量
export
function
getAfterPendingNum
(
data
)
{
return
request
.
post
(
'
/api/kdsp/op/afs/getPendingNum
'
,
{
prefix
:
kdspApi
,
data
,
});
}
src/pages/AfterSaleManageNew/data.js
deleted
100644 → 0
View file @
17b8b15c
import
{
Tag
,
Badge
,
Statistic
,
Button
}
from
'
antd
'
;
import
React
from
'
react
'
;
import
moment
from
'
moment
'
;
import
{
SEARCH_TYPE
}
from
'
@/components/FormSearch
'
;
const
{
Countdown
}
=
Statistic
;
// 商户审核中/商户审核拒绝/待填写退货物流信息/待退货入库/退货拒收/退款成功/用户撤销”
// 仅退款(未发货)/仅退款/退货退款,新增【仅退款(未发货)】即取消订单待审核
// 售后类型
const
AFTER_TYPE
=
[
{
value
:
'
1
'
,
name
:
'
商户审核中
'
,
},
{
value
:
'
2
'
,
name
:
'
商户审核拒绝
'
,
},
{
value
:
'
3
'
,
name
:
'
待填写退货物流信息
'
,
},
{
value
:
'
4
'
,
name
:
'
待退货入库
'
,
},
{
value
:
'
5
'
,
name
:
'
退货拒收
'
,
},
{
value
:
'
5
'
,
name
:
'
退款成功
'
,
},
{
value
:
'
6
'
,
name
:
'
用户撤销”
'
,
},
];
// 售后状态
const
AFTER_STATUS
=
[
{
value
:
'
1
'
,
name
:
'
仅退款(未发货)
'
,
},
{
value
:
'
1
'
,
name
:
'
仅退款
'
,
},
{
value
:
'
1
'
,
name
:
'
退货退款
'
,
},
];
export
const
getFormConfig
=
(
props
=
{})
=>
{
const
{
setTableParams
}
=
props
;
return
{
formConfig
:
[
{
type
:
SEARCH_TYPE
.
INPUT
,
label
:
'
订单ID
'
,
bindKey
:
'
orderNo
'
,
column
:
5
,
},
{
type
:
SEARCH_TYPE
.
INPUT
,
label
:
'
售后单ID
'
,
bindKey
:
'
serviceNo
'
,
column
:
5
,
},
{
type
:
SEARCH_TYPE
.
SELECT
,
label
:
'
售后状态
'
,
column
:
5
,
bindKey
:
'
dealStatus
'
,
options
:
AFTER_STATUS
,
},
{
type
:
SEARCH_TYPE
.
SELECT
,
label
:
'
售后类型
'
,
column
:
5
,
bindKey
:
'
type
'
,
options
:
AFTER_TYPE
,
},
{
type
:
SEARCH_TYPE
.
INPUT
,
label
:
'
收货人姓名
'
,
column
:
5
,
bindKey
:
'
receiverName
'
,
},
{
type
:
SEARCH_TYPE
.
INPUT
,
label
:
'
收货人手机号
'
,
column
:
5
,
bindKey
:
'
receiverPhone
'
,
},
{
type
:
SEARCH_TYPE
.
DATE_PICKER
,
label
:
'
订单开始日期
'
,
column
:
5
,
bindKey
:
'
startDate
'
,
},
{
type
:
SEARCH_TYPE
.
DATE_PICKER
,
label
:
'
订单结束日期
'
,
column
:
5
,
bindKey
:
'
endDate
'
,
},
],
btnConfig
:
[
{
label
:
'
筛选
'
,
clickType
:
'
submit
'
,
onClick
:
({
type
,
params
})
=>
{
setTableParams
(
params
);
},
},
{
label
:
'
重置
'
,
type
:
''
,
clickType
:
'
reset
'
,
onClick
:
()
=>
{
setTableParams
({});
},
},
],
};
};
export
const
appealType
=
{
1
:
'
已申诉
'
,
0
:
'
未申诉
'
,
};
export
const
getColumns
=
props
=>
{
const
{
openAudit
,
viewAppeal
,
viewProofs
,
openLogistics
,
viewDetail
,
viewLog
,
canEditable
,
}
=
props
;
return
[
{
title
:
'
审核倒计时
'
,
dataIndex
:
'
serviceTime
'
,
key
:
'
serviceTime
'
,
hideInSearch
:
true
,
width
:
150
,
render
:
(
val
,
record
)
=>
{
const
serviceTime
=
moment
(
record
.
approvalEndTime
).
valueOf
();
return
(
<
Countdown
format
=
"
HH时mm分ss秒
"
value
=
{
serviceTime
}
valueStyle
=
{{
color
:
'
red
'
,
fontSize
:
'
14px
'
}}
/
>
);
},
},
{
title
:
'
售后状态
'
,
dataIndex
:
'
serviceStatus
'
,
hideInSearch
:
true
,
width
:
120
,
},
{
title
:
'
售后类型
'
,
dataIndex
:
'
serviceType
'
,
hideInSearch
:
true
,
width
:
120
,
render
:
serviceType
=>
{
if
(
+
serviceType
===
1
)
{
return
<
span
style
=
{{
color
:
'
#ff1616
'
}}
>
仅退款
<
/span>
;
}
return
<
span
>
退货退款
<
/span>
;
},
},
{
title
:
'
订单ID
'
,
dataIndex
:
'
orderNo
'
,
hideInTable
:
true
,
width
:
200
,
},
{
title
:
'
售后单ID
'
,
dataIndex
:
'
serviceNo
'
,
width
:
300
,
render
:
(
serviceNo
,
r
)
=>
(
<
div
>
{
r
.
timeout
?
<
Tag
color
=
"
red
"
>
{
serviceNo
}
<
/Tag> : serviceNo
}
{
<
Badge
count
=
{
r
.
reminderFlag
?
'
催
'
:
''
}
size
=
"
default
"
/>
}
<
/div
>
),
},
{
title
:
'
订单ID
'
,
dataIndex
:
'
orderNo
'
,
hideInSearch
:
true
,
width
:
300
,
},
{
title
:
'
售后状态
'
,
dataIndex
:
'
dealStatus
'
,
hideInTable
:
true
,
valueEnum
:
{
0
:
'
待审核
'
,
10
:
'
三方审核中
'
,
11
:
'
三方审核通过
'
,
12
:
'
三方审核拒绝
'
,
13
:
'
客服审核通过
'
,
14
:
'
商户审核中
'
,
15
:
'
商户审核通过
'
,
16
:
'
商户审核拒绝
'
,
20
:
'
审核拒绝
'
,
21
:
'
申诉中
'
,
30
:
'
待填写退货物流信息
'
,
40
:
'
待退货入库
'
,
50
:
'
退货拒收
'
,
60
:
'
待退款
'
,
61
:
'
退货处理中
'
,
70
:
'
售后成功
'
,
99
:
'
用户取消
'
,
},
width
:
100
,
},
{
title
:
'
售后类型
'
,
dataIndex
:
'
type
'
,
hideInTable
:
true
,
width
:
120
,
valueEnum
:
{
1
:
'
仅退款
'
,
2
:
'
退货退款
'
,
},
},
{
title
:
'
收货人姓名
'
,
dataIndex
:
'
receiverName
'
,
width
:
200
,
},
{
title
:
'
收货人手机号
'
,
dataIndex
:
'
receiverPhone
'
,
width
:
200
,
},
{
title
:
'
收货人地址
'
,
dataIndex
:
'
receiveAddress
'
,
width
:
200
,
hideInSearch
:
true
,
},
{
title
:
'
订单开始时间
'
,
width
:
120
,
dataIndex
:
'
startDate
'
,
key
:
'
startDate
'
,
valueType
:
'
date
'
,
hideInTable
:
true
,
},
{
title
:
'
订单结束时间
'
,
width
:
120
,
dataIndex
:
'
endDate
'
,
key
:
'
endDate
'
,
valueType
:
'
date
'
,
hideInTable
:
true
,
},
{
title
:
'
售后原因
'
,
dataIndex
:
'
serviceReason
'
,
hideInSearch
:
true
,
width
:
200
,
},
{
title
:
'
售后发生时间
'
,
dataIndex
:
'
serviceTime
'
,
hideInSearch
:
true
,
width
:
200
,
},
{
title
:
'
超时时间
'
,
dataIndex
:
'
overtime
'
,
hideInSearch
:
true
,
width
:
200
,
},
{
title
:
'
是否催办
'
,
dataIndex
:
'
reminderFlag
'
,
hideInSearch
:
true
,
width
:
120
,
valueEnum
:
{
true
:
'
是
'
,
false
:
'
否
'
,
},
},
{
title
:
'
是否同意售后
'
,
dataIndex
:
'
isAgree
'
,
hideInSearch
:
true
,
width
:
120
,
},
{
title
:
'
拒绝原因
'
,
dataIndex
:
'
refuseReason
'
,
hideInSearch
:
true
,
width
:
200
,
},
{
title
:
'
售后凭证
'
,
dataIndex
:
'
proofs
'
,
hideInSearch
:
true
,
width
:
100
,
render
:
(
val
,
r
)
=>
<
a
onClick
=
{()
=>
viewProofs
(
r
.
proofs
)}
>
查看凭证
<
/a>
,
},
{
title
:
'
售后申诉
'
,
dataIndex
:
'
appealFlag
'
,
valueEnum
:
appealType
,
hideInSearch
:
true
,
width
:
120
,
render
:
(
appealFlag
,
r
)
=>
{
if
(
appealFlag
)
{
return
<
a
onClick
=
{()
=>
viewAppeal
(
r
)}
>
已申诉
<
/a>
;
}
return
<
div
>
未申诉
<
/div>
;
},
},
{
title
:
'
操作
'
,
hideInSearch
:
true
,
dataIndex
:
'
action
'
,
width
:
250
,
fixed
:
'
right
'
,
render
:
(
val
,
r
)
=>
{
const
operations
=
[
<
Button
key
=
"
link1
"
onClick
=
{()
=>
openAudit
(
r
)}
className
=
"
mr10 mt10
"
type
=
"
primary
"
>
审核
<
/Button>
,
<
Button
disabled
=
{
r
.
serviceType
!==
1
||
(
r
.
serviceType
===
1
&&
r
.
intercept
)}
onClick
=
{()
=>
openLogistics
(
r
)}
className
=
"
mr10 mt10
"
type
=
"
primary
"
>
物流拦截
<
/Button>
,
<
Button
className
=
"
mr10 mt10
"
key
=
"
link
"
onClick
=
{()
=>
viewDetail
(
r
)}
type
=
"
primary
"
>
订单详情
<
/Button>
,
<
Button
className
=
"
mr10 mt10
"
type
=
"
primary
"
onClick
=
{()
=>
viewLog
(
r
)}
>
查看记录
<
/Button>
,
];
// 不可编辑直接隐藏可操作按钮
if
(
!
canEditable
)
{
return
[
operations
[
2
],
operations
[
3
]];
}
// 服务订单删除物流拦截
if
(
!
[
'
vip
'
,
'
self
'
].
includes
(
r
.
supplierType
))
{
return
[
operations
[
0
],
operations
[
2
],
operations
[
3
]];
}
return
operations
;
},
},
];
};
src/pages/AfterSaleManageNew/index.jsx
deleted
100644 → 0
View file @
17b8b15c
import
React
,
{
useRef
,
useState
}
from
'
react
'
;
import
{
Tabs
,
notification
,
Form
,
Modal
}
from
'
antd
'
;
import
{
PageHeaderWrapper
}
from
'
@ant-design/pro-layout
'
;
import
ProTable
from
'
@ant-design/pro-table
'
;
import
{
AFTER_SALE_ORDER
}
from
'
@/../config/permission.config
'
;
import
{
connect
}
from
'
dva
'
;
import
{
FormSearch
}
from
'
@/components/FormSearch
'
;
import
moment
from
'
moment
'
;
import
AuditModal
from
'
./components/auditModal
'
;
import
DetailTable
from
'
./components/detailTable
'
;
import
ProofsModal
from
'
./components/proofsModal
'
;
import
AppealDetail
from
'
@/pages/afterSale/components/detail
'
;
import
AfterLog
from
'
./components/AfterLog
'
;
import
{
getColumns
,
getFormConfig
}
from
'
./data.js
'
;
import
{
getDetail
}
from
'
@/pages/afterSale/appeal/services
'
;
import
{
searchList
,
logisticsIntercept
,
orderDetail
,
getOpLog
,
auditInfoApi
}
from
'
./services
'
;
import
styles
from
'
./index.less
'
;
const
{
TabPane
}
=
Tabs
;
const
{
confirm
}
=
Modal
;
const
AfterSale
=
props
=>
{
const
{
permissions
}
=
props
;
const
canEditable
=
permissions
[
AFTER_SALE_ORDER
.
EDITABLE
];
const
actionRef
=
useRef
();
const
formRef
=
useRef
();
const
[
tableParams
,
setTableParams
]
=
useState
({});
const
[
appealDetailModal
,
setAppealDetailModal
]
=
useState
(
false
);
const
[
selectedRow
,
setSelectedRow
]
=
useState
({});
// 申诉
const
[
proofsData
,
setProofsData
]
=
useState
([]);
const
[
proofsVisible
,
setProofsVisible
]
=
useState
(
false
);
// 详情
const
[
detailVisible
,
setDetailVisible
]
=
useState
(
false
);
const
[
detailInfo
,
setDetailInfo
]
=
useState
([]);
// 售后操作记录
const
[
afterVisible
,
setAfterVisible
]
=
useState
(
false
);
const
[
afterList
,
setAfterList
]
=
useState
([]);
// 审核
const
[
visible
,
setVisible
]
=
useState
(
false
);
const
[
auditInfo
,
setAuditInfo
]
=
useState
({});
// 关闭modal
const
closeModal
=
isReload
=>
{
if
(
isReload
===
true
)
{
// eslint-disable-next-line no-unused-expressions
actionRef
.
current
?.
reload
?.();
}
setVisible
(
false
);
setDetailVisible
(
false
);
setProofsVisible
(
false
);
setAppealDetailModal
(
false
);
setAfterVisible
(
false
);
};
// 查看申诉详情
const
viewAppeal
=
async
r
=>
{
const
detailData
=
await
getDetail
({
appealNo
:
r
.
appealNo
});
setAppealDetailModal
(
true
);
setSelectedRow
(
detailData
);
};
// 查看凭证
const
viewProofs
=
proofs
=>
{
if
(
!
proofs
)
{
notification
.
warning
({
message
:
'
该订单没有凭证
'
});
return
;
}
const
list
=
proofs
.
replace
(
/
(\u
ff1b|
\u
ff0c|
\u
003b
)
/g
,
'
,
'
).
split
(
'
,
'
);
setProofsData
(
list
);
setProofsVisible
(
true
);
};
// 审核
const
openAudit
=
async
({
serviceNo
,
serviceType
})
=>
{
const
data
=
await
auditInfoApi
({
serviceNo
});
setAuditInfo
({
...
data
?.
data
,
serviceNo
,
serviceType
});
setVisible
(
true
);
};
// 物流拦截
const
openLogistics
=
r
=>
{
confirm
({
title
:
'
温馨提示
'
,
okText
:
'
确认拦截
'
,
cancelText
:
'
取消拦截
'
,
content
:
(
<
div
>
请48小时内自行联系物流公司进行物流拦截,系统监测拦截成功后
<
span
className=
{
styles
.
redTipBold
}
>
自动同意
</
span
>
退款
</
div
>
),
async
onOk
()
{
const
data
=
await
logisticsIntercept
({
serviceNo
:
r
.
serviceNo
});
if
(
data
.
businessCode
===
'
0000
'
)
{
notification
.
success
({
message
:
'
拦截成功
'
});
actionRef
.
current
.
reload
();
}
else
{
notification
.
error
({
message
:
data
.
msg
||
'
拦截失败
'
});
}
},
onCancel
()
{
console
.
log
(
'
Cancel
'
);
},
});
};
// 查看
const
viewDetail
=
async
({
serviceNo
})
=>
{
const
res
=
await
orderDetail
({
serviceNo
});
const
data
=
res
.
data
||
[];
setDetailInfo
(
data
);
setDetailVisible
(
true
);
};
// 查看售后操作日志
const
viewLog
=
async
r
=>
{
const
data
=
await
getOpLog
(
r
.
serviceNo
);
if
(
data
?.
data
?.
length
)
{
setAfterList
(
data
.
data
);
setAfterVisible
(
true
);
}
};
const
tabChange
=
e
=>
{
console
.
log
(
e
);
};
const
[
form
]
=
Form
.
useForm
();
const
formConfig
=
getFormConfig
({
setTableParams
,
});
const
FormSearchProps
=
{
form
,
initialValues
:
{},
formOptions
:
{},
...
formConfig
,
};
const
columns
=
getColumns
({
openAudit
,
viewAppeal
,
viewProofs
,
openLogistics
,
viewDetail
,
viewLog
,
canEditable
,
});
// 表格属性
const
tableProps
=
{
columns
,
params
:
tableParams
,
bordered
:
true
,
scroll
:
{
x
:
'
100%
'
,
y
:
500
},
rowKey
:
r
=>
r
.
serviceNo
,
request
:
async
params
=>
{
console
.
log
(
params
);
console
.
log
(
'
搜索
'
,
params
);
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
requestParams
=
{
page
,
size
,
queryStatus
:
1
,
...
params
,
startDate
,
endDate
,
};
const
res
=
await
searchList
(
requestParams
);
const
{
records
=
[],
total
}
=
res
.
data
;
return
{
data
:
records
,
total
,
};
},
toolBarRender
:
null
,
};
return
(
<
PageHeaderWrapper
>
<
FormSearch
{
...
FormSearchProps
}
/>
<
div
className=
{
styles
[
'
tab-box
'
]
}
>
<
Tabs
onChange=
{
tabChange
}
size=
"large"
tabBarStyle=
{
{
padding
:
'
0 30px
'
}
}
>
<
TabPane
key=
""
tab=
"全部"
></
TabPane
>
<
TabPane
key=
{
1
}
tab=
"仅退款(未发货)"
></
TabPane
>
<
TabPane
key=
{
2
}
tab=
"待审核0"
></
TabPane
>
<
TabPane
key=
{
3
}
tab=
"仅退款待审核8"
></
TabPane
>
<
TabPane
key=
{
4
}
tab=
"退货退款待审核0"
></
TabPane
>
<
TabPane
key=
{
5
}
tab=
"退货入库待审核0"
></
TabPane
>
<
TabPane
key=
{
6
}
tab=
"已完成0"
></
TabPane
>
</
Tabs
>
</
div
>
<
ProTable
{
...
tableProps
}
actionRef=
{
actionRef
}
formRef=
{
formRef
}
search=
{
false
}
toolBarRender=
{
false
}
/>
<
AuditModal
visible=
{
visible
}
onCancel=
{
closeModal
}
formData=
{
auditInfo
}
/>
<
DetailTable
visible=
{
detailVisible
}
onCancel=
{
closeModal
}
dataSource=
{
detailInfo
}
/>
<
ProofsModal
visible=
{
proofsVisible
}
onCancel=
{
closeModal
}
data=
{
proofsData
}
/>
<
AppealDetail
data=
{
selectedRow
}
modalVisible=
{
appealDetailModal
}
onCancel=
{
closeModal
}
></
AppealDetail
>
<
AfterLog
visible=
{
afterVisible
}
onCancel=
{
closeModal
}
data=
{
afterList
}
/>
</
PageHeaderWrapper
>
);
};
export
default
connect
(({
menu
})
=>
({
permissions
:
menu
.
permissions
,
}))(
AfterSale
);
src/pages/AfterSaleManage/PassAudit/index.jsx
→
src/pages/AfterSaleManage
Old
/PassAudit/index.jsx
View file @
7534953c
File moved
src/pages/AfterSaleManage/Pending/index.jsx
→
src/pages/AfterSaleManage
Old
/Pending/index.jsx
View file @
7534953c
File moved
src/pages/AfterSaleManage
New
/components/AfterLog.jsx
→
src/pages/AfterSaleManage
Old
/components/AfterLog.jsx
View file @
7534953c
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
/* eslint-disable guard-for-in */
/* eslint-disable guard-for-in */
import
React
,
{
useState
,
useEffect
}
from
'
react
'
;
import
React
,
{
useState
,
useEffect
}
from
'
react
'
;
import
{
Modal
,
Timeline
,
Button
}
from
'
antd
'
;
import
{
Modal
,
Timeline
,
Button
}
from
'
antd
'
;
import
styles
from
'
../
index
.less
'
;
import
styles
from
'
../
styles
.less
'
;
const
LogisticsCom
=
props
=>
{
const
LogisticsCom
=
props
=>
{
const
{
visible
,
onCancel
,
data
}
=
props
;
const
{
visible
,
onCancel
,
data
}
=
props
;
...
...
src/pages/AfterSaleManage
New
/components/auditModal.jsx
→
src/pages/AfterSaleManage
Old
/components/auditModal.jsx
View file @
7534953c
...
@@ -3,7 +3,7 @@ import { Form } from '@ant-design/compatible';
...
@@ -3,7 +3,7 @@ import { Form } from '@ant-design/compatible';
import
'
@ant-design/compatible/assets/index.css
'
;
import
'
@ant-design/compatible/assets/index.css
'
;
import
{
Modal
,
Input
,
Cascader
,
notification
,
InputNumber
}
from
'
antd
'
;
import
{
Modal
,
Input
,
Cascader
,
notification
,
InputNumber
}
from
'
antd
'
;
import
{
shopAudit
}
from
'
../services
'
;
import
{
shopAudit
}
from
'
../services
'
;
import
styles
from
'
../
index
.less
'
;
import
styles
from
'
../
styles
.less
'
;
const
FormItem
=
Form
.
Item
;
const
FormItem
=
Form
.
Item
;
const
{
TextArea
}
=
Input
;
const
{
TextArea
}
=
Input
;
...
...
src/pages/AfterSaleManage
New
/components/detailTable.jsx
→
src/pages/AfterSaleManage
Old
/components/detailTable.jsx
View file @
7534953c
File moved
src/pages/AfterSaleManage
New
/components/proofsModal.jsx
→
src/pages/AfterSaleManage
Old
/components/proofsModal.jsx
View file @
7534953c
import
React
,
{
useState
}
from
'
react
'
;
import
React
,
{
useState
}
from
'
react
'
;
import
{
Modal
}
from
'
antd
'
;
import
{
Modal
}
from
'
antd
'
;
import
style
from
'
../
index
.less
'
;
import
style
from
'
../
styles
.less
'
;
export
default
props
=>
{
export
default
props
=>
{
const
{
visible
,
onCancel
,
data
}
=
props
;
const
{
visible
,
onCancel
,
data
}
=
props
;
...
...
src/pages/AfterSaleManage
New
/components/rejectModal.jsx
→
src/pages/AfterSaleManage
Old
/components/rejectModal.jsx
View file @
7534953c
File moved
src/pages/AfterSaleManageOld/data.js
0 → 100644
View file @
7534953c
import
{
Tag
,
Badge
}
from
'
antd
'
;
import
React
from
'
react
'
;
export
const
appealType
=
{
1
:
'
已申诉
'
,
0
:
'
未申诉
'
,
};
export
const
columnSticData
=
[
{
title
:
'
售后类型
'
,
dataIndex
:
'
serviceType
'
,
hideInSearch
:
true
,
width
:
120
,
render
:
serviceType
=>
{
if
(
+
serviceType
===
1
)
{
return
<
span
style
=
{{
color
:
'
#ff1616
'
}}
>
仅退款
<
/span>
;
}
return
<
span
>
退货退款
<
/span>
;
},
},
{
title
:
'
订单ID
'
,
dataIndex
:
'
orderNo
'
,
hideInTable
:
true
,
width
:
200
,
},
{
title
:
'
售后单ID
'
,
dataIndex
:
'
serviceNo
'
,
width
:
300
,
render
:
(
serviceNo
,
r
)
=>
(
<
div
>
{
r
.
timeout
?
<
Tag
color
=
"
red
"
>
{
serviceNo
}
<
/Tag> : serviceNo
}
{
<
Badge
count
=
{
r
.
reminderFlag
?
'
催
'
:
''
}
size
=
"
default
"
/>
}
<
/div
>
),
},
{
title
:
'
订单ID
'
,
dataIndex
:
'
orderNo
'
,
hideInSearch
:
true
,
width
:
300
,
},
{
title
:
'
售后状态
'
,
dataIndex
:
'
dealStatus
'
,
hideInTable
:
true
,
valueEnum
:
{
0
:
'
待审核
'
,
10
:
'
三方审核中
'
,
11
:
'
三方审核通过
'
,
12
:
'
三方审核拒绝
'
,
13
:
'
客服审核通过
'
,
14
:
'
商户审核中
'
,
15
:
'
商户审核通过
'
,
16
:
'
商户审核拒绝
'
,
20
:
'
审核拒绝
'
,
21
:
'
申诉中
'
,
30
:
'
待填写退货物流信息
'
,
40
:
'
待退货入库
'
,
50
:
'
退货拒收
'
,
60
:
'
待退款
'
,
61
:
'
退货处理中
'
,
70
:
'
售后成功
'
,
99
:
'
用户取消
'
,
},
width
:
100
,
},
{
title
:
'
售后类型
'
,
dataIndex
:
'
type
'
,
hideInTable
:
true
,
width
:
120
,
valueEnum
:
{
1
:
'
仅退款
'
,
2
:
'
退货退款
'
,
},
},
{
title
:
'
收货人姓名
'
,
dataIndex
:
'
receiverName
'
,
width
:
200
,
},
{
title
:
'
收货人手机号
'
,
dataIndex
:
'
receiverPhone
'
,
width
:
200
,
},
{
title
:
'
收货人地址
'
,
dataIndex
:
'
receiveAddress
'
,
width
:
200
,
hideInSearch
:
true
,
},
{
title
:
'
订单开始时间
'
,
width
:
120
,
dataIndex
:
'
startDate
'
,
key
:
'
startDate
'
,
valueType
:
'
date
'
,
hideInTable
:
true
,
},
{
title
:
'
订单结束时间
'
,
width
:
120
,
dataIndex
:
'
endDate
'
,
key
:
'
endDate
'
,
valueType
:
'
date
'
,
hideInTable
:
true
,
},
{
title
:
'
售后原因
'
,
dataIndex
:
'
serviceReason
'
,
hideInSearch
:
true
,
width
:
200
,
},
{
title
:
'
售后发生时间
'
,
dataIndex
:
'
serviceTime
'
,
hideInSearch
:
true
,
width
:
200
,
},
{
title
:
'
超时时间
'
,
dataIndex
:
'
overtime
'
,
hideInSearch
:
true
,
width
:
200
,
},
{
title
:
'
是否催办
'
,
dataIndex
:
'
reminderFlag
'
,
hideInSearch
:
true
,
width
:
120
,
valueEnum
:
{
true
:
'
是
'
,
false
:
'
否
'
,
},
},
{
title
:
'
是否同意售后
'
,
dataIndex
:
'
isAgree
'
,
hideInSearch
:
true
,
width
:
120
,
},
{
title
:
'
拒绝原因
'
,
dataIndex
:
'
refuseReason
'
,
hideInSearch
:
true
,
width
:
200
,
},
];
export
const
columnPassAudit
=
[
...
columnSticData
,
{
title
:
'
商家退货地址
'
,
dataIndex
:
'
merchantAddress
'
,
hideInSearch
:
true
,
width
:
200
,
},
{
title
:
'
退回物流
'
,
dataIndex
:
'
expressCompanyName
'
,
hideInSearch
:
true
,
width
:
150
,
},
{
title
:
'
退回物流单号
'
,
dataIndex
:
'
deliveryNo
'
,
hideInSearch
:
true
,
width
:
200
,
},
{
title
:
'
售后状态
'
,
dataIndex
:
'
serviceStatus
'
,
hideInSearch
:
true
,
width
:
120
,
},
];
src/pages/AfterSaleManageOld/index.jsx
0 → 100644
View file @
7534953c
import
{
Tabs
}
from
'
antd
'
;
import
React
from
'
react
'
;
import
{
PageHeaderWrapper
}
from
'
@ant-design/pro-layout
'
;
import
{
AFTER_SALE_ORDER
}
from
'
@/../config/permission.config
'
;
import
{
connect
}
from
'
dva
'
;
import
Pending
from
'
./Pending
'
;
import
PassAudit
from
'
./PassAudit
'
;
const
{
TabPane
}
=
Tabs
;
function
AfterSale
(
props
)
{
const
{
permissions
}
=
props
;
const
canEditable
=
permissions
[
AFTER_SALE_ORDER
.
EDITABLE
];
return
(
<
PageHeaderWrapper
>
<
Tabs
defaultActiveKey=
"1"
>
<
TabPane
tab=
"未审核"
key=
"1"
>
<
Pending
canEditable=
{
canEditable
}
/>
</
TabPane
>
<
TabPane
tab=
"已审核"
key=
"2"
>
<
PassAudit
canEditable=
{
canEditable
}
/>
</
TabPane
>
</
Tabs
>
</
PageHeaderWrapper
>
);
}
export
default
connect
(({
menu
})
=>
({
permissions
:
menu
.
permissions
,
}))(
AfterSale
);
src/pages/AfterSaleManage
New
/services.js
→
src/pages/AfterSaleManage
Old
/services.js
View file @
7534953c
...
@@ -6,40 +6,31 @@ import _ from 'lodash';
...
@@ -6,40 +6,31 @@ import _ from 'lodash';
const
{
kdspApi
}
=
config
;
const
{
kdspApi
}
=
config
;
// 分页查询所有数据
// 分页查询所有数据
export
const
searchList
=
params
=>
export
async
function
searchList
(
params
,
queryStatus
)
{
request
.
post
(
'
/api/kdsp/op/afs/shop/list
'
,
{
const
param
=
{
...
params
,
pageNo
:
params
.
current
,
pageSize
:
params
.
pageSize
||
20
,
queryStatus
,
};
const
data
=
await
request
.
post
(
'
/api/kdsp/op/afs/shop/list
'
,
{
prefix
:
kdspApi
,
prefix
:
kdspApi
,
data
:
stringify
(
_
.
omitBy
(
param
s
,
v
=>
!
v
)),
data
:
stringify
(
_
.
omitBy
(
param
,
v
=>
!
v
)),
headers
:
{
headers
:
{
'
Content-Type
'
:
'
application/x-www-form-urlencoded
'
,
'
Content-Type
'
:
'
application/x-www-form-urlencoded
'
,
},
},
});
});
if
(
data
.
data
)
{
// export async function searchList(params, queryStatus) {
return
{
// const param = {
total
:
data
.
data
.
total
,
// ...params,
data
:
data
.
data
.
records
,
// pageNo: params.current,
};
// pageSize: params.pageSize || 20,
}
// queryStatus,
return
{
// };
total
:
0
,
// const data = await request.post('/api/kdsp/op/afs/shop/list', {
data
:
[],
// prefix: kdspApi,
};
// data: stringify(_.omitBy(param, v => !v)),
}
// headers: {
// 'Content-Type': 'application/x-www-form-urlencoded',
// },
// });
// if (data.data) {
// return {
// total: data.data.total,
// data: data.data.records,
// };
// }
// return {
// total: 0,
// data: [],
// };
// }
// 售后单详情
// 售后单详情
export
async
function
orderDetail
(
params
)
{
export
async
function
orderDetail
(
params
)
{
...
...
src/pages/AfterSaleManage/styles.less
→
src/pages/AfterSaleManage
Old
/styles.less
View file @
7534953c
File moved
src/services/messageReminder.js
View file @
7534953c
import
request
from
'
@/utils/request
'
;
import
request
from
'
@/utils/request
'
;
import
config
from
'
../../config/env.config
'
;
import
config
from
'
../../config/env.config
'
;
const
{
msgApi
}
=
config
;
const
{
msgApi
,
wsApi
}
=
config
;
export
const
getSocketUrl
=
({
token
,
channelId
})
=>
`
${
wsApi
}
/ws?token=
${
token
}
&channelId=
${
channelId
}
`
;
/**
/**
* @name 商户消息列表
* @name 商户消息列表
* @see http://yapi.quantgroups.com/project/193/interface/api/41792
* @see http://yapi.quantgroups.com/project/193/interface/api/41792
...
@@ -21,9 +25,6 @@ export function apiGetBussinessMsgList(data, params) {
...
@@ -21,9 +25,6 @@ export function apiGetBussinessMsgList(data, params) {
export
function
apiGetBusinessMsgUnReadCount
(
data
)
{
export
function
apiGetBusinessMsgUnReadCount
(
data
)
{
return
request
.
post
(
'
/v1/send/message/getBusinessMsgUnReadCount
'
,
{
return
request
.
post
(
'
/v1/send/message/getBusinessMsgUnReadCount
'
,
{
data
,
data
,
headers
:
{
'
Content-Type
'
:
'
application/x-www-form-urlencoded
'
,
},
prefix
:
msgApi
,
prefix
:
msgApi
,
});
});
}
}
...
...
src/utils/websocket.js
View file @
7534953c
...
@@ -76,13 +76,16 @@ class Socket extends EventEmitter {
...
@@ -76,13 +76,16 @@ class Socket extends EventEmitter {
if
(
e
.
code
===
'
4500
'
)
{
if
(
e
.
code
===
'
4500
'
)
{
this
.
socket
.
close
();
this
.
socket
.
close
();
}
else
{
}
else
{
this
.
taskRemindInterval
=
setInterval
(()
=>
{
const
reconnect
=
()
=>
{
clearTimeout
(
this
.
taskRemindInterval
);
this
.
taskRemindInterval
=
setTimeout
(()
=>
{
if
(
!
this
.
connected
)
{
if
(
!
this
.
connected
)
{
this
.
connection
();
this
.
connection
();
}
else
{
reconnect
();
clearInterval
(
this
.
taskRemindInterval
);
}
}
},
2000
);
},
5000
);
};
reconnect
();
}
}
};
};
...
...
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