扫描二维码入场逻辑
This commit is contained in:
@@ -1,12 +1,23 @@
|
||||
package com.sv.api.controller;
|
||||
|
||||
import com.enums.BarCodeStatusEnum;
|
||||
import com.enums.EnterEnum;
|
||||
import com.sv.dto.BarCodeResult;
|
||||
import com.sv.entity.Barcode;
|
||||
import com.sv.entity.Device;
|
||||
import com.sv.entity.Venue;
|
||||
import com.sv.mapper.BarcodeMapper;
|
||||
import com.sv.netty.utils.AesUtil;
|
||||
import com.sv.netty.utils.MakeCode;
|
||||
import com.sv.service.api.VenueService;
|
||||
import com.sv.service.oms.DeviceService;
|
||||
import com.ydd.framework.core.common.Pagination;
|
||||
import com.ydd.framework.core.common.dto.ResponseDTO;
|
||||
import com.ydd.framework.core.controller.BaseApiController;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@@ -83,10 +94,14 @@ public class VenueController extends BaseApiController {
|
||||
*/
|
||||
@RequestMapping(value = "/venue/detail", method = RequestMethod.POST)
|
||||
public ResponseDTO detail(@RequestParam("venueId") Integer venueId) {
|
||||
Integer loginMemberId = getLoginMemberId();
|
||||
Integer loginMemberId = getMemberIdByAccessToken();
|
||||
return ResponseDTO.ok().addAttribute("venues", venueService.findByVenueId(venueId,loginMemberId));
|
||||
}
|
||||
|
||||
@Resource
|
||||
DeviceService deviceService;
|
||||
@Resource
|
||||
BarcodeMapper barcodeMapper;
|
||||
/**
|
||||
* 我要进场
|
||||
*
|
||||
@@ -94,8 +109,21 @@ public class VenueController extends BaseApiController {
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/venue/join", method = RequestMethod.GET)
|
||||
@Transactional
|
||||
public ResponseDTO join(@RequestParam("venueId") Integer venueId) {
|
||||
return ResponseDTO.ok().addAttribute("flg", venueService.join(getMemberIdByAccessToken(), venueId));
|
||||
Integer memberId = getMemberIdByAccessToken();
|
||||
BarCodeResult join = venueService.join(memberId, venueId);
|
||||
if (join.getFlg() == 0) {
|
||||
Device byDevice = deviceService.findByDevice(venueId);
|
||||
if (byDevice == null) {
|
||||
join.setFlg(999);
|
||||
join.setMsg("通讯异常,门禁设备离线中");
|
||||
}else {
|
||||
String barcode = newBarcode(byDevice.getName(), EnterEnum.ENTER, venueId, memberId);
|
||||
join.setBarcode(barcode);
|
||||
}
|
||||
}
|
||||
return ResponseDTO.ok().addAttribute("join", join);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,9 +133,42 @@ public class VenueController extends BaseApiController {
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/venue/out", method = RequestMethod.GET)
|
||||
@Transactional
|
||||
public ResponseDTO out(@RequestParam("venueId") Integer venueId) {
|
||||
return ResponseDTO.ok().addAttribute("flg", venueService.join(getMemberIdByAccessToken(), venueId));
|
||||
|
||||
Integer memberId = getMemberIdByAccessToken();
|
||||
BarCodeResult out = venueService.out(memberId, venueId);
|
||||
if (out.getFlg() == 0) {
|
||||
Device byDevice = deviceService.findByDevice(venueId);
|
||||
if (byDevice == null) {
|
||||
out.setFlg(999);
|
||||
out.setMsg("通讯异常,门禁设备离线中");
|
||||
}else {
|
||||
String barcode = newBarcode(byDevice.getName(),EnterEnum.OUT,venueId,memberId);
|
||||
out.setBarcode(barcode);
|
||||
}
|
||||
}
|
||||
return ResponseDTO.ok().addAttribute("out", out);
|
||||
}
|
||||
|
||||
|
||||
private String newBarcode (String deviceName,EnterEnum enterEnum,Integer venueId,Integer memberId){
|
||||
String barcode = "";
|
||||
Barcode res = barcodeMapper.findBarcode(venueId, memberId);
|
||||
if (res == null) {
|
||||
barcode = MakeCode.makeCode(venueId, memberId, deviceName, enterEnum.getValue() + "");
|
||||
Barcode b = new Barcode();
|
||||
logger.info("用户扫码【" + memberId + "$" + venueId + "】生成二维码为" + barcode);
|
||||
b.setBarcode(barcode);
|
||||
b.setStatus(BarCodeStatusEnum.INIT.getValue());
|
||||
b.setMemberId(memberId);
|
||||
b.setVenueId(venueId);
|
||||
b.setEnter(enterEnum.getValue());
|
||||
barcodeMapper.insert(b);
|
||||
}else {
|
||||
barcode = res.getBarcode();
|
||||
}
|
||||
return barcode;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package com.sv.netty.controller;
|
||||
|
||||
import com.sv.entity.Venue;
|
||||
import com.enums.DeviceStatusEnum;
|
||||
import com.sv.entity.Device;
|
||||
import com.sv.netty.config.NettyConstant;
|
||||
import com.sv.netty.netty.service.MessageService;
|
||||
import com.sv.service.oms.DeviceService;
|
||||
import com.ydd.framework.core.common.dto.ResponseDTO;
|
||||
import com.ydd.framework.core.controller.BaseApiController;
|
||||
import com.ydd.framework.core.exception.ServiceException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -15,32 +18,36 @@ import javax.annotation.Resource;
|
||||
* 小程序二维码进场Controller
|
||||
*/
|
||||
@RestController
|
||||
public class QREnterController extends BaseApiController {
|
||||
public class AdminNettyController extends BaseApiController {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(QREnterController.class);
|
||||
private final Logger logger = LoggerFactory.getLogger(AdminNettyController.class);
|
||||
@Resource
|
||||
DeviceService deviceService;
|
||||
@Resource
|
||||
private MessageService messageService;
|
||||
/**
|
||||
* 进场指令发布
|
||||
*/
|
||||
@RequestMapping(value = "/qrCode/enter", method = RequestMethod.GET)
|
||||
public ResponseDTO enter(@RequestParam("deviceId") String deviceId) {
|
||||
Integer memberId = getMemberIdByAccessToken();
|
||||
Integer venueId = getVenueId(deviceId);
|
||||
String deviceName = getDeviceName(deviceId);
|
||||
Venue venue = new Venue();// TODO
|
||||
if (venue!=null){
|
||||
if (true){
|
||||
// 出场
|
||||
messageService.outVenue(deviceName,venueId,memberId,venue);
|
||||
}else{
|
||||
// 进场
|
||||
messageService.enterVenue(deviceName,venueId,memberId,venue);
|
||||
}
|
||||
@RequestMapping(value = "/admin/enter/{id}", method = RequestMethod.POST)
|
||||
public ResponseDTO enter(@PathVariable("id") Integer id) {
|
||||
Device device = deviceService.findById(id);
|
||||
if (!DeviceStatusEnum.ONLINE.value.equals(device.getStatus())){
|
||||
throw new ServiceException("设备离线!请检查连接");
|
||||
}
|
||||
return ResponseDTO.ok();
|
||||
messageService.adminEnter(device.getName(),device.getVenueId());
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/admin/out/{id}", method = RequestMethod.POST)
|
||||
public ResponseDTO out(@PathVariable("id") Integer id) {
|
||||
Device device = deviceService.findById(id);
|
||||
if (!DeviceStatusEnum.ONLINE.value.equals(device.getStatus())){
|
||||
throw new ServiceException("设备离线!请检查连接");
|
||||
}
|
||||
messageService.adminOut(device.getName(),device.getVenueId());
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字符串获取场馆
|
||||
* @param deviceId
|
||||
@@ -1,11 +1,10 @@
|
||||
package com.sv.netty.netty;
|
||||
|
||||
import com.sv.netty.config.ChannelParam;
|
||||
import com.sv.netty.config.HeartBeat;
|
||||
import com.sv.netty.config.NettyConstant;
|
||||
import com.sv.netty.config.SpringContextHolder;
|
||||
import com.enums.EnterEnum;
|
||||
import com.sv.netty.config.*;
|
||||
import com.sv.netty.netty.service.MessageService;
|
||||
import com.sv.netty.utils.JsonUtils;
|
||||
import com.sv.netty.utils.MakeCode;
|
||||
import io.netty.channel.*;
|
||||
import io.netty.handler.timeout.IdleState;
|
||||
import io.netty.handler.timeout.IdleStateEvent;
|
||||
@@ -50,12 +49,29 @@ public class ServerHandler extends SimpleChannelInboundHandler<String> {
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, String msg) {
|
||||
String clientIp = ctx.channel().attr(NettyConstant.CHANNEL_PARAM).get().getClientIp();
|
||||
logger.info("接收服务器响应msg:[" + msg + "]");
|
||||
try {
|
||||
HeartBeat hb = JsonUtils.decode(msg,HeartBeat.class);
|
||||
logger.info("客户端【" + clientIp + "】上报心跳...");
|
||||
ctx.channel().attr(NettyConstant.CHANNEL_PARAM).get().setVenueId(hb.getVenueId());
|
||||
ctx.channel().attr(NettyConstant.CHANNEL_PARAM).get().setDeviceName(hb.getDeviceName());
|
||||
messageService.online(clientIp,ctx.channel(), hb);
|
||||
VenueMessage message = JsonUtils.decode(msg, VenueMessage.class);
|
||||
switch (message.getMessageType()) {
|
||||
case HB:
|
||||
HeartBeat hb = JsonUtils.decode(message.getMessage(),HeartBeat.class);
|
||||
logger.info("客户端【" + clientIp + "】上报心跳...");
|
||||
ctx.channel().attr(NettyConstant.CHANNEL_PARAM).get().setVenueId(hb.getVenueId());
|
||||
ctx.channel().attr(NettyConstant.CHANNEL_PARAM).get().setDeviceName(hb.getDeviceName());
|
||||
messageService.online(clientIp,ctx.channel(), hb);
|
||||
break;
|
||||
case SCAN_CODE:
|
||||
logger.info("客户端【" + clientIp + "】开门了...");
|
||||
VenueBarCode venueBarCode = MakeCode.decodeCode(message.getMessage());
|
||||
if (EnterEnum.ENTER.getValue() == venueBarCode.getDirection()) {
|
||||
messageService.enterVenue(message.getMessage());
|
||||
} else {
|
||||
messageService.outVenue(message.getMessage());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
logger.info( "default");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("[" + clientIp + "] host unknown error",e);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.sv.netty.netty.service;
|
||||
|
||||
import com.sv.entity.Venue;
|
||||
import com.sv.netty.config.HeartBeat;
|
||||
import com.sv.netty.config.VenueBarCode;
|
||||
import io.netty.channel.Channel;
|
||||
|
||||
import java.util.Set;
|
||||
@@ -37,21 +38,19 @@ public interface MessageService {
|
||||
Set<String> countConnection();
|
||||
/**
|
||||
* 出场
|
||||
* @param deviceName
|
||||
* @param venueId
|
||||
* @param memberId
|
||||
* @param venue
|
||||
* @param barcode
|
||||
*/
|
||||
void outVenue(String deviceName, Integer venueId, Integer memberId, Venue venue);
|
||||
void outVenue(String barcode);
|
||||
|
||||
/**
|
||||
* 进场
|
||||
* @param deviceName
|
||||
* @param venueId
|
||||
* @param memberId
|
||||
* @param venue
|
||||
* @param barcode
|
||||
*/
|
||||
void enterVenue(String deviceName, Integer venueId, Integer memberId, Venue venue);
|
||||
void enterVenue(String barcode);
|
||||
|
||||
public void adminEnter(String deviceName, Integer venueId);
|
||||
|
||||
public void adminOut(String deviceName, Integer venueId);
|
||||
|
||||
void testLoad(String deviceName, Integer venueId);
|
||||
}
|
||||
|
||||
@@ -1,279 +0,0 @@
|
||||
package com.sv.netty.netty.service.impl;
|
||||
|
||||
import com.sv.entity.Member;
|
||||
import com.sv.entity.MemberEnterVenueLog;
|
||||
import com.sv.entity.Venue;
|
||||
import com.sv.netty.config.*;
|
||||
import com.sv.netty.netty.service.MessageService;
|
||||
import com.sv.netty.utils.JsonUtils;
|
||||
import com.sv.netty.utils.ServerMessageUtils;
|
||||
import com.sv.service.api.MemberEnterVenueLogService;
|
||||
import com.sv.service.api.MemberService;
|
||||
import com.sv.service.api.VenueService;
|
||||
import com.sv.service.oms.ConfigService;
|
||||
import com.sv.service.oms.DeviceService;
|
||||
import com.ydd.oms.entity.sys.Config;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
/**
|
||||
* 消息实现类
|
||||
*
|
||||
* @Author peakren
|
||||
* @Date 08/05/2017 10:43 PM
|
||||
*/
|
||||
@Service("messageService")
|
||||
public class AppMessageHandlerAdapter implements MessageService {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(AppMessageHandlerAdapter.class);
|
||||
|
||||
/**
|
||||
* 存储设备通道类型
|
||||
* 此处存储客户端的channel 信息key 为 【deviceId + venueId】
|
||||
* value: 1Tcp 2WebSocket
|
||||
*/
|
||||
private ConcurrentMap<String, Channel> links = PlatformDependent.newConcurrentHashMap();
|
||||
|
||||
@Resource
|
||||
private MemberService memberService;
|
||||
|
||||
@Resource
|
||||
private VenueService venueService;
|
||||
|
||||
@Resource
|
||||
private DeviceService deviceService;
|
||||
|
||||
@Resource
|
||||
private ConfigService configService;
|
||||
|
||||
@Resource(name = "scheduledExecutorService")
|
||||
private ScheduledExecutorService scheduledExecutorService;
|
||||
|
||||
@Resource
|
||||
private MemberEnterVenueLogService memberEnterVenueLogService;
|
||||
|
||||
/**
|
||||
* 处理心跳信息,存储心跳信息
|
||||
* @param clientId
|
||||
* @param channel
|
||||
* @param heartBeat
|
||||
*/
|
||||
@Override
|
||||
public void online(String clientId, Channel channel, HeartBeat heartBeat) {
|
||||
logger.error("=========" + JsonUtils.encode(heartBeat) + clientId);
|
||||
// 处理心跳信息
|
||||
if (!contains(heartBeat.getDeviceName(),heartBeat.getVenueId())){
|
||||
// 此处存储客户端的channel 信息key 为 deviceId + venueId
|
||||
Venue thisVenue = venueService.findById(heartBeat.getVenueId());
|
||||
if (thisVenue == null ){
|
||||
logger.error("this client choose venue Error! venueId == " + heartBeat.getVenueId());
|
||||
} else {
|
||||
deviceService.online(heartBeat.getDeviceName(),heartBeat.getVenueId(),thisVenue.getType(),clientId);
|
||||
addLinks(heartBeat.getDeviceName(),heartBeat.getVenueId(),channel);
|
||||
VenueMessage venueMessage = new VenueMessage(MessageType.LINK,"欢迎扫码进场!");
|
||||
ServerMessageUtils.INSTANCE.sendMsg(channel,venueMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备下线
|
||||
* @param deviceName
|
||||
* @param venueId
|
||||
*/
|
||||
@Override
|
||||
public void Offline(String deviceName, Integer venueId) {
|
||||
if (deviceName != null && venueId != null){
|
||||
removeChannelType(deviceName,venueId);
|
||||
deviceService.offline(deviceName,venueId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试客户端连接
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public void testLoad(String deviceName, Integer venueId) {
|
||||
Channel currentChannel = getCurrentChannel(deviceName, venueId);
|
||||
ServerMessageUtils.INSTANCE.sendMsg(currentChannel,new VenueMessage(MessageType.LINK,"测试链接"));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void outVenue(String deviceName, Integer venueId, Integer memberId, Venue venue) {
|
||||
Channel channel = getCurrentChannel(deviceName,venueId);
|
||||
Member member = memberService.findByMember(memberId);
|
||||
if (member != null) {
|
||||
//出场 不用判断直接出
|
||||
MemberEnterVenueLog memberEnterVenueLog = new MemberEnterVenueLog();
|
||||
memberEnterVenueLog.setOrderSn("");
|
||||
memberEnterVenueLog.setType(1);
|
||||
memberEnterVenueLog.setMemberId(member.getId());
|
||||
// memberEnterVenueLog.setVeneuType(device.getVenueType());
|
||||
// memberEnterVenueLog.setVenueId(device.getVenueId());
|
||||
memberEnterVenueLog.setPlatformId(member.getPlatformId());
|
||||
memberEnterVenueLogService.save(memberEnterVenueLog);
|
||||
logger.info("用户" + member.getNickname() + "出场");
|
||||
// MemberDto memberMessageDto = new MemberDto();
|
||||
// memberMessageDto.setAmount(member.getMoney());
|
||||
// memberMessageDto.setName(member.getNickname());
|
||||
// memberMessageDto.setAvatar(member.getAvatar());
|
||||
// memberMessageDto.setMobile(member.getMobile());
|
||||
// memberMessageDto.setPlaceName("");
|
||||
// memberMessageDto.setMessage("欢迎下次再来" + venue.getName());
|
||||
// memberMessageDto.setCode(2);
|
||||
// VenueMessage VenueMessage = new VenueMessage();
|
||||
// VenueMessage.setCmdId(Cmd.OPEN_DOOR.id);
|
||||
// VenueMessage.setDoor(2);
|
||||
// sendOpenMessage(VenueMessage, device.getId());
|
||||
// 校验完就可以出场了
|
||||
// sendMessage(memberMessageDto, device.getId());
|
||||
// venueService.addNumber(venue.getId(), -1, member.getId());
|
||||
// venue = venueService.findById(venue.getId());
|
||||
// sendNumberChange(venue.getNumber());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 进场逻辑
|
||||
* @param deviceName
|
||||
* @param venueId
|
||||
* @param memberId
|
||||
* @param venue
|
||||
*/
|
||||
@Override
|
||||
public void enterVenue(String deviceName, Integer venueId, Integer memberId, Venue venue) {
|
||||
Member member = memberService.findByMember(memberId);
|
||||
Channel channel = getCurrentChannel(deviceName, venueId);
|
||||
// 校验入场时间是否正常
|
||||
if (checkInterval(member,venueId)) {
|
||||
if(venueService.qrCodeEnterVenue(memberId,deviceName,venueId,venue)){
|
||||
// 可以进场
|
||||
scheduledExecutorService.schedule(() -> {
|
||||
ServerMessageUtils.INSTANCE.sendMsg(channel,new VenueMessage(MessageType.OPEN_DOOR,"OK"));
|
||||
}, 5, TimeUnit.SECONDS);
|
||||
} else {
|
||||
// 进场失败
|
||||
ServerMessageUtils.INSTANCE.sendMsg(channel,new VenueMessage(MessageType.FAILED, ErrorCode.NO_USE_CARD.getMsg()));
|
||||
}
|
||||
} else {
|
||||
logger.info(member == null ? "null" : member.getId() + "入场失败:连续入场");
|
||||
Config config = configService.findById(1);
|
||||
ServerMessageUtils.INSTANCE.sendMsg(channel,new VenueMessage(MessageType.OPEN_DOOR, MessageFormat.format(ErrorCode.CHECK_ENTER_INTERVAL.getMsg(),config.getValue())));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkInterval(Member member,Integer venueId){
|
||||
if (member == null || venueId == null) {
|
||||
return false;
|
||||
}else{
|
||||
//最后进场记录
|
||||
MemberEnterVenueLog enterVenueLog = memberEnterVenueLogService.findMemberLastLogNoType(member.getId(), venueId);
|
||||
if (enterVenueLog != null) {
|
||||
//有记录 查看 最后一次是否是出场
|
||||
if (true) {// TODO
|
||||
return true;
|
||||
} else {
|
||||
//是进场
|
||||
Date date = new Date();
|
||||
//本日连续进场次数
|
||||
int continuityEnterCount = memberEnterVenueLogService.countEnterByDate(member.getId(), venueId, date);
|
||||
logger.info("连续进场次数:" + continuityEnterCount);
|
||||
//距离上次入场差多少秒
|
||||
int differenceSeconds = (int) (date.getTime() - enterVenueLog.getCreatedTime().getTime()) / (1000);
|
||||
if (continuityEnterCount <= 0) {
|
||||
//没有连续进场 间隔5分钟
|
||||
Config config = configService.findById(1);
|
||||
if (differenceSeconds <= (Integer.parseInt(config.getValue()) * 60)) {
|
||||
//
|
||||
return false;
|
||||
}
|
||||
} else if (continuityEnterCount == 1) {
|
||||
//有过一次连续进场 间隔20分钟
|
||||
Config config = configService.findById(2);
|
||||
if (differenceSeconds <= (Integer.parseInt(config.getValue()) * 60)) {
|
||||
//小于20分钟 不允许入场
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
//当日超过两次连续入场 入场失败
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作连接
|
||||
*/
|
||||
/**
|
||||
* 缓存通道
|
||||
*/
|
||||
public void addLinks(String deviceName, Integer venueId, Channel channel) {
|
||||
String clientId = deviceName + NettyConstant.SPIT_WORD + venueId;
|
||||
links.put(clientId, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前通道
|
||||
*/
|
||||
public Channel getCurrentChannel(String deviceName, Integer venueId){
|
||||
String clientId = deviceName + NettyConstant.SPIT_WORD + venueId;
|
||||
return links.get(clientId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取通道
|
||||
*/
|
||||
public boolean contains(String deviceName, Integer venueId) {
|
||||
String clientId = deviceName + NettyConstant.SPIT_WORD + venueId + NettyConstant.SPIT_WORD;
|
||||
return links.containsKey(clientId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除通道
|
||||
*/
|
||||
public void removeChannelType(String deviceName, Integer venueId) {
|
||||
String clientId = deviceName + NettyConstant.SPIT_WORD + venueId ;
|
||||
links.remove(clientId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计目前有多少链接数
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Set<String> countConnection() {
|
||||
return links.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* 控制硬件,篮球馆的门禁灯光控制
|
||||
* @param number
|
||||
*/
|
||||
// public void sendNumberChange(Integer number) {
|
||||
// HttpHeaders headers = new HttpHeaders();
|
||||
// headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
||||
// MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
|
||||
// param.add("LingtekID", "5d14229fcb1f5c1a9046f429");
|
||||
// param.add("Number", number.toString());
|
||||
// HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(param, headers);
|
||||
// ResponseEntity<Result> result = restTemplate.exchange("http://lingtek.jalasmart.com/api/v1/lingtek/number", HttpMethod.PUT, request, Result.class);
|
||||
// logger.info("灯光结果" + JsonMapper.nonDefaultMapper().toJson(result));
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
package com.sv.netty.netty.service.impl;
|
||||
|
||||
import com.enums.EnterEnum;
|
||||
import com.sv.entity.Member;
|
||||
import com.sv.entity.MemberEnterVenueLog;
|
||||
import com.sv.entity.MemberMoneyLog;
|
||||
import com.sv.entity.Venue;
|
||||
import com.sv.mapper.BarcodeMapper;
|
||||
import com.sv.netty.config.*;
|
||||
import com.sv.netty.netty.service.MessageService;
|
||||
import com.sv.netty.utils.JsonUtils;
|
||||
import com.sv.netty.utils.MakeCode;
|
||||
import com.sv.netty.utils.ServerMessageUtils;
|
||||
import com.sv.service.api.MemberEnterVenueLogService;
|
||||
import com.sv.service.api.MemberMoneyLogService;
|
||||
import com.sv.service.api.MemberService;
|
||||
import com.sv.service.api.VenueService;
|
||||
import com.sv.service.oms.DeviceService;
|
||||
import com.ydd.framework.core.exception.ServiceException;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
/**
|
||||
* 消息实现类
|
||||
*
|
||||
* @Author peakren
|
||||
* @Date 08/05/2017 10:43 PM
|
||||
*/
|
||||
@Service("messageService")
|
||||
public class ServerMessageHandlerAdapter implements MessageService {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(ServerMessageHandlerAdapter.class);
|
||||
|
||||
/**
|
||||
* 存储设备通道类型
|
||||
* 此处存储客户端的channel 信息key 为 【deviceId + venueId】
|
||||
* value: 1Tcp 2WebSocket
|
||||
*/
|
||||
private ConcurrentMap<String, Channel> links = PlatformDependent.newConcurrentHashMap();
|
||||
|
||||
@Resource
|
||||
private MemberService memberService;
|
||||
|
||||
@Resource
|
||||
private VenueService venueService;
|
||||
|
||||
@Resource
|
||||
private DeviceService deviceService;
|
||||
|
||||
@Resource
|
||||
private MemberEnterVenueLogService memberEnterVenueLogService;
|
||||
|
||||
@Resource
|
||||
private MemberMoneyLogService memberMoneyLogService;
|
||||
|
||||
@Resource
|
||||
private BarcodeMapper barcodeMapper;
|
||||
|
||||
/**
|
||||
* 处理心跳信息,存储心跳信息
|
||||
* @param clientId
|
||||
* @param channel
|
||||
* @param heartBeat
|
||||
*/
|
||||
@Override
|
||||
public void online(String clientId, Channel channel, HeartBeat heartBeat) {
|
||||
logger.info("=========" + JsonUtils.encode(heartBeat) + clientId);
|
||||
// 处理心跳信息
|
||||
if (!contains(heartBeat.getDeviceName(),heartBeat.getVenueId())){
|
||||
// 此处存储客户端的channel 信息key 为 deviceId + venueId
|
||||
Venue thisVenue = venueService.findById(heartBeat.getVenueId());
|
||||
if (thisVenue == null ){
|
||||
logger.error("this client choose venue Error! venueId == " + heartBeat.getVenueId());
|
||||
} else {
|
||||
deviceService.online(heartBeat.getDeviceName(),heartBeat.getVenueId(),thisVenue.getType(),clientId);
|
||||
addLinks(heartBeat.getDeviceName(),heartBeat.getVenueId(),channel);
|
||||
// VenueMessage venueMessage = new VenueMessage(MessageType.LINK,"欢迎扫码进场!");
|
||||
// ServerMessageUtils.INSTANCE.sendMsg(channel,venueMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备下线
|
||||
* @param deviceName
|
||||
* @param venueId
|
||||
*/
|
||||
@Override
|
||||
public void Offline(String deviceName, Integer venueId) {
|
||||
if (deviceName != null && venueId != null){
|
||||
removeChannelType(deviceName,venueId);
|
||||
deviceService.offline(deviceName,venueId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 核销扫码出场逻辑
|
||||
* @param barcode
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public void outVenue(String barcode) {
|
||||
VenueBarCode venueBarCode = MakeCode.decodeCode(barcode);
|
||||
barcode = MakeCode.reWriteBarcode(barcode);
|
||||
Channel channel = getCurrentChannel(venueBarCode.getDeviceName(),venueBarCode.getVenueId());
|
||||
Member member = memberService.findByMember(venueBarCode.getMemberId());
|
||||
if (member != null) {
|
||||
MemberMoneyLog memberMoneyLog = memberMoneyLogService.selectLastLog(member.getId(), venueBarCode.getVenueId());
|
||||
MemberEnterVenueLog memberEnterVenueLog = new MemberEnterVenueLog();
|
||||
memberEnterVenueLog.setOrderSn(barcode);
|
||||
memberEnterVenueLog.setType(EnterEnum.OUT.getValue());
|
||||
memberEnterVenueLog.setMemberId(member.getId());
|
||||
memberEnterVenueLog.setPlatformId(member.getPlatformId() == null ? 1 : member.getPlatformId());
|
||||
memberEnterVenueLog.setVenueId(venueBarCode.getVenueId());
|
||||
if (memberMoneyLog != null) {
|
||||
memberEnterVenueLog.setPayType(memberMoneyLog.getPayType());
|
||||
}
|
||||
memberEnterVenueLogService.save(memberEnterVenueLog);
|
||||
logger.info("用户" + member.getNickname() + "出场");
|
||||
writeOffCode(barcode);
|
||||
ServerMessageUtils.INSTANCE.sendMsg(channel,new VenueMessage(MessageType.OUT_DOOR,"OK"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 核销扫码进场逻辑
|
||||
* @param barcode
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public void enterVenue(String barcode) {
|
||||
VenueBarCode venueBarCode = MakeCode.decodeCode(barcode);
|
||||
barcode = MakeCode.reWriteBarcode(barcode);
|
||||
Channel channel = getCurrentChannel(venueBarCode.getDeviceName(), venueBarCode.getVenueId());
|
||||
Member member = memberService.findByMember(venueBarCode.getMemberId());
|
||||
if (member != null) {
|
||||
MemberEnterVenueLog memberEnterVenueLog = new MemberEnterVenueLog();
|
||||
memberEnterVenueLog.setOrderSn(barcode);
|
||||
memberEnterVenueLog.setType(EnterEnum.ENTER.getValue());
|
||||
memberEnterVenueLog.setMemberId(member.getId());
|
||||
memberEnterVenueLog.setPlatformId(member.getPlatformId() == null ? 1 : member.getPlatformId());
|
||||
memberEnterVenueLog.setVenueId(venueBarCode.getVenueId());
|
||||
memberEnterVenueLogService.save(memberEnterVenueLog);
|
||||
writeOffCode(barcode);
|
||||
logger.info("用户" + member.getNickname() + "入场");
|
||||
ServerMessageUtils.INSTANCE.sendMsg(channel,new VenueMessage(MessageType.ENTER_DOOR,"OK"));
|
||||
}
|
||||
}
|
||||
|
||||
private void writeOffCode(String barcode) {
|
||||
barcodeMapper.writeOffCode(barcode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计目前有多少链接数
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Set<String> countConnection() {
|
||||
return links.keySet();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 测试客户端连接
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public void testLoad(String deviceName, Integer venueId) {
|
||||
Channel currentChannel = getCurrentChannel(deviceName, venueId);
|
||||
ServerMessageUtils.INSTANCE.sendMsg(currentChannel,new VenueMessage(MessageType.HB,"测试链接"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理员入场
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public void adminEnter(String deviceName, Integer venueId) {
|
||||
Channel channel = getCurrentChannel(deviceName, venueId);
|
||||
if (channel == null) {
|
||||
throw new ServiceException("设备离线!请检查连接");
|
||||
}
|
||||
logger.info("管理员入场");
|
||||
ServerMessageUtils.INSTANCE.sendMsg(channel,new VenueMessage(MessageType.ENTER_DOOR,"OK"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理员入场
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public void adminOut(String deviceName, Integer venueId) {
|
||||
Channel channel = getCurrentChannel(deviceName, venueId);
|
||||
if (channel == null) {
|
||||
throw new ServiceException("设备离线!请检查连接");
|
||||
}
|
||||
logger.info("管理员入场");
|
||||
ServerMessageUtils.INSTANCE.sendMsg(channel,new VenueMessage(MessageType.OUT_DOOR,"OK"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 控制硬件,篮球馆的门禁灯光控制
|
||||
* @param number
|
||||
*/
|
||||
// public void sendNumberChange(Integer number) {
|
||||
// HttpHeaders headers = new HttpHeaders();
|
||||
// headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
||||
// MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
|
||||
// param.add("LingtekID", "5d14229fcb1f5c1a9046f429");
|
||||
// param.add("Number", number.toString());
|
||||
// HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(param, headers);
|
||||
// ResponseEntity<Result> result = restTemplate.exchange("http://lingtek.jalasmart.com/api/v1/lingtek/number", HttpMethod.PUT, request, Result.class);
|
||||
// logger.info("灯光结果" + JsonMapper.nonDefaultMapper().toJson(result));
|
||||
// }
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 操作连接
|
||||
*/
|
||||
/**
|
||||
* 缓存通道
|
||||
*/
|
||||
public void addLinks(String deviceName, Integer venueId, Channel channel) {
|
||||
String clientId = deviceName + NettyConstant.SPIT_WORD + venueId;
|
||||
links.put(clientId, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前通道
|
||||
*/
|
||||
public Channel getCurrentChannel(String deviceName, Integer venueId){
|
||||
String clientId = deviceName + NettyConstant.SPIT_WORD + venueId;
|
||||
return links.get(clientId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否有该通道
|
||||
*/
|
||||
public boolean contains(String deviceName, Integer venueId) {
|
||||
String clientId = deviceName + NettyConstant.SPIT_WORD + venueId + NettyConstant.SPIT_WORD;
|
||||
return links.containsKey(clientId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除通道
|
||||
*/
|
||||
public void removeChannelType(String deviceName, Integer venueId) {
|
||||
String clientId = deviceName + NettyConstant.SPIT_WORD + venueId ;
|
||||
links.remove(clientId);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user