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
373c4702
Commit
373c4702
authored
Sep 01, 2022
by
李腾
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of git.quantgroup.cn:ui/merchant-manage-ui into feature/serviceGoods20220804
parents
1a04ac87
501554e9
Changes
17
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
475 additions
and
116 deletions
+475
-116
env.config.js
config/env.config.js
+5
-6
index.jsx
src/pages/AfterSaleManage/Pending/index.jsx
+10
-42
auditModal.jsx
src/pages/AfterSaleManage/components/auditModal.jsx
+52
-11
data.js
src/pages/AfterSaleManage/data.js
+12
-10
styles.less
src/pages/AfterSaleManage/styles.less
+9
-0
index.jsx
src/pages/GoodsManage/SearchForm/index.jsx
+49
-8
index.jsx
src/pages/GoodsManage/UpdateStock/index.jsx
+68
-23
index.jsx
src/pages/GoodsManage/index.jsx
+74
-7
service.js
src/pages/GoodsManage/service.js
+33
-0
staticdata.js
src/pages/GoodsManage/staticdata.js
+6
-7
style.less
src/pages/GoodsManage/style.less
+11
-0
index.jsx
src/pages/orderManage/batchDelivery/index.jsx
+2
-1
DelayDeliverGoods.jsx
...age/pendingDeliveryOrder/components/DelayDeliverGoods.jsx
+66
-0
index.jsx
src/pages/orderManage/pendingDeliveryOrder/index.jsx
+44
-1
service.js
src/pages/orderManage/pendingDeliveryOrder/service.js
+7
-0
styles.less
src/pages/orderManage/pendingDeliveryOrder/styles.less
+9
-0
validator.js
src/utils/validator.js
+18
-0
No files found.
config/env.config.js
View file @
373c4702
...
...
@@ -3,14 +3,13 @@ const isPre = process.env.PRE_ENV === 'pre';
const
envAPi
=
{
api
:
'
https://backstms-xyqb.liangkebang.net
'
,
kdspOpApi
:
'
https://sc-merchant-api-xyqb.liangkebang.net
'
,
kdspApi
:
'
https://sc-merchant-api-xyqb.liangkebang.net
'
,
goodsApi
:
'
https://sc-merchant-api-xyqb.liangkebang.net
'
,
// kdspOpApi: 'https://kdsp-operation-xyqb.liangkebang.net',
// kdspApi: 'https://sc-op-api-xyqb.liangkebang.net',
// goodsApi: 'https://sc-op-api-xyqb.liangkebang.net',
kdspOpApi
:
'
https://kdsp-operation-xyqb.liangkebang.net
'
,
kdspApi
:
'
https://sc-op-api-xyqb.liangkebang.net
'
,
goodsApi
:
'
https://sc-op-api-xyqb.liangkebang.net
'
,
querysApi
:
'
https://sc-settlement-api-xyqb.liangkebang.net
'
,
// goodsApi: '//192.168.188.111:7000',
prologueDomain
:
'
https://mall-xyqb.liangkebang.net
'
,
// qiniuHost: 'https://appsync.lkbang.net',
qiniuHost
:
'
https://kdspstatic.q-gp.com/
'
,
opapiHost
:
'
https://opapi-xyqb.liangkebang.net
'
,
};
...
...
src/pages/AfterSaleManage/Pending/index.jsx
View file @
373c4702
...
...
@@ -11,6 +11,7 @@ import ProofsModal from '../components/proofsModal';
import
{
getDetail
}
from
'
../../afterSale/appeal/services
'
;
import
AppealDetail
from
'
../../afterSale/components/detail
'
;
import
AfterLog
from
'
../components/AfterLog
'
;
import
styles
from
'
../styles.less
'
;
const
{
Countdown
}
=
Statistic
;
...
...
@@ -25,8 +26,6 @@ export default () => {
const
[
auditInfo
,
setAuditInfo
]
=
useState
({});
const
[
appealDetailModal
,
setAppealDetailModal
]
=
useState
(
false
);
const
[
selectedRow
,
setSelectedRow
]
=
useState
({});
const
[
timeString
,
setTimeString
]
=
useState
({});
const
[
time
,
setTime
]
=
useState
({});
const
[
afterVisible
,
setAfterVisible
]
=
useState
(
false
);
const
[
afterList
,
setAfterList
]
=
useState
([]);
const
viewDetail
=
async
({
serviceNo
})
=>
{
...
...
@@ -73,7 +72,15 @@ export default () => {
};
const
openLogistics
=
r
=>
{
confirm
({
content
:
'
请在48小时内完成物流包裹拦截,确认是否需要进行物流拦截?
'
,
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
'
)
{
...
...
@@ -88,39 +95,6 @@ export default () => {
},
});
};
// const renderContent = (record, index, action) => {
// if (!time[record.serviceNo]) {
// const serviceTime = moment(record.approvalEndTime).valueOf();
// const nowTime = moment(record.nowTime).valueOf();
// let timeNumber = (serviceTime - nowTime) / 1000;
// time[record.serviceNo] = setInterval(() => {
// if (timeNumber > 0) {
// timeNumber -= 1;
// // eslint-disable-next-line radix
// const hours = parseInt(timeNumber / 3600)
// .toString()
// .padStart(2, '0');
// // eslint-disable-next-line radix
// const minutes = parseInt((timeNumber / 60) % 60)
// .toString()
// .padStart(2, '0');
// // eslint-disable-next-line radix
// const seconds = parseInt(timeNumber % 60)
// .toString()
// .padStart(2, '0');
// const str = `${hours}时${minutes}分${seconds}秒`;
// timeString[record.serviceNo] = str;
// const strings = _.cloneDeep(timeString);
// setTimeString(strings);
// } else {
// clearInterval(time[record.serviceNo]);
// timeString[record.serviceNo] = '0时0分0秒';
// const strings = _.cloneDeep(timeString);
// setTimeString(strings);
// }
// }, 1000);
// }
// };
const
columns
=
[
{
title
:
'
审核倒计时
'
,
...
...
@@ -128,12 +102,6 @@ export default () => {
key
:
'
serviceTime
'
,
hideInSearch
:
true
,
width
:
150
,
// render: (val, record, index, action) => [
// <span style={{ color: 'red' }}>
// {renderContent(record, index, action)}
// {timeString[record.serviceNo]}
// </span>,
// ],
render
:
(
val
,
record
)
=>
{
const
serviceTime
=
moment
(
record
.
approvalEndTime
).
valueOf
();
return
(
...
...
src/pages/AfterSaleManage/components/auditModal.jsx
View file @
373c4702
...
...
@@ -3,9 +3,11 @@ import { Form } from '@ant-design/compatible';
import
'
@ant-design/compatible/assets/index.css
'
;
import
{
Modal
,
Input
,
Cascader
,
notification
,
InputNumber
}
from
'
antd
'
;
import
{
shopAudit
}
from
'
../services
'
;
import
styles
from
'
../styles.less
'
;
const
FormItem
=
Form
.
Item
;
const
{
TextArea
}
=
Input
;
const
{
confirm
}
=
Modal
;
const
AuditModal
=
props
=>
{
const
{
visible
,
...
...
@@ -13,6 +15,7 @@ const AuditModal = props => {
form
:
{
getFieldDecorator
,
getFieldValue
,
validateFields
,
resetFields
},
formData
=
{},
}
=
props
;
const
handleCancel
=
isSuccess
=>
{
resetFields
();
onCancel
(
isSuccess
);
...
...
@@ -57,19 +60,43 @@ const AuditModal = props => {
],
},
];
const
submitCheckResult
=
async
fieldsValue
=>
{
const
{
auditResult
}
=
fieldsValue
;
const
data
=
await
shopAudit
({
...
fieldsValue
,
refuseCode
:
auditResult
?.[
1
],
auditResult
:
auditResult
?.[
0
],
serviceNo
:
formData
?.
serviceNo
,
});
if
(
data
.
businessCode
===
'
0000
'
)
{
notification
.
success
({
message
:
'
审核成功
'
});
handleCancel
(
true
);
}
};
const
handleOk
=
()
=>
{
validateFields
(
async
(
error
,
fieldsValue
)
=>
{
validateFields
((
error
,
fieldsValue
)
=>
{
if
(
!
error
)
{
const
{
auditResult
}
=
fieldsValue
;
const
data
=
await
shopAudit
({
...
fieldsValue
,
refuseCode
:
auditResult
?.[
1
],
auditResult
:
auditResult
?.[
0
],
serviceNo
:
formData
?.
serviceNo
,
});
if
(
data
.
businessCode
===
'
0000
'
)
{
notification
.
success
({
message
:
'
审核成功
'
});
handleCancel
(
true
);
// 如果为仅退款 并且 审核同意 弹出二次确认提示
if
(
+
formData
.
serviceType
===
1
&&
auditResult
?.[
0
]
===
1
)
{
confirm
({
title
:
'
温馨提示
'
,
content
:
(
<
div
>
当前类型为【
<
span
className=
{
styles
.
redTipBold
}
>
仅退款
</
span
>
】,请核查该订单物流状态,如有在途物流,务必自行拦截后点击确认;
</
div
>
),
okText
:
'
确认退款
'
,
onOk
()
{
submitCheckResult
(
fieldsValue
);
},
onCancel
()
{
handleCancel
(
true
);
},
});
}
else
{
submitCheckResult
(
fieldsValue
);
}
}
});
...
...
@@ -89,9 +116,23 @@ const AuditModal = props => {
onOk=
{
()
=>
handleOk
()
}
onCancel=
{
()
=>
handleCancel
()
}
>
{
+
formData
.
serviceType
===
1
&&
(
<
div
className=
{
styles
.
redTip
}
>
温馨提示:当前售后类型为用户未收到产品,申请
<
span
className=
{
styles
.
redTipBold
}
>
仅退款
</
span
>
,请务必检查此单物流状态后审核。
</
div
>
)
}
<
Form
{
...
layout
}
name=
"formData"
>
<
FormItem
label=
"审核结果"
>
{
getFieldDecorator
(
'
auditResult
'
)(
{
getFieldDecorator
(
'
auditResult
'
,
{
rules
:
[
{
required
:
true
,
message
:
'
请选择审核结果!
'
,
},
],
})(
<
Cascader
allowClear
showSearch
...
...
src/pages/AfterSaleManage/data.js
View file @
373c4702
...
...
@@ -6,6 +6,18 @@ export const appealType = {
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
'
,
...
...
@@ -97,16 +109,6 @@ export const columnSticData = [
valueType
:
'
date
'
,
hideInTable
:
true
,
},
{
title
:
'
售后类型
'
,
dataIndex
:
'
serviceType
'
,
hideInSearch
:
true
,
width
:
120
,
valueEnum
:
{
1
:
'
仅退款
'
,
2
:
'
退货退款
'
,
},
},
{
title
:
'
售后原因
'
,
dataIndex
:
'
serviceReason
'
,
...
...
src/pages/AfterSaleManage/styles.less
View file @
373c4702
...
...
@@ -21,3 +21,12 @@
display: inherit;
margin: 20px auto;
}
.redTip {
color: #ff4d4f;
font-size: 14px;
}
.redTipBold {
color: #ff1616;
font-weight: bold;
}
src/pages/GoodsManage/SearchForm/index.jsx
View file @
373c4702
...
...
@@ -5,15 +5,19 @@ import {
Select
,
notification
,
Upload
,
Tag
,
Cascader
,
InputNumber
,
Popover
,
Divider
,
}
from
'
antd
'
;
import
React
,
{
Component
}
from
'
react
'
;
import
React
,
{
Component
,
useState
}
from
'
react
'
;
import
{
connect
}
from
'
dva
'
;
import
{
saveAs
}
from
'
file-saver
'
;
import
{
format
}
from
'
date-fns
'
;
import
styles
from
'
../style.less
'
;
import
{
stateList
}
from
'
../staticdata
'
;
import
{
apiGoodsInfosExport
}
from
'
../service
'
;
const
FormItem
=
Form
.
Item
;
const
{
Option
}
=
Select
;
...
...
@@ -23,6 +27,10 @@ const { Option } = Select;
class
goodsManage
extends
Component
{
formRef
=
React
.
createRef
();
state
=
{
loading
:
false
,
};
componentDidMount
()
{
this
.
props
.
onRef
(
this
);
this
.
handleSearch
();
...
...
@@ -59,6 +67,33 @@ class goodsManage extends Component {
this
.
props
.
setArea
(
isAll
,
type
);
};
// 验证是否可以修改库存
checkEnableUpdateStock
=
()
=>
{
if
(
this
.
props
.
selectNum
)
{
this
.
props
.
checkStock
();
}
else
{
notification
.
info
({
message
:
'
请选择
'
});
}
};
// 导出明细
onExportGoodsInfo
=
async
()
=>
{
this
.
setState
({
loading
:
true
,
});
const
form
=
this
.
formRef
?.
current
?.
getFieldValue
();
const
res
=
await
apiGoodsInfosExport
(
form
);
this
.
setState
({
loading
:
false
,
});
if
(
res
)
{
const
blob
=
new
Blob
([
res
]);
saveAs
(
blob
,
`商品明细-
${
format
(
new
Date
(),
'
yyyyMMdd
'
)}
.xlsx`
);
}
else
{
notification
.
error
({
message
:
'
下载失败
'
});
}
};
render
()
{
const
{
treeData
}
=
this
.
props
;
const
selectW
=
{
width
:
250
};
...
...
@@ -81,6 +116,10 @@ class goodsManage extends Component {
<
Button
style=
{
{
border
:
'
none
'
}
}
onClick=
{
()
=>
this
.
setArea
(
0
,
'
after
'
)
}
>
勾选商品售后地址设置
</
Button
>
<
br
/>
<
Button
style=
{
{
border
:
'
none
'
}
}
onClick=
{
()
=>
this
.
checkEnableUpdateStock
()
}
>
勾选商品库存修改
</
Button
>
</
div
>
);
// const uploadProps = {
...
...
@@ -173,19 +212,21 @@ class goodsManage extends Component {
<
Button
onClick=
{
()
=>
this
.
onReset
()
}
type=
"primary"
className=
{
styles
.
button
}
>
重置
</
Button
>
<
Button
loading=
{
this
.
state
.
loading
}
onClick=
{
()
=>
this
.
onExportGoodsInfo
()
}
className=
{
styles
.
button
}
>
导出
</
Button
>
</
FormItem
>
<
FormItem
style=
{
{
float
:
'
right
'
}
}
>
<
Popover
content=
{
content
}
onVisibleChange=
{
this
.
handleVisibleChange
}
>
<
Button
type=
"primary"
className=
{
styles
.
button
}
>
批量
操作
批量
设置
</
Button
>
</
Popover
>
<
Button
type=
"primary"
className=
{
styles
.
button
}
onClick=
{
this
.
addSpu
}
>
新增商品
</
Button
>
<
Button
type=
"primary"
className=
{
styles
.
button
}
onClick=
{
this
.
props
.
serviceVisbleOpen
}
>
新增服务类商品
</
Button
>
{
this
.
props
.
selectNum
>
0
&&
<
Tag
color=
"green"
>
已选商品
{
this
.
props
.
selectNum
}
</
Tag
>
}
{
/* <Button
className={styles.button}
type="primary"
...
...
src/pages/GoodsManage/UpdateStock/index.jsx
View file @
373c4702
import
{
Form
}
from
'
@ant-design/compatible
'
;
import
'
@ant-design/compatible/assets/index.css
'
;
import
{
Modal
,
InputNumber
,
notification
,
Input
,
Radio
}
from
'
antd
'
;
import
React
from
'
react
'
;
import
{
updateStock
}
from
'
../service
'
;
import
React
,
{
useState
}
from
'
react
'
;
import
{
apiCreateGoodsLog
}
from
'
../service
'
;
import
styles
from
'
../style.less
'
;
import
{
isNumberSection
}
from
'
@/utils/validator
'
;
const
UpdateStock
=
props
=>
{
const
{
getFieldDecorator
,
validateFields
,
resetFields
,
getFieldValue
}
=
props
.
form
;
const
valueInfo
=
props
.
info
;
getFieldDecorator
(
'
stockChangeType
'
,
{
initialValue
:
1
});
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
submit
=
async
()
=>
{
validateFields
(
async
(
err
,
{
stock
,
changeReason
,
stockC
hangeType
})
=>
{
validateFields
(
async
(
err
,
{
stock
,
changeReason
,
c
hangeType
})
=>
{
if
(
err
)
return
;
const
error
=
await
updateStock
({
stock
,
id
:
valueInfo
.
id
,
setLoading
(
true
);
const
params
=
{
afterChange
:
stock
,
supplierId
:
valueInfo
.
supplierId
,
stockChangeType
,
productIdType
:
2
,
changeType
,
changeReason
,
});
if
(
!
error
)
{
notification
.
success
({
message
:
'
操作成功!
'
});
productIds
:
props
.
skuIds
,
};
console
.
log
(
'
params :>>
'
,
params
);
const
res
=
await
apiCreateGoodsLog
(
params
);
if
(
res
?.
businessCode
===
'
0000
'
)
{
notification
.
success
({
message
:
'
库存更改申请已提交!
'
});
props
.
onCancel
(
'
success
'
);
resetFields
();
}
setLoading
(
false
);
});
};
const
onCancel
=
()
=>
{
...
...
@@ -31,48 +40,84 @@ const UpdateStock = props => {
};
const
formItemLayout
=
{
labelCol
:
{
span
:
8
,
span
:
7
,
},
wrapperCol
:
{
span
:
1
6
,
span
:
1
5
,
},
};
const
validatorCallback
=
(
rule
,
value
,
callback
)
=>
{
// 减库存存时,校验可售库存-输入值>=0,即可售库存不可为负;
const
stockChangeType
=
getFieldValue
(
'
stockC
hangeType
'
);
const
changeType
=
getFieldValue
(
'
c
hangeType
'
);
const
increment
=
valueInfo
.
marketableStock
-
value
;
return
!
stockChangeType
&&
increment
<
0
?
callback
(
new
Error
(
rule
.
message
))
:
callback
();
console
.
log
(
'
value :>>
'
,
value
,
valueInfo
.
marketableStock
);
console
.
log
(
'
valueInfo :>>
'
,
valueInfo
,
increment
);
return
+
changeType
===
29
&&
increment
<
0
?
callback
(
new
Error
(
rule
.
message
))
:
callback
();
};
return
(
<
Modal
title=
"修改库存"
visible=
{
props
.
visible
}
onCancel=
{
onCancel
}
onOk=
{
submit
}
width=
{
400
}
>
<
Modal
title=
"修改库存"
visible=
{
props
.
visible
}
okButtonProps=
{
{
loading
,
disabled
:
valueInfo
.
status
===
1
}
}
onCancel=
{
onCancel
}
onOk=
{
submit
}
width=
{
500
}
>
<
Form
{
...
formItemLayout
}
>
{
valueInfo
.
curStock
?
(
<
Form
.
Item
label=
"当前库存:"
>
<
span
>
{
valueInfo
.
curStock
}
</
span
>
</
Form
.
Item
>
)
:
(
<
Form
.
Item
label=
"可修改库存商品数:"
>
<
span
>
{
props
.
skuIds
.
length
}
</
span
>
</
Form
.
Item
>
)
}
<
Form
.
Item
label=
"变更类型:"
>
{
getFieldDecorator
(
'
stockC
hangeType
'
,
{
{
getFieldDecorator
(
'
c
hangeType
'
,
{
rules
:
[{
required
:
true
,
message
:
'
请选择类型!
'
}],
initialValue
:
valueInfo
.
changeType
||
28
,
})(
<
Radio
.
Group
>
<
Radio
value=
{
1
}
>
增库存
</
Radio
>
<
Radio
value=
{
0
}
>
减库存
</
Radio
>
<
Radio
.
Group
disabled=
{
valueInfo
.
status
===
1
}
>
<
Radio
value=
{
28
}
>
增库存
</
Radio
>
<
Radio
value=
{
29
}
>
减库存
</
Radio
>
<
Radio
value=
{
30
}
>
使用新值
</
Radio
>
</
Radio
.
Group
>,
)
}
<
div
className=
{
styles
.
stockTip
}
>
库存变更审批通过后生效
</
div
>
</
Form
.
Item
>
<
Form
.
Item
label=
"库存数:"
>
{
getFieldDecorator
(
'
stock
'
,
{
rules
:
[
{
required
:
true
,
message
:
'
请输入库存!
'
},
{
validator
:
validatorCallback
,
message
:
'
减库存,输入库存数不可大于可售库存!
'
},
{
validator
:
isNumberSection
,
min
:
1
,
max
:
500
,
message
:
'
请输入1-500的整数
'
},
],
validateTrigger
:
[
'
onSubmit
'
],
})(<
InputNumber
min=
{
0
}
precision=
{
0
}
placeholder=
"请输入库存"
style=
{
{
width
:
200
}
}
/>)
}
validateTrigger
:
[
'
onSubmit
'
,
'
onChange
'
],
initialValue
:
valueInfo
.
stock
,
})(
<
InputNumber
min=
{
0
}
precision=
{
0
}
placeholder=
"请输入库存"
disabled=
{
valueInfo
.
status
===
1
}
style=
{
{
width
:
200
}
}
/>,
)
}
</
Form
.
Item
>
<
Form
.
Item
label=
"变更原因:"
>
{
getFieldDecorator
(
'
changeReason
'
,
{
rules
:
[{
required
:
true
,
message
:
'
请输入变更原因!
'
}],
initialValue
:
valueInfo
.
changeReason
,
})(<
Input
.
TextArea
/>)
}
})(<
Input
.
TextArea
disabled=
{
valueInfo
.
status
===
1
}
maxLength=
{
50
}
/>)
}
</
Form
.
Item
>
{
valueInfo
.
stateDesc
&&
(
<
div
className=
{
styles
.
stockErrMsg
}
>
{
valueInfo
.
stateDesc
}
:
{
valueInfo
.
rejectReason
}
</
div
>
)
}
</
Form
>
</
Modal
>
);
...
...
src/pages/GoodsManage/index.jsx
View file @
373c4702
...
...
@@ -18,6 +18,8 @@ import {
getTemplateList
,
specList
,
queryAllAfterAddress
,
apiEnableUpdataStock
,
apiQueryLastChangeLog
,
}
from
'
./service
'
;
import
LogModal
from
'
./LogModal
'
;
import
CreateModal
from
'
./createModal
'
;
...
...
@@ -48,6 +50,7 @@ class goodsManage extends Component {
selectedRowKeys
:
[],
isAll
:
0
,
templateList
:
[],
stockSkuIds
:
[],
isType
:
''
,
serviceVisble
:
false
,
...
...
@@ -68,6 +71,7 @@ class goodsManage extends Component {
}
handleSearch
=
page
=>
{
this
.
onSelectChange
([]);
const
currentPage
=
this
.
state
.
pageNo
;
this
.
setState
(
{
...
...
@@ -222,6 +226,28 @@ class goodsManage extends Component {
filterShopList
=
(
list
=
[],
isEdit
)
=>
list
.
filter
(
item
=>
isEdit
||
!
JDSHOPID
.
includes
(
item
.
id
));
// 验证是否可以修改库存
checkEnableUpdateStock
=
async
()
=>
{
const
ids
=
this
.
state
.
selectedRowKeys
.
join
(
'
,
'
);
if
(
ids
)
{
const
res
=
await
apiEnableUpdataStock
(
ids
);
if
(
res
.
data
)
{
if
(
res
.
data
.
successSkuIds
?.
length
)
{
this
.
setState
({
priceInfo
:
{},
stockSkuIds
:
res
.
data
.
successSkuIds
,
});
this
.
openModal
({},
1
);
}
else
{
const
message
=
res
.
data
.
failedInfoList
[
0
]?.
message
||
'
未存在可修改库存的商品
'
;
notification
.
info
({
message
});
}
}
}
else
{
notification
.
info
({
message
:
'
请选择
'
});
}
};
openModal
=
(
{
skuId
,
...
...
@@ -232,6 +258,7 @@ class goodsManage extends Component {
supplierId
,
stock
,
productStock
,
state
,
},
isStock
,
)
=>
{
...
...
@@ -250,10 +277,39 @@ class goodsManage extends Component {
marketPrice
,
salePrice
,
supplierId
,
state
,
},
});
};
onShowStockModal
=
async
row
=>
{
const
res
=
await
apiQueryLastChangeLog
(
row
.
skuId
);
let
priceInfo
=
{
id
:
row
.
skuId
,
curStock
:
row
.
productStock
,
supplierId
:
row
.
supplierId
,
marketableStock
:
row
.
stock
,
};
if
(
res
.
data
&&
[
1
,
3
].
includes
(
+
res
.
data
.
status
))
{
priceInfo
=
Object
.
assign
(
{
changeReason
:
res
.
data
.
changeReason
,
stock
:
+
res
.
data
.
afterChange
,
changeType
:
res
.
data
.
changeType
,
status
:
res
.
data
.
status
,
stateDesc
:
res
.
data
.
statusDesc
,
rejectReason
:
res
.
data
.
rejectReason
,
},
priceInfo
,
);
}
this
.
setState
({
updateStockVisible
:
true
,
priceInfo
,
stockSkuIds
:
[
row
.
skuId
],
});
};
cancel
=
query
=>
{
this
.
setState
({
updateStockVisible
:
false
});
if
(
query
)
{
...
...
@@ -316,11 +372,6 @@ class goodsManage extends Component {
}
};
serviceVisbleOpen
=
()
=>
{
console
.
log
(
'
============>open
'
);
this
.
serviceVisbleClose
(
true
);
};
serviceVisbleClose
=
(
flag
,
refresh
)
=>
{
this
.
setState
({
serviceVisble
:
flag
,
...
...
@@ -343,6 +394,20 @@ class goodsManage extends Component {
return
(
<
PageHeaderWrapper
>
<
Spin
spinning=
{
this
.
state
.
createloading
}
>
<
Button
type=
"primary"
className=
{
styles
.
button
}
onClick=
{
()
=>
this
.
setState
({
createVisible
:
true
,
initData
:
{}
})
}
>
新增商品
</
Button
>
<
Button
type=
"primary"
className=
{
styles
.
button
}
onClick=
{
()
=>
this
.
serviceVisbleClose
(
true
)
}
>
新增服务类商品
</
Button
>
<
Card
>
<
SearchForm
handleSearch=
{
this
.
handleSearch
}
...
...
@@ -353,9 +418,10 @@ class goodsManage extends Component {
}
}
treeData=
{
this
.
state
.
treeData
}
shopList=
{
this
.
shopList
}
addSpu=
{
()
=>
this
.
setState
({
createVisible
:
true
,
initData
:
{}
})
}
checkStock=
{
this
.
checkEnableUpdateStock
}
// addSpu={() => this.setState({ createVisible: true, initData: {} })}
selectNum=
{
selectedRowKeys
.
length
}
setArea=
{
(
isALL
,
type
)
=>
this
.
setArea
(
isALL
,
type
)
}
serviceVisbleOpen=
{
this
.
serviceVisbleOpen
}
/>
</
Card
>
<
Spin
spinning=
{
this
.
state
.
loading
}
>
...
...
@@ -425,6 +491,7 @@ class goodsManage extends Component {
<
UpdateStock
visible=
{
this
.
state
.
updateStockVisible
}
skuIds=
{
this
.
state
.
stockSkuIds
}
info=
{
this
.
state
.
priceInfo
}
onCancel=
{
this
.
cancel
}
/>
...
...
src/pages/GoodsManage/service.js
View file @
373c4702
...
...
@@ -197,3 +197,36 @@ export async function getAfterAddress(params) {
});
return
data
;
}
/**
* 商品是否可以做库存变更
* skuIds: 多个用英文逗号隔开
*/
export
const
apiEnableUpdataStock
=
skuIds
=>
request
.
get
(
`/api/kdsp/sku/can/stockChange?skuIds=
${
skuIds
}
`
,
{
prefix
:
goodsApi
,
});
// 商品明细导出
export
const
apiGoodsInfosExport
=
params
=>
request
.
post
(
'
/api/kdsp/sku/export
'
,
{
prefix
:
goodsApi
,
data
:
params
,
responseType
:
'
arrayBuffer
'
,
headers
:
{
'
Content-Type
'
:
'
application/json;charset=UTF-8
'
,
},
});
// 新建商品审核记录
export
const
apiCreateGoodsLog
=
params
=>
request
.
post
(
'
/api/kdsp/product/audit/create
'
,
{
data
:
params
,
prefix
:
goodsApi
,
});
// 查询sku最后一条库存变更记录
export
const
apiQueryLastChangeLog
=
skuId
=>
request
.
get
(
`/api/kdsp/sku/last/stockChange/record?skuId=
${
skuId
}
`
,
{
prefix
:
goodsApi
,
});
src/pages/GoodsManage/staticdata.js
View file @
373c4702
...
...
@@ -108,13 +108,12 @@ export function column() {
align
:
'
center
'
,
sorter
:
(
a
,
b
)
=>
a
.
stock
-
b
.
stock
,
render
:
(
_
,
row
)
=>
{
// const stockView =
// row.state !== 4 ? (
// <a onClick={() => this.openModal(row, 'productStock')}>{row.productStock}</a>
// ) : (
// <span>{row.productStock}</span>
// );
const
stockView
=
row
.
productStock
;
// const stockView = row.productStock;
const
stockView
=
(
<
Button
type
=
"
link
"
onClick
=
{()
=>
this
.
onShowStockModal
(
row
)}
style
=
{{
padding
:
0
}}
>
{
row
.
productStock
}
<
/Button
>
);
return
(
<>
<
p
>
当前库存:
{
stockView
}
<
/p
>
...
...
src/pages/GoodsManage/style.less
View file @
373c4702
...
...
@@ -99,3 +99,14 @@
.sizeTitle {
font-size: 12px;
}
.stockTip {
color: #d9363e;
line-height: 1;
}
.stockErrMsg {
box-sizing: border-box;
padding-left: 30%;
color: #d9363e;
line-height: 1;
}
src/pages/orderManage/batchDelivery/index.jsx
View file @
373c4702
...
...
@@ -11,6 +11,7 @@ import {
const
TableList
=
ref
=>
{
const
actionRef
=
useRef
(
null
);
const
columns
=
[
{
title
:
'
批次号
'
,
...
...
@@ -99,7 +100,7 @@ const TableList = ref => {
<
Button
type=
"primary"
style=
{
{
marginR
ottom
:
'
10px
'
,
marginR
ight
:
'
10px
'
,
}
}
onClick=
{
()
=>
{
downUploadeOrder
({
batchNo
:
record
.
batchNo
,
status
:
0
});
...
...
src/pages/orderManage/pendingDeliveryOrder/components/DelayDeliverGoods.jsx
0 → 100644
View file @
373c4702
import
{
Form
}
from
'
@ant-design/compatible
'
;
import
'
@ant-design/compatible/assets/index.css
'
;
import
{
Modal
,
notification
,
Input
}
from
'
antd
'
;
import
React
,
{
useState
}
from
'
react
'
;
import
{
apiDelayDeliverGoods
}
from
'
../service
'
;
const
UpdateStock
=
props
=>
{
const
{
getFieldDecorator
,
validateFields
,
resetFields
}
=
props
.
form
;
const
valueInfo
=
{};
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
submit
=
async
()
=>
{
validateFields
(
async
(
err
,
{
remark
})
=>
{
if
(
err
)
return
;
setLoading
(
true
);
const
params
=
{
orderIds
:
[
props
.
orderId
],
operationType
:
5
,
remark
,
};
console
.
log
(
'
params :>>
'
,
params
);
const
res
=
await
apiDelayDeliverGoods
(
params
);
if
(
res
?.
businessCode
===
'
0000
'
)
{
notification
.
success
({
message
:
'
提交成功!
'
});
props
.
onCancel
(
'
success
'
);
resetFields
();
}
setLoading
(
false
);
});
};
const
onCancel
=
()
=>
{
props
.
onCancel
();
resetFields
();
};
const
formItemLayout
=
{
labelCol
:
{
span
:
7
,
},
wrapperCol
:
{
span
:
15
,
},
};
return
(
<
Modal
title=
"异常订单报备"
visible=
{
props
.
visible
}
okButtonProps=
{
{
loading
}
}
onCancel=
{
onCancel
}
onOk=
{
submit
}
width=
{
500
}
>
<
Form
{
...
formItemLayout
}
>
<
Form
.
Item
label=
"异常原因:"
>
{
getFieldDecorator
(
'
remark
'
,
{
rules
:
[{
required
:
true
,
message
:
'
请输入异常原因!
'
}],
initialValue
:
valueInfo
.
remark
,
})(<
Input
.
TextArea
maxLength=
{
30
}
showCount
/>)
}
</
Form
.
Item
>
</
Form
>
</
Modal
>
);
};
export
default
Form
.
create
()(
UpdateStock
);
src/pages/orderManage/pendingDeliveryOrder/index.jsx
View file @
373c4702
import
{
Button
,
notification
}
from
'
antd
'
;
import
{
Button
,
notification
,
Modal
}
from
'
antd
'
;
import
React
,
{
useState
,
useEffect
,
useRef
}
from
'
react
'
;
import
{
PageHeaderWrapper
}
from
'
@ant-design/pro-layout
'
;
import
ProTable
from
'
@ant-design/pro-table
'
;
...
...
@@ -8,6 +8,7 @@ import LogisticsForm from './components/LogisticsForm';
import
style
from
'
./styles.less
'
;
import
PopoverDom
from
'
./components/PreviewImage
'
;
import
LogisticsCom
from
'
./components/LogisticsCom
'
;
import
DelayDeliverGoods
from
'
./components/DelayDeliverGoods
'
;
import
{
queryToSend
,
queryExpress
,
...
...
@@ -17,6 +18,8 @@ import {
getJDLogisticsInfo
,
}
from
'
./service
'
;
const
{
confirm
}
=
Modal
;
const
TableList
=
props
=>
{
const
dateFormat
=
'
YYYY-MM-DD
'
;
const
[
companys
,
setCompanys
]
=
useState
([]);
...
...
@@ -37,6 +40,9 @@ const TableList = props => {
const
[
orderStatus
,
setorderStatus
]
=
useState
(
1
);
const
[
endTimeStr
,
setEndTimeStr
]
=
useState
(
moment
().
format
(
dateFormat
));
const
[
visibleDelay
,
setVisibleDelay
]
=
useState
(
false
);
const
[
delayOrderIDs
,
setDelayOrderIDs
]
=
useState
(
0
);
// const startDisabledDate = current =>
// current && (endTime.diff(current, 'days') > 30 || endTime.diff(current, 'days') < 0);
// const endDisabledDate = current =>
...
...
@@ -68,6 +74,29 @@ const TableList = props => {
setLogisticsComList
(
tempObj
);
};
const
onDelay
=
(
id
,
state
,
content
)
=>
{
if
(
state
===
1
)
{
confirm
({
title
:
'
提示
'
,
content
,
cancelButtonProps
:
{
style
:
{
display
:
'
none
'
,
},
},
});
}
else
{
setDelayOrderIDs
(
id
);
setVisibleDelay
(
true
);
}
};
const
onCancelDelay
=
e
=>
{
setVisibleDelay
(
false
);
if
(
e
&&
actionRef
.
current
)
{
actionRef
.
current
.
reload
();
}
};
const
renderContent
=
(
record
,
key
)
=>
{
if
(
record
.
mchOrderSkuVoList
)
{
return
record
?.
mchOrderSkuVoList
.
map
((
item
,
index
)
=>
(
...
...
@@ -295,6 +324,15 @@ const TableList = props => {
{
props
.
type
===
2
?
'
更新物流信息
'
:
'
填写物流信息
'
}
</
Button
>
)
}
{
props
.
type
!==
2
&&
(
<
Button
type=
"primary"
className=
{
+
record
.
delayStatus
===
1
?
style
.
btnWarning
:
''
}
onClick=
{
()
=>
onDelay
(
record
.
orderId
,
+
record
.
delayStatus
,
record
.
delayRemark
)
}
>
{
+
record
.
delayStatus
===
1
?
'
异常订单已报备
'
:
'
异常订单报备
'
}
</
Button
>
)
}
</
React
.
Fragment
>
),
},
...
...
@@ -406,6 +444,11 @@ const TableList = props => {
value=
{
LogisticsComList
}
key=
{
LogisticsComList
.
key
}
/>
<
DelayDeliverGoods
visible=
{
visibleDelay
}
orderId=
{
delayOrderIDs
}
onCancel=
{
e
=>
onCancelDelay
(
e
)
}
/>
</
PageHeaderWrapper
>
);
};
...
...
src/pages/orderManage/pendingDeliveryOrder/service.js
View file @
373c4702
...
...
@@ -144,3 +144,10 @@ export async function downUploadeOrder(params) {
};
saveAs
(
blob
,
`批量发货-
${
status
[
params
.
status
]}
-
${
format
(
new
Date
(),
'
yyyyMMddHHmmss
'
)}
.xlsx`
);
}
// 延迟发货
export
function
apiDelayDeliverGoods
(
data
)
{
return
request
.
post
(
'
/api/kdsp/order/operation/record/create
'
,
{
data
,
prefix
:
config
.
kdspApi
,
});
}
src/pages/orderManage/pendingDeliveryOrder/styles.less
View file @
373c4702
...
...
@@ -27,3 +27,12 @@
}
}
}
.btnWarning {
background-color: rgb(247, 143, 74);
border-color: rgb(247, 143, 74);
}
.btnWarning:hover,
.btnWarning:focus {
background-color: rgb(253, 168, 111);
border-color: rgb(253, 168, 111);
}
src/utils/validator.js
View file @
373c4702
...
...
@@ -172,6 +172,24 @@ export const isIntegerNotZero = (rule, value, callback) => {
}
};
/**
* 验证 数字区间
* rule.min: 0
* rule.max: 100
*/
export
const
isNumberSection
=
(
rule
,
value
,
callback
)
=>
{
if
([
''
,
undefined
,
null
].
includes
(
value
))
{
callback
();
}
if
(
!
Number
(
value
))
{
callback
(
new
Error
(
'
请输入数字
'
));
}
else
if
(
rule
.
min
>
+
value
||
rule
.
max
<
+
value
)
{
callback
(
new
Error
(
rule
.
message
||
`请输入
${
rule
.
min
}
-
${
rule
.
max
}
区间的数字`
));
}
else
{
callback
();
}
};
// 验证是否整数,非必填
export
function
isIntegerNotMust
(
rule
,
value
,
callback
)
{
if
(
!
value
)
{
...
...
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