Bläddra i källkod

fix 重复用户信息插入;订单关闭前校验订单支付状态;
实物权益发货车票未发;增加支付回调日志

fix

fix 关闭订单

zoujiajian 3 år sedan
förälder
incheckning
76237dc962

+ 25 - 6
netflix-service/src/main/java/com/cyksj/service/exchange/impl/ExchangeCodeServiceImpl.java

@@ -289,30 +289,35 @@ public class ExchangeCodeServiceImpl extends ServiceImpl<ExchangeCodeMapper, Exc
 	public GroupsRelation getRelationNoOrder(GoodsDonSku sku, Long userId) {
 		GroupsRelation relation = null;
 		Integer retryNum = 1;
-		relation = getFinalRelation(sku, userId, relation, retryNum);
+		List<Long> errorsRelationIds = new ArrayList<>();
+		relation = getFinalRelation(sku, userId, relation, retryNum, errorsRelationIds);
 		return relation;
 	}
 
-	public GroupsRelation getFinalRelation(GoodsDonSku sku, Long userId, GroupsRelation relation, Integer retryNum) {
+	public GroupsRelation getFinalRelation(GoodsDonSku sku, Long userId, GroupsRelation relation, Integer retryNum, List<Long> errorsRelationIds) {
 		//寻找差不多过期时间规格的车位
-		relation = groupRelationFrontService.getSimilarExpiredGroupRelation(sku.getId(), sku.getMonths());
+		relation = groupRelationFrontService.getSimilarExpiredGroupRelation(sku.getId(), sku.getMonths(), errorsRelationIds);
 		if (relation == null) {
 			GroupsTrips groups = groupsMapper.selectOne(Wrappers.lambdaQuery(GroupsTrips.class).eq(GroupsTrips::getSkuId, sku.getId()).gt(GroupsTrips::getAvailableNum, 0).last("limit 1").orderByAsc(GroupsTrips::getAvailableNum));
 			if (groups == null) {
 				//新增车位 并关联
 				relation = createNewGroupTripsAndRelation(sku, groups, relation);
+				log.info("无合适规格车队,新增新车队,获取车位relationId:{}", relation.getId());
 			} else {
 				//寻找快满编车队进行占座
 				relation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
 						.eq(GroupsRelation::getGroupsId, groups.getId())
+						.notIn(errorsRelationIds != null && errorsRelationIds.size() > 0, GroupsRelation::getId, errorsRelationIds)
 						.eq(GroupsRelation::getStatus, "none")
 						.eq(GroupsRelation::getUserId, 0)
 						.orderByAsc(GroupsRelation::getNum)
 						.last("limit 1")
 				);
+				log.info("寻找快满编车队的车位relationId:{}", relation.getId());
 				//如果占位失败 新增车位并关联
 				if (relation == null) {
 					relation = createNewGroupTripsAndRelation(sku, groups, relation);
+					log.info("占位新车队车位失败,再次新增新车队,获取车位relationId:{}", relation.getId());
 				}
 			}
 		}
@@ -327,18 +332,32 @@ public class ExchangeCodeServiceImpl extends ServiceImpl<ExchangeCodeMapper, Exc
 			Date newDate = DateUtil.offset(expiryTime, DateField.MONTH, sku.getMonths() * 1);
 			relation.setExpiryTime(newDate);
 			relation.setStartTime(relation.getStartTime() == null ? new Date() : null);
-			groupsRelationMapper.updateById(relation);
+
+			int isSuccess = groupsRelationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
+					.set(GroupsRelation::getUserId, userId)
+					.set(GroupsRelation::getStatus, GroupsRelation.Status.validity)
+					.set(GroupsRelation::getStartTime, relation.getStartTime())
+					.set(GroupsRelation::getExpiryTime, relation.getExpiryTime())
+					.eq(GroupsRelation::getId, relation.getId())
+					.eq(GroupsRelation::getUserId, 0)
+					.eq(GroupsRelation::getStatus, GroupsRelation.Status.none));
+			if (isSuccess != 1) {
+				log.error("该车位已被占,用户userId:{}更新上车relationId:{}状态失败", userId, relation.getId());
+				throw BusinessRuntimeException.getInstance("该车位已被占");
+			}
+			redisService.del(RedisKey.GROUPS_RELATION_NUM_KEY + relation.getId());
 		} catch (Exception e) {
 			Object value = redisService.get(RedisKey.GROUPS_RELATION_NUM_KEY + relation.getId());
 			if (value != null && userId.equals(Long.parseLong(value.toString()))) {
 				redisService.del(RedisKey.GROUPS_RELATION_NUM_KEY + relation.getId());
 			}
-			if (retryNum == 10) {
+			errorsRelationIds.add(relation.getId());
+			if (retryNum == 15) {
 				log.error("用户:{}获取车票:{}异常", userId, relation.getId());
 				throw BusinessRuntimeException.getInstance("获取车票异常,请联系客服");
 			}
 			//失败重新给他分配车位
-			getFinalRelation(sku, userId, relation, ++retryNum);
+			getFinalRelation(sku, userId, relation, ++retryNum, errorsRelationIds);
 		}
 		return relation;
 	}

+ 13 - 0
netflix-service/src/main/java/com/cyksj/service/order/OrderDonService.java

@@ -1,7 +1,10 @@
 package com.cyksj.service.order;
 
+import com.alipay.api.AlipayApiException;
 import com.alipay.api.AlipayResponse;
 import com.alipay.api.response.AlipayFundTransCommonQueryResponse;
+import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
+import com.alipay.api.response.AlipayTradeQueryResponse;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.cyksj.dto.Result;
 import com.cyksj.model.dto.AliPayParams;
@@ -94,4 +97,14 @@ public interface OrderDonService extends IService<OrderDon> {
      * 查询支付宝转账状态
      */
     AlipayFundTransCommonQueryResponse getTransFerStatusByTid(String translationId) throws Exception;
+
+    /**
+     * 支付宝订单详情
+     */
+    AlipayTradeQueryResponse getZfbOrderDetail(String shopId, String orderNo) throws AlipayApiException;
+
+    /**
+     * 支付宝退款订单详情
+     */
+    AlipayTradeFastpayRefundQueryResponse getZfbRefundDetail(String shopId, String orderNo) throws AlipayApiException;
 }

+ 176 - 38
netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java

@@ -13,6 +13,8 @@ import com.alipay.api.domain.*;
 import com.alipay.api.internal.util.AlipaySignature;
 import com.alipay.api.request.*;
 import com.alipay.api.response.AlipayFundTransCommonQueryResponse;
+import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
+import com.alipay.api.response.AlipayTradeQueryResponse;
 import com.alipay.api.response.AlipayTradeRefundResponse;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -235,7 +237,7 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 
 				} else {
 					//寻找差不多过期时间规格的车位
-					relation = groupRelationFrontService.getSimilarExpiredGroupRelation(sku.getId(), sku.getMonths());
+					relation = groupRelationFrontService.getSimilarExpiredGroupRelation(sku.getId(), sku.getMonths(), null);
 					if (relation == null) {
 						//TODO 如果没指定座位,等待逻辑确认
 						GroupsTrips groups = groupsMapper.selectOne(Wrappers.lambdaQuery(GroupsTrips.class).eq(GroupsTrips::getSkuId, payRequest.getSkuId()).gt(GroupsTrips::getAvailableNum, 0).last("limit 1").orderByAsc(GroupsTrips::getAvailableNum));
@@ -462,6 +464,8 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		if (null == order) {
 			throw BusinessRuntimeException.getInstance("订单不存在.");
 		}
+		log.info("微信商家订单号orderNo:{},status:{},进行回调", order.getOrderNo(), order.getStatus());
+
 		String appId = map.get("mch_id");
 
 		// 校验签名
@@ -476,7 +480,7 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 
 		String transactionId = map.get("transaction_id");
 
-		if (order.getStatus().equals(OrderDon.Status.hasPayment)) {
+		if (!order.getStatus().equals(OrderDon.Status.noPayment) && !order.getStatus().equals(OrderDon.Status.close)) {
 			log.info("已回调,重复修改状态 id:{}", order.getId());
 			return;
 		}
@@ -499,6 +503,15 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 			order.setStatus(OrderDon.Status.hasPayment);
 		}
 
+		boolean isSuccess = update(Wrappers.lambdaUpdate(OrderDon.class)
+				.set(OrderDon::getStatus, order.getStatus())
+				.in(OrderDon::getStatus, List.of(OrderDon.Status.noPayment, OrderDon.Status.close))
+				.eq(OrderDon::getId, order.getId()));
+		if (!isSuccess) {
+			log.info("微信回调商家订单号:{}订单状态已修改", order.getOrderNo());
+			return;
+		}
+
 		if (!order.getIsNoLogin()) {
 			if (order.getOrderType() == 2 && order.getIsChangeTicket()) {
 				//将奈飞月付车票更换成其他规格的车票
@@ -563,23 +576,26 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		//关闭订单逻辑
 		OrderDon orderDon = getById(orderId);
 		if (OrderDon.Status.noPayment.equals(orderDon.getStatus())) {
-			//查询微信支付是否已支付
-			orderDon.setStatus(OrderDon.Status.close);
-			updateById(orderDon);
-
-			//关闭车位锁定
-			GroupsRelation groupsRelation = groupsRelationMapper.selectById(orderDon.getRelationId());
-			if (groupsRelation != null) {
-				if (!groupsRelation.getUserId().equals(orderDon.getUserId())) {
-					throw new BusinessRuntimeException("订单用户与车位用户不匹配!");
-				} else {
-					if (GroupsRelation.Status.locking.equals(groupsRelation.getStatus())) {
-						groupsRelation.setUserId(0L);
-						groupsRelation.setStatus(GroupsRelation.Status.none);
-						groupsRelationMapper.updateById(groupsRelation);
-						delRelation(groupsRelation.getId());
-
-						//车位空余发送模板消息
+			//调用微信、支付宝第三方接口查询订单是否支付
+			OrderDon.Status status = isHasPaid(orderDon);
+			if (status == OrderDon.Status.noPayment) {
+				//查询微信支付是否已支付
+				orderDon.setStatus(OrderDon.Status.close);
+				updateById(orderDon);
+				//关闭车位锁定
+				GroupsRelation groupsRelation = groupsRelationMapper.selectById(orderDon.getRelationId());
+				if (groupsRelation != null) {
+					if (!groupsRelation.getUserId().equals(orderDon.getUserId())) {
+						throw new BusinessRuntimeException("订单用户与车位用户不匹配!");
+					} else {
+						if (GroupsRelation.Status.locking.equals(groupsRelation.getStatus())) {
+							log.info("清理用户userId:{}未支付订单orderNo:", orderDon.getUserId(), orderDon.getOrderNo());
+							groupsRelation.setUserId(0L);
+							groupsRelation.setStatus(GroupsRelation.Status.none);
+							groupsRelationMapper.updateById(groupsRelation);
+							delRelation(groupsRelation.getId());
+
+							//车位空余发送模板消息
 //						TASK_POOL.execute(() -> {
 //							try {
 //								List<CustomerService> customerServices = customerServiceMapper.selectList(null);
@@ -591,12 +607,13 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 //								log.error("发送{}空车位模板消息至客服失败:{}", orderDon.getGoodsId(), e);
 //							}
 //						});
+						}
 					}
 				}
-			}
-			//返还优惠券
-			if (orderDon.getCouponUserId() != 0) {
-				updateOrderDonCouponStatus(orderDon);
+				//返还优惠券
+				if (orderDon.getCouponUserId() != 0) {
+					updateOrderDonCouponStatus(orderDon);
+				}
 			}
 		}
 	}
@@ -796,8 +813,7 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		}
 		String transactionId = params.get("trade_no");
 		String payTimeStr = params.get("gmt_payment");
-
-		if (orderDon.getStatus().equals(OrderDon.Status.hasPayment)) {
+		if (!orderDon.getStatus().equals(OrderDon.Status.noPayment) && !orderDon.getStatus().equals(OrderDon.Status.close)) {
 			log.info("支付宝已回调,重复修改状态 id:{}", orderDon.getId());
 			return;
 		}
@@ -819,6 +835,14 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		if (orderDon.getIsNoLogin()) {
 			orderDon.setStatus(OrderDon.Status.hasPayment);
 		}
+		boolean isSuccess = update(Wrappers.lambdaUpdate(OrderDon.class)
+				.set(OrderDon::getStatus, orderDon.getStatus())
+				.in(OrderDon::getStatus, List.of(OrderDon.Status.noPayment, OrderDon.Status.close))
+				.eq(OrderDon::getId, orderDon.getId()));
+		if (!isSuccess) {
+			log.info("支付宝回调商家订单号:{}订单状态已修改", orderDon.getOrderNo());
+			return;
+		}
 		if (!orderDon.getIsNoLogin()) {
 			if (orderDon.getOrderType() == 2 && orderDon.getIsChangeTicket()) {
 				//将奈飞月付车票更换成其他规格的车票
@@ -1240,21 +1264,26 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 				throw new BusinessRuntimeException("您有未支付订单.");
 			}
 		}
-
-		if (redisService.get(RedisKey.GROUPS_RELATION_NUM_KEY + relationId) != null) {
-			log.info("=====>用户:{}获取了已有人座位:{}", userId, relationId);
-			throw new BusinessRuntimeException("客官手慢啦,该座位已经有人啦!");
-		} else {
-			if (!redisService.setNx(RedisKey.GROUPS_RELATION_NUM_KEY + relationId, userId, 60 * 5L)) {
-				log.info("=====>用户:{}未抢到座位:{}", userId, relationId);
-				throw new BusinessRuntimeException("客官手慢啦,该座位已经有人啦!");
-			}
+		Object value = redisService.get(RedisKey.GROUPS_RELATION_NUM_KEY + relationId);
+		if (value != null) {
 			GroupsRelation relation = groupsRelationMapper.selectById(relationId);
-			int count = groupsMapper.decrAvailableNum(relation.getGroupsId());
-			if (count == 0) {
-				log.error("车位异常 groupId:{}", relation.getGroupsId());
-				throw new BusinessRuntimeException("车位异常");
+			if (relation != null && relation.getUserId() == 0l) {
+				redisService.del(RedisKey.GROUPS_RELATION_NUM_KEY + relationId);
 			}
+			if (relation != null && relation.getUserId() != 0l) {
+				log.info("=====>用户:{}获取了已有人座位:{}", userId, relationId);
+				throw new BusinessRuntimeException("客官手慢啦,该座位已经有人啦!");
+			}
+		}
+		if (!redisService.setNx(RedisKey.GROUPS_RELATION_NUM_KEY + relationId, userId, 60 * 5L)) {
+			log.info("=====>用户:{}未抢到座位:{}", userId, relationId);
+			throw new BusinessRuntimeException("客官手慢啦,该座位已经有人啦!");
+		}
+		GroupsRelation relation = groupsRelationMapper.selectById(relationId);
+		int count = groupsMapper.decrAvailableNum(relation.getGroupsId());
+		if (count == 0) {
+			log.error("车位异常 groupId:{}", relation.getGroupsId());
+			throw new BusinessRuntimeException("车位异常");
 		}
 	}
 
@@ -1354,6 +1383,53 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		return transUniTransferRequest;
 	}
 
+	/**
+	 * 查询支付宝订单详情
+	 */
+	@Override
+	public AlipayTradeQueryResponse getZfbOrderDetail(String shopId, String orderNo) throws AlipayApiException {
+		AlipayClient alipayClient = AliPayClientFactory.getAlipayClient(shopId);
+		AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
+		AlipayTradeWapPayModel bizModel = new AlipayTradeWapPayModel();
+		bizModel.setOutTradeNo(orderNo);
+		request.setBizModel(bizModel);
+		AlipayTradeQueryResponse response;
+		ShopConfig shopConfig = shopConfigMapper.selectOne(Wrappers.lambdaQuery(ShopConfig.class).eq(ShopConfig::getAppId, shopId));
+		if (shopConfig != null && shopConfig.getIsCert()) {
+			response = alipayClient.certificateExecute(request);
+		} else {
+			response = alipayClient.execute(request);
+		}
+		if (response.isSuccess()) {
+			return response;
+		}
+		return null;
+	}
+
+	/**
+	 * 查询支付宝退款订单详情
+	 */
+	@Override
+	public AlipayTradeFastpayRefundQueryResponse getZfbRefundDetail(String shopId, String orderNo) throws AlipayApiException {
+		AlipayClient alipayClient = AliPayClientFactory.getAlipayClient(shopId);
+		AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
+		AlipayTradeRefundModel bizModel = new AlipayTradeRefundModel();
+		bizModel.setOutTradeNo(orderNo);
+		bizModel.setOutRequestNo(orderNo);
+		request.setBizModel(bizModel);
+		AlipayTradeFastpayRefundQueryResponse response;
+		ShopConfig shopConfig = shopConfigMapper.selectOne(Wrappers.lambdaQuery(ShopConfig.class).eq(ShopConfig::getAppId, shopId));
+		if (shopConfig != null && shopConfig.getIsCert()) {
+			response = alipayClient.certificateExecute(request);
+		} else {
+			response = alipayClient.execute(request);
+		}
+		if (response.isSuccess()) {
+			return response;
+		}
+		return null;
+	}
+
 	public AliPayParams commonAliPay(Long orderId, String returnUrl, String productCode, String appId, String qrPayMode) throws Exception {
 		AlipayClient alipayClient = AliPayClientFactory.getAlipayClient(Optional.ofNullable(appId).orElse(ShopConfig.ZFB_DEFAULT_APP_ID));
 		// 创建API对应的request
@@ -1435,10 +1511,12 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 
 	public void updateCarParkAndSendMsg(GoodsDon goodsDon, GoodsDonSku sku, OrderDon order) {
 		if (goodsDon.getType() == 1) {
+			log.info("虚物订单orderNo:{}开始更新车票信息", order.getOrderNo());
 			//修改车位状态
 			GroupsRelation relation = groupsRelationMapper.selectById(order.getRelationId());
 			GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
 			if (GroupsRelation.Status.locking.equals(relation.getStatus()) || GroupsRelation.Status.validity.equals(relation.getStatus())) {
+				log.info("订单号orderNo:{}开始修改车位:{}状态", order.getOrderNo(), relation.getId());
 				relation.setStatus(GroupsRelation.Status.validity);
 				//续费后,下一次续费意愿状态为false
 				relation.setRenewStatus(false);
@@ -1452,6 +1530,7 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 					relation.setExpiryTime(newDate);
 					relation.setStartTime(relation.getStartTime() == null ? new Date() : null);
 				} else if (GroupsTrips.Status.waiting.equals(groupsTrips.getStatus())) {
+					log.info("车位groupsId:{}未发车,修改订单号orderNo:{}订单为已付款状态:{}", groupsTrips.getId(), order.getOrderNo());
 					order.setStatus(OrderDon.Status.hasPayment);
 				}
 				//TODO 如未发车逻辑
@@ -1931,4 +2010,63 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 
 		userRenewChangeTicketRecordMapper.insert(record);
 	}
+
+	/**
+	 * 查询第三放接口订单是否已支付
+	 */
+	public OrderDon.Status isHasPaid(OrderDon orderDon) {
+		OrderDon.Status noPayment = OrderDon.Status.noPayment;
+		GoodsDon goodsDon = goodsDonMapper.selectById(orderDon.getGoodsId());
+		if (orderDon.getType() == OrderDon.Type.WeChat) {
+			try {
+				Map<String, String> reMap = weChatService.getWxOrderDetail(orderDon.getShopId(), orderDon.getOrderNo());
+				if (reMap != null) {
+					String orderStatus = reMap.get("trade_state");
+					if ("SUCCESS".equals(orderStatus)) {
+						orderDon.setStatus(goodsDon.getType() == 1 && goodsDon.getSecondType() == 2 ? OrderDon.Status.complete : OrderDon.Status.hasPayment);
+						orderDon.setTransactionId(reMap.get("transaction_id"));
+						return updateNoPayment(noPayment, orderDon, goodsDon);
+					}
+				}
+			} catch (Exception e) {
+
+			}
+		} else if (orderDon.getType() == OrderDon.Type.ALI_PAY) {
+			try {
+				AlipayTradeQueryResponse zfbOrderDetail = getZfbOrderDetail(orderDon.getShopId(), orderDon.getOrderNo());
+				if (zfbOrderDetail != null) {
+					String tradeStatus = zfbOrderDetail.getTradeStatus();
+					if ("TRADE_SUCCESS".equals(tradeStatus)) {
+						orderDon.setStatus(goodsDon.getType() == 1 && goodsDon.getSecondType() == 2 ? OrderDon.Status.complete : OrderDon.Status.hasPayment);
+						orderDon.setTransactionId(zfbOrderDetail.getTradeNo());
+						return updateNoPayment(noPayment, orderDon, goodsDon);
+					}
+				}
+			} catch (Exception e) {
+
+			}
+		}
+		return orderDon.getStatus();
+	}
+
+	private OrderDon.Status updateNoPayment(OrderDon.Status noPayment, OrderDon orderDon, GoodsDon goodsDon) {
+		boolean isSuccess = update(Wrappers.lambdaUpdate(OrderDon.class)
+				.set(OrderDon::getStatus, orderDon.getStatus())
+				.set(OrderDon::getTransactionId, orderDon.getTransactionId())
+				.eq(OrderDon::getStatus, noPayment)
+				.eq(OrderDon::getId, orderDon.getId()));
+		if (isSuccess) {
+			//更新车位情况
+			GoodsDonSku sku = goodsDonSkuMapper.selectById(orderDon.getSkuId());
+			if (orderDon.getOrderType() == 2 && orderDon.getIsChangeTicket()) {
+				//将奈飞月付车票更换成其他规格的车票
+				changeTicketAndRecord(orderDon.getPreSkuId(), orderDon.getRelationId(), orderDon.getId(), orderDon.getNum(), sku, orderDon.getUserId());
+			} else {
+				updateCarParkAndSendMsg(goodsDon, sku, orderDon);
+			}
+			updateById(orderDon);
+			return orderDon.getStatus();
+		}
+		return noPayment;
+	}
 }

+ 1 - 1
netflix-service/src/main/java/com/cyksj/service/relation/GroupRelationFrontService.java

@@ -16,5 +16,5 @@ public interface GroupRelationFrontService {
 
 	Boolean isJoinCorpWx(Long userId, Boolean isJoin, Boolean noCoupon);
 
-	GroupsRelation getSimilarExpiredGroupRelation(Long skuId, Integer months);
+	GroupsRelation getSimilarExpiredGroupRelation(Long skuId, Integer months, List<Long> errorsRelationIds);
 }

+ 5 - 2
netflix-service/src/main/java/com/cyksj/service/relation/impl/GroupRelationFrontServiceImpl.java

@@ -107,7 +107,7 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 	public Boolean isJoinCorpWx(Long userId, Boolean isJoin, Boolean noCoupon) {
 		if (!isJoin) {
 			User user = userMapper.selectById(userId);
-			if (StrUtil.isEmpty(user.getUnionid())) {
+			if (user == null || StrUtil.isEmpty(user.getUnionid())) {
 				return true;
 			}
 			CorpUser corpUser = corpUserMapper.selectOne(Wrappers.lambdaQuery(CorpUser.class)
@@ -133,19 +133,22 @@ public class GroupRelationFrontServiceImpl implements GroupRelationFrontService
 	}
 
 	@Override
-	public GroupsRelation getSimilarExpiredGroupRelation(Long skuId, Integer months) {
+	public GroupsRelation getSimilarExpiredGroupRelation(Long skuId, Integer months, List<Long> errorsRelationIds) {
 		DateTime expiryTime = DateUtil.offsetMonth(DateTime.now(), months);
 		DateTime minExpiryTime = DateUtil.offsetDay(expiryTime, -5);
 		Long groupsId = groupsRelationMapper.selectSimilarExpiredRelation(skuId, minExpiryTime);
 		if (groupsId == null) {
+			log.info("暂无相似过期时间车队");
 			return null;
 		}
 		GroupsRelation relation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
+				.notIn(errorsRelationIds != null && errorsRelationIds.size() > 0, GroupsRelation::getId, errorsRelationIds)
 				.eq(GroupsRelation::getGroupsId, groupsId)
 				.eq(GroupsRelation::getStatus, GroupsRelation.Status.none)
 				.eq(GroupsRelation::getUserId, 0)
 				.orderByAsc(GroupsRelation::getNum)
 				.last("limit 1"));
+		log.info("获取相似车队的车位relationId:{}", relation.getId());
 		return relation;
 	}
 }

+ 9 - 3
netflix-service/src/main/java/com/cyksj/service/user/impl/UserServiceImpl.java

@@ -16,10 +16,10 @@ import com.cyksj.mapper.channel.ChannelPopularizeMapper;
 import com.cyksj.model.dto.GzhOAuth2UserInfo;
 import com.cyksj.model.dto.UserWhoami;
 import com.cyksj.model.entity.*;
+import com.cyksj.redis.RedisService;
 import com.cyksj.service.distribute.DistributeService;
 import com.cyksj.service.distribute.equipment.EquipmentDistributeService;
 import com.cyksj.service.mange.coupon.CouponCommonService;
-import com.cyksj.service.sys.SysConfigService;
 import com.cyksj.service.user.UserService;
 import com.ejlchina.searcher.BeanSearcher;
 import lombok.RequiredArgsConstructor;
@@ -53,7 +53,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
 
 	private final BeanSearcher beanSearcher;
 
-	private final SysConfigService sysConfigService;
+	private final RedisService redisService;
 
 	private static final GlobalThreadPoolTaskExecutor TASK_POOL = GlobalThreadPoolTaskExecutor.getInstance();
 
@@ -97,8 +97,14 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
 		if (user.getId() == null) {
 			isNewUser = true;
 			user.setPopularizeId(pid);
+			if (!redisService.setNx(RedisService.key.REPEAT_USER_KEY.getNameFormat(user.getUnionid()), user.getUnionid(), RedisService.key.REPEAT_USER_KEY.getTimeout())) {
+				return this.getOne(Wrappers.lambdaQuery(User.class)
+						.eq(User::getUnionid, unionid).last("limit 1"));
+			}
+			this.save(user);
+		} else {
+			this.updateById(user);
 		}
-		this.saveOrUpdate(user);
 		if (sharedId != null && isNewUser) {
 			if (dsType == null || dsType == 1) {
 				distributeService.saveDistributionInvitation(sharedId, user.getId());

+ 5 - 0
netflix-service/src/main/java/com/cyksj/service/wechat/WeChatService.java

@@ -83,4 +83,9 @@ public interface WeChatService {
      * 获取公众号带参数的永久二维码
      */
     String getNotExpiredWxGzhQrCode(String sceneKey) throws Exception;
+
+    /**
+     * 获取微信订单信息 校验订单是否已支付
+     */
+    Map<String, String> getWxOrderDetail(String shopId, String orderNo) throws Exception;
 }

+ 41 - 5
netflix-service/src/main/java/com/cyksj/service/wechat/impl/WeChatServiceImpl.java

@@ -40,10 +40,7 @@ import java.net.URLEncoder;
 import java.net.http.HttpRequest;
 import java.net.http.HttpResponse;
 import java.security.KeyStore;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.Map;
-import java.util.Optional;
+import java.util.*;
 
 
 /**
@@ -534,6 +531,33 @@ public class WeChatServiceImpl implements WeChatService {
         return url;
     }
 
+    @Override
+    public Map<String, String> getWxOrderDetail(String shopId, String orderNo) throws Exception {
+        String url = "https://api.mch.weixin.qq.com/pay/orderquery";
+        // 拼接统一下单实体类
+        Map<String, String> map = new TreeMap<>();
+        map.put("appid", weChatConfig.getAppid());
+        map.put("mch_id", shopId);
+        map.put("out_trade_no", orderNo);
+        map.put("nonce_str", "d1234");
+        String sign = getMd5Sign(map);
+        map.put("sign", sign);
+        String xml = Xmls.toXml(map);
+        HttpResponse<String> send = J11HttpC.custom()
+                .ofPost()
+                .url(url)
+                .headers(J11HttpC.ReqType.raw_xml)
+                .body(HttpRequest.BodyPublishers.ofString(xml, IoKit.Charsets.UTF_8.getCharset()))
+                .send(HttpResponse.BodyHandlers.ofString());
+        Map<String, String> orderSearch = Xmls.toMap(send.body());
+        log.info("微信返回值 xml转map: \n{}", orderSearch);
+        if (!StringUtils.equals(orderSearch.get("result_code"), "SUCCESS")) {
+            log.error("调用微信h5查询订单详情接口失败. 微信返回: " + orderSearch);
+            return null;
+        }
+        return orderSearch;
+    }
+
     /**
      * sha256_HMAC加密
      * @param message 消息
@@ -573,5 +597,17 @@ public class WeChatServiceImpl implements WeChatService {
         return hs.toString().toLowerCase();
     }
 
-
+    public String getMd5Sign(Map<String, String> map) throws Exception {
+        StringBuilder sb = new StringBuilder();
+        map.forEach((k, v) -> {
+            sb.append(k).append("=").append(v).append("&");
+        });
+        sb.append("key").append("=").append(shopConfigMapper.getByAppId(map.get("mch_id")).getSecret());
+        String sign = Codec.DoDigest.custom()
+                .setAlgorithm(Codec.DoDigest.Algorithm.MD5)
+                .setStringData(sb.toString())
+                .toHexString()
+                .toUpperCase();
+        return sign;
+    }
 }

+ 5 - 3
netflix-web/src/main/java/com/cyksj/web/controller/payment/OrderController.java

@@ -309,10 +309,12 @@ public class OrderController {
 		////将异步通知中收到的所有参数都存放到map中
 		Map<String, String> params = convertRequestParamsToMap(request);
 		String tradeStatus = params.get("trade_status");
-		if (AliPayTradeStatus.TRADE_SUCCESS.getStatus().equals(tradeStatus) || AliPayTradeStatus.TRADE_FINISHED.getStatus().equals(tradeStatus)) {
-			orderDonService.aliPayNotify(params);
+        String orderNo = params.get("out_trade_no");
+        if (AliPayTradeStatus.TRADE_SUCCESS.getStatus().equals(tradeStatus) || AliPayTradeStatus.TRADE_FINISHED.getStatus().equals(tradeStatus)) {
+            log.info("支付宝商家订单号orderNo:{},status:{}开始回调", orderNo, tradeStatus);
+            orderDonService.aliPayNotify(params);
 		} else {
-			log.error("支付宝回调 error 状态不符合 成功或完成 status:{} ,orderNo:{}", tradeStatus, params.get("out_trade_no"));
+			log.error("支付宝回调 error 状态不符合 成功或完成 status:{} ,orderNo:{}", tradeStatus, orderNo);
 			return "fail";
 		}
 		return "success";

+ 4 - 1
netflix-web/src/main/java/com/cyksj/web/controller/user/AuthorizationController.java

@@ -130,7 +130,10 @@ public class AuthorizationController {
         GzhOAuth2UserInfo userinfo = weChatService.getUserInfo(token.getAccessToken(), token.getOpenid());
 
         //保存用户信息
-        User user = userService.saveAuth(userinfo, re.getSharedId(),re.getDsType(), re.getPid());
+        User user = userService.saveAuth(userinfo, re.getSharedId(), re.getDsType(), re.getPid());
+        if (user == null) {
+            throw BusinessRuntimeException.getInstance("系统错误,请重新授权");
+        }
 
         //写回登陆信息
         StpUserUtil.login(user.getId());