release-20260330 - 修改为手机开门,不扫码。

This commit is contained in:
2026-03-30 10:58:00 +08:00
parent 0d5c4af3a6
commit c0b011c098
13 changed files with 260 additions and 96 deletions

127
RELEASE.md Normal file
View File

@@ -0,0 +1,127 @@
# Release Notes
## 2026-03-29 - 场馆入场计费逻辑重构
### 一、按时计费流程
```
入场 join()
├─ price = basePrice × 2 (2小时押金)
├─ 返回 flg=2, 等待支付
└─ 支付成功 → paySuccess()
└─ 创建订单 (orderSn=原始订单号, paying=0)
出场 out()
├─ actualCost = (minutes / 60) × basePrice (保留2位小数)
├─ deposit = basePrice × 2
├─ difference = actualCost - deposit
├─ difference > 0 (需补费)
│ └─ 返回 flg=2, 等待支付
│ └─ 支付成功 → paySuccess(enterFlag=OUT)
│ └─ 设置 orderAddSn=补费订单号, paying=2
├─ difference < 0 (需退款)
│ └─ payMoney = |difference| (BigDecimal, 2位小数)
│ └─ paying=1, status=USED
│ └─ 用户可立即重新入场
│ └─ 批处理退款
└─ difference = 0 (刚好)
└─ paying=2, status=USED
批处理 refundOrder()
├─ 扫描 paying=1 的订单
├─ 如果 orderAddSn 存在 → 跳过(补费订单)
├─ 如果 orderAddSn 不存在 → 退款
└─ 调用微信退款接口 (元转分)
```
### 二、按次计费流程
```
入场 join()
├─ price = basePrice (单次费用)
├─ 返回 flg=2, 等待支付
└─ 支付成功 → paySuccess()
└─ 创建订单 (orderSn=原始订单号, paying=0, 有效期=timePayHour)
出场 out()
└─ paying=1, 10分钟宽限期
重新入场 join()
├─ 如果 paying=1 且按次计费 → 重置 paying=0
└─ 否则 → 已在场内
批处理 refundOrder()
├─ 扫描 paying=1 的订单
├─ 按次计费: 10分钟后关闭订单
└─ 按时计费: 立即退款(如果无补费记录)
批处理 execute()
└─ order_end < now → 关闭订单
```
### 三、管理员手动退费
```
enterOrderAccount(enterId, payMoney)
├─ 检查: paying != 1 (不能重复结算)
├─ 检查: orderAddSn 为空 (不能退补费订单)
├─ 检查: 退款金额 <= 原订单金额
└─ 设置 paying=1, payMoney=指定金额
└─ 等待批处理处理
```
### 四、金额类型规范
| 位置 | 类型 | 精度 | 说明 |
|---|---|---|---|
| 数据库 pay_money | DECIMAL(10,2) | 2位小数 | |
| 数据库 sum_pay_money | DECIMAL(10,2) | 2位小数 | |
| 实体 BarcodeOrderTime.payMoney | BigDecimal | 2位小数 | |
| 实体 BarcodeOrderTime.sumPayMoney | BigDecimal | 2位小数 | |
| 微信支付接口 | Integer | 分 | 元×100 |
| 微信退款接口 | Integer | 分 | 元×100 |
### 五、关键表字段变动
| 场景 | sv_barcode_order_time | sv_member_refund | sv_member_money_log |
|---|---|---|---|
| 入场支付成功 | order_sn=A, paying=0 | - | type=JOIN |
| 出场需退款 | paying=1, payMoney=退款额 | - | - |
| 批处理退款 | paying=0, status=USED | money=退款额 | type=REFUND |
| 出场需补费 | paying=1, payMoney=-1 | - | - |
| 补费支付成功 | order_add_sn=B, paying=2 | - | type=JOIN |
| 管理员退费 | paying=1, payMoney=指定额 | - | - |
### 六、已修复的问题
| 问题 | 修复 |
|---|---|
| payMoney 类型 | Integer → BigDecimal |
| sumPayMoney 类型 | Integer → BigDecimal |
| XML 映射 | jdbcType INTEGER → DECIMAL |
| 金额比较 | \> 0 → compareTo(ZERO) > 0 |
| 金额计算 | int 加法 → BigDecimal.add() |
| 退款金额精度 | intValue() → setScale(2) |
| 退款金额单位混乱 | 统一为元,微信接口转分 |
| 补费订单退款 | 跳过不处理 |
| 管理员退费限制 | 有补费记录时拒绝 |
| 8小时兜底逻辑 | 删除(冗余) |
| 10分钟宽限期 | 只给按次计费 |
| 出场退款后无法立即入场 | 设置 status=USED允许立即重新入场 |
### 七、修改文件清单
| 文件 | 修改内容 |
|---|---|
| `BarcodeOrderTime.java` | payMoney, sumPayMoney: Integer → BigDecimal |
| `BarcodeOrderTimeMapper.xml` | jdbcType: INTEGER → DECIMAL |
| `VenueEnterService.java` | 重写 out() 按分钟计费setPayMoney() 参数改为 BigDecimal |
| `OrderService.java` | setPayMoney(-1) → setPayMoney(new BigDecimal(-1)) |
| `MemberRefundService.java` | sumPayMoney 计算改为 BigDecimal.add() |
| `BarcodeTimeOrderTask.java` | 删除8小时兜底getPayMoney() 比较改为 compareTo() |
| `ServerMessageHandlerAdapter.java` | getPayMoney() 比较改为 compareTo() |
| `MemberEnterVeneuLogController.java` | payMoney 参数改为 BigDecimal |
| `WechatPayService.java` | refundInputMoney() 方法签名改为接收原订单金额和退款金额 |

View File

@@ -187,7 +187,7 @@ public class ServerMessageHandlerAdapter implements MessageService {
BarcodeOrderTime lastOrder = barcodeOrderTimeMapper.findLastOrder(member.getId(), venueBarCode.getVenueId());
lastOrder.setLastOut(new Date());
// 不需要补交钱且需要退钱
if (lastOrder.getPayMoney() != null && lastOrder.getPayMoney() > 0) {
if (lastOrder.getPayMoney() != null && lastOrder.getPayMoney().compareTo(java.math.BigDecimal.ZERO) > 0) {
lastOrder.setModifiedTime(new Date());
}
barcodeOrderTimeMapper.updateByPrimaryKey(lastOrder);

View File

@@ -42,15 +42,14 @@ public class WxServiceTest {
MemberRefund memberRefund = new MemberRefund();
memberRefund.setMemberId(memberId);
memberRefund.setLessonId(1);
memberRefund.setMoney(order.getPrice());
// memberRefund.setMoney(new BigDecimal(0.01));
memberRefund.setMoney(new BigDecimal(0.01));
memberRefund.setOrderSn(orderSn);
memberRefund.setTransactionId(order.getTradeSn());
memberRefund.setOrderId(order.getId());
memberRefund.setOutRefundNo(orderService.createSn());//商户退款单号
memberRefund.setPlatformId(1);
memberRefundMapper.insert(memberRefund);
wechatPayService.refundInputMoney(memberRefund,new BigDecimal(0.01));
wechatPayService.refundInputMoney(memberRefund, order.getPrice(), new BigDecimal(0.01));
}

View File

@@ -1,5 +1,6 @@
package com.sv.entity;
import java.math.BigDecimal;
import java.util.Date;
public class BarcodeOrderTime {
@@ -36,12 +37,12 @@ public class BarcodeOrderTime {
/**
* 退款金额 -1 代表出场还需要交钱
*/
private Integer payMoney;
private BigDecimal payMoney;
/**
* 总退款金额
*/
private Integer sumPayMoney;
private BigDecimal sumPayMoney;
private String orderSn;
@@ -51,7 +52,7 @@ public class BarcodeOrderTime {
private String orderAddSn;
public BarcodeOrderTime(Integer id, Integer memberId, Integer venueId, Date createdTime, Date modifiedTime, Date orderStart, Date orderEnd, Date lastEnter, Date lastOut, Integer status ,Integer paying,
Integer payMoney, Integer sumPayMoney, String orderSn, String orderAddSn) {
BigDecimal payMoney, BigDecimal sumPayMoney, String orderSn, String orderAddSn) {
this.id = id;
this.memberId = memberId;
this.venueId = venueId;
@@ -145,11 +146,11 @@ public class BarcodeOrderTime {
this.paying = paying;
}
public Integer getPayMoney() {
public BigDecimal getPayMoney() {
return payMoney;
}
public void setPayMoney(Integer payMoney) {
public void setPayMoney(BigDecimal payMoney) {
this.payMoney = payMoney;
}
@@ -185,11 +186,11 @@ public class BarcodeOrderTime {
this.lastOut = lastOut;
}
public Integer getSumPayMoney() {
public BigDecimal getSumPayMoney() {
return sumPayMoney;
}
public void setSumPayMoney(Integer sumPayMoney) {
public void setSumPayMoney(BigDecimal sumPayMoney) {
this.sumPayMoney = sumPayMoney;
}
}

View File

@@ -1,37 +1,81 @@
package com.sv.intergration.impl;
import Net.PC15.Command.CommandDetial;
import Net.PC15.Command.INCommand;
import Net.PC15.Command.INCommandResult;
import Net.PC15.Connector.ConnectorAllocator;
import Net.PC15.Connector.ConnectorDetial;
import Net.PC15.Connector.E_ControllerType;
import Net.PC15.Connector.INConnectorEvent;
import Net.PC15.Connector.TCPClient.TCPClientDetial;
import Net.PC15.Data.INData;
import Net.PC15.FC8800.Command.Door.OpenDoor;
import Net.PC15.FC8800.Command.Door.Parameter.OpenDoor_Parameter;
import Net.PC15.FC8800.FC8800Identity;
import com.sv.intergration.DoorService;
import com.sv.netty.config.NettyConstant;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import com.sv.netty.utils.JsonUtils;
public class OldDoorService implements DoorService {
private static INConnectorEvent listener;
static {
listener = new INConnectorEvent() {
@Override
public void CommandCompleteEvent(INCommand inCommand, INCommandResult inCommandResult) {
logger.info("CommandCompleteEvent open door success");
}
@Override
public void CommandProcessEvent(INCommand inCommand) {
logger.info("CommandProcessEvent open door ...");
}
@Override
public void ConnectorErrorEvent(INCommand inCommand, boolean b) {
logger.info("CommandProcessEvent open door ... the bool is " + b);
}
@Override
public void ConnectorErrorEvent(ConnectorDetial connectorDetial) {
logger.error("ConnectorErrorEvent open door error");
}
@Override
public void CommandTimeout(INCommand inCommand) {
logger.error("CommandTimeout open door time out");
}
@Override
public void PasswordErrorEvent(INCommand inCommand) {
logger.error("PasswordErrorEvent open door password error");
}
@Override
public void ChecksumErrorEvent(INCommand inCommand) {
logger.error("ChecksumErrorEvent open door error");
}
@Override
public void WatchEvent(ConnectorDetial connectorDetial, INData inData) {
logger.error("WatchEvent open door ...");
}
};
}
@Override
public void enterOpenDoor() {
opendoor(1);
openDoor(1);
}
@Override
public void outOpenDoor() {
opendoor(2);
openDoor(2);
}
private void opendoor(int doorSn) {
private void openDoor(int doorSn) {
try {
// 1. 先检查网络连通性Java 层)
if (!isNetworkReachable("192.168.1.150", 8000, 2000)) {
throw new RuntimeException("net socket error: 192.168.1.150:8000");
}
ConnectorAllocator connector = ConnectorAllocator.GetAllocator();
TCPClientDetial tcpClientDetial = new TCPClientDetial("192.168.1.150", Integer.valueOf("8000"));
connector.GetCommandCount(tcpClientDetial);
@@ -39,29 +83,16 @@ public class OldDoorService implements DoorService {
CommandDetial detial = new CommandDetial();
detial.Connector = tcpClientDetial;
String clientSn = System.getProperty(NettyConstant.VENUE_CLIENT_SN);
// detial.Identity = new FC8800Identity("MC-5824T23014127", "12345678", E_ControllerType.FC8900);
detial.Identity = new FC8800Identity(clientSn, "12345678", E_ControllerType.FC8900);
OpenDoor_Parameter openDoorParameter = new OpenDoor_Parameter(detial);
openDoorParameter.Door.SetDoor(doorSn, 1);
for (int i = 0; i < 3; i++) {
logger.info("{} times to try...", i + 1);
boolean connected = connector.IsForciblyConnect(tcpClientDetial);
if (connected) {
logger.info("[{}] connected");
break;
}
logger.warn("[{}] times to try, trying", i + 1);
Thread.sleep(1000); // 等待 1 秒后重试
}
OpenDoor openDoor = new OpenDoor(openDoorParameter);
boolean command = connector.AddCommand(openDoor);
if (!command) {
logger.error("sn-{} door open command exec fail",doorSn);
}
connector.AddListener(listener);
System.out.println(connector.IsRelease());
if (openDoor.getIsTimeout()) {
logger.info("----sn-{} open door timeout ----",doorSn);
}
@@ -70,15 +101,4 @@ public class OldDoorService implements DoorService {
}
}
// 网络连通性检查Java 层)
private boolean isNetworkReachable(String host, int port, int timeoutMs) {
try (Socket socket = new Socket()) {
socket.connect(new InetSocketAddress(host, port), timeoutMs);
return true;
} catch (IOException e) {
logger.error("net link error: {}:{} - {}", host, port, e.getMessage());
return false;
}
}
}

View File

@@ -1,9 +1,11 @@
package com.sv.oms.controller;
import com.sv.entity.MemberEnterVenueLog;
import com.sv.exception.oms.OmsException;
import com.sv.service.api.VenueEnterService;
import com.sv.service.oms.MemberEnterVenueLogService;
import com.ydd.framework.core.common.Pagination;
import com.ydd.framework.core.common.dto.ResponseDTO;
import com.ydd.framework.core.exception.ServiceException;
import com.ydd.oms.controller.OmsController;
import org.slf4j.Logger;
@@ -84,8 +86,14 @@ public class MemberEnterVeneuLogController extends OmsController {
}
@RequestMapping(value = "/member/enter/veneu/account", method = RequestMethod.POST)
public ResponseDTO enterOrderAccount(@RequestParam("EnterId") Integer enterId,@RequestParam("payMoney") Integer payMoney) {
public ResponseDTO enterOrderAccount(@RequestParam("EnterId") Integer enterId,@RequestParam("payMoney") java.math.BigDecimal payMoney) {
try {
venueEnterService.enterOrderAccount(enterId,payMoney);
}catch (Exception e) {
if (e instanceof ServiceException) {
throw new OmsException(e.getMessage());
}
}
return ResponseDTO.ok("结算成功");
}

View File

@@ -10,6 +10,7 @@ import com.sv.mapper.OrderMapper;
import com.sv.service.api.config.WechatPayService;
import com.sv.service.api.util.DateUtilCard;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -41,7 +42,7 @@ public class BarcodeTimeOrderTask {
@Resource
WechatPayService wechatPayService;
@Scheduled(cron = "0 0/5 * * * ?")
@Scheduled(cron = "0 0/8 * * * ?")
public void execute(){
logger.error("执行BarcodeTimeOrderTask.execute");
Date date = new Date();
@@ -56,14 +57,14 @@ public class BarcodeTimeOrderTask {
}
}
@Scheduled(cron = "0 0/2 * * * ?")
@Scheduled(cron = "0 0/5 * * * ?")
public void refundOrder(){
logger.error("执行BarcodeTimeOrderTask.refundOrder");
List<BarcodeOrderTime> barcodeOrderTimes = barcodeOrderTimeMapper.needPayOrderList();
if (barcodeOrderTimes != null && barcodeOrderTimes.size() > 0){
Date date = new Date();
for (BarcodeOrderTime barcodeOrderTime : barcodeOrderTimes) {
boolean isHourlyRefund = barcodeOrderTime.getPayMoney() != null && barcodeOrderTime.getPayMoney() > 0;
boolean isHourlyRefund = barcodeOrderTime.getPayMoney() != null && barcodeOrderTime.getPayMoney().compareTo(BigDecimal.ZERO) > 0;
if (!isHourlyRefund) {
// 按次计费10分钟宽限期
@@ -81,20 +82,26 @@ public class BarcodeTimeOrderTask {
// 按时计费退款
if (isHourlyRefund) {
// 如果有补费订单号,跳过退款(与管理员退费逻辑一致)
if (!StringUtils.isEmpty(barcodeOrderTime.getOrderAddSn())) {
logger.info("用户" + barcodeOrderTime.getMemberId() + "的订单有补费记录,跳过退款");
continue;
}
Order order = orderMapper.findOrderSn(barcodeOrderTime.getOrderSn(), barcodeOrderTime.getMemberId());
if (order != null) {
logger.info("用户" + barcodeOrderTime.getMemberId() + "的订单" + barcodeOrderTime.getOrderSn() + "需要退款" + barcodeOrderTime.getPayMoney());
BigDecimal refundAmount = barcodeOrderTime.getPayMoney();
logger.info("用户" + barcodeOrderTime.getMemberId() + "的订单" + barcodeOrderTime.getOrderSn() + "需要退款" + refundAmount + "");
MemberRefund memberRefund = new MemberRefund();
memberRefund.setMemberId(barcodeOrderTime.getMemberId());
memberRefund.setLessonId(barcodeOrderTime.getId());
memberRefund.setMoney(order.getPrice());
memberRefund.setMoney(refundAmount);
memberRefund.setOrderSn(barcodeOrderTime.getOrderSn());
memberRefund.setTransactionId(order.getTradeSn());
memberRefund.setOrderId(order.getId());
memberRefund.setOutRefundNo(createSn());
memberRefund.setPlatformId(1);
memberRefundMapper.insert(memberRefund);
wechatPayService.refundInputMoney(memberRefund,new BigDecimal(barcodeOrderTime.getPayMoney()));
wechatPayService.refundInputMoney(memberRefund, order.getPrice(), refundAmount);
}
}
}

View File

@@ -2,6 +2,7 @@ package com.sv.service.api;
import com.enums.MoneyLogEnum;
import com.enums.PayTypeEnum;
import com.enums.VenueTypeEnum;
import com.github.pagehelper.PageHelper;
import com.sv.dto.api.MemberLessonTicketDetailDTO;
import com.sv.dto.api.wechat.BaseResult;
@@ -22,6 +23,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
@@ -184,24 +186,24 @@ public class MemberRefundService extends BaseServiceImpl {
memberRefund.setSuccessTime(time);
memberRefundMapper.update(memberRefund);
Integer venueType = null;
// 如果是球场订单(更新总退款金额) add by limqsh
BarcodeOrderTime barcodeOrderTime = barcodeOrderTimeMapper.selectByPrimaryKey(memberRefund.getLessonId());
if (barcodeOrderTime != null) {
venueType = VenueTypeEnum.BASKETBALL.value;
if (barcodeOrderTime.getOrderSn() != null
&& barcodeOrderTime.getOrderSn().equals(memberRefund.getOrderSn())) {
barcodeOrderTime.setSumPayMoney(
(barcodeOrderTime.getSumPayMoney() == null ? 0 : barcodeOrderTime.getSumPayMoney())
+ memberRefund.getMoney().intValue());
barcodeOrderTime.setPayMoney(0);
BigDecimal currentSumPayMoney = barcodeOrderTime.getSumPayMoney() == null ? BigDecimal.ZERO : barcodeOrderTime.getSumPayMoney();
barcodeOrderTime.setSumPayMoney(currentSumPayMoney.add(memberRefund.getMoney()));
barcodeOrderTime.setPayMoney(BigDecimal.ZERO);
barcodeOrderTime.setModifiedTime(new Date());
barcodeOrderTimeMapper.updateByPrimaryKey(barcodeOrderTime);
}
}
// 如果是球场订单(更新总退款金额) add by limqsh end
// 记录到‘用户账单(余额,微信,会员卡)记录’
memberMoneyLogService.create(memberRefund.getMemberId(),platformId,MoneyLogEnum.REFUND.value,memberRefund.getMoney(),PayTypeEnum.WEI_XIN.value,
null,null,null,memberRefund.getLessonId());
null,null,venueType,memberRefund.getLessonId());
}catch (Exception e){
e.printStackTrace();
}

View File

@@ -297,7 +297,7 @@ public class OrderService extends BaseServiceImpl {
BarcodeOrderTime lastOrder = barcodeOrderTimeMapper.findLastOrder(memberId, venueId);
if (lastOrder != null) {
lastOrder.setPaying(1);
lastOrder.setPayMoney(-1);
lastOrder.setPayMoney(new BigDecimal(-1));
lastOrder.setOrderAddSn(order.getOrderSn());
// lastOrder.setOrderSn(order.getOrderSn());
lastOrder.setModifiedTime(new Date());

View File

@@ -167,8 +167,9 @@ public class VenueEnterService extends BaseServiceImpl {
result.setMsg("您此次入场" + minutes + "分钟,实际费用" + actualCost + "元,需补交" + difference + "");
} else if (difference.compareTo(BigDecimal.ZERO) < 0) {
BigDecimal refundAmount = difference.abs();
lastOrder.setPayMoney(refundAmount.multiply(new BigDecimal(100)).intValue());
lastOrder.setPayMoney(refundAmount.setScale(2, BigDecimal.ROUND_HALF_UP));
lastOrder.setPaying(1);
lastOrder.setStatus(BarCodeStatusEnum.USED.getValue());
lastOrder.setModifiedTime(new Date());
barcodeOrderTimeMapper.updateByPrimaryKey(lastOrder);
result.setFlg(0);
@@ -272,13 +273,13 @@ public class VenueEnterService extends BaseServiceImpl {
Venue venue = venueMapper.findById(venueId);
createMemberMoneyLog(MoneyLogEnum.JOIN.value, order.getPrice(), memberId, order.getPlatformId(), PayTypeEnum.WEI_XIN.value, null,venue.getId(), venue.getType());
if (EnterEnum.OUT.value != enterFlag) {
Integer timePayHour = 2; // 此处修改押金小时数
Integer timePayHour = 8; // 此处修改押金小时数
if(PayStyleEnum.TIME.getValue() == venue.getPayStyle()){
// 按次入场先收钱,且多久不收钱,出场不收钱
// 该用户上次订单的是否逾期
timePayHour = venue.getTimePayHour();
if (timePayHour == null) {
timePayHour = 4;
timePayHour = 8;
}
}
createBarcodeTimeOrder(memberId,venueId,timePayHour,order.getOrderSn());
@@ -338,7 +339,7 @@ public class VenueEnterService extends BaseServiceImpl {
return memberEnterOrderDTO;
}
public void enterOrderAccount(Integer enterId, Integer payMoney) {
public void enterOrderAccount(Integer enterId, BigDecimal payMoney) {
logger.info("手动结算【" + enterId + "】,结算金额为:" + payMoney);
BarcodeOrderTime barcodeOrder = barcodeOrderTimeMapper.selectByPrimaryKey(enterId);
if (barcodeOrder == null) {
@@ -347,7 +348,7 @@ public class VenueEnterService extends BaseServiceImpl {
if (1 == barcodeOrder.getPaying()) {
throw new ServiceException("订单正在结算,无法结算!");
}
if (payMoney <=0 ) {
if (payMoney.compareTo(BigDecimal.ZERO) <= 0) {
throw new ServiceException("退款金额不能为负数!");
}
String orderSn = barcodeOrder.getOrderSn();
@@ -356,11 +357,12 @@ public class VenueEnterService extends BaseServiceImpl {
throw new ServiceException("订单多次支付(使用超时),无法进行退款!");
}
Order baseOrder = orderMapper.findByOrderSn(orderSn);
if ((barcodeOrder.getSumPayMoney() == null ? 0 : barcodeOrder.getSumPayMoney() + payMoney) > baseOrder.getPrice().intValue()) {
BigDecimal currentSumPayMoney = barcodeOrder.getSumPayMoney() == null ? BigDecimal.ZERO : barcodeOrder.getSumPayMoney();
if (currentSumPayMoney.add(payMoney).compareTo(baseOrder.getPrice()) > 0) {
throw new ServiceException("退款金额不能超过总支付金额!");
}
barcodeOrder.setPaying(1);
barcodeOrder.setPayMoney(payMoney); // 此次支付金额
barcodeOrder.setPayMoney(payMoney);
logger.info("手动结算【" + enterId + "】,结算金额为:" + payMoney + "成功!");
barcodeOrderTimeMapper.updateByPrimaryKey(barcodeOrder);
}

View File

@@ -261,13 +261,14 @@ public class WechatPayService extends BaseServiceImpl {
}
/**
* 退款接口
* 退款接口(支持部分退款)
* @param memberRefund 退款记录
* @param originalAmount 原始订单金额(元)
* @param refundAmount 退款金额(元)
*/
@Transactional
public void refundInputMoney(MemberRefund memberRefund,BigDecimal aMoney){
OrderPaySignResponse.WechatPayParam wechatPayParam;
public void refundInputMoney(MemberRefund memberRefund, BigDecimal originalAmount, BigDecimal refundAmount){
try {
PayConfig payConfig = payConfigService.findKey("face");
Assert.hasText(payConfig.getCert(), "证书找不到");
String nonceStr = CommonUtils.CreateNonceStr(30);
@@ -275,21 +276,18 @@ public class WechatPayService extends BaseServiceImpl {
weChatPayHelper.setAppId(payConfig.getAppId());
weChatPayHelper.setMchId(payConfig.getMchId());
weChatPayHelper.setKey(payConfig.getKey());
Integer payMoney = Integer.valueOf(memberRefund.getMoney().multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP).toString());
Integer refundMoney = Integer.valueOf(aMoney.multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP).toString());
// 元转分
Integer payMoney = originalAmount.multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
Integer refundMoney = refundAmount.multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
weChatPayHelper.setParameter("notify_url", payConfig.getNotifyUrl());
logger.info("申请退款请求参数" + ToStringBuilder.reflectionToString(weChatPayHelper));
// 调用申请退款
// String notifyUrl = "https://api.smartvenue.ydd100.cn//weixin/order/refund";
logger.info("申请退款,原订单金额:" + originalAmount + "元,退款金额:" + refundAmount + "");
OrderResponse response = weChatPayHelper.refund("",memberRefund.getOrderSn(),memberRefund.getOutRefundNo(),payMoney,refundMoney,payConfig.getCancel());
logger.info(ToStringBuilder.reflectionToString(response));
System.out.println(ToStringBuilder.reflectionToString(response));
if (response.isSuccess()) {
String refundId = response.getRefundId();
//更新‘用户退款记录表’中微信退款单号
memberRefund.setRefundId(refundId);
memberRefund.setMoney(aMoney);
memberRefund.setMoney(refundAmount);
memberRefundService.update(memberRefund);
}else{
logger.error("返回的结果为:"+ToStringBuilder.reflectionToString(response));

View File

@@ -14,8 +14,8 @@
<arg column="last_out" jdbcType="TIMESTAMP" javaType="java.util.Date" />
<arg column="status" jdbcType="INTEGER" javaType="java.lang.Integer" />
<arg column="paying" jdbcType="INTEGER" javaType="java.lang.Integer" />
<arg column="pay_money" jdbcType="INTEGER" javaType="java.lang.Integer" />
<arg column="sum_pay_money" jdbcType="INTEGER" javaType="java.lang.Integer" />
<arg column="pay_money" jdbcType="DECIMAL" javaType="java.math.BigDecimal" />
<arg column="sum_pay_money" jdbcType="DECIMAL" javaType="java.math.BigDecimal" />
<arg column="order_sn" jdbcType="VARCHAR" javaType="java.lang.String" />
<arg column="order_add_sn" jdbcType="VARCHAR" javaType="java.lang.String" />
</constructor>
@@ -40,7 +40,7 @@
values (#{id,jdbcType=INTEGER}, #{memberId,jdbcType=INTEGER}, #{venueId,jdbcType=INTEGER},
#{createdTime,jdbcType=TIMESTAMP}, #{modifiedTime,jdbcType=TIMESTAMP}, #{orderStart,jdbcType=TIMESTAMP},
#{orderEnd,jdbcType=TIMESTAMP}, #{lastEnter,jdbcType=TIMESTAMP}, #{lastOut,jdbcType=TIMESTAMP}, #{status,jdbcType=INTEGER},
#{paying,jdbcType=INTEGER},#{payMoney,jdbcType=INTEGER}, #{sumPayMoney,jdbcType=INTEGER},
#{paying,jdbcType=INTEGER},#{payMoney,jdbcType=DECIMAL}, #{sumPayMoney,jdbcType=DECIMAL},
#{orderSn,jdbcType=VARCHAR},#{orderAddSn,jdbcType=VARCHAR})
</insert>
<insert id="insertSelective" parameterType="com.sv.entity.BarcodeOrderTime" >
@@ -127,10 +127,10 @@
#{paying,jdbcType=INTEGER},
</if>
<if test="payMoney != null" >
#{payMoney,jdbcType=INTEGER},
#{payMoney,jdbcType=DECIMAL},
</if>
<if test="sumPayMoney != null" >
#{sumPayMoney,jdbcType=INTEGER},
#{sumPayMoney,jdbcType=DECIMAL},
</if>
<if test="orderSn != null" >
#{orderSn,jdbcType=VARCHAR},
@@ -174,10 +174,10 @@
paying = #{paying,jdbcType=INTEGER},
</if>
<if test="payMoney != null" >
pay_money = #{payMoney,jdbcType=INTEGER},
pay_money = #{payMoney,jdbcType=DECIMAL},
</if>
<if test="sumPayMoney != null" >
sum_pay_money = #{sumPayMoney,jdbcType=INTEGER},
sum_pay_money = #{sumPayMoney,jdbcType=DECIMAL},
</if>
<if test="orderSn != null" >
order_sn = #{orderSn,jdbcType=VARCHAR},
@@ -200,11 +200,11 @@
last_out = #{lastOut,jdbcType=TIMESTAMP},
status = #{status,jdbcType=INTEGER},
paying = #{paying,jdbcType=INTEGER},
pay_money = #{payMoney,jdbcType=INTEGER},
sum_pay_money = #{sumPayMoney,jdbcType=INTEGER},
pay_money = #{payMoney,jdbcType=DECIMAL},
sum_pay_money = #{sumPayMoney,jdbcType=DECIMAL},
order_sn = #{orderSn,jdbcType=VARCHAR},
order_add_sn = #{orderAddSn,jdbcType=VARCHAR}
where id = #{id,jdbcType=VARCHAR}
where id = #{id,jdbcType=INTEGER}
</update>
<select id="findEffOrder" resultType="int">

View File

@@ -321,7 +321,7 @@
card_type,
venue_id,
venue_type,
lesson_id,
(case when venue_type = '1' then null else lesson_id end) lesson_id,
created_time
FROM
sv_member_money_log