记得上下班打卡 | git大法好,push需谨慎

Commit ffa8849e authored by 张国柄's avatar 张国柄

+会员退款;

parent 8214bcc6
...@@ -2,150 +2,229 @@ ...@@ -2,150 +2,229 @@
<html lang="zh" xmlns:th="http://www.thymeleaf.org" > <html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head> <head>
<th:block th:include="include :: header('会员订单详情')" /> <th:block th:include="include :: header('会员订单详情')" />
<th:block th:include="include :: datetimepicker-css" /> <style type="text/css">.user-info-head{position:relative;display:inline-block;}.user-info-head:hover:after{content:'\f030';position:absolute;left:0;right:0;top:0;bottom:0;color:#eee;background:rgba(0,0,0,0.5);font-family:FontAwesome;font-size:24px;font-style:normal;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;cursor:pointer;line-height:110px;border-radius:50%;}</style>
</head> </head>
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content"> <body class="gray-bg" style="font: 14px Helvetica Neue, Helvetica, PingFang SC, 微软雅黑, Tahoma, Arial, sans-serif !important;">
<form class="form-horizontal m" id="form-order-edit" th:object="${orderDetailsVo}"> <section class="section-content">
<div class="form-group"> <div class="row">
<label class="col-sm-3 control-label">订单状态:</label> <div class="col-sm-4 pr5">
<div class="col-sm-8" th:text="*{@dict.getLabel('zhengzai_member_order_status',adamMemberOrderVo.state)}"> <div class="ibox float-e-margins">
</div> <div class="ibox-title ibox-title-gray dashboard-header gray-bg">
</div> <h5>会员信息([[${orderDetailsVo.adamMemberOrderVo.memberName}]])</h5>
<div class="form-group"> </div>
<label class="col-sm-3 control-label">价格:</label> <div class="ibox-content">
<div class="col-sm-8"> <div class="text-center">
<input name="pricePaid" th:field="*{adamMemberOrderVo.price}" class="form-control" type="text" readonly> <p class="user-info-head"><img class="img-circle img-sm" th:src="${orderDetailsVo.adamUserInfoVo.avatar}" ></p>
</div> </div>
</div> <ul class="list-group list-group-striped">
<div class="form-group"> <li class="list-group-item"><i class="fa fa-user"></i>
<label class="col-sm-3 control-label">可用时间(天):</label> <b class="font-noraml">昵称:</b>
<div class="col-sm-8"> <p class="pull-right">[[${orderDetailsVo.adamUserInfoVo.nickname}]]</p>
<input name="days" th:field="*{adamMemberOrderVo.days}" class="form-control" type="text" readonly> </li>
<li class="list-group-item"><i class="fa fa-id-card"></i>
<b class="font-noraml">用户ID:</b>
<p class="pull-right">[[${orderDetailsVo.adamUser.uid}]]</p>
</li>
<li class="list-group-item"><i class="fa fa-diamond"></i>
<b class="font-noraml">会员ID:</b>
<p class="pull-right">[[${orderDetailsVo.adamUserMemberVo.memberNo}]]</p>
</li>
<li class="list-group-item"><i class="fa fa-birthday-cake"></i>
<b class="font-noraml">会员生日:</b>
<p class="pull-right">[[${orderDetailsVo.adamUserInfoVo.birthday}]]</p>
</li>
<li class="list-group-item"><i class="fa fa-paw"></i>
<b class="font-noraml">地区:</b>
<p class="pull-right">[[${orderDetailsVo.adamUserInfoVo.area}]]</p>
</li>
<li class="list-group-item"><i class="fa fa-phone"></i>
<b class="font-noraml">手机号码:</b>
<p class="pull-right">[[${orderDetailsVo.adamUser.mobile}]]</p>
</li>
<li class="list-group-item"><i class="fa fa-plane"></i>
<b class="font-noraml">会员地址:</b>
<p class="pull-right">
[[${orderDetailsVo.adamMemberOrderExtVo.expressReceiver}]]
</p>
</li>
<li class="list-group-item"><i class="fa fa-crosshairs"></i>
<p class="pull-right">
[[${orderDetailsVo.adamMemberOrderExtVo.expressAddress}]]
</p>
</li>
<li class="list-group-item"><i class="fa fa-heart"></i>
<b class="font-noraml">会员状态:</b>
<p class="pull-right">
<span class='badge badge-primary' th:if="${orderDetailsVo.adamUserMemberVo.state == 1}">正常 / [[${#temporals.format(orderDetailsVo.adamUserMemberVo.expiryAt, 'dd-MM-yyyy')}]]</span>
<span class='badge badge-danger' th:if="${orderDetailsVo.adamUserMemberVo.state != 1}">到期 / [[${#temporals.format(orderDetailsVo.adamUserMemberVo.expiryAt, 'dd-MM-yyyy')}]]</span>
</p>
</li>
<li class="list-group-item"><i class="fa fa-calendar-check-o"></i>
<b class="font-noraml">创建时间:</b>
<p class="pull-right">[[${#temporals.format(orderDetailsVo.adamUserMemberVo.createdAt, 'yyyy-MM-dd HH:mm')}]]</p>
</li>
</ul>
</div> </div>
</div> </div>
<div class="form-group">
<label class="col-sm-3 control-label">订单号:</label>
<div class="col-sm-8">
<input name="orderNo" th:field="*{adamMemberOrderVo.orderNo}" class="form-control" type="text" readonly>
</div> </div>
<div class="col-sm-8 about">
<div class="ibox float-e-margins">
<div class="ibox-title ibox-title-gray dashboard-header">
<h5>订单信息</h5>
</div>
<div class="ibox-content">
<ul class="list-group list-group-striped">
<li class="list-group-item">
<b class="font-noraml">订单编号:</b>
<p class="pull-right">[[${orderDetailsVo.adamMemberOrderVo.orderNo}]]</p>
</li>
<li class="list-group-item">
<b class="font-noraml">支付编号:</b>
<p class="pull-right">[[${orderDetailsVo.adamMemberOrderVo.payNo}]]</p>
</li>
<li class="list-group-item">
<b class="font-noraml">创建时间:</b>
<p class="pull-right">[[${#temporals.format(orderDetailsVo.adamMemberOrderVo.createdAt, 'yyyy-MM-dd HH:mm:ss')}]]</p>
</li>
<li class="list-group-item">
<b class="font-noraml">支付时间:</b>
<p class="pull-right">[[${#temporals.format(orderDetailsVo.adamMemberOrderVo.paymentAt, 'yyyy-MM-dd HH:mm:ss')}]]</p>
</li>
<li class="list-group-item">
<b class="font-noraml">支付方式:</b>
<p class="pull-right">[[${#strings.toUpperCase(orderDetailsVo.adamMemberOrderVo.deviceFrom)}]][[${#strings.toUpperCase(orderDetailsVo.adamMemberOrderVo.payType)}]]</p>
</li>
<li class="list-group-item">
<b class="font-noraml">支付价格:</b>
<p class="pull-right">[[${orderDetailsVo.adamMemberOrderVo.pricePaid}]]</p>
</li>
<li class="list-group-item">
<b class="font-noraml">订单状态:</b>
<p class="pull-right">
<span class='badge badge-white' th:if="${orderDetailsVo.adamMemberOrderVo.state == 0}">未支付</span>
<span class='badge badge-success' th:if="${orderDetailsVo.adamMemberOrderVo.state == 1}">已支付</span>
<span class='badge badge-disable' th:if="${orderDetailsVo.adamMemberOrderVo.state == 2}">已关闭</span>
<span class='badge badge-danger' th:if="${orderDetailsVo.adamMemberOrderVo.state == 4}">退款中</span>
<span class='badge badge-inverse' th:if="${orderDetailsVo.adamMemberOrderVo.state == 5}">已退款</span>
</p>
</li>
<li class="list-group-item">
<b class="font-noraml">来源信息:</b>
<p class="pull-right">[[${orderDetailsVo.adamMemberOrderVo.source}]] / [[${orderDetailsVo.adamMemberOrderVo.clientIp}]] / [[${orderDetailsVo.adamMemberOrderVo.version}]]</p>
</li>
</ul>
</div> </div>
<div class="form-group">
<label class="col-sm-3 control-label">生成时间:</label> <div class="text-center" style="margin-top: -15px;margin-bottom: 10px;">
<div class="col-sm-8"> <a data-toggle="modal" class="btn btn-danger" href="#" onclick="closeItem()">&nbsp;&nbsp;&nbsp;&nbsp;</a>&nbsp;&nbsp;
<input name="createdAt" th:field="*{adamMemberOrderVo.createdAt}" class="form-control" type="text" readonly> <a data-toggle="modal" class="btn btn-primary" href="#member-refund-form">申请退款</a>
</div>
</div> </div>
<div id="member-refund-form" class="modal fade" aria-hidden="true">
<div class="modal-dialog" style="width:33%;">
<div class="modal-content">
<div class="modal-body">
<div class="row">
<div>
<h3 class="m-t-none m-b text-center">会员退款</h3>
<form role="form" id="form-member-order-refund">
<input name="orderNo" id="id" type="hidden" th:value="${orderDetailsVo.adamMemberOrderVo.orderNo}" readonly>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">购买人手机号:</label> <label class="pull-left"><i class="fa fa-cny"></i>&nbsp;支付金额:</label>
<div class="col-sm-8"> <!-- <span>[[${orderDetailsVo.adamMemberOrderVo.pricePaid}]]元</span>-->
<input name="memberName" th:field="*{adamUser.mobile}" class="form-control" type="text" readonly> <input type="number" name="pricePaid" th:value="${orderDetailsVo.adamMemberOrderVo.pricePaid}" class="form-control" style="width: 30%;height: 20px;" readonly>
</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">版本:</label> <label class="pull-left"><i class="fa fa-cny"></i>&nbsp;退款金额:</label>
<div class="col-sm-8"> <input type="number" name="refundAmt" th:value="${orderDetailsVo.adamMemberOrderVo.pricePaid}" class="form-control" style="width: 30%;height: 20px;">
<input name="version" th:field="*{adamMemberOrderVo.version}" class="form-control" type="text" readonly>
</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">客户端:</label> <!-- <label>退款原因:</label>-->
<div class="col-sm-8"> <textarea rows="3" name="reason" placeholder="请输入退款原因" class="form-control"></textarea>
<input name="source" th:field="*{adamMemberOrderVo.source}" class="form-control" type="text" readonly>
</div> </div>
<div>
<label>是否能继续购买会员:</label>
<div class="radio check-box">
<input type="radio" value="1" name="renewable">
</div> </div>
<!-- &lt;!&ndash; 会员卡信息&ndash;&gt;--> <div class="radio check-box">
<div class="form-group"> <input type="radio" checked="" value="2" name="renewable">
<label class="col-sm-3 control-label">会员卡ID:</label>
<div class="col-sm-8">
<input name="memberNo" th:field="*{adamUserMemberVo.memberNo}" class="form-control" type="text" readonly>
</div> </div>
</div> </div>
<div class="text-center" style="margin-bottom: -15px;margin-top: 10px;">
<div class="form-group"> <button class="btn btn-sm btn-primary m-t-n-xs" type="button" onclick="memberOrderRefund()">
<label class="col-sm-3 control-label">会员卡名称:</label> <strong>确认退款</strong>
<div class="col-sm-8"> </button>
<input name="memberName" th:field="*{adamMemberOrderVo.memberName}" class="form-control" type="text" readonly>
</div>
</div>
<!-- <div class="form-group">-->
<!-- <label class="col-sm-3 control-label">会员勋章:</label>-->
<!-- <div class="col-sm-8">-->
<!-- <input name="memberNo" th:field="*{adamMemberOrderVo.memberNo}" class="form-control" type="text">-->
<!-- </div>-->
<!-- </div>-->
<div class="form-group">
<label class="col-sm-3 control-label">会员头像:</label>
<div class="col-sm-8">
<img class="img-circle img-lg" th:src="(*{#strings.isEmpty(adamUserInfoVo.avatar)}) ? @{/img/profile.jpg} : @{*{adamUserInfoVo.avatar}}" th:onerror="'this.src=\'' + @{'/img/profile.jpg'} + '\''">
</div> </div>
</form>
</div> </div>
<!-- &lt;!&ndash; 套餐信息&ndash;&gt;-->
<div class="form-group">
<label class="col-sm-3 control-label">用户生日:</label>
<div class="col-sm-8">
<div class="input-group">
<input th:value="*{adamMemberOrderVo.birthday}" class="form-control" type="text" readonly>
</div> </div>
</div> </div>
</div> </div>
<!-- <div class="form-group">-->
<!-- <label class="col-sm-3 control-label">喜欢的音乐人:</label>-->
<!-- <div class="col-sm-8">-->
<!-- <input name="version" th:field="*{version}" class="form-control" type="text">-->
<!-- </div>-->
<!-- </div>-->
<div class="form-group">
<label class="col-sm-3 control-label">收件人:</label>
<div class="col-sm-8">
<input name="expressReceiver" th:value="|*{adamMemberOrderExtVo.expressReceiver} / *{adamMemberOrderExtVo.expressPhone}|" class="form-control" type="text" readonly>
</div> </div>
</div> </div>
<div class="form-group">
<label class="col-sm-3 control-label">收件地址:</label>
<div class="col-sm-8">
<input name="expressAddress" th:value="*{adamMemberOrderExtVo.expressAddress}" class="form-control" type="text" readonly>
</div> </div>
</div> </div>
</form>
</div> </div>
<th:block th:include="include :: footer" /> </section>
<th:block th:include="include :: datetimepicker-js" />
<script th:inline="javascript">
var prefix = ctx + "kylin/order";
$("#form-order-edit").validate({
focusCleanup: true
});
function submitHandler() { <th:block th:include="include :: footer" />
if ($.validate.form()) { <script>
$.operate.save(prefix + "/edit", $('#form-order-edit').serialize()); var pricePaid = [[${orderDetailsVo.adamMemberOrderVo.pricePaid}]];
}
}
$("input[name='birthday']").datetimepicker({ $(function(){
format: "yyyy-mm-dd", //键盘按下ESC时关闭窗口!
minView: "month", $(document).keypress(function(e){
autoclose: true if(e.keyCode==27){
//关闭窗口的方法
window.opener = null;
window.close();
}
}); });
$("input[name='paymentAt']").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true
}); });
$("input[name='createdAt']").datetimepicker({ $("#form-member-order-refund").validate({
format: "yyyy-mm-dd", onkeyup: false,
minView: "month", rules:{
autoclose: true refundAmt: {
}); required: true,
number: true,
min: 0.01,
max: pricePaid
},
reason: {
required: true,
minlength: 2,
maxlength: 100
}
},
messages: {
refundAmt: {
required: "请输入退款金额",
number: "退款金额必须为数字",
min: "退款金额必须不得小于0.01",
max: "退款金额不能大于支付金额"
},
reason: {
required: "请输入退款原因",
minlength: "退款原因不能大于100个字符",
maxlength: "退款原因不能小于2个字符"
}
$("input[name='updatedAt']").datetimepicker({ },
format: "yyyy-mm-dd", focusCleanup: true
minView: "month",
autoclose: true
}); });
</script> function memberOrderRefund () {
if ($.validate.form("form-member-order-refund")) {
$.operate.saveModal(ctx + "adam/order/orderList/refund", $('#form-member-order-refund').serialize());
}
}
</script>
</body> </body>
</html> </html>
<!DOCTYPE html> <!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro"> <html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head> <head>
<th:block th:include="include :: header('【请填写功能名称】列表')" /> <th:block th:include="include :: header('会员订单列表')" />
</head> </head>
<body class="gray-bg"> <body class="gray-bg">
<div class="container-div"> <div class="container-div">
...@@ -90,17 +90,19 @@ ...@@ -90,17 +90,19 @@
var options = { var options = {
url: prefix + "/list", url: prefix + "/list",
createUrl: prefix + "/add", createUrl: prefix + "/add",
updateUrl: prefix + "/edit/{id}",
removeUrl: prefix + "/remove",
exportUrl: prefix + "/export",
detailUrl: prefix + "/detail/{id}", detailUrl: prefix + "/detail/{id}",
modalName: "【请填写功能名称】", modalName: "会员订单",
columns: [{ columns: [{
checkbox: true checkbox: true,
}, },
{ {
field: 'orderNo', field: 'orderNo',
title: '订单号' title: '订单号',
formatter: function(value, row, index) {
var actions = [];
actions.push('<a class="btn btn-xs" href="javascript:void(0)" onclick="$.operate.detailTab(\'' + row.orderNo + '\')">' + value + '</a>');
return actions.join('');
}
}, },
{ {
field: 'state', field: 'state',
...@@ -111,10 +113,13 @@ ...@@ -111,10 +113,13 @@
}, },
{ {
field: 'payType', field: 'payType',
title: '支付方式' title: '支付方式',
formatter: function (value) {
return '<span class="nav-label">' + value.toLocaleUpperCase() + '</span>';
}
}, },
{ {
field: 'price', field: 'pricePaid',
title: '价格(元)' title: '价格(元)'
}, },
{ {
...@@ -149,7 +154,7 @@ ...@@ -149,7 +154,7 @@
align: 'center', align: 'center',
formatter: function(value, row, index) { formatter: function(value, row, index) {
var actions = []; var actions = [];
actions.push('<a class="btn btn-warning btn-xs ' + detailFlag + '" href="javascript:void(0)" onclick="$.operate.detail(\'' + row.orderNo + '\')"><i class="fa fa-search"></i>详细</a>'); actions.push('<a class="btn btn-warning btn-xs ' + detailFlag + '" href="javascript:void(0)" onclick="$.operate.detailTab(\'' + row.orderNo + '\')"><i class="fa fa-search"></i>查看详情</a>');
return actions.join(''); return actions.join('');
} }
}] }]
......
...@@ -69,7 +69,7 @@ public class AdamMemberOrderAdminServiceImpl extends ServiceImpl<AdamMemberOrder ...@@ -69,7 +69,7 @@ public class AdamMemberOrderAdminServiceImpl extends ServiceImpl<AdamMemberOrder
@Value("${liquidnet.url-refund.apply}") @Value("${liquidnet.url-refund.apply}")
private String applyUrl; private String applyUrl;
@Value("${liquidnet.url-refund.notify}") @Value("${liquidnet.url-refund.notify-member}")
private String notifyUrl; private String notifyUrl;
@Override @Override
...@@ -118,6 +118,7 @@ public class AdamMemberOrderAdminServiceImpl extends ServiceImpl<AdamMemberOrder ...@@ -118,6 +118,7 @@ public class AdamMemberOrderAdminServiceImpl extends ServiceImpl<AdamMemberOrder
// 查取快递信息 // 查取快递信息
AdamMemberOrderExt adamMemberOrderExt = adamMemberOrderExtMapper.selectOne(Wrappers.lambdaQuery(AdamMemberOrderExt.class).eq(AdamMemberOrderExt::getOrderNo, orderNo)); AdamMemberOrderExt adamMemberOrderExt = adamMemberOrderExtMapper.selectOne(Wrappers.lambdaQuery(AdamMemberOrderExt.class).eq(AdamMemberOrderExt::getOrderNo, orderNo));
adamUserMemberVo.setState(adamUserMemberVo.isActive() ? 1 : 2);
detailAdminVo.setAdamMemberOrderVo(adamMemberOrderVo); detailAdminVo.setAdamMemberOrderVo(adamMemberOrderVo);
detailAdminVo.setAdamUserMemberVo(adamUserMemberVo); detailAdminVo.setAdamUserMemberVo(adamUserMemberVo);
detailAdminVo.setAdamUserInfoVo(adamUserInfoVo); detailAdminVo.setAdamUserInfoVo(adamUserInfoVo);
...@@ -131,10 +132,12 @@ public class AdamMemberOrderAdminServiceImpl extends ServiceImpl<AdamMemberOrder ...@@ -131,10 +132,12 @@ public class AdamMemberOrderAdminServiceImpl extends ServiceImpl<AdamMemberOrder
public AjaxResult refundProcessing(AdamMemberOrderRefundParam param, AdamMemberOrder memberOrder) { public AjaxResult refundProcessing(AdamMemberOrderRefundParam param, AdamMemberOrder memberOrder) {
LinkedMultiValueMap<String, String> linkedMultiValueMap = new LinkedMultiValueMap<>(); LinkedMultiValueMap<String, String> linkedMultiValueMap = new LinkedMultiValueMap<>();
String refundNo = IDGenerator.nextTimeId2().concat("VR");
linkedMultiValueMap.add("code", memberOrder.getPayNo()); linkedMultiValueMap.add("code", memberOrder.getPayNo());
linkedMultiValueMap.add("notifyUrl", notifyUrl); linkedMultiValueMap.add("notifyUrl", notifyUrl);
linkedMultiValueMap.add("orderCode", memberOrder.getOrderNo()); linkedMultiValueMap.add("orderCode", memberOrder.getOrderNo());
linkedMultiValueMap.add("orderRefundCode", IDGenerator.nextTimeId2()); linkedMultiValueMap.add("orderRefundCode", refundNo);
linkedMultiValueMap.add("paymentId", null); linkedMultiValueMap.add("paymentId", null);
linkedMultiValueMap.add("paymentType", (memberOrder.getDeviceFrom() + memberOrder.getPayType()).toUpperCase()); linkedMultiValueMap.add("paymentType", (memberOrder.getDeviceFrom() + memberOrder.getPayType()).toUpperCase());
linkedMultiValueMap.add("price", String.valueOf(param.getRefundAmt())); linkedMultiValueMap.add("price", String.valueOf(param.getRefundAmt()));
...@@ -153,12 +156,12 @@ public class AdamMemberOrderAdminServiceImpl extends ServiceImpl<AdamMemberOrder ...@@ -153,12 +156,12 @@ public class AdamMemberOrderAdminServiceImpl extends ServiceImpl<AdamMemberOrder
LocalDateTime now = LocalDateTime.now(); LocalDateTime now = LocalDateTime.now();
AdamMemberRefund memberRefund = new AdamMemberRefund(); AdamMemberRefund memberRefund = new AdamMemberRefund();
memberRefund.setRefundNo(IDGenerator.nextTimeId2().concat("VR")); memberRefund.setRefundNo(refundNo);
memberRefund.setOrderNo(memberOrder.getOrderNo()); memberRefund.setOrderNo(memberOrder.getOrderNo());
memberRefund.setRefundPrice(param.getRefundAmt()); memberRefund.setRefundPrice(param.getRefundAmt());
memberRefund.setRefundReason(param.getReason()); memberRefund.setRefundReason(param.getReason());
memberRefund.setRenewable(param.getRenewable()); memberRefund.setRenewable(param.getRenewable());
memberRefund.setRefundState(0); memberRefund.setRefundState(9);
memberRefund.setRefundNo(postResultJNode.get("refundCode").asText()); memberRefund.setRefundNo(postResultJNode.get("refundCode").asText());
memberRefund.setOperator(ShiroUtils.getLoginName()); memberRefund.setOperator(ShiroUtils.getLoginName());
memberRefund.setCreatedAt(now); memberRefund.setCreatedAt(now);
......
...@@ -75,9 +75,9 @@ public class AdamMemberRefund implements Serializable { ...@@ -75,9 +75,9 @@ public class AdamMemberRefund implements Serializable {
private LocalDateTime updatedAt; private LocalDateTime updatedAt;
/** /**
* 完成时间 * 退款时间
*/ */
private LocalDateTime completeAt; private LocalDateTime refundAt;
private String comment; private String comment;
......
...@@ -383,11 +383,11 @@ create table adam_member_refund ...@@ -383,11 +383,11 @@ create table adam_member_refund
repay_no varchar(64) comment '支付中心退款编号', repay_no varchar(64) comment '支付中心退款编号',
repay_reason varchar(200) comment '支付中心退款描述', repay_reason varchar(200) comment '支付中心退款描述',
refund_at datetime(3) comment '退款时间',
operator varchar(64) comment '操作人', operator varchar(64) comment '操作人',
created_at datetime(3) not null, created_at datetime(3) not null,
updated_at datetime(3), updated_at datetime(3),
complete_at datetime(3) comment '完成时间',
comment varchar(255) comment varchar(255)
) engine = InnoDB comment '会员退款'; ) engine = InnoDB comment '会员退款';
......
package com.liquidnet.service.platform.controller.adam;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.platform.service.impl.adam.PlatformMemberRefundService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@Api(tags = "会员退款回调处理")
@Slf4j
@RestController
@RequestMapping("amorder/callack")
public class PlatformAdamMemberOrderCallbackController {
@Autowired
private PlatformMemberRefundService platformMemberRefundService;
@ApiOperationSupport(order = 1)
@ApiOperation(value = "退款回调")
@ApiImplicitParams({
@ApiImplicitParam(type = "form", required = true, dataType = "String", name = "status", value = "1-成功|0-失败", example = "1"),
@ApiImplicitParam(type = "form", required = true, dataType = "String", name = "orderCode", value = "会员订单号", example = "77062761607274496V"),
@ApiImplicitParam(type = "form", required = true, dataType = "String", name = "code", value = "支付订单号", example = "20210616153954199964032352974P"),
@ApiImplicitParam(type = "form", required = true, dataType = "String", name = "type", value = "购买类型", example = "VIP"),
@ApiImplicitParam(type = "form", required = true, dataType = "String", name = "price", value = "支付金额", example = "0.01"),
@ApiImplicitParam(type = "form", required = true, dataType = "String", name = "paymentType", value = "支付类型", example = "APPALIPAY"),
@ApiImplicitParam(type = "form", required = true, dataType = "String", name = "paymentAt", value = "支付时间", example = "2021-06-16 15:40:02"),
@ApiImplicitParam(type = "form", required = true, dataType = "String", name = "paymentId", value = "支付ID", example = "2021061622001468121421203878"),
})
@PostMapping("refund")
public String refund(HttpServletRequest request) {
log.debug("/amorder/callack/refund:[mapParameter:{},token:{}]", JsonUtils.toJson(request.getParameterMap()), request.getHeader("token"));
// TODO: 2021/6/13 验签
if (!platformMemberRefundService.refundProcessing(request)) {
log.warn("###会员退款回调处理失败:param:{}", JsonUtils.toJson(request.getParameterMap()));
return "fail";
}
return "success";
}
}
package com.liquidnet.service.platform.service.impl.adam;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.service.adam.constant.AdamRedisConst;
import com.liquidnet.service.adam.dto.vo.AdamMemberOrderVo;
import com.liquidnet.service.adam.dto.vo.AdamUserMemberVo;
import com.liquidnet.service.adam.entity.AdamMemberOrder;
import com.liquidnet.service.adam.entity.AdamMemberRefund;
import com.liquidnet.service.adam.entity.AdamUserMember;
import com.liquidnet.service.adam.mapper.AdamMemberOrderMapper;
import com.liquidnet.service.adam.mapper.AdamMemberRefundMapper;
import com.liquidnet.service.adam.mapper.AdamUserMemberMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.stream.IntStream;
@Slf4j
@Service
public class PlatformMemberRefundService extends ServiceImpl<AdamMemberRefundMapper, AdamMemberRefund> {
@Autowired
private AdamMemberOrderMapper adamMemberOrderMapper;
@Autowired
private AdamUserMemberMapper adamUserMemberMapper;
@Autowired
private RedisUtil redisUtil;
public boolean refundProcessing(HttpServletRequest request) {
String refundNo = request.getParameter("orderRefundCode");
String refundAt = request.getParameter("refundAt");
String orderNo = request.getParameter("refundCode");
String refundError = request.getParameter("refundError");
String refundAmt = request.getParameter("refundPrice");
int status = Integer.parseInt(request.getParameter("status"));
AdamMemberRefund memberRefund = this.getOne(Wrappers.lambdaQuery(AdamMemberRefund.class)
.eq(AdamMemberRefund::getRefundNo, refundNo).eq(AdamMemberRefund::getOrderNo, orderNo));
if (null == memberRefund) {
log.warn("会员退款回调处理失败:订单不存在[orderNo:{},refundNo:{}]", orderNo, refundNo);
return false;
}
if (memberRefund.getRefundState() != 9) {
log.warn("会员退款回调处理失败:订单已处理[orderNo:{},refundNo:{}]", orderNo, refundNo);
return true;
}
LocalDateTime now = LocalDateTime.now();
LambdaUpdateWrapper<AdamMemberRefund> memberRefundLambdaUpdateWrapper = Wrappers.lambdaUpdate(AdamMemberRefund.class)
.eq(AdamMemberRefund::getRefundNo, refundNo).eq(AdamMemberRefund::getOrderNo, orderNo);
memberRefundLambdaUpdateWrapper.set(AdamMemberRefund::getRefundAt, refundAt);
memberRefundLambdaUpdateWrapper.set(AdamMemberRefund::getRefundReason, refundError);
memberRefundLambdaUpdateWrapper.set(AdamMemberRefund::getUpdatedAt, now);
switch (status) {
case 0:// 失败
memberRefundLambdaUpdateWrapper.set(AdamMemberRefund::getRefundState, 3);
return this.update(memberRefundLambdaUpdateWrapper);
case 1:// 成功
memberRefundLambdaUpdateWrapper.set(AdamMemberRefund::getRefundState, 1);
if (this.update(memberRefundLambdaUpdateWrapper)) {
this.refundSuccProcessing(orderNo, now);
return true;
} else {
return false;
}
default:
log.warn("会员退款回调处理失败:未知的状态[orderNo:{},refundNo:{},status:{}]", orderNo, refundNo, status);
return false;
}
}
/* -------------------------------------------------------------------------- */
private void refundSuccProcessing(String orderNo, LocalDateTime now) {
AdamMemberOrder memberOrder = adamMemberOrderMapper.selectOne(Wrappers.lambdaUpdate(AdamMemberOrder.class).eq(AdamMemberOrder::getOrderNo, orderNo));
{// 同步用户端信息
String moKey = AdamRedisConst.INFO_MEMBER_ORDER + memberOrder.getUid();
ArrayList<AdamMemberOrderVo> vos = (ArrayList<AdamMemberOrderVo>) redisUtil.get(moKey);
int idx = IntStream.range(0, vos.size()).filter(i -> vos.get(i).getOrderNo().equals(memberOrder.getOrderNo())).findFirst().orElse(-1);
AdamMemberOrderVo vo = vos.get(idx);
vo.setState(5);
vo.setUpdatedAt(now);
vos.set(idx, vo);
boolean syncVo = redisUtil.set(moKey, vos);
log.warn("###会员退款回调处理成功:更新REDIS会员订单状态{}[orderNo:{},uid:{}]", syncVo ? "成功" : "失败", orderNo, memberOrder.getUid());
String umKey = AdamRedisConst.INFO_USER_MEMBER.concat(memberOrder.getUid());
AdamUserMemberVo userMemberVo = (AdamUserMemberVo) redisUtil.get(umKey);
userMemberVo.setState(2);
userMemberVo.setUpdatedAt(now);
syncVo = redisUtil.set(umKey, userMemberVo);
log.warn("###会员退款回调处理成功:更新REDIS会员状态{}[orderNo:{},uid:{}]", syncVo ? "成功" : "失败", orderNo, memberOrder.getUid());
}
AdamUserMember updateInfoUserMember = new AdamUserMember();
updateInfoUserMember.setState(2);
updateInfoUserMember.setUpdatedAt(now);
updateInfoUserMember.setComment("R");
int updateRst = adamUserMemberMapper.update(updateInfoUserMember, Wrappers.lambdaUpdate(AdamUserMember.class).eq(AdamUserMember::getUid, memberOrder.getUid()));
log.warn("###会员退款回调处理成功:更新用户会员状态{}[orderNo:{},uid:{}]", updateRst <= 0 ? "失败" : "成功", orderNo, memberOrder.getUid());
AdamMemberOrder updateInfoMemberOrder = new AdamMemberOrder();
updateInfoMemberOrder.setMid(memberOrder.getMid());
updateInfoMemberOrder.setState(5);
updateInfoMemberOrder.setUpdatedAt(now);
updateRst = adamMemberOrderMapper.updateById(updateInfoMemberOrder);
log.warn("###会员退款回调处理成功:更新会员订单状态{}[orderNo:{}]", updateRst <= 0 ? "失败" : "成功", orderNo);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment