diff --git a/api/src/main/java/com/sv/netty/config/ErrorCode.java b/api/src/main/java/com/sv/netty/config/ErrorCode.java index a05ca71..e4f08a4 100644 --- a/api/src/main/java/com/sv/netty/config/ErrorCode.java +++ b/api/src/main/java/com/sv/netty/config/ErrorCode.java @@ -2,7 +2,9 @@ package com.sv.netty.config; public enum ErrorCode { MEMBER_NOT_EXIST(10001,"用户校验失败"), - NO_ENOUGH_AMOUNT(10002,"余额不足"); + NO_ENOUGH_AMOUNT(10002,"余额不足"), + NO_USE_CARD(10003,"您好,暂无可用会员卡,请扫描门禁上张贴的小程序二维码购买!"), + CHECK_ENTER_INTERVAL(10004,"无出门记录连续入场,请{0}分钟之后再试"); private int code; diff --git a/api/src/main/java/com/sv/netty/controller/QREnterController.java b/api/src/main/java/com/sv/netty/controller/QREnterController.java index 8715423..66e3eff 100644 --- a/api/src/main/java/com/sv/netty/controller/QREnterController.java +++ b/api/src/main/java/com/sv/netty/controller/QREnterController.java @@ -37,12 +37,13 @@ public class QREnterController extends BaseApiController { DeviceType enterOrOut = getEnterOrOut(deviceId); Venue venue = qrCodeService.initEnter(venueId, deviceName); if (venue!=null){ + Channel channel = ClientChannelCache.getCurrentChannel(deviceName,venueId ,enterOrOut); if (DeviceType.OUT == enterOrOut){ // 出场 - messageService.outVenue(deviceName,venueId,memberId,venue); + messageService.outVenue(deviceName,venueId,memberId,venue,channel); }else{ // 进场 - messageService.enterVenue(deviceName,venueId,memberId,venue); + messageService.enterVenue(deviceName,venueId,memberId,venue,channel); } } return ResponseDTO.ok(); diff --git a/api/src/main/java/com/sv/netty/netty/message/MessageDTO.java b/api/src/main/java/com/sv/netty/netty/message/MessageDTO.java index 376f493..d3961eb 100644 --- a/api/src/main/java/com/sv/netty/netty/message/MessageDTO.java +++ b/api/src/main/java/com/sv/netty/netty/message/MessageDTO.java @@ -7,6 +7,11 @@ public class MessageDTO implements Serializable { private MessageType messageType; private String message; + public MessageDTO(MessageType messageType, String message) { + this.messageType = messageType; + this.message = message; + } + public MessageType getMessageType() { return messageType; } diff --git a/api/src/main/java/com/sv/netty/netty/message/MessageType.java b/api/src/main/java/com/sv/netty/netty/message/MessageType.java index 15e103a..60a85cc 100644 --- a/api/src/main/java/com/sv/netty/netty/message/MessageType.java +++ b/api/src/main/java/com/sv/netty/netty/message/MessageType.java @@ -2,7 +2,8 @@ package com.sv.netty.netty.message; public enum MessageType { LOAD("加载"), - OPENDOOR("开门"); + OPENDOOR("开门"), + FAILED("开门校验失败"); private String message; MessageType(String message) { diff --git a/api/src/main/java/com/sv/netty/netty/service/MessageService.java b/api/src/main/java/com/sv/netty/netty/service/MessageService.java index db82d08..637a975 100644 --- a/api/src/main/java/com/sv/netty/netty/service/MessageService.java +++ b/api/src/main/java/com/sv/netty/netty/service/MessageService.java @@ -46,7 +46,7 @@ public interface MessageService { * @param memberId * @param venue */ - void outVenue(String deviceName, Integer venueId, Integer memberId, Venue venue); + void outVenue(String deviceName, Integer venueId, Integer memberId, Venue venue,Channel channel); /** * 进场 @@ -55,5 +55,5 @@ public interface MessageService { * @param memberId * @param venue */ - void enterVenue(String deviceName, Integer venueId, Integer memberId, Venue venue); + void enterVenue(String deviceName, Integer venueId, Integer memberId, Venue venue,Channel channel); } diff --git a/api/src/main/java/com/sv/netty/netty/service/impl/AppMessageHandlerAdapter.java b/api/src/main/java/com/sv/netty/netty/service/impl/AppMessageHandlerAdapter.java index 45f196b..260d3e2 100644 --- a/api/src/main/java/com/sv/netty/netty/service/impl/AppMessageHandlerAdapter.java +++ b/api/src/main/java/com/sv/netty/netty/service/impl/AppMessageHandlerAdapter.java @@ -1,10 +1,11 @@ package com.sv.netty.netty.service.impl; -import com.sv.dto.EnterResult; +import com.enums.DeviceType; import com.sv.entity.Member; import com.sv.entity.MemberEnterVenueLog; import com.sv.entity.Venue; import com.sv.netty.config.ClientChannelCache; +import com.sv.netty.config.ErrorCode; import com.sv.netty.netty.message.HeartBeat; import com.sv.netty.netty.message.MessageDTO; import com.sv.netty.netty.message.MessageType; @@ -22,8 +23,10 @@ import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import javax.annotation.Resource; +import java.text.MessageFormat; import java.util.*; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; /** @@ -111,9 +114,7 @@ public class AppMessageHandlerAdapter implements MessageService { Member thisMember = memberService.findByMember(memberId); if (thisMember!=null){ String nickname = thisMember.getNickname(); - MessageDTO messageDTO = new MessageDTO(); - messageDTO.setMessageType(MessageType.LOAD); - messageDTO.setMessage("欢迎光临" + nickname); + MessageDTO messageDTO = new MessageDTO(MessageType.LOAD,"欢迎光临!" + nickname); sendMessage(channel,messageDTO); return true; } @@ -122,7 +123,7 @@ public class AppMessageHandlerAdapter implements MessageService { @Override - public void outVenue(String deviceName, Integer venueId, Integer memberId, Venue venue) { + public void outVenue(String deviceName, Integer venueId, Integer memberId, Venue venue,Channel channel) { Member member = memberService.findByMember(memberId); if (member != null) { //出场 不用判断直接出 @@ -163,74 +164,35 @@ public class AppMessageHandlerAdapter implements MessageService { * @param venue */ @Override - public void enterVenue(String deviceName, Integer venueId, Integer memberId, Venue venue) { - try { + public void enterVenue(String deviceName, Integer venueId, Integer memberId, Venue venue,Channel channel) { Member member = memberService.findByMember(memberId); + // 校验入场时间是否正常 if (checkInterval(member,venueId)) { - EnterResult result = venueService.qrCodeEnterVenue(memberId,deviceName,venueId,venue); - if (result.getStatus() >= 0) { -// memberMessageDto.setCode(1); - if (result.getStatus() == 1) { -// memberMessageDto.setCardName("会员卡"); - } - if (result.getStatus() == 2) { -// memberMessageDto.setPlacePrice(result.getMoney()); -// memberMessageDto.setFirst(true); -// logger.info(member.getId() + "入场成功:" + member.getMoney().toString()); -// member = memberService.findByFaceId(response.getPerson().getId()); -// memberMessageDto.setAmount(member.getMoney()); - //5秒后开门 -// scheduledExecutorService.schedule(new Runnable() { -// @Override -// public void run() { -//// MessageDto messageDto = new MessageDto(); -//// messageDto.setCmdId(Cmd.OPEN_DOOR.id); -//// messageDto.setDoor(1); -//// sendOpenMessage(messageDto, 1); -// } -// }, 5, TimeUnit.SECONDS); - } else { - //开门 -// MessageDto messageDto = new MessageDto(); -// messageDto.setCmdId(Cmd.OPEN_DOOR.id); -// messageDto.setDoor(1); -// sendOpenMessage(messageDto, 1); - logger.info(member.getId() + "入场成功:" + member.getMoney().toString()); - - } -// memberMessageDto.setMessage("门禁已开,请入门"); - venueService.addNumber(venue.getId(), 1, member.getId()); -// venue = venueService.findById(venue.getId()); -// sendNumberChange(venue.getNumber()); + if(venueService.qrCodeEnterVenue(memberId,deviceName,venueId,venue)){ + // 可以进场 + scheduledExecutorService.schedule(() -> { + sendMessage(channel,new MessageDTO(MessageType.OPENDOOR,"OK")); + }, 5, TimeUnit.SECONDS); } else { - logger.info(member.getId() + "入场失败:" + member.getMoney().toString()); -// memberMessageDto.setCode(-1); -// memberMessageDto.setMessage(member.getName() + "您好,您的余额不足,请扫描门禁上张贴的小程序二维码充值"); + // 进场失败 + sendMessage(channel,new MessageDTO(MessageType.FAILED, ErrorCode.NO_USE_CARD.getMsg())); } } else { logger.info(member.getId() + "入场失败:连续入场"); -// memberMessageDto.setCode(0); Config config = configService.findById(1); -// memberMessageDto.setMessage("无出门记录连续入场,请" + config.getValue() + "分钟之后再试"); + sendMessage(channel,new MessageDTO(MessageType.OPENDOOR, MessageFormat.format(ErrorCode.CHECK_ENTER_INTERVAL.getMsg(),config.getValue()))); } - // TODO 校验完,就可以进场了 -// sendMessage(memberMessageDto, device.getId()); - } catch (Exception e) { - logger.error("进场失败",e); - } } private boolean checkInterval(Member member,Integer venueId){ - if (member == null) { + if (member == null || venueId == null) { return false; }else{ //最后进场记录 MemberEnterVenueLog enterVenueLog = memberEnterVenueLogService.findMemberLastLogNoType(member.getId(), venueId); - if (enterVenueLog == null) { - return true; - }else { + if (enterVenueLog != null) { //有记录 查看 最后一次是否是出场 - if (enterVenueLog.getType() == 1) { + if (enterVenueLog.getType().intValue() == DeviceType.OUT.getCode()) { return true; } else { //是进场 @@ -260,8 +222,8 @@ public class AppMessageHandlerAdapter implements MessageService { } } } + return true; } - return true; } /** diff --git a/entity/src/main/java/com/enums/DeviceType.java b/entity/src/main/java/com/enums/DeviceType.java index ffd2fe4..44a5e76 100644 --- a/entity/src/main/java/com/enums/DeviceType.java +++ b/entity/src/main/java/com/enums/DeviceType.java @@ -5,20 +5,21 @@ package com.enums; */ public enum DeviceType { - ENTER("ENTER","进场"), - OUT("OUTER","出场"); - private String code; + ENTER(0,"进场"), + OUT(1,"出场"); + private int code; private String name; - DeviceType(String code, String name) { + DeviceType(int code, String name) { this.code = code; this.name = name; } - public String getCode() { + + public int getCode() { return code; } - public void setCode(String code) { + public void setCode(int code) { this.code = code; } diff --git a/entity/src/main/java/com/sv/dto/EnterResult.java b/entity/src/main/java/com/sv/dto/EnterResult.java deleted file mode 100644 index a4ee37e..0000000 --- a/entity/src/main/java/com/sv/dto/EnterResult.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.sv.dto; - -import java.math.BigDecimal; - -public class EnterResult { - private Integer status; - private BigDecimal money; - - public Integer getStatus() { - return status; - } - - public void setStatus(Integer status) { - this.status = status; - } - - public BigDecimal getMoney() { - return money; - } - - public void setMoney(BigDecimal money) { - this.money = money; - } -} diff --git a/service/src/main/java/com/sv/service/api/VenueService.java b/service/src/main/java/com/sv/service/api/VenueService.java index 1f7ebb0..2831641 100644 --- a/service/src/main/java/com/sv/service/api/VenueService.java +++ b/service/src/main/java/com/sv/service/api/VenueService.java @@ -2,7 +2,6 @@ package com.sv.service.api; import com.enums.*; import com.github.pagehelper.PageHelper; -import com.sv.dto.EnterResult; import com.sv.dto.api.MemberCardDTO; import com.sv.dto.api.MemberCardVenuesDTO; import com.sv.dto.api.VenueDTO; @@ -12,15 +11,11 @@ import com.sv.mapper.VenueMapper; import com.sv.service.api.util.DateUtilCard; import com.sv.service.api.util.GeoHashUtils; import com.sv.service.common.FaceService; -import com.sv.service.common.OSSClientUtil; -import com.sv.service.common.PlatformService; import com.sv.service.oms.DeviceService; import com.ydd.framework.core.common.Pagination; import com.ydd.framework.core.common.utils.ValidationUtils; import com.ydd.framework.core.exception.ServiceException; -import com.ydd.framework.core.service.CacheService; import com.ydd.framework.core.service.impl.BaseServiceImpl; -import com.ydd.framework.core.service.impl.WxXCXService; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,9 +23,9 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; -import java.io.InputStream; import java.math.BigDecimal; import java.util.*; +import java.util.stream.Collectors; /** * Service - 场馆 @@ -356,7 +351,7 @@ public class VenueService extends BaseServiceImpl { // //进场之前 查看是否有会员卡 // List cards = memberCardService.findByMemberId(device.getVenueId(), member.getId()); // if (cards.size() > 0) { -// //有会员卡 查看是否是免费卡 +// //有会员卡 查看是否是免费卡 【// 发现这里的逻辑不是优先使用免费卡】 // MemberCard useCard = null; // for (MemberCard card : cards) { // if (!VipTypeEnum.FREECARD.value.equals(card.getCardType())) { @@ -406,100 +401,81 @@ public class VenueService extends BaseServiceImpl { // } /** - * 人脸失败用户入场(篮球场) + * 是否可以成功入场 * * @return 0成功 -1失败 */ @Transactional - public synchronized EnterResult qrCodeEnterVenue(Integer memberId, String deviceName,Integer venueId,Venue venue) { - EnterResult result = new EnterResult(); + public synchronized boolean qrCodeEnterVenue(Integer memberId, String deviceName,Integer venueId,Venue venue) { synchronized (("enter" + memberId).intern()) { - Date now = new Date(); Device device = deviceService.findByDevice(deviceName,venueId, DeviceType.ENTER); - // 查询当前时间内,场馆对应的价格 - String time = DateUtilCard.nowTime().toString(); - VenuePrice venuePrice = venuePriceService.findPrice(device.getVenueId(), time); - if (venuePrice == null) { - logger.info("场馆暂未开放"); - result.setStatus(-2); - return result; - } + // 查询当前时间内,场馆对应的价格(健身房没有价格) if (venue.getStatus().intValue() == 1) { logger.info(venue.getName() + "被禁用,入场失败"); - result.setStatus(-2); - return result; + return false; } Member member = memberService.findByMember(memberId); memberService.verify(member); - if (venue == null || member == null) { - result.setStatus(-1); - return result; - } - //判断8小时之内 是否连续进场 - MemberEnterVenueLog enterVenueLog = memberEnterVenueLogService.findMemberLastLog(member.getId(), device.getVenueId()); + // 记录用户进场记录 MemberEnterVenueLog log = new MemberEnterVenueLog(); log.setMemberId(member.getId()); log.setVeneuType(device.getVenueType()); log.setVenueId(device.getVenueId()); log.setPlatformId(member.getPlatformId()); - if (enterVenueLog != null) { - if ((now.getTime() - enterVenueLog.getCreatedTime().getTime()) <= (8 * 60 * 60 * 1000)) { - //小于8小时直接进场 - log.setOrderSn(""); - logger.info("用户:" + member.getNickname() + "小于8小时直接进场"); - memberEnterVenueLogService.save(log); - result.setStatus(0); - return result; - } - } + log.setType(DeviceType.ENTER.getCode()); //进场之前 查看是否有会员卡 List cards = memberCardService.findByMemberId(device.getVenueId(), member.getId()); if (cards.size() > 0) { - //有会员卡 查看是否是免费卡 MemberCard useCard = null; - for (MemberCard card : cards) { - if (!VipTypeEnum.FREECARD.value.equals(card.getCardType())) { - useCard = card; - break; - } else { - //查看该免费卡是否可用 (一天用一次) - if (memberEnterVenueLogService.isFreeCardUseful(card.getId())) { - useCard = card; - break; + //有会员卡 查看是否有免费卡 + List freeCard = cards.stream().filter(free -> VipTypeEnum.FREECARD.value.equals(free.getCardType())).collect(Collectors.toList()); + //有会员卡 查看是否有单次卡 + List onceCard = cards.stream().filter(free -> + VipTypeEnum.ONCECARD.value.equals(free.getCardType()) || VipTypeEnum.PUB_ONCECARD.value.equals(free.getCardType())).collect(Collectors.toList()); + boolean canUseFree = false; + if (freeCard !=null && freeCard.size() > 0){ + for (MemberCard f : freeCard){ + if (memberEnterVenueLogService.isFreeCardUseful(f.getId())){ + canUseFree = true; + // 如果有一张可以用的免费卡就用免费卡 + useCard = f; } } } + if (!canUseFree) { + if (onceCard != null && onceCard.size() > 0) + // 不能用免费卡,优先单次卡,取第一张可用的单次卡 + useCard = onceCard.get(0); + } else { + // 单次卡和免费卡都不能用,随意用一张季卡或者年卡 + useCard = cards.get(0); + } if (useCard != null) { //使用会员卡入场 logger.info("用户" + member.getNickname() + "使用" + useCard.getCardType() + "入场"); log.setMemberCardId(useCard.getId()); log.setPayType(EnterVenuePayTypeEnum.MEMBER_CARD.value); - String orderSn = orderService.createEnterVenueOrder(venue, member.getId(), PayTypeEnum.MEMBER_CARD, venuePrice.getPrice()); + String orderSn = orderService.createEnterVenueOrder(venue, member.getId(), PayTypeEnum.MEMBER_CARD, BigDecimal.ZERO); // 会员卡入场,增加记录 createMemberMoneyLog(MoneyLogEnum.JOIN.value, venue.getPrice(), member.getId(), member.getPlatformId(), PayTypeEnum.MEMBER_CARD.value, useCard.getCardType(), venue.getId(), venue.getType()); log.setOrderSn(orderSn); memberEnterVenueLogService.save(log); - result.setStatus(1); - return result; + // 如果是单次卡,清除单次卡 + if (VipTypeEnum.ONCECARD.value.equals(useCard.getCardType()) + || VipTypeEnum.PUB_ONCECARD.value.equals(useCard.getCardType())){ + memberCardService.delete(useCard.getId()); + } + return true; + }else { + //查无可用会员卡 + logger.info("用户" + member.getNickname() + "您好!请先购买会员卡再进场"); + return false; } - } - //没有会员卡 扣余额 - //判断余额是否够 - if (memberService.isMoneyEnough(member.getId(), venuePrice.getPrice())) { - logger.info("用户" + member.getNickname() + "使用余额进场"); - result.setMoney(venuePrice.getPrice()); - String orderSn = orderService.createEnterVenueOrder(venue, member.getId(), PayTypeEnum.BALANCE, venuePrice.getPrice()); - log.setOrderSn(orderSn); - log.setPayType(EnterVenuePayTypeEnum.WEI_XIN.value); - memberEnterVenueLogService.save(log); - result.setStatus(2); - return result; - } else { - //余额不足 - logger.info("用户" + member.getNickname() + "余额不足进场失败"); - result.setStatus(-2); - return result; + }else { + //没有可用会员卡 健身房也不支持扣余额 + logger.info("用户" + member.getNickname() + "您好!请先购买会员卡再进场"); + return false; } } }