release-20260330 - 修改为手机开门,不扫码。
This commit is contained in:
127
RELEASE.md
Normal file
127
RELEASE.md
Normal 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() 方法签名改为接收原订单金额和退款金额 |
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
venueEnterService.enterOrderAccount(enterId,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("结算成功");
|
||||
}
|
||||
|
||||
|
||||
@@ -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,15 +57,15 @@ 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分钟宽限期
|
||||
int minutes = DateUtilCard.diffMinute(barcodeOrderTime.getModifiedTime(), date);
|
||||
@@ -72,29 +73,35 @@ public class BarcodeTimeOrderTask {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 关闭订单
|
||||
barcodeOrderTime.setPaying(0);
|
||||
barcodeOrderTime.setModifiedTime(date);
|
||||
barcodeOrderTime.setStatus(BarCodeStatusEnum.USED.getValue());
|
||||
barcodeOrderTimeMapper.updateByPrimaryKey(barcodeOrderTime);
|
||||
|
||||
|
||||
// 按时计费退款
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user