扫描二维码入场逻辑

This commit is contained in:
2023-09-05 09:27:00 +08:00
parent f0ef32ffc6
commit 52aa9659a2
41 changed files with 1562 additions and 492 deletions

View File

@@ -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;
}
}

View File

@@ -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,29 +18,33 @@ 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("设备离线!请检查连接");
}
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();
}

View File

@@ -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);
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);
}

View File

@@ -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);
}

View File

@@ -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));
// }
}

View File

@@ -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);
}
}

View File

@@ -0,0 +1,42 @@
package com.enums;
/**
* Enum - 入场标志
*
*/
public enum BarCodeStatusEnum {
INIT(0, "未核销"),
USED(1, "核销");
public Integer value;
public String name;
BarCodeStatusEnum(Integer value, String name) {
this.value = value;
this.name = name;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static BarCodeStatusEnum getByValue(Integer value) {
for (BarCodeStatusEnum type : BarCodeStatusEnum.values()) {
if (type.value.equals(value)) {
return type;
}
}
return null;
}
}

View File

@@ -5,7 +5,7 @@ package com.enums;
*
*/
public enum MoneyLogEnum {
JOIN(1, "进场"),
JOIN(1, "扫码订单"),
VIPCARD(2, "购买会员卡"),
BUY_LESSON(3, "购买课程"),
RECHARGE(4, "充值"),

View File

@@ -7,9 +7,9 @@ public class BarCodeResult implements Serializable {
private String barcode;
/**
* 0 - 成功 1 - 失败
* 返回的字符串,根据结果显示
*/
private String code;
private Integer flg;
private String msg;
@@ -21,12 +21,12 @@ public class BarCodeResult implements Serializable {
this.barcode = barcode;
}
public String getCode() {
return code;
public Integer getFlg() {
return flg;
}
public void setCode(String code) {
this.code = code;
public void setFlg(Integer flg) {
this.flg = flg;
}
public String getMsg() {

View File

@@ -0,0 +1,122 @@
package com.sv.entity;
import java.util.Date;
public class Barcode {
private Integer id;
private String barcode;
private Integer status;
private Integer memberId;
private Integer venueId;
private Integer enter;
private Integer createdId;
private Integer modifiedId;
private Date createdTime;
private Date modifiedTime;
public Barcode(Integer id, String barcode, Integer status, Integer memberId, Integer venueId, Integer enter, Integer createdId, Integer modifiedId, Date createdTime, Date modifiedTime) {
this.id = id;
this.barcode = barcode;
this.status = status;
this.memberId = memberId;
this.venueId = venueId;
this.enter = enter;
this.createdId = createdId;
this.modifiedId = modifiedId;
this.createdTime = createdTime;
this.modifiedTime = modifiedTime;
}
public Barcode() {
super();
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getBarcode() {
return barcode;
}
public void setBarcode(String barcode) {
this.barcode = barcode == null ? null : barcode.trim();
}
public Integer getMemberId() {
return memberId;
}
public void setMemberId(Integer memberId) {
this.memberId = memberId;
}
public Integer getVenueId() {
return venueId;
}
public void setVenueId(Integer venueId) {
this.venueId = venueId;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Integer getEnter() {
return enter;
}
public void setEnter(Integer enter) {
this.enter = enter;
}
public Integer getCreatedId() {
return createdId;
}
public void setCreatedId(Integer createdId) {
this.createdId = createdId;
}
public Integer getModifiedId() {
return modifiedId;
}
public void setModifiedId(Integer modifiedId) {
this.modifiedId = modifiedId;
}
public Date getCreatedTime() {
return createdTime;
}
public void setCreatedTime(Date createdTime) {
this.createdTime = createdTime;
}
public Date getModifiedTime() {
return modifiedTime;
}
public void setModifiedTime(Date modifiedTime) {
this.modifiedTime = modifiedTime;
}
}

View File

@@ -35,10 +35,6 @@ public class Device implements Serializable {
private Integer venueId;
private Integer venueType;
private Integer bindMember;
private Date bindTime;
/**
* 创建者编号
*/
@@ -244,20 +240,4 @@ public class Device implements Serializable {
public void setVenueType(Integer venueType) {
this.venueType = venueType;
}
public Integer getBindMember() {
return bindMember;
}
public void setBindMember(Integer bindMember) {
this.bindMember = bindMember;
}
public Date getBindTime() {
return bindTime;
}
public void setBindTime(Date bindTime) {
this.bindTime = bindTime;
}
}

View File

@@ -0,0 +1,44 @@
package com.sv.barcode;
import java.io.Serializable;
public class ClientConfig implements Serializable {
String serverIp;
String serverPort;
String clientSN;
String clientVid;
public String getServerIp() {
return serverIp;
}
public void setServerIp(String serverIp) {
this.serverIp = serverIp;
}
public String getServerPort() {
return serverPort;
}
public void setServerPort(String serverPort) {
this.serverPort = serverPort;
}
public String getClientSN() {
return clientSN;
}
public void setClientSN(String clientSN) {
this.clientSN = clientSN;
}
public String getClientVid() {
return clientVid;
}
public void setClientVid(String clientVid) {
this.clientVid = clientVid;
}
}

View File

@@ -0,0 +1,27 @@
package com.sv.barcode;
import javax.swing.*;
import java.awt.*;
public class ListenKeyFrame extends Thread{
Frame frame;
public void newFrame (int i) {
frame = new Frame("智慧云馆门禁" + i);
frame.setBounds(300,100,600,500);
frame.setLayout(new FlowLayout(FlowLayout.CENTER,5,200));//设计布局
JLabel label = new JLabel("请保持该界面被选中,否则将无法监听二维码扫描!");
frame.addKeyListener(new ScanBarCode());
frame.add(label);
frame.setVisible(true);
frame.setFocusable(true);
}
public void close() {
if (frame != null) {
frame.dispose();
}
}
}

View File

@@ -0,0 +1,38 @@
package com.sv.barcode;
import com.sv.netty.ClientThread;
import com.sv.netty.config.NettyConstant;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.LinkedList;
import java.util.List;
public class ScanBarCode extends KeyAdapter {
private List<Character> barcode = new LinkedList<>();
@Override
public void keyTyped(KeyEvent e) {
if (barcode.size() > 200) {
barcode.clear();
}
char keyChar = e.getKeyChar();
if (NettyConstant.BARCODE_END == keyChar) {
String barStr = "";
if (barcode.size() > 0 && barcode != null) {
for (Character character : barcode) {
barStr = barStr + character;
}
}
System.err.println(barStr);
ClientThread.getInstance().checkBarcode(barStr);
barcode.clear();
}
barcode.add(keyChar);
if (NettyConstant.BARCODE_BEGIN == keyChar) {
barcode.clear();
}
}
}

View File

@@ -0,0 +1,8 @@
package com.sv.intergration;
/**
* 对接场馆门禁
*/
public interface DoorService {
}

View File

@@ -1,4 +1,4 @@
package com.sv.service;
package com.sv.intergration;
import com.sv.netty.config.VenueMessage;
import org.slf4j.Logger;
@@ -34,8 +34,11 @@ public class MessageService {
*/
public void execute(VenueMessage message) {
switch (message.getMessageType()) {
case OPEN_DOOR:
openDoor();
case ENTER_DOOR:
enterDoor();
break;
case OUT_DOOR:
outDoor();
break;
default:
logger.info( "default");
@@ -45,7 +48,15 @@ public class MessageService {
/**
* 门禁开门
*/
public void openDoor() {
public void enterDoor() {
// 开门
logger.info("开门成功!!!");
}
/**
* 门禁开门
*/
public void outDoor() {
// 开门
logger.info("开门成功!!!");
}

View File

@@ -1,10 +1,8 @@
package com.sv.netty;
import com.sv.netty.config.HeartBeat;
import com.sv.intergration.MessageService;
import com.sv.netty.config.VenueMessage;
import com.sv.netty.utils.EncodeMsg;
import com.sv.netty.utils.JsonUtils;
import com.sv.service.MessageService;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
@@ -69,23 +67,12 @@ public class ClientHandler extends SimpleChannelInboundHandler<String> {
if (IdleStateEvent.class.isAssignableFrom(evt.getClass())) {
IdleStateEvent event = (IdleStateEvent) evt;
if (event.state() == IdleState.ALL_IDLE) {
ctx.write(EncodeMsg.INSTANCE.encode(getHbMessage()));
ctx.write(MessageHandler.sendHeartBeat());
ctx.flush();
}
}
}
/**
* 封装心跳请求包
* @throws Exception
*/
private HeartBeat getHbMessage() {
HeartBeat hb = new HeartBeat();
hb.setDeviceName("dsadasdasd");
hb.setVenueId(32);
return hb;
}
/**
* 处理异常
* @param ctx

View File

@@ -1,10 +1,12 @@
package com.sv.netty;
import com.sv.netty.config.NettyConstant;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.util.internal.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -36,7 +38,9 @@ public class ClientThread extends Thread{
if (instance == null) {
synchronized (ClientThread.class) {
if (instance == null) {
instance = new ClientThread("127.0.0.1", 56792);
String serverIp = System.getProperty(NettyConstant.VENUE_SERVER_IP);
String serverPort = System.getProperty(NettyConstant.VENUE_SERVER_PORT);
instance = new ClientThread(serverIp, Integer.parseInt(serverPort));
}
}
}
@@ -67,6 +71,23 @@ public class ClientThread extends Thread{
doConnect();
}
public void checkBarcode(String barcode) {
try {
if (future != null) {
Channel channel = future.channel();
if (channel != null) {
String sendCode = MessageHandler.checkBarcode(barcode);
if (StringUtil.isNullOrEmpty(sendCode)){
return;
}
channel.writeAndFlush(sendCode);
}
}
}catch (Exception e) {
logger.error("链接失败,发送二维码失败",e);
}
}
public void clearFuture(){
future = null;
}

View File

@@ -0,0 +1,42 @@
package com.sv.netty;
import com.sv.netty.config.*;
import com.sv.netty.utils.EncodeMsg;
import com.sv.netty.utils.JsonUtils;
import com.sv.netty.utils.MakeCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MessageHandler {
private static final Logger logger = LoggerFactory.getLogger(MessageHandler.class);
public static String sendHeartBeat() {
VenueMessage venueMessage = new VenueMessage();
venueMessage.setMessageType(MessageType.HB);
String clientSn = System.getProperty(NettyConstant.VENUE_CLIENT_SN);
String clientVid = System.getProperty(NettyConstant.VENUE_CLIENT_VID);
HeartBeat hb = new HeartBeat();
hb.setDeviceName(clientSn);
hb.setVenueId(Integer.parseInt(clientVid));
venueMessage.setMessage(JsonUtils.encode(hb));
return EncodeMsg.INSTANCE.encode(venueMessage);
}
/**
* 核销二维码
* @return
*/
public static String checkBarcode(String barcode) {
VenueBarCode venueBarCode = MakeCode.decodeCode(barcode);
if (venueBarCode == null) {
logger.error("二维码不合法" + barcode);
return null;
}
VenueMessage venueMessage = new VenueMessage();
venueMessage.setMessageType(MessageType.SCAN_CODE);
venueMessage.setMessage(barcode);
logger.info("核销二维码===" + barcode);
return EncodeMsg.INSTANCE.encode(venueMessage);
}
}

View File

@@ -1,6 +1,15 @@
package com.sv.service;
import com.sv.barcode.ClientConfig;
import com.sv.barcode.ListenKeyFrame;
import com.sv.netty.ClientThread;
import com.sv.netty.config.NettyConstant;
import com.sv.netty.utils.JsonUtils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
/**
* 启动socker和websocket服务
@@ -10,9 +19,41 @@ import com.sv.netty.ClientThread;
*/
public class ClientService {
public static void main(String[] args) {
public static void main(String[] args) throws IOException, InterruptedException {
File file = new File("/home/venue/client/venue.conf");
// File file = new File("/Users/limqhz/home/venue/client/venue.conf");
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String line = bufferedReader.readLine();
if (line != null) {
ClientConfig decode = JsonUtils.decode(line, ClientConfig.class);
System.setProperty(NettyConstant.VENUE_SERVER_IP,decode.getServerIp());
System.setProperty(NettyConstant.VENUE_SERVER_PORT,decode.getServerPort());
System.setProperty(NettyConstant.VENUE_CLIENT_SN,decode.getClientSN());
System.setProperty(NettyConstant.VENUE_CLIENT_VID,decode.getClientVid());
}
bufferedReader.close();
fileReader.close();
ClientThread instance = ClientThread.getInstance();
instance.start();
Thread.sleep(3000);
ListenKeyFrame listenKeyFrame = new ListenKeyFrame();
listenKeyFrame.newFrame(1);
Thread.sleep(3000);
listenKeyFrame.close();
ListenKeyFrame listenKeyFrame1 = new ListenKeyFrame();
listenKeyFrame1.newFrame(2);
Thread.sleep(3000);
listenKeyFrame1.close();
ListenKeyFrame listenKeyFrame2 = new ListenKeyFrame();
listenKeyFrame2.newFrame(3);
Thread.sleep(3000);
listenKeyFrame2.close();
ListenKeyFrame listenKeyFrame3 = new ListenKeyFrame();
listenKeyFrame3.newFrame(4);
}
}

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF8"?>
<configuration>
<jmxConfigurator />
<property name="LOG_HOME" value="./home/logs/netty_log"/>
<property name="LOG_HOME" value="/home/venue/logs/netty_log"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">

View File

@@ -1,9 +1,10 @@
package com.sv.netty.config;
public enum MessageType {
LINK("连接"),
OPEN_DOOR("开门"),
FAILED("开门校验失败");
HB("心跳"),
SCAN_CODE("扫码"),
ENTER_DOOR("进门"),
OUT_DOOR("出门");
private String message;
MessageType(String message) {

View File

@@ -3,14 +3,23 @@ package com.sv.netty.config;
import io.netty.util.AttributeKey;
public interface NettyConstant {
String SERVER_IP = "120.27.209.4";
Integer SERVER_PORT = 56791;
String VENUE_SERVER_IP = "VENUE_SERVER_IP";
String VENUE_SERVER_PORT = "VENUE_SERVER_PORT";
String VENUE_CLIENT_SN = "VENUE_CLIENT_SN";
String VENUE_CLIENT_VID = "VENUE_CLIENT_VID";
/**
* session中存储终端发送的额外参数
*/
AttributeKey<ChannelParam> CHANNEL_PARAM = AttributeKey.newInstance("CHANNEL_PARAM");
String SPIT_WORD = "#";
/**
* 条形码
*/
String SPIT_WORD = "&&&";
char BARCODE_BEGIN = '@';
char BARCODE_END = '#';
}

View File

@@ -0,0 +1,46 @@
package com.sv.netty.config;
import java.io.Serializable;
public class VenueBarCode implements Serializable {
private Integer venueId;
private Integer memberId;
private String deviceName;
private Integer direction;
public Integer getVenueId() {
return venueId;
}
public void setVenueId(Integer venueId) {
this.venueId = venueId;
}
public Integer getMemberId() {
return memberId;
}
public void setMemberId(Integer memberId) {
this.memberId = memberId;
}
public String getDeviceName() {
return deviceName;
}
public void setDeviceName(String deviceName) {
this.deviceName = deviceName;
}
public Integer getDirection() {
return direction;
}
public void setDirection(Integer direction) {
this.direction = direction;
}
}

View File

@@ -0,0 +1,60 @@
package com.sv.netty.utils;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* @author: wuyou
* @create: 2019-05-09 14:18
**/
public class AesUtil {
public static final String SECRET_KEY = "a69i3z8b516gd370";
/**
* Encrypt string.
*
* @param sSrc the s src
* @return the string
*/
public static String encrypt(String sSrc) {
try {
if (sSrc == null){
return null;
}
byte[] raw = SECRET_KEY.getBytes();
SecretKeySpec sKeySpec = new SecretKeySpec(raw, "AES");
// "算法/模式/补码方式"
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// 使用CBC模式需要一个向量iv可增加加密算法的强度
IvParameterSpec iv = new IvParameterSpec("0102030405060708".getBytes());
cipher.init(Cipher.ENCRYPT_MODE, sKeySpec, iv);
byte[] encrypted = cipher.doFinal(sSrc.getBytes());
// 此处使用BASE64做转码功能同时能起到2次加密的作用。
return Base64.encodeS(encrypted);
} catch (Throwable e) {
return null;
}
}
/**
* Decrypt string.
*
* @param sSrc the s src
* @return the string
*/
public static String decrypt(String sSrc) {
try {
byte[] raw = SECRET_KEY.getBytes("ASCII");
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec("0102030405060708".getBytes());
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
// 先用base64解密
byte[] encrypted1 = Base64.decode(sSrc);
byte[] original = cipher.doFinal(encrypted1);
return new String(original);
} catch (Throwable th) {
return null;
}
}
}

View File

@@ -0,0 +1,285 @@
package com.sv.netty.utils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
/**
* @author: wuyou
* @create: 2019-05-09 14:19
**/
public class Base64 {
private static final byte[] ENCODING_TABLE = {(byte) 'A', (byte) 'B',
(byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G',
(byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L',
(byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P', (byte) 'Q',
(byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', (byte) 'V',
(byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', (byte) 'a',
(byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f',
(byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k',
(byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o', (byte) 'p',
(byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u',
(byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z',
(byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4',
(byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9',
(byte) '+', (byte) '/'};
private static final byte[] DECODING_TABLE;
static {
DECODING_TABLE = new byte[128];
for (int i = 0; i < 128; i++) {
DECODING_TABLE[i] = (byte) -1;
}
for (int i = 'A'; i <= 'Z'; i++) {
DECODING_TABLE[i] = (byte) (i - 'A');
}
for (int i = 'a'; i <= 'z'; i++) {
DECODING_TABLE[i] = (byte) (i - 'a' + 26);
}
for (int i = '0'; i <= '9'; i++) {
DECODING_TABLE[i] = (byte) (i - '0' + 52);
}
DECODING_TABLE['+'] = 62;
DECODING_TABLE['/'] = 63;
}
public static String encodeS(byte[] data) {
return new String(encode(data));
}
public static byte[] encode(byte[] data) {
byte[] bytes;
int modulus = data.length % 3;
if (modulus == 0) {
bytes = new byte[(4 * data.length) / 3];
} else {
bytes = new byte[4 * ((data.length / 3) + 1)];
}
int dataLength = (data.length - modulus);
int a1;
int a2;
int a3;
for (int i = 0, j = 0; i < dataLength; i += 3, j += 4) {
a1 = data[i] & 0xff;
a2 = data[i + 1] & 0xff;
a3 = data[i + 2] & 0xff;
bytes[j] = ENCODING_TABLE[(a1 >>> 2) & 0x3f];
bytes[j + 1] = ENCODING_TABLE[((a1 << 4) | (a2 >>> 4)) & 0x3f];
bytes[j + 2] = ENCODING_TABLE[((a2 << 2) | (a3 >>> 6)) & 0x3f];
bytes[j + 3] = ENCODING_TABLE[a3 & 0x3f];
}
int b1;
int b2;
int b3;
int d1;
int d2;
switch (modulus) {
//nothing left to do
case 0:
break;
case 1:
d1 = data[data.length - 1] & 0xff;
b1 = (d1 >>> 2) & 0x3f;
b2 = (d1 << 4) & 0x3f;
bytes[bytes.length - 4] = ENCODING_TABLE[b1];
bytes[bytes.length - 3] = ENCODING_TABLE[b2];
bytes[bytes.length - 2] = (byte) '=';
bytes[bytes.length - 1] = (byte) '=';
break;
case 2:
d1 = data[data.length - 2] & 0xff;
d2 = data[data.length - 1] & 0xff;
b1 = (d1 >>> 2) & 0x3f;
b2 = ((d1 << 4) | (d2 >>> 4)) & 0x3f;
b3 = (d2 << 2) & 0x3f;
bytes[bytes.length - 4] = ENCODING_TABLE[b1];
bytes[bytes.length - 3] = ENCODING_TABLE[b2];
bytes[bytes.length - 2] = ENCODING_TABLE[b3];
bytes[bytes.length - 1] = (byte) '=';
break;
default:
break;
}
return bytes;
}
public static byte[] decode(byte[] data) {
byte[] bytes;
byte b1;
byte b2;
byte b3;
byte b4;
data = discardNonBase64Bytes(data);
if (data[data.length - 2] == '=') {
bytes = new byte[(((data.length / 4) - 1) * 3) + 1];
} else if (data[data.length - 1] == '=') {
bytes = new byte[(((data.length / 4) - 1) * 3) + 2];
} else {
bytes = new byte[((data.length / 4) * 3)];
}
for (int i = 0, j = 0; i < (data.length - 4); i += 4, j += 3) {
b1 = DECODING_TABLE[data[i]];
b2 = DECODING_TABLE[data[i + 1]];
b3 = DECODING_TABLE[data[i + 2]];
b4 = DECODING_TABLE[data[i + 3]];
bytes[j] = (byte) ((b1 << 2) | (b2 >> 4));
bytes[j + 1] = (byte) ((b2 << 4) | (b3 >> 2));
bytes[j + 2] = (byte) ((b3 << 6) | b4);
}
if (data[data.length - 2] == '=') {
b1 = DECODING_TABLE[data[data.length - 4]];
b2 = DECODING_TABLE[data[data.length - 3]];
bytes[bytes.length - 1] = (byte) ((b1 << 2) | (b2 >> 4));
} else if (data[data.length - 1] == '=') {
b1 = DECODING_TABLE[data[data.length - 4]];
b2 = DECODING_TABLE[data[data.length - 3]];
b3 = DECODING_TABLE[data[data.length - 2]];
bytes[bytes.length - 2] = (byte) ((b1 << 2) | (b2 >> 4));
bytes[bytes.length - 1] = (byte) ((b2 << 4) | (b3 >> 2));
} else {
b1 = DECODING_TABLE[data[data.length - 4]];
b2 = DECODING_TABLE[data[data.length - 3]];
b3 = DECODING_TABLE[data[data.length - 2]];
b4 = DECODING_TABLE[data[data.length - 1]];
bytes[bytes.length - 3] = (byte) ((b1 << 2) | (b2 >> 4));
bytes[bytes.length - 2] = (byte) ((b2 << 4) | (b3 >> 2));
bytes[bytes.length - 1] = (byte) ((b3 << 6) | b4);
}
return bytes;
}
public static byte[] decode(String data) {
byte[] bytes;
byte b1;
byte b2;
byte b3;
byte b4;
data = discardNonBase64Chars(data);
if (data.charAt(data.length() - 2) == '=') {
bytes = new byte[(((data.length() / 4) - 1) * 3) + 1];
} else if (data.charAt(data.length() - 1) == '=') {
bytes = new byte[(((data.length() / 4) - 1) * 3) + 2];
} else {
bytes = new byte[((data.length() / 4) * 3)];
}
for (int i = 0, j = 0; i < (data.length() - 4); i += 4, j += 3) {
b1 = DECODING_TABLE[data.charAt(i)];
b2 = DECODING_TABLE[data.charAt(i + 1)];
b3 = DECODING_TABLE[data.charAt(i + 2)];
b4 = DECODING_TABLE[data.charAt(i + 3)];
bytes[j] = (byte) ((b1 << 2) | (b2 >> 4));
bytes[j + 1] = (byte) ((b2 << 4) | (b3 >> 2));
bytes[j + 2] = (byte) ((b3 << 6) | b4);
}
if (data.charAt(data.length() - 2) == '=') {
b1 = DECODING_TABLE[data.charAt(data.length() - 4)];
b2 = DECODING_TABLE[data.charAt(data.length() - 3)];
bytes[bytes.length - 1] = (byte) ((b1 << 2) | (b2 >> 4));
} else if (data.charAt(data.length() - 1) == '=') {
b1 = DECODING_TABLE[data.charAt(data.length() - 4)];
b2 = DECODING_TABLE[data.charAt(data.length() - 3)];
b3 = DECODING_TABLE[data.charAt(data.length() - 2)];
bytes[bytes.length - 2] = (byte) ((b1 << 2) | (b2 >> 4));
bytes[bytes.length - 1] = (byte) ((b2 << 4) | (b3 >> 2));
} else {
b1 = DECODING_TABLE[data.charAt(data.length() - 4)];
b2 = DECODING_TABLE[data.charAt(data.length() - 3)];
b3 = DECODING_TABLE[data.charAt(data.length() - 2)];
b4 = DECODING_TABLE[data.charAt(data.length() - 1)];
bytes[bytes.length - 3] = (byte) ((b1 << 2) | (b2 >> 4));
bytes[bytes.length - 2] = (byte) ((b2 << 4) | (b3 >> 2));
bytes[bytes.length - 1] = (byte) ((b3 << 6) | b4);
}
return bytes;
}
private static byte[] discardNonBase64Bytes(byte[] data) {
byte[] temp = new byte[data.length];
int bytesCopied = 0;
for (int i = 0; i < data.length; i++) {
if (isValidBase64Byte(data[i])) {
temp[bytesCopied++] = data[i];
}
}
byte[] newData = new byte[bytesCopied];
System.arraycopy(temp, 0, newData, 0, bytesCopied);
return newData;
}
private static String discardNonBase64Chars(String data) {
StringBuffer sb = new StringBuffer();
int length = data.length();
for (int i = 0; i < length; i++) {
if (isValidBase64Byte((byte) (data.charAt(i)))) {
sb.append(data.charAt(i));
}
}
return sb.toString();
}
private static boolean isValidBase64Byte(byte b) {
if (b == '=') {
return true;
} else if ((b < 0) || (b >= 128)) {
return false;
} else if (DECODING_TABLE[b] == -1) {
return false;
}
return true;
}
public static byte[] compressBytes(byte input[]) {
int cachesize = 1024;
Deflater compresser = new Deflater();
compresser.reset();
compresser.setInput(input);
compresser.finish();
byte output[] = new byte[0];
ByteArrayOutputStream o = new ByteArrayOutputStream(input.length);
try {
byte[] buf = new byte[cachesize];
int got;
while (!compresser.finished()) {
got = compresser.deflate(buf);
o.write(buf, 0, got);
}
output = o.toByteArray();
} finally {
try {
o.close();
} catch (IOException e) {
}
}
return output;
}
public static byte[] decompressBytes(byte input[]) {
int cachesize = 1024;
Inflater decompresser = new Inflater();
byte output[] = new byte[0];
decompresser.reset();
decompresser.setInput(input);
ByteArrayOutputStream o = new ByteArrayOutputStream(input.length);
try {
byte[] buf = new byte[cachesize];
int got;
while (!decompresser.finished()) {
got = decompresser.inflate(buf);
o.write(buf, 0, got);
}
output = o.toByteArray();
} catch (Exception e) {
} finally {
try {
o.close();
} catch (IOException e) {
}
}
return output;
}
}

View File

@@ -0,0 +1,46 @@
package com.sv.netty.utils;
import com.sv.netty.config.NettyConstant;
import com.sv.netty.config.VenueBarCode;
public class MakeCode {
/**
* 生成二维码
* @return
*/
public static String makeCode (Integer venueId, Integer memberId, String deviceName, String direction) {
String information = memberId + NettyConstant.SPIT_WORD + venueId + NettyConstant.SPIT_WORD + deviceName + NettyConstant.SPIT_WORD + direction;
return NettyConstant.BARCODE_BEGIN + AesUtil.encrypt(information) + NettyConstant.BARCODE_END;
}
/**
* 解析二维码
*/
public static VenueBarCode decodeCode (String barcode) {
VenueBarCode venueBarCode = null;
String decrypt = AesUtil.decrypt(barcode);
String [] list = new String[0];
if (decrypt!=null && decrypt.contains(NettyConstant.SPIT_WORD)){
list = decrypt.split(NettyConstant.SPIT_WORD);
}
if (list != null && list.length == 4) {
venueBarCode = new VenueBarCode();
venueBarCode.setMemberId(Integer.parseInt(list[0]));
venueBarCode.setVenueId(Integer.parseInt(list[1]));
venueBarCode.setDeviceName(list[2]);
venueBarCode.setDirection(Integer.parseInt(list[3]));
} else {
return null;
}
return venueBarCode;
}
/**
* 还原二维码
*/
public static String reWriteBarcode(String barcode) {
return NettyConstant.BARCODE_BEGIN + barcode + NettyConstant.BARCODE_END;
}
}

View File

@@ -1,4 +1,5 @@
package com.sv.oms.controller;
import com.enums.EnterEnum;
import com.sv.service.oms.DeviceService;
import com.ydd.framework.core.common.Pagination;
import com.ydd.framework.core.common.dto.ResponseDTO;
@@ -72,4 +73,26 @@ public class DeviceController extends OmsController {
return ResponseDTO.ok("开始连接,请等待连接完成");
}
/**
* 重新连接
* @param deviceId
* @return
*/
@RequestMapping("/device/admin/enter/{id}")
public ResponseDTO adminEnter(@PathVariable("id") Integer deviceId){
deviceService.adminOperate(deviceId,EnterEnum.ENTER);
return ResponseDTO.ok("入场开门成功!");
}
/**
* 重新连接
* @param deviceId
* @return
*/
@RequestMapping("/device/admin/out/{id}")
public ResponseDTO adminOut(@PathVariable("id") Integer deviceId){
deviceService.adminOperate(deviceId, EnterEnum.OUT);
return ResponseDTO.ok("出场开门成功!");
}
}

View File

@@ -0,0 +1,26 @@
package com.sv.mapper;
import com.sv.annotation.NoPlatform;
import com.sv.entity.Barcode;
import org.apache.ibatis.annotations.Param;
public interface BarcodeMapper {
int deleteByPrimaryKey(Integer id);
@NoPlatform
int insert(Barcode record);
int insertSelective(Barcode record);
Barcode selectByPrimaryKey(Integer id);
int updateByPrimaryKeySelective(Barcode record);
int updateByPrimaryKey(Barcode record);
@NoPlatform
void writeOffCode(@Param("barcode") String barcode);
@NoPlatform
Barcode findBarcode(@Param("venueId") Integer venueId,@Param("memberId") Integer memberId);
}

View File

@@ -1,5 +1,6 @@
package com.sv.mapper;
import com.common.DeviceDTO;
import com.sv.annotation.NoPlatform;
import com.sv.entity.Device;
import org.apache.ibatis.annotations.Param;
@@ -50,6 +51,7 @@ public interface DeviceMapper {
* @param id 编号
* @return 门禁设备
*/
@NoPlatform
Device findById(Integer id);
/**
@@ -78,11 +80,11 @@ public interface DeviceMapper {
/**
* 根据记录找设备
* @param deviceName
* @param venueId
* @return
*/
Device findByDevice(@Param("deviceName") String deviceName,@Param("venueId") Integer venueId);
@NoPlatform
Device findByDevice(@Param("venueId") Integer venueId);
/**
* 设备绑定正在扫码的用户

View File

@@ -71,4 +71,6 @@ public interface MemberMoneyLogMapper {
* api 查询用户账单
*/
List<MemberMoneyLogDTO> findAllBill(Integer memberId);
MemberMoneyLog selectLastLog(@Param("memberId")Integer memberId, @Param("venueId")Integer venueId);
}

View File

@@ -23,6 +23,7 @@ import javax.annotation.Resource;
*/
@Service
@Transactional(readOnly = true)
@Deprecated
public class MemberFaceInfoService extends BaseServiceImpl {
private final Logger logger = LoggerFactory.getLogger(MemberFaceInfoService.class);

View File

@@ -132,5 +132,12 @@ public class MemberMoneyLogService extends MemberMoney {
public void insert(MemberMoneyLog memberMoneyLog){
memberMoneyLogMapper.insert(memberMoneyLog);
}
/**
* 插入
*/
public MemberMoneyLog selectLastLog(Integer memberId,Integer venueId){
return memberMoneyLogMapper.selectLastLog(memberId,venueId);
}
}

View File

@@ -251,6 +251,7 @@ public class OrderService extends BaseServiceImpl {
* @param memberId
* @return
*/
@Deprecated
public String createEnterVenueOrder(Venue venue, Integer memberId,PayTypeEnum payTypeEnum,BigDecimal price){
//创建订单
Order order = new Order();

View File

@@ -11,7 +11,6 @@ import com.sv.exception.api.ExceptionCodeTemplate;
import com.sv.mapper.VenueMapper;
import com.sv.service.api.util.DateUtilCard;
import com.sv.service.api.util.GeoHashUtils;
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;
@@ -54,11 +53,6 @@ public class VenueService extends BaseServiceImpl {
@Resource
private MemberEnterVenueLogService memberEnterVenueLogService;
@Resource(name = "OrderServiceApi")
private OrderService orderService;
@Resource
private DeviceService deviceService;
@Resource
private MemberMoneyLogService memberMoneyLogService;
@Resource
@@ -120,10 +114,15 @@ public class VenueService extends BaseServiceImpl {
*/
public VenueDTO findByVenueId(Integer id,Integer memberId) {
VenueDTO getVenue = venueMapper.findByVenueId(id);
if (getVenue != null) {
getVenue.setEnterFlag(EnterEnum.OUT.getValue());
if (VenueTypeEnum.BASKETBALL.getValue().equals(getVenue.getType())){
MemberEnterVenueLog memberLastLog = memberEnterVenueLogService.findMemberLastLog(memberId, id);
if (memberLastLog != null) {
getVenue.setEnterFlag(memberLastLog.getType());
}
}
}
return getVenue;
}
@@ -206,8 +205,8 @@ public class VenueService extends BaseServiceImpl {
* api 接口
* 我要进场
*/
public Integer join(Integer memberId, Integer venueId) {
public BarCodeResult join(Integer memberId, Integer venueId) {
BarCodeResult barCodeResult = new BarCodeResult();
Integer flag = 0;
// 判断用户是否登录
if (memberId == null) {
@@ -215,17 +214,8 @@ public class VenueService extends BaseServiceImpl {
}
//参数校验
ValidationUtils.assertNotNull(venueId);
/*// 1.判断用户有没有人脸识别的图像,根据用户ID查找一个用户只能有一条
MemberFaceInfo memberFaceInfo = memberFaceInfoService.findByMemberId(memberId);
if (memberFaceInfo == null) {
flag = 1;
return flag;
}*/
// 1.判断用户有没有该馆的会员卡(有效期内,如果有免费卡和别的卡,优先使用别的卡),有不判断余额
List<MemberCard> memberCards = memberCardService.findByMemberId(venueId, memberId);
// 2. 查询该场馆需要的费用,并比较用户余额是否足够
// 查询当前时间内,场馆对应的价格
String time = DateUtilCard.nowTime().toString();
@@ -233,23 +223,20 @@ public class VenueService extends BaseServiceImpl {
if (venuePrice == null) {
throw new ServiceException(ExceptionCodeTemplate.VENUE_ERROR);
}
Venue venue = venueMapper.findById(venueId);
if (memberCards.size() == 0) {
Member member = memberService.findById(memberId);
if (member.getMoney().compareTo(venuePrice.getPrice()) == -1) {
flag = 2;
return flag;
}
}
barCodeResult.setFlg(flag);
// 3.判断用户有没有人脸识别的图像,根据用户ID查找一个用户只能有一条
// MemberFaceInfo memberFaceInfo = memberFaceInfoService.findByMemberId(memberId);
// if (memberFaceInfo == null) {
// flag = 1;
// return flag;
// }
return flag;
return barCodeResult;
}
/**
@@ -260,7 +247,7 @@ public class VenueService extends BaseServiceImpl {
*/
public BarCodeResult out(Integer memberId, Integer venueId) {
BarCodeResult result = new BarCodeResult();
result.setCode("0");
result.setFlg(0);
// 判断用户是否登录
if (memberId == null) {
throw new ServiceException(com.ydd.framework.core.exception.ExceptionCodeTemplate.NEED_LOGIN);
@@ -268,17 +255,10 @@ public class VenueService extends BaseServiceImpl {
//参数校验
ValidationUtils.assertNotNull(venueId);
Venue venue = venueMapper.findById(venueId);
synchronized (("enter" + memberId).intern()) {
synchronized (("scancode" + memberId).intern()) {
// 查询当前时间内,场馆对应的价格(健身房没有价格)
Member member = memberService.findByMember(memberId);
memberService.verify(member);
// 记录用户进场记录
MemberEnterVenueLog log = new MemberEnterVenueLog();
log.setMemberId(member.getId());
log.setVeneuType(venue.getType());
log.setVenueId(venue.getId());
log.setPlatformId(member.getPlatformId());
log.setType(0);
//进场之前 查看是否有会员卡
List<MemberCard> cards = memberCardService.findByMemberId(venue.getId(), member.getId());
if (cards.size() > 0) {
@@ -309,24 +289,18 @@ public class VenueService extends BaseServiceImpl {
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, 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);
// 如果是单次卡,清除单次卡
if (VipTypeEnum.ONCECARD.value.equals(useCard.getCardType())
|| VipTypeEnum.PUB_ONCECARD.value.equals(useCard.getCardType())){
memberCardService.delete(useCard.getId());
}
result.setBarcode("test123456");
}else {
//查无可用会员卡
logger.info("用户" + member.getNickname() + "您好!请先购买会员卡再进场");
result.setCode("1");
result.setFlg(1);
result.setMsg("未查询到会员卡,请先购买");
}
}else {
@@ -335,15 +309,12 @@ public class VenueService extends BaseServiceImpl {
VenuePrice venuePrice = venuePriceService.findPrice(venueId, time);
if (memberService.isMoneyEnough(member.getId(), venuePrice.getPrice())) {
logger.info("用户" + member.getNickname() + "使用余额进场");
String orderSn = orderService.createEnterVenueOrder(venue, member.getId(), PayTypeEnum.BALANCE, venuePrice.getPrice());
log.setOrderSn(orderSn);
log.setPayType(EnterVenuePayTypeEnum.WEI_XIN.value);
memberEnterVenueLogService.save(log);
result.setBarcode("test123456");
createMemberMoneyLog(MoneyLogEnum.JOIN.value, venuePrice.getPrice(), member.getId(), member.getPlatformId(), PayTypeEnum.BALANCE.value, null,
venue.getId(), venue.getType());
} else {
//余额不足
logger.error("用户" + member.getNickname() + "余额不足进场失败");
result.setCode("1");
result.setFlg(1);
result.setMsg("余额不足,请先充值");
}
}
@@ -398,32 +369,11 @@ public class VenueService extends BaseServiceImpl {
return StringUtils.isNotBlank(longitude) && StringUtils.isNotBlank(latitude);
}
/**
* 二维码入场-判断是否成功入场
*
* @return 0成功 -1失败
*/
@Transactional
public synchronized boolean qrCodeEnterVenue(Integer memberId, String deviceName,Integer venueId,Venue venue) {
return false;
}
// 记录使用会员卡入场记录
// 记录入场记录
@Transactional
public void createMemberMoneyLog(Integer type, BigDecimal price, Integer memberId, Integer platformId, Integer payType, String cardType,
Integer venueId, Integer venueType) {
MemberMoneyLog memberMoneyLog = new MemberMoneyLog();
memberMoneyLog.setType(type);
memberMoneyLog.setMoney(price.negate());
memberMoneyLog.setMemberId(memberId);
memberMoneyLog.setPlatformId(platformId);
memberMoneyLog.setPayType(payType);
memberMoneyLog.setCardType(cardType);
memberMoneyLog.setVenueId(venueId);
memberMoneyLog.setVenueType(venueType);
// memberMoneyLog.setLessonId(lessonId);
memberMoneyLogService.insert(memberMoneyLog);
memberMoneyLogService.create(memberId,platformId == null ? 1 : platformId,type,price.negate(),payType,cardType,venueId,venueType,null);
}
@Transactional(rollbackFor = Exception.class)

View File

@@ -2,6 +2,7 @@ package com.sv.service.oms;
import com.common.DeviceDTO;
import com.enums.DeviceStatusEnum;
import com.enums.EnterEnum;
import com.github.pagehelper.PageHelper;
import com.sv.entity.Device;
import com.sv.exception.oms.OmsException;
@@ -20,8 +21,6 @@ import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
/**
@@ -170,12 +169,13 @@ public class DeviceService extends BaseServiceImpl {
deviceMapper.update(device);
}
@Deprecated
public void reconnect(Integer deviceId){
try {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(null,headers);
ResponseDTO responseDTO = restTemplate.postForObject("http://127.0.0.1:8000/device/reconnect/"+deviceId, request, ResponseDTO.class);
ResponseDTO responseDTO = restTemplate.postForObject("http://127.0.0.1:8093/device/reconnect/"+deviceId, request, ResponseDTO.class);
Integer code = (Integer) responseDTO.get(ResponseDTO.ERR_CODE);
if(0 != code){
throw new OmsException("重启失败!");
@@ -183,15 +183,35 @@ public class DeviceService extends BaseServiceImpl {
}catch (Exception e){
throw new OmsException("连接失败!");
}
}
public void adminOperate(Integer deviceId,EnterEnum enterEnum){
try {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(null,headers);
ResponseDTO responseDTO = null;
if (EnterEnum.ENTER.equals(enterEnum)){
responseDTO = restTemplate.postForObject("http://127.0.0.1:8093/admin/enter/"+deviceId, request, ResponseDTO.class);
}else {
responseDTO = restTemplate.postForObject("http://127.0.0.1:8093/admin/out/"+deviceId, request, ResponseDTO.class);
}
Integer code = (Integer) responseDTO.get(ResponseDTO.ERR_CODE);
if(0 != code){
throw new OmsException("开门失败,设备离线或者门禁异常!");
}
}catch (Exception e){
logger.error("设备离线或者门禁异常",e);
throw new OmsException("开门失败,设备离线或者门禁异常!");
}
}
/**
* find by DeviceName
*/
public Device findByDevice(String deviceName, Integer venueId){
return deviceMapper.findByDevice(deviceName,venueId);
public Device findByDevice(Integer venueId){
return deviceMapper.findByDevice(venueId);
}
}

View File

@@ -0,0 +1,171 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sv.mapper.BarcodeMapper" >
<resultMap id="BaseResultMap" type="com.sv.entity.Barcode" >
<constructor >
<idArg column="id" jdbcType="INTEGER" javaType="java.lang.Integer" />
<arg column="barcode" jdbcType="VARCHAR" javaType="java.lang.String" />
<arg column="status" jdbcType="INTEGER" javaType="java.lang.Integer" />
<arg column="member_id" jdbcType="INTEGER" javaType="java.lang.Integer" />
<arg column="venue_id" jdbcType="INTEGER" javaType="java.lang.Integer" />
<arg column="enter" jdbcType="INTEGER" javaType="java.lang.Integer" />
<arg column="created_id" jdbcType="INTEGER" javaType="java.lang.Integer" />
<arg column="modified_id" jdbcType="INTEGER" javaType="java.lang.Integer" />
<arg column="created_time" jdbcType="TIMESTAMP" javaType="java.util.Date" />
<arg column="modified_time" jdbcType="TIMESTAMP" javaType="java.util.Date" />
</constructor>
</resultMap>
<sql id="Base_Column_List" >
id, barcode, status, member_id, venue_id, enter, created_id, modified_id, created_time,
modified_time
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
select
<include refid="Base_Column_List" />
from sv_barcode
where id = #{id,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
delete from sv_barcode
where id = #{id,jdbcType=INTEGER}
</delete>
<insert id="insert" parameterType="com.sv.entity.Barcode" >
insert into sv_barcode (id, barcode, status,
member_id, venue_id, enter,
created_id, modified_id, created_time,
modified_time)
values (#{id,jdbcType=INTEGER}, #{barcode,jdbcType=VARCHAR}, #{status,jdbcType=INTEGER},
#{memberId,jdbcType=INTEGER}, #{venueId,jdbcType=INTEGER}, #{enter,jdbcType=INTEGER},
#{createdId,jdbcType=INTEGER}, #{modifiedId,jdbcType=INTEGER}, #{createdTime,jdbcType=TIMESTAMP},
#{modifiedTime,jdbcType=TIMESTAMP})
</insert>
<insert id="insertSelective" parameterType="com.sv.entity.Barcode" >
insert into sv_barcode
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="id != null" >
id,
</if>
<if test="barcode != null" >
barcode,
</if>
<if test="status != null" >
status,
</if>
<if test="memberId != null" >
member_id,
</if>
<if test="venueId != null" >
venue_id,
</if>
<if test="enter != null" >
enter,
</if>
<if test="createdId != null" >
created_id,
</if>
<if test="modifiedId != null" >
modified_id,
</if>
<if test="createdTime != null" >
created_time,
</if>
<if test="modifiedTime != null" >
modified_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="id != null" >
#{id,jdbcType=INTEGER},
</if>
<if test="barcode != null" >
#{barcode,jdbcType=VARCHAR},
</if>
<if test="status != null" >
#{status,jdbcType=INTEGER},
</if>
<if test="memberId != null" >
#{memberId,jdbcType=INTEGER},
</if>
<if test="venueId != null" >
#{venueId,jdbcType=INTEGER},
</if>
<if test="enter != null" >
#{enter,jdbcType=INTEGER},
</if>
<if test="createdId != null" >
#{createdId,jdbcType=INTEGER},
</if>
<if test="modifiedId != null" >
#{modifiedId,jdbcType=INTEGER},
</if>
<if test="createdTime != null" >
#{createdTime,jdbcType=TIMESTAMP},
</if>
<if test="modifiedTime != null" >
#{modifiedTime,jdbcType=TIMESTAMP},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.sv.entity.Barcode" >
update sv_barcode
<set >
<if test="barcode != null" >
barcode = #{barcode,jdbcType=VARCHAR},
</if>
<if test="status != null" >
status = #{status,jdbcType=INTEGER},
</if>
<if test="memberId != null" >
member_id = #{memberId,jdbcType=INTEGER},
</if>
<if test="venueId != null" >
venue_id = #{venueId,jdbcType=INTEGER},
</if>
<if test="enter != null" >
enter = #{enter,jdbcType=INTEGER},
</if>
<if test="createdId != null" >
created_id = #{createdId,jdbcType=INTEGER},
</if>
<if test="modifiedId != null" >
modified_id = #{modifiedId,jdbcType=INTEGER},
</if>
<if test="createdTime != null" >
created_time = #{createdTime,jdbcType=TIMESTAMP},
</if>
<if test="modifiedTime != null" >
modified_time = #{modifiedTime,jdbcType=TIMESTAMP},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="com.sv.entity.Barcode" >
update sv_barcode
set barcode = #{barcode,jdbcType=VARCHAR},
status = #{status,jdbcType=INTEGER},
member_id = #{memberId,jdbcType=INTEGER},
venue_id = #{venueId,jdbcType=INTEGER},
enter = #{enter,jdbcType=INTEGER},
created_id = #{createdId,jdbcType=INTEGER},
modified_id = #{modifiedId,jdbcType=INTEGER},
created_time = #{createdTime,jdbcType=TIMESTAMP},
modified_time = #{modifiedTime,jdbcType=TIMESTAMP}
where id = #{id,jdbcType=INTEGER}
</update>
<update id="writeOffCode" parameterType="String" >
update sv_barcode
set status = 1
where barcode = #{barcode,jdbcType=VARCHAR}
</update>
<select id="findBarcode" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
select
<include refid="Base_Column_List" />
from sv_barcode
where member_id = #{memberId,jdbcType=INTEGER}
and venue_id = #{venueId,jdbcType=INTEGER}
and status = 0
</select>
</mapper>

View File

@@ -8,8 +8,6 @@
<result column="stream" property="stream"/>
<result column="venue_id" property="venueId"/>
<result column="venue_type" property="venueType"/>
<result column="bind_member" property="bindMember"/>
<result column="bind_time" property="bindTime"/>
<result column="status" property="status"/>
<result column="created_id" property="createdId"/>
<result column="modified_id" property="modifiedId"/>
@@ -35,9 +33,6 @@
venue_id,
status,
venue_type,
device_type,
bind_member,
bind_time,
created_id,
modified_id,
created_time,
@@ -52,8 +47,6 @@
#{stream, jdbcType=VARCHAR},
#{venue_id, jdbcType=INTEGER},
#{venue_type, jdbcType=INTEGER},
#{bind_member, jdbcType=INTEGER},
#{bind_time, jdbcType=TIMESTAMP},
#{createdId, jdbcType=INTEGER},
#{modifiedId, jdbcType=INTEGER},
#{createdTime, jdbcType=TIMESTAMP},
@@ -92,12 +85,6 @@
<if test="venueType != null">
venue_type,
</if>
<if test="bindMember != null">
bind_member,
</if>
<if test="bindTime != null">
bind_time,
</if>
<if test="status != null">
status,
</if>
@@ -133,12 +120,6 @@
<if test="venueType != null">
#{venueType},
</if>
<if test="bindMember != null">
#{bindMember},
</if>
<if test="bindTime != null">
#{bindTime},
</if>
<if test="status != null">
#{status},
</if>
@@ -203,12 +184,6 @@
<if test="venueType != null">
venue_type = #{venueType},
</if>
<if test="bindMember != null">
bind_member = #{bindMember},
</if>
<if test="bindTime != null">
bind_time = #{bindTime},
</if>
<if test="createdId != null">
created_id = #{createdId},
</if>
@@ -275,16 +250,16 @@
<select id="findByDevice" resultType="com.sv.entity.Device">
SELECT
<include refid="Field"></include> FROM sv_device
WHERE 1=1 AND name = #{deviceName} and venue_id=#{venueId} and deleted = 0
WHERE 1=1 and venue_id=#{venueId} and deleted = 0 and status = 2
</select>
<update id="bindMember">
UPDATE sv_device set bind_member = #{bindMember},bind_time = now()
WHERE name = #{deviceName} and venue_id=#{venueId}
</update>
<!-- <update id="bindMember">-->
<!-- UPDATE sv_device set bind_member = #{bindMember},bind_time = now()-->
<!-- WHERE name = #{deviceName} and venue_id=#{venueId}-->
<!-- </update>-->
<update id="unBindMember">
UPDATE sv_device set bind_member = null,bind_time = null
WHERE name = #{deviceName} and venue_id=#{venueId}
</update>
<!-- <update id="unBindMember">-->
<!-- UPDATE sv_device set bind_member = null,bind_time = null-->
<!-- WHERE name = #{deviceName} and venue_id=#{venueId}-->
<!-- </update>-->
</mapper>

View File

@@ -331,7 +331,7 @@
<select id="findLastByMember" resultMap="MemberEnterVeneuLogMap">
SELECT id,member_id,venue_id,created_time,member_card_id,type
FROM sv_member_enter_veneu_log
WHERE member_id = #{memberId} and type = 0 and venue_id = #{venueId} and deleted = 0 order by created_time desc LIMIT 1
WHERE member_id = #{memberId} and venue_id = #{venueId} and deleted = 0 order by created_time desc LIMIT 1
</select>
<select id="findLastNoTypeByMember" resultMap="MemberEnterVeneuLogMap">

View File

@@ -331,4 +331,20 @@
ORDER BY
created_time DESC
</select>
<!-- oms 查询用户账单 -->
<select id="selectLastLog" resultMap="MemberMoneyLogMap">
SELECT
<include refid="Field"></include>
FROM
sv_member_money_log
WHERE
member_id = #{memberId}
AND venue_id = #{venueId}
AND deleted = 0
ORDER BY
created_time DESC
LIMIT 1
</select>
</mapper>

View File

@@ -90,7 +90,7 @@
domainObjectName 给表对应的 model 起名字
注意:大小写敏感问题。
-->
<table tableName="sys_wx_config" domainObjectName="WxConfig"
<table tableName="sv_barcode" domainObjectName="Barcode"
enableInsert="true"
enableDeleteByPrimaryKey="true"
enableSelectByPrimaryKey="true"