- 退款流程基本走完

This commit is contained in:
sin 2019-05-09 22:46:30 +08:00
parent 3677aab9ae
commit ddf2f0ea1f
13 changed files with 333 additions and 59 deletions

View File

@ -1,4 +1,5 @@
import { list } from '../../services/orderRefunds';
import { message } from 'antd';
import { list, agree, refuse, confirmReceipt, confirmRefund } from '../../services/orderRefunds';
export default {
namespace: 'orderRefunds',
@ -18,6 +19,54 @@ export default {
payload: response.data,
});
},
*agree({ payload }, { call }) {
const { callback, params } = payload;
const response = yield call(agree, params);
if (response.code !== 0) {
message.error('操作失败!');
} else {
message.success('操作成功!');
if (callback) {
callback(response);
}
}
},
*refuse({ payload }, { call }) {
const { callback, params } = payload;
const response = yield call(refuse, params);
if (response.code !== 0) {
message.error('操作失败!');
} else {
message.success('操作成功!');
if (callback) {
callback(response);
}
}
},
*confirmReceipt({ payload }, { call }) {
const { callback, params } = payload;
const response = yield call(confirmReceipt, params);
if (response.code !== 0) {
message.error('操作失败!');
} else {
message.success('操作成功!');
if (callback) {
callback(response);
}
}
},
*confirmRefund({ payload }, { call }) {
const { callback, params } = payload;
const response = yield call(confirmRefund, params);
if (response.code !== 0) {
message.error('操作失败!');
} else {
message.success('操作成功!');
if (callback) {
callback(response);
}
}
},
},
reducers: {

View File

@ -1,7 +1,7 @@
import React, { PureComponent } from 'react';
import { connect } from 'dva';
import moment from 'moment';
import { Card, Tabs, Table } from 'antd';
import { Card, Tabs, Modal, Table, Divider } from 'antd';
import PageHeaderWrapper from '../../components/PageHeaderWrapper';
import DictionaryText from '../../components/Dictionary/DictionaryText';
import TableSearch from './TableSearch';
@ -19,29 +19,46 @@ import dictionary from '../../utils/dictionary';
class OrderRefundsList extends PureComponent {
componentDidMount() {
// 查询 list
this.queryList({ index: 1 }, {});
this.queryList({ index: 1, pageSize: 10 }, {});
}
handleSearch = searchParams => {
const { orderRefunds } = this.props;
const { index, pageSize } = orderRefunds;
this.queryList({ index, pageSize }, searchParams);
this.queryList(
{ index, pageSize },
{
...searchParams,
...this.tabsValue,
}
);
};
queryList = ({ index = 0, pageSize = 10 }, searchParams) => {
queryList = (pageParams, searchParams) => {
const { dispatch } = this.props;
this.pageParams = pageParams;
this.searchParams = searchParams;
dispatch({
type: 'orderRefunds/list',
payload: {
index,
pageSize,
...pageParams,
...searchParams,
},
});
};
handleTabsChange = value => {
console.log(value);
this.tabsValue = {
status: value,
};
this.queryList(
{ index: 1, pageSize: 10 },
{
...this.searchParams,
status: value,
}
);
};
handleTableChange = pagination => {
@ -49,11 +66,116 @@ class OrderRefundsList extends PureComponent {
this.queryList({ pageSize, index: current }, {});
};
handleAgreeClick = ({ id }) => {
const { dispatch } = this.props;
const self = this;
Modal.confirm({
title: '提示消息',
content: '确认同意!',
onOk() {
dispatch({
type: 'orderRefunds/agree',
payload: {
params: {
id,
},
callback: () => {
self.queryList(self.pageParams, self.searchParams);
},
},
});
},
onCancel() {
console.log('Cancel');
},
});
};
handleRefuse = ({ id }) => {
const { dispatch } = this.props;
const self = this;
Modal.confirm({
title: '提示消息',
content: '确认拒绝!',
onOk() {
dispatch({
type: 'orderRefunds/refuse',
payload: {
params: {
id,
},
callback: () => {
self.queryList(self.pageParams, self.searchParams);
},
},
});
},
onCancel() {
console.log('Cancel');
},
});
};
handleConfirmReceipt = ({ id }) => {
const { dispatch } = this.props;
const self = this;
Modal.confirm({
title: '提示消息',
content: '确认收货!',
onOk() {
dispatch({
type: 'orderRefunds/confirmReceipt',
payload: {
params: {
id,
},
callback: () => {
self.queryList(self.pageParams, self.searchParams);
},
},
});
},
onCancel() {
console.log('Cancel');
},
});
};
handleConfirmRefund = ({ id }) => {
const { dispatch } = this.props;
const self = this;
Modal.confirm({
title: '提示消息',
content: '确认退款!',
onOk() {
dispatch({
type: 'orderRefunds/confirmRefund',
payload: {
params: {
id,
},
callback: () => {
self.queryList(self.pageParams, self.searchParams);
},
},
});
},
onCancel() {
console.log('Cancel');
},
});
};
render() {
const { orderRefunds } = this.props;
const { orderRefunds, loading } = this.props;
const { list, totalCount, index, pageSize } = orderRefunds;
const columns = [
{
title: '订单号',
dataIndex: 'orderId',
key: 'orderId',
},
{
title: '服务编号',
dataIndex: 'serviceNumber',
@ -111,12 +233,31 @@ class OrderRefundsList extends PureComponent {
},
{
title: '操作',
render() {
return (
render: row => {
const { status } = row;
let buttons;
if (status === 1) {
buttons = (
<div>
<a>同意</a>
<a onClick={this.handleAgreeClick.bind(this, row)}>同意</a>
<Divider type="vertical" />
<a onClick={this.handleRefuse.bind(this, row)}>拒绝</a>
</div>
);
} else if (status === 2) {
buttons = (
<div>
<a onClick={this.handleConfirmReceipt.bind(this, row)}>确认收货</a>
</div>
);
} else if (status === 5) {
buttons = (
<div>
<a onClick={this.handleConfirmRefund.bind(this, row)}>退款</a>
</div>
);
}
return buttons;
},
},
];
@ -137,11 +278,14 @@ class OrderRefundsList extends PureComponent {
<Tabs defaultActiveKey={null} onChange={this.handleTabsChange}>
<Tabs.TabPane tab="全部" key={null} />
<Tabs.TabPane tab="待处理" key={1} />
<Tabs.TabPane tab="已处理" key={2} />
<Tabs.TabPane tab="已完成" key={4} />
<Tabs.TabPane tab="待收货" key={2} />
<Tabs.TabPane tab="已收货" key={5} />
<Tabs.TabPane tab="已完成" key={6} />
<Tabs.TabPane tab="已拒绝" key={3} />
</Tabs>
<Table
loading={loading}
rowKey="id"
dataSource={list}
columns={columns}

View File

@ -9,12 +9,13 @@ const FormItem = Form.Item;
* @type {React.ComponentClass<RcBaseFormProps & Omit<FormComponentProps, keyof FormComponentProps>>}
*/
const TableSearch = Form.create()(props => {
const { getFieldDecorator, form, handleSearch } = props.form;
const { handleSearch } = props;
const { getFieldDecorator, validateFields, form } = props.form;
function onSubmit(e) {
e.preventDefault();
form.validateFields((err, fields) => {
validateFields((err, fields) => {
const buildTime = (fieldValue, key) => {
const res = {};
if (fieldValue && fieldValue.length >= 2) {
@ -68,6 +69,11 @@ const TableSearch = Form.create()(props => {
{getFieldDecorator('orderNo')(<Input placeholder="请输入订单号" />)}
</FormItem>
</Col>
<Col md={8} sm={24}>
<FormItem label="服务号">
{getFieldDecorator('serviceNumber')(<Input placeholder="请输入服务号" />)}
</FormItem>
</Col>
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>

View File

@ -8,8 +8,26 @@ export async function list(params) {
});
}
export async function orderPage(params) {
return request(`/order-api/admins/order/page?${stringify(params)}`, {
method: 'GET',
export async function agree(params) {
return request(`/order-api/admins/order_return/agree?${stringify(params)}`, {
method: 'POST',
});
}
export async function refuse(params) {
return request(`/order-api/admins/order_return/refuse?${stringify(params)}`, {
method: 'POST',
});
}
export async function confirmReceipt(params) {
return request(`/order-api/admins/order_return/confirm_receipt?${stringify(params)}`, {
method: 'POST',
});
}
export async function confirmRefund(params) {
return request(`/order-api/admins/order_return/confirm_refund?${stringify(params)}`, {
method: 'POST',
});
}

View File

@ -14,6 +14,7 @@ body {
border-right: 1px solid #ccc2bf;
}
@media screen and (min-width: 769px) {
#app, .van-goods-action, .van-overflow-hidden {
max-width: 600px!important;
margin: 0 auto;
@ -26,6 +27,13 @@ body {
left:0;
right:0;
}
}
.wap-wrap {
font-size: 0.32rem;
width: 100%;
}
#maxWidth {

View File

@ -46,13 +46,13 @@ public class AdminOrderReturnController {
return orderReturnService.orderReturnRefuse(id);
}
@PostMapping("confirm_commodity")
public CommonResult confirmCommodity(@RequestParam("id") Integer id) {
@PostMapping("confirm_receipt")
public CommonResult confirmReceipt(@RequestParam("id") Integer id) {
return orderReturnService.confirmReceipt(id);
}
@PostMapping("confirm_order")
public CommonResult confirmOrder(HttpServletRequest request, @RequestParam("id") Integer id) {
@PostMapping("confirm_refund")
public CommonResult confirmRefund(HttpServletRequest request, @RequestParam("id") Integer id) {
String ip = HttpUtil.getIp(request);
return orderReturnService.refund(id, ip);
}

View File

@ -2,6 +2,7 @@ package cn.iocoder.mall.order.application.po.admin;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
@ -26,14 +27,24 @@ public class OrderReturnQueryPO implements Serializable {
* 订单编号
*/
private Integer orderNo;
/**
* 服务号
*/
private String serviceNumber;
/**
* 创建时间 - 开始
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date startCreateTime;
/**
* 创建时间 - 结束
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date endCreateTime;
/**
* 状态
*/
private Integer status;
///
/// 分页信息

View File

@ -25,6 +25,10 @@ public class OrderReturnQueryDTO implements Serializable {
* 订单编号
*/
private Integer orderNo;
/**
* 服务号
*/
private String serviceNumber;
/**
* 创建时间 - 开始
*/
@ -33,6 +37,10 @@ public class OrderReturnQueryDTO implements Serializable {
* 创建时间 - 结束
*/
private Date endCreateTime;
/**
* 状态
*/
private Integer status;
///
/// 分页信息

View File

@ -30,7 +30,7 @@ public interface OrderReturnMapper {
* @param orderReturnDO
* @return
*/
int updateByOrderId(OrderReturnDO orderReturnDO);
int updateById(OrderReturnDO orderReturnDO);
/**
* 查询 - 根据 orderId

View File

@ -63,6 +63,10 @@ public class OrderReturnDO extends BaseDO {
* 同意时间
*/
private Date approvalTime;
/**
* 拒绝时间
*/
private Date refuseTime;
/**
* 物流时间填写物流单号时间
*/
@ -90,8 +94,7 @@ public class OrderReturnDO extends BaseDO {
* - 3申请失败
* - 4退货中
* - 5已收货
* - 6拒绝退款
* - 7退货成功
* - 6退货成功
*/
private Integer status;
}

View File

@ -3,15 +3,14 @@ package cn.iocoder.mall.order.biz.service;
import cn.iocoder.common.framework.constant.DeletedStatusEnum;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.admin.api.DataDictService;
import cn.iocoder.mall.admin.api.bo.DataDictBO;
import cn.iocoder.mall.order.api.OrderLogisticsService;
import cn.iocoder.mall.order.api.OrderReturnService;
import cn.iocoder.mall.order.api.bo.OrderLastLogisticsInfoBO;
import cn.iocoder.mall.order.api.bo.OrderReturnInfoBO;
import cn.iocoder.mall.order.api.bo.OrderReturnListBO;
import cn.iocoder.mall.order.api.constant.OrderErrorCodeEnum;
import cn.iocoder.mall.order.api.constant.OrderReturnStatusEnum;
import cn.iocoder.mall.order.api.constant.OrderStatusEnum;
import cn.iocoder.mall.order.api.constant.PayAppId;
import cn.iocoder.mall.order.api.constant.*;
import cn.iocoder.mall.order.api.dto.OrderReturnApplyDTO;
import cn.iocoder.mall.order.api.dto.OrderReturnQueryDTO;
import cn.iocoder.mall.order.biz.convert.OrderReturnConvert;
@ -55,6 +54,9 @@ public class OrderReturnServiceImpl implements OrderReturnService {
private OrderLogisticsService orderLogisticsService;
@Reference(validation = "true", version = "${dubbo.consumer.PayRefundService.version}")
private PayRefundService payRefundService;
@Reference(validation = "true", version = "${dubbo.consumer.DataDictService.version}")
private DataDictService dataDictService;
@Override
public CommonResult orderReturnApply(OrderReturnApplyDTO orderReturnDTO) {
@ -156,9 +158,10 @@ public class OrderReturnServiceImpl implements OrderReturnService {
.error(OrderErrorCodeEnum.ORDER_RETURN_NOT_EXISTENT.getCode());
}
orderReturnMapper.updateByOrderId(
orderReturnMapper.updateById(
new OrderReturnDO()
.setId(id)
.setApprovalTime(new Date())
.setStatus(OrderReturnStatusEnum.APPLICATION_SUCCESSFUL.getValue())
);
return CommonResult.success(null);
@ -171,9 +174,10 @@ public class OrderReturnServiceImpl implements OrderReturnService {
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_RETURN_NOT_EXISTENT.getCode());
}
orderReturnMapper.updateByOrderId(
orderReturnMapper.updateById(
new OrderReturnDO()
.setId(id)
.setRefuseTime(new Date())
.setStatus(OrderReturnStatusEnum.APPLICATION_FAIL.getValue())
);
return CommonResult.success(null);
@ -186,9 +190,10 @@ public class OrderReturnServiceImpl implements OrderReturnService {
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_RETURN_NOT_EXISTENT.getCode());
}
orderReturnMapper.updateByOrderId(
orderReturnMapper.updateById(
new OrderReturnDO()
.setId(id)
.setReceiverTime(new Date())
.setStatus(OrderReturnStatusEnum.ORDER_RECEIPT.getValue())
);
return CommonResult.success(null);
@ -207,13 +212,24 @@ public class OrderReturnServiceImpl implements OrderReturnService {
// TODO: 2019/5/8 sin 退货+退款退回商品签收后支付系统退款
// TODO: 2019/5/8 sin 事务一致性 [重要]
CommonResult<DataDictBO> dataDictResult = dataDictService
.getDataDict(DictKeyConstants.ORDER_RETURN_REASON, orderReturnDO.getReason());
if (dataDictResult.isError()) {
return ServiceExceptionUtil.error(OrderErrorCodeEnum.DICT_SERVER_INVOKING_FAIL.getCode());
}
// 支付退款
String orderDescription = dataDictResult.getData()
.getDisplayName() + "(" + orderReturnDO.getDescribe() + ")";
CommonResult payResult = payRefundService.submitRefund(
new PayRefundSubmitDTO()
.setAppId(PayAppId.APP_ID_SHOP_ORDER)
.setOrderId(String.valueOf(orderReturnDO.getOrderId()))
.setPrice(orderReturnDO.getRefundPrice())
.setOrderDescription("")
.setOrderDescription(orderDescription)
.setCreateIp(ip)
);
@ -222,9 +238,10 @@ public class OrderReturnServiceImpl implements OrderReturnService {
}
// 更新 订单退货 信息
orderReturnMapper.updateByOrderId(
orderReturnMapper.updateById(
new OrderReturnDO()
.setId(id)
.setClosingTime(new Date())
.setStatus(OrderReturnStatusEnum.RETURN_SUCCESS.getValue())
);
@ -232,13 +249,16 @@ public class OrderReturnServiceImpl implements OrderReturnService {
orderMapper.updateById(
new OrderDO()
.setId(orderReturnDO.getOrderId())
.setClosingTime(new Date())
.setStatus(OrderStatusEnum.COMPLETED.getValue())
);
// 更新订单
orderItemMapper.updateByOrderId(
orderReturnDO.getOrderId(),
new OrderItemDO().setStatus(OrderStatusEnum.COMPLETED.getValue())
new OrderItemDO()
.setClosingTime(new Date())
.setStatus(OrderStatusEnum.COMPLETED.getValue())
);
return CommonResult.success(null);
}

View File

@ -12,6 +12,7 @@
reason,
`describe`,
approval_time,
refuse_time,
logistics_time,
receiver_time,
closing_time,
@ -28,13 +29,13 @@
INSERT INTO `order_return` (
service_number, order_id, order_no, order_logistics_id,
refund_price, reason, `describe`,
approval_time, logistics_time, receiver_time, closing_time,
approval_time, refuse_time, logistics_time, receiver_time, closing_time,
service_type, status,
create_time, update_time)
VALUES (
#{serviceNumber}, #{orderId}, #{orderNo}, #{orderLogisticsId},
${refundPrice}, #{reason}, #{describe},
#{approvalTime}, #{logisticsTime}, #{receiverTime}, #{closingTime},
#{approvalTime}, #{refuse_time}, #{logisticsTime}, #{receiverTime}, #{closingTime},
#{serviceType}, #{status}, #{createTime}, #{updateTime})
</insert>
@ -58,20 +59,20 @@
<if test="approvalTime != null">
, approval_time = #{approvalTime}
</if>
<if test="refuseTime != null">
, refuse_time = #{refuseTime}
</if>
<if test="logisticsTime != null">
, logistics_time = #{logisticsTime}
</if>
<if test="receiverTime != null">
, receiver_time = #{receiverTime}
</if>
<if test="deliveryTime != null">
, delivery_time = #{deliveryTime}
</if>
<if test="closingTime != null">
, closing_time = #{closingTime}
</if>
<if test="returnType != null">
, return_type = #{returnType}
<if test="serviceType != null">
, service_type = #{serviceType}
</if>
<if test="status != null">
, status = #{status}
@ -88,10 +89,10 @@
<!--
更新 - 根据 id 更新
-->
<update id="updateByOrderId" parameterType="OrderReturnDO">
<update id="updateById" parameterType="OrderReturnDO">
UPDATE `order_return`
<include refid="updateFieldSql"/>
WHERE order_id = #{orderId}
WHERE id = #{id}
</update>
<!--
@ -109,6 +110,12 @@
列表查询 - where
-->
<sql id="selectListWhere">
<if test="status != null">
AND status = #{status}
</if>
<if test="serviceNumber != null">
AND service_number = #{serviceNumber}
</if>
<if test="orderId != null">
AND order_id = #{orderId}
</if>

View File

@ -67,7 +67,7 @@ public class AdminSecurityInterceptor extends HandlerInterceptorAdapter {
}
// 校验是否需要已授权
// TODO sin 暂时不校验
// checkPermission(request, authentication);
checkPermission(request, authentication);
// 返回成功
return super.preHandle(request, response, handler);
}