线下订单驱动开门

This commit is contained in:
2023-11-24 22:37:12 +08:00
parent c79b75708d
commit 07a648c3f5
24 changed files with 1621 additions and 37 deletions

View File

@@ -7,13 +7,17 @@ import com.sv.entity.Barcode;
import com.sv.entity.Device;
import com.sv.entity.Venue;
import com.sv.mapper.BarcodeMapper;
import com.sv.netty.config.NettyConstant;
import com.sv.netty.utils.AesUtil;
import com.sv.netty.utils.MakeCode;
import com.sv.service.api.VenueService;
import com.sv.service.common.DoorLockUtil;
import com.sv.service.common.RedisCache;
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 com.ydd.framework.core.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
@@ -21,6 +25,7 @@ import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
/**
* Controller - 场馆
@@ -35,6 +40,8 @@ public class VenueController extends BaseApiController {
@Resource
private VenueService venueService;
@Resource
private DoorLockUtil doorLockUtil;
/**
* 分页查询场馆列表
@@ -119,8 +126,14 @@ public class VenueController extends BaseApiController {
join.setFlg(999);
join.setMsg("通讯异常,门禁设备离线中");
}else {
String barcode = newBarcode(byDevice.getName(), EnterEnum.ENTER, venueId, memberId);
String doorSn = byDevice.getName();
boolean lockStat = doorLockUtil.checkDoorLock(doorSn);
if (lockStat) {
throw new ServiceException("有人正在使用门禁,请稍后再试");
}
String barcode = newBarcode(doorSn, EnterEnum.ENTER, venueId, memberId);
join.setBarcode(barcode);
doorLockUtil.lockDoor(doorSn);
}
}
return ResponseDTO.ok().addAttribute("join", join);
@@ -144,14 +157,19 @@ public class VenueController extends BaseApiController {
out.setFlg(999);
out.setMsg("通讯异常,门禁设备离线中");
}else {
String barcode = newBarcode(byDevice.getName(),EnterEnum.OUT,venueId,memberId);
String doorSn = byDevice.getName();
boolean lockStat = doorLockUtil.checkDoorLock(doorSn);
if (lockStat) {
throw new ServiceException("有人正在使用门禁,请稍后再试");
}
String barcode = newBarcode(doorSn,EnterEnum.OUT,venueId,memberId);
out.setBarcode(barcode);
doorLockUtil.lockDoor(doorSn);
}
}
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);

View File

@@ -4,15 +4,23 @@ 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.netty.utils.MakeCode;
import com.sv.service.common.DoorLockUtil;
import com.sv.service.oms.DeviceService;
import com.sv.service.utils.VenueBarcodeUtil;
import com.ydd.framework.core.common.dto.ResponseDTO;
import com.ydd.framework.core.controller.BaseApiController;
import com.ydd.framework.core.exception.ServiceException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
/**
* 小程序二维码进场Controller
@@ -25,6 +33,8 @@ public class AdminNettyController extends BaseApiController {
DeviceService deviceService;
@Resource
private MessageService messageService;
@Resource
DoorLockUtil doorLockUtil;
/**
* 进场指令发布
*/
@@ -81,13 +91,102 @@ public class AdminNettyController extends BaseApiController {
* 检验客户端读取能力
* @return
*/
@RequestMapping("/checkAlive")
public ResponseDTO checkAlive(@RequestParam String id) {
Integer venueId = getVenueId(id);
String deviceName = getDeviceName(id);
logger.info("验证设备"+ id + "通讯情况");
messageService.testLoad(deviceName,venueId);
@RequestMapping("/checkAlive/{id}")
public ResponseDTO checkAlive(@PathVariable("id") Integer id) {
Device device = deviceService.findById(id);
if (device == null){
throw new ServiceException("设备不存在");
}
if (!DeviceStatusEnum.ONLINE.value.equals(device.getStatus())){
throw new ServiceException("设备离线!请检查连接");
}
messageService.testLoad(device.getName(),device.getVenueId());
return ResponseDTO.ok();
}
/**
* 下载线下入场凭证(二维码)
* @param id
* @param response
* @throws IOException
* @throws InvalidFormatException
*/
@RequestMapping(value = "/qrcode/print/{id}")
public void print(@PathVariable("id") Integer id, HttpServletResponse response) throws IOException, InvalidFormatException {
Device device = deviceService.findById(id);
if (device == null){
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
PrintWriter writer = response.getWriter();
writer.write("设备不存在!!!");
writer.flush();
writer.close();
return;
}
String doorSn = device.getName();
if(doorLockUtil.checkBarcode(doorSn)){
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
PrintWriter writer = response.getWriter();
writer.write("生成二维码过于频繁,请稍候再试!!!");
writer.flush();
writer.close();
return;
}
long l = System.currentTimeMillis();
String barcodeSn = "venue-" + l;
String barcode = MakeCode.makeOfflineCode(barcodeSn);
deviceService.makeDeviceBarcode(device.getName(),device.getVenueId(),barcode);
String documentPath = getDocument(barcodeSn);
response.setHeader("Content-disposition","attachment; filename=" + barcodeSn + ".docx");
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
response.setCharacterEncoding("UTF-8");
OutputStream out = response.getOutputStream();
BufferedInputStream fin = new BufferedInputStream(new FileInputStream(documentPath));
try {
byte[] content = new byte[1024];
int length;
while ((length = fin.read(content, 0, content.length)) != -1) {
out.write(content, 0, length);
}
doorLockUtil.lockBarcode(doorSn);
} catch (Exception e) {
logger.error(e.getMessage(), e);
logger.info("文件下载失败", e.getMessage());
throw e;
} finally {
fin.close();
out.flush();
out.close();
}
}
private static String getDocument(String barcodeSn) throws IOException, InvalidFormatException {
String newFilePath = "/Users/limqhz/home/test/document.docx";
XWPFDocument document = new XWPFDocument();
XWPFParagraph paragraph = document.createParagraph();
paragraph.setAlignment(ParagraphAlignment.CENTER);
XWPFRun run = paragraph.createRun();
// 入场二维码
run.setText("订单号:" + barcodeSn);
run.addBreak();
String imgFile = VenueBarcodeUtil.generateBarcode("jdoiawjdoiawioe1","202311161.jpg");
int imgFormat = XWPFDocument.PICTURE_TYPE_JPEG;
run.addPicture(new FileInputStream(imgFile), imgFormat, "image description",
Units.toEMU(200), Units.toEMU(200));
// run.addBreak(BreakType.PAGE);
// // 出场二维码
// run.setText("出场二维码");
// run.addBreak();
// String imgFile2 = VenueBarcodeUtil.generateBarcode("jdoiawjdoiawioe2","202311162.jpg");
// run.addPicture(new FileInputStream(imgFile2), imgFormat, "image description",
// Units.toEMU(200), Units.toEMU(200));
// 保存文件
document.write(new FileOutputStream(newFilePath));
document.close();
return newFilePath;
}
}

View File

@@ -3,6 +3,7 @@ package com.sv.netty.netty;
import com.enums.EnterEnum;
import com.sv.netty.config.*;
import com.sv.netty.netty.service.MessageService;
import com.sv.netty.utils.AesUtil;
import com.sv.netty.utils.JsonUtils;
import com.sv.netty.utils.MakeCode;
import io.netty.channel.*;
@@ -62,6 +63,11 @@ public class ServerHandler extends SimpleChannelInboundHandler<String> {
break;
case SCAN_CODE:
logger.info("客户端【" + clientIp + "】开门了...");
String offline = MakeCode.decodeOfflineCode(message.getMessage());
if (offline.startsWith("venue-")) {
// 这是线下开门的逻辑
messageService.offlineOpenDoor(message.getMessage());
}
VenueBarCode venueBarCode = MakeCode.decodeCode(message.getMessage());
if (EnterEnum.ENTER.getValue() == venueBarCode.getDirection()) {
messageService.enterVenue(message.getMessage());

View File

@@ -1,8 +1,6 @@
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;
@@ -53,4 +51,6 @@ public interface MessageService {
public void adminOut(String deviceName, Integer venueId);
void testLoad(String deviceName, Integer venueId);
void offlineOpenDoor(String message);
}

View File

@@ -3,7 +3,9 @@ package com.sv.netty.netty.service.impl;
import com.enums.BarCodeStatusEnum;
import com.enums.EnterEnum;
import com.sv.entity.*;
import com.sv.mapper.BarcodeEnterLogMapper;
import com.sv.mapper.BarcodeMapper;
import com.sv.mapper.BarcodeOfflineMapper;
import com.sv.netty.config.*;
import com.sv.netty.netty.service.MessageService;
import com.sv.netty.utils.JsonUtils;
@@ -13,6 +15,7 @@ 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.common.DoorLockUtil;
import com.sv.service.oms.DeviceService;
import com.ydd.framework.core.exception.ServiceException;
import io.netty.channel.Channel;
@@ -25,7 +28,6 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ConcurrentMap;
/**
* 消息实现类
*
@@ -62,6 +64,14 @@ public class ServerMessageHandlerAdapter implements MessageService {
@Resource
private BarcodeMapper barcodeMapper;
@Resource
private DoorLockUtil doorLockUtil;
@Resource
private BarcodeOfflineMapper barcodeOfflineMapper;
@Resource
private BarcodeEnterLogMapper barcodeEnterLogMapper;
/**
* 处理心跳信息,存储心跳信息
* @param clientId
@@ -107,11 +117,16 @@ public class ServerMessageHandlerAdapter implements MessageService {
@Transactional
public void outVenue(String barcode) {
VenueBarCode venueBarCode = MakeCode.decodeCode(barcode);
String doorSn = venueBarCode.getDeviceName();
boolean lockStat = doorLockUtil.checkDoorLock(doorSn);
if (lockStat) {
throw new ServiceException("有人正在操作,请稍后再试");
}
barcode = MakeCode.reWriteBarcode(barcode);
if (!checkBarcode(barcode)){
throw new ServiceException("二维码已经使用");
}
Channel channel = getCurrentChannel(venueBarCode.getDeviceName(),venueBarCode.getVenueId());
Channel channel = getCurrentChannel(doorSn,venueBarCode.getVenueId());
Member member = memberService.findByMember(venueBarCode.getMemberId());
if (member != null) {
MemberMoneyLog memberMoneyLog = memberMoneyLogService.selectLastLog(member.getId(), venueBarCode.getVenueId());
@@ -125,6 +140,7 @@ public class ServerMessageHandlerAdapter implements MessageService {
memberEnterVenueLog.setPayType(memberMoneyLog.getPayType());
}
memberEnterVenueLogService.save(memberEnterVenueLog);
doorLockUtil.lockDoor(doorSn);
logger.info("用户" + member.getNickname() + "出场");
writeOffCode(barcode);
ServerMessageUtils.INSTANCE.sendMsg(channel,new VenueMessage(MessageType.OUT_DOOR,"OK"));
@@ -139,11 +155,16 @@ public class ServerMessageHandlerAdapter implements MessageService {
@Transactional
public void enterVenue(String barcode) {
VenueBarCode venueBarCode = MakeCode.decodeCode(barcode);
String doorSn = venueBarCode.getDeviceName();
boolean lockStat = doorLockUtil.checkDoorLock(doorSn);
if (lockStat) {
throw new ServiceException("有人正在操作,请稍后再试");
}
barcode = MakeCode.reWriteBarcode(barcode);
if (!checkBarcode(barcode)){
throw new ServiceException("二维码已经使用");
}
Channel channel = getCurrentChannel(venueBarCode.getDeviceName(), venueBarCode.getVenueId());
Channel channel = getCurrentChannel(doorSn, venueBarCode.getVenueId());
Member member = memberService.findByMember(venueBarCode.getMemberId());
if (member != null) {
MemberEnterVenueLog memberEnterVenueLog = new MemberEnterVenueLog();
@@ -153,6 +174,7 @@ public class ServerMessageHandlerAdapter implements MessageService {
memberEnterVenueLog.setPlatformId(member.getPlatformId() == null ? 1 : member.getPlatformId());
memberEnterVenueLog.setVenueId(venueBarCode.getVenueId());
memberEnterVenueLogService.save(memberEnterVenueLog);
doorLockUtil.lockDoor(doorSn);
writeOffCode(barcode);
logger.info("用户" + member.getNickname() + "入场");
ServerMessageUtils.INSTANCE.sendMsg(channel,new VenueMessage(MessageType.ENTER_DOOR,"OK"));
@@ -199,6 +221,47 @@ public class ServerMessageHandlerAdapter implements MessageService {
ServerMessageUtils.INSTANCE.sendMsg(currentChannel,new VenueMessage(MessageType.HB,"测试链接"));
}
/**
* 线下订单
*/
@Override
public void offlineOpenDoor(String message) {
String barcode = MakeCode.reWriteBarcode(message);
BarcodeOffline barcodeOffline = barcodeOfflineMapper.selectByBarcode(barcode);
String doorSn = barcodeOffline.getDeviceName();
// 校验barcode是否失效
Date endTime = barcodeOffline.getEndTime();
if (endTime.before(new Date())) {
// 二维码已经失效了
throw new ServiceException("二维码已经失效,无法继续使用");
}
boolean lockStat = doorLockUtil.checkDoorLock(doorSn);
if (lockStat) {
throw new ServiceException("有人正在操作,请稍后再试");
}
BarcodeEnterLog lastByBarcode = barcodeEnterLogMapper.findLastByBarcode(barcode);
Integer venueId = barcodeOffline.getVenueId();
Channel channel = getCurrentChannel(doorSn, venueId);
if (lastByBarcode != null && EnterEnum.ENTER.getValue().equals(lastByBarcode.getType())) {
//出场
BarcodeEnterLog barcodeEnterLog = new BarcodeEnterLog();
barcodeEnterLog.setBarcode(barcode);
barcodeEnterLog.setType(EnterEnum.OUT.getValue());
barcodeEnterLog.setVenueId(venueId);
barcodeEnterLogMapper.insert(barcodeEnterLog);
doorLockUtil.lockDoor(doorSn);
ServerMessageUtils.INSTANCE.sendMsg(channel,new VenueMessage(MessageType.OUT_DOOR,"OK"));
return;
}
BarcodeEnterLog barcodeEnterLog = new BarcodeEnterLog();
barcodeEnterLog.setBarcode(barcode);
barcodeEnterLog.setType(EnterEnum.ENTER.getValue());
barcodeEnterLog.setVenueId(venueId);
barcodeEnterLogMapper.insert(barcodeEnterLog);
doorLockUtil.lockDoor(doorSn);
ServerMessageUtils.INSTANCE.sendMsg(channel,new VenueMessage(MessageType.ENTER_DOOR,"OK"));
}
/**
* 管理员入场
* @return

View File

@@ -0,0 +1,111 @@
package com.sv.entity;
import java.util.Date;
public class BarcodeEnterLog {
private Integer id;
private String barcode;
private Integer venueId;
private Integer platformId;
private Integer createdId;
private Integer modifiedId;
private Date createdTime;
private Date modifiedTime;
private Integer type;
public BarcodeEnterLog(Integer id, String barcode, Integer venueId, Integer platformId, Integer createdId, Integer modifiedId, Date createdTime, Date modifiedTime, Integer type) {
this.id = id;
this.barcode = barcode;
this.venueId = venueId;
this.platformId = platformId;
this.createdId = createdId;
this.modifiedId = modifiedId;
this.createdTime = createdTime;
this.modifiedTime = modifiedTime;
this.type = type;
}
public BarcodeEnterLog() {
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 getVenueId() {
return venueId;
}
public void setVenueId(Integer venueId) {
this.venueId = venueId;
}
public Integer getPlatformId() {
return platformId;
}
public void setPlatformId(Integer platformId) {
this.platformId = platformId;
}
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;
}
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
}

View File

@@ -0,0 +1,122 @@
package com.sv.entity;
import java.util.Date;
public class BarcodeOffline {
private Integer id;
private String barcode;
private Date startTime;
private Date endTime;
private Integer venueId;
private Integer createdId;
private Integer modifiedId;
private Date createdTime;
private Date modifiedTime;
private String deviceName;
public BarcodeOffline(Integer id, String barcode, Date startTime, Date endTime, Integer venueId, Integer createdId, Integer modifiedId, Date createdTime, Date modifiedTime, String deviceName) {
this.id = id;
this.barcode = barcode;
this.startTime = startTime;
this.endTime = endTime;
this.venueId = venueId;
this.createdId = createdId;
this.modifiedId = modifiedId;
this.createdTime = createdTime;
this.modifiedTime = modifiedTime;
this.deviceName = deviceName;
}
public BarcodeOffline() {
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 Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
public Integer getVenueId() {
return venueId;
}
public void setVenueId(Integer venueId) {
this.venueId = venueId;
}
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;
}
public String getDeviceName() {
return deviceName;
}
public void setDeviceName(String deviceName) {
this.deviceName = deviceName == null ? null : deviceName.trim();
}
}

View File

@@ -8,20 +8,23 @@ import Net.PC15.FC8800.Command.Door.OpenDoor;
import Net.PC15.FC8800.Command.Door.Parameter.OpenDoor_Parameter;
import Net.PC15.FC8800.FC8800Identity;
import com.sv.intergration.DoorService;
import com.sv.netty.config.NettyConstant;
public class OldDoorService implements DoorService {
@Override
public void enterOpenDoor() {
try {
logger.info("----init open door tcp ----");
ConnectorAllocator connector = ConnectorAllocator.GetAllocator();
TCPClientDetial tcpClientDetial = new TCPClientDetial("192.168.1.150", Integer.valueOf("8000"));
connector.GetCommandCount(tcpClientDetial);
connector.OpenForciblyConnect(tcpClientDetial);
CommandDetial detial = new CommandDetial();
detial.Connector = tcpClientDetial;
detial.Identity = new FC8800Identity("MC-5824T23014127", "12345678", E_ControllerType.FC8900);
String clientSn = System.getProperty(NettyConstant.VENUE_CLIENT_SN);
System.out.println(clientSn);
// detial.Identity = new FC8800Identity("MC-5824T23014127", "12345678", E_ControllerType.FC8900);
detial.Identity = new FC8800Identity(clientSn, "12345678", E_ControllerType.FC8900);
OpenDoor_Parameter openDoorParameter = new OpenDoor_Parameter(detial);
openDoorParameter.Door.SetDoor(1, 1);
OpenDoor openDoor = new OpenDoor(openDoorParameter);
@@ -40,19 +43,19 @@ public class OldDoorService implements DoorService {
@Override
public void outOpenDoor() {
try {
logger.info("----init open door tcp ----");
ConnectorAllocator connector = ConnectorAllocator.GetAllocator();
TCPClientDetial tcpClientDetial = new TCPClientDetial("192.168.1.150", Integer.valueOf("8000"));
connector.GetCommandCount(tcpClientDetial);
connector.OpenForciblyConnect(tcpClientDetial);
CommandDetial detial = new CommandDetial();
detial.Connector = tcpClientDetial;
detial.Identity = new FC8800Identity("MC-5824T23014127", "12345678", E_ControllerType.FC8900);
String clientSn = System.getProperty(NettyConstant.VENUE_CLIENT_SN);
// detial.Identity = new FC8800Identity("MC-5824T23014127", "12345678", E_ControllerType.FC8900);
detial.Identity = new FC8800Identity(clientSn, "12345678", E_ControllerType.FC8900);
OpenDoor_Parameter openDoorParameter = new OpenDoor_Parameter(detial);
openDoorParameter.Door.SetDoor(2, 1);
OpenDoor openDoor = new OpenDoor(openDoorParameter);
boolean command = connector.AddCommand(openDoor);
System.out.println(command);
if (!command) {
logger.error("出场开门命令执行失败");
}
@@ -65,9 +68,9 @@ public class OldDoorService implements DoorService {
}
// 测试
public static void main(String[] args) {
OldDoorService oldDoorService = new OldDoorService();
oldDoorService.enterOpenDoor();
oldDoorService.outOpenDoor();
}
// public static void main(String[] args) {
// OldDoorService oldDoorService = new OldDoorService();
// oldDoorService.enterOpenDoor();
// oldDoorService.outOpenDoor();
// }
}

View File

@@ -1,6 +1,7 @@
package com.sv.netty;
import com.sv.netty.config.*;
import com.sv.netty.utils.AesUtil;
import com.sv.netty.utils.EncodeMsg;
import com.sv.netty.utils.JsonUtils;
import com.sv.netty.utils.MakeCode;
@@ -27,10 +28,14 @@ public class MessageHandler {
* @return
*/
public static String checkBarcode(String barcode) {
String decrypt = AesUtil.decrypt(barcode);
// 这个二维码是线下的二维码
if (!decrypt.startsWith("venue-")){
VenueBarCode venueBarCode = MakeCode.decodeCode(barcode);
if (venueBarCode == null) {
logger.error("二维码不合法" + barcode);
return null;
if (venueBarCode == null) {
logger.error("二维码不合法" + barcode);
return null;
}
}
VenueMessage venueMessage = new VenueMessage();
venueMessage.setMessageType(MessageType.SCAN_CODE);

View File

@@ -1 +1 @@
{"serverIp":"127.0.0.1","serverPort":"56792","clientSN":"20230901venue","clientVid":"41"}
{"serverIp":"127.0.0.1","serverPort":"56792","clientSN":"MC-5824T23014127","clientVid":"41"}

View File

@@ -14,6 +14,14 @@ public class MakeCode {
return NettyConstant.BARCODE_BEGIN + AesUtil.encrypt(information) + NettyConstant.BARCODE_END;
}
/**
* 生成二维码
* @return
*/
public static String makeOfflineCode (String barcodeSn) {
return NettyConstant.BARCODE_BEGIN + AesUtil.encrypt(barcodeSn) + NettyConstant.BARCODE_END;
}
/**
* 解析二维码
*/
@@ -36,6 +44,13 @@ public class MakeCode {
return venueBarCode;
}
/**
* 解析二维码
*/
public static String decodeOfflineCode (String barcodeSn) {
return AesUtil.decrypt(barcodeSn);
}
/**
* 还原二维码
*/

View File

@@ -1,16 +1,24 @@
package com.sv.oms.controller;
import com.enums.DeviceStatusEnum;
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;
import com.ydd.framework.core.exception.ServiceException;
import com.ydd.oms.controller.OmsController;
import com.sv.entity.Device;
import com.ydd.oms.util.VenueBarcodeUtil;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
/**
* Controller - 门禁设备
@@ -95,4 +103,72 @@ public class DeviceController extends OmsController {
return ResponseDTO.ok("出场开门成功!");
}
/**
* 重新连接
* @param deviceId
* @return
*/
@RequestMapping("device/checkAlive/{id}")
public ResponseDTO checkAlive(@PathVariable("id") Integer deviceId){
Device device = deviceService.findById(deviceId);
if (device == null) {
throw new ServiceException("设备离线!请检查连接");
}
if (!DeviceStatusEnum.ONLINE.value.equals(device.getStatus())){
throw new ServiceException("设备离线!请检查连接");
}
return ResponseDTO.ok();
}
@RequestMapping(value = "/qrcode/print/{id}")
public void print(@PathVariable("id") Integer id, HttpServletResponse response) throws IOException, InvalidFormatException {
String documentPath = getDocument();
response.setHeader("Content-disposition","attachment; filename=venue.docx");
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("UTF-8");
OutputStream out = response.getOutputStream();
BufferedInputStream fin = new BufferedInputStream(new FileInputStream(documentPath));
try {
byte[] content = new byte[1024];
int length;
while ((length = fin.read(content, 0, content.length)) != -1) {
out.write(content, 0, length);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
logger.info("文件下载失败", e.getMessage());
throw e;
} finally {
fin.close();
out.flush();
out.close();
}
}
private static String getDocument() throws IOException, InvalidFormatException {
String newFilePath = "/Users/limqhz/home/test/document.docx";
XWPFDocument document = new XWPFDocument();
XWPFParagraph paragraph = document.createParagraph();
paragraph.setAlignment(ParagraphAlignment.CENTER);
XWPFRun run = paragraph.createRun();
// 入场二维码
run.setText("入场二维码");
run.addBreak();
String imgFile = VenueBarcodeUtil.generateBarcode("jdoiawjdoiawioe1","202311161.jpg");
int imgFormat = XWPFDocument.PICTURE_TYPE_JPEG;
run.addPicture(new FileInputStream(imgFile), imgFormat, "image description",
Units.toEMU(200), Units.toEMU(200));
run.addBreak(BreakType.PAGE);
// 出场二维码
run.setText("出场二维码");
run.addBreak();
String imgFile2 = VenueBarcodeUtil.generateBarcode("jdoiawjdoiawioe2","202311162.jpg");
run.addPicture(new FileInputStream(imgFile2), imgFormat, "image description",
Units.toEMU(200), Units.toEMU(200));
// 保存文件
document.write(new FileOutputStream(newFilePath));
document.close();
return newFilePath;
}
}

View File

@@ -0,0 +1,109 @@
package com.ydd.oms.util;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.ydd.framework.core.exception.ServiceException;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Hashtable;
public class VenueBarcodeUtil {
private static final int BLACK = 0xFF000000;
private static final int WHITE = 0xFFFFFFFF;
private static final int margin = 0;
public static String generateBarcode(String barcodeValue,String fileName) {
try {
String geneFilePath = "/Users/limqhz/home/test/" + fileName;
makeBarcode(geneFilePath,barcodeValue);
return geneFilePath;
}catch (WriterException e) {
throw new ServiceException("生成二维码图片文件有问题");
}
}
private static void makeBarcode(String path, String barcodeValue) throws WriterException {
//二维码内容
String content = barcodeValue;
String format = "jpg";
int width = 200; // 二维码宽度
int height = 200;// 二维码高度
// 设置二维码矩阵的信息
BitMatrix bitMatrix = setBitMatrix(content, width, height);
// 设置输出流
OutputStream outStream = null;
try {
outStream = new FileOutputStream(new File(path));
// 目前 针对容错等级为H reduceWhiteArea 二维码空白区域的大小 根据实际情况设置,如果二维码内容长度不固定的话 需要自己根据实际情况计算reduceWhiteArea的大小
writeToFile(bitMatrix, format, outStream, 5);
outStream.close();
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
outStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 设置生成二维码矩阵信息
* @param content 二维码图片内容
* @param width 二维码图片宽度
* @param height 二维码图片高度
* @throws WriterException
*/
private static BitMatrix setBitMatrix(String content, int width, int height) throws WriterException {
BitMatrix bitMatrix = null;
Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 指定编码方式,避免中文乱码
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 指定纠错等级 如果二维码里面的内容比较多的话推荐使用H 容错率30% 这样可以避免一些扫描不出来的问题
hints.put(EncodeHintType.MARGIN, margin); // 指定二维码四周白色区域大小 官方的这个方法目前没有没有作用默认设置为0
bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
return bitMatrix;
}
/**
* @param matrix
* @param format
* @param outStream
* @param reduceWhiteArea 二维码空白区域设置
* @throws IOException
*/
private static void writeToFile(BitMatrix matrix, String format, OutputStream outStream, int reduceWhiteArea) throws IOException {
BufferedImage image = toBufferedImage(matrix, reduceWhiteArea);
ImageIO.write(image, format, outStream);
}
/**
*
* @param matrix
* @param reduceWhiteArea
* @return
*/
private static BufferedImage toBufferedImage(BitMatrix matrix, int reduceWhiteArea) {
int width = matrix.getWidth();
int height = matrix.getHeight();
BufferedImage image = new BufferedImage(width - 2 * reduceWhiteArea, height - 2 * reduceWhiteArea, BufferedImage.TYPE_3BYTE_BGR);
for (int x = reduceWhiteArea; x < width - reduceWhiteArea; x++) {
for (int y = reduceWhiteArea; y < height - reduceWhiteArea; y++) {
image.setRGB(x - reduceWhiteArea, y - reduceWhiteArea, matrix.get(x, y) ? BLACK : WHITE);
}
}
return image;
}
}

View File

@@ -3,7 +3,7 @@ spring:
# url: jdbc:mysql://yingdiandian.mysql.rds.aliyuncs.com:3306/smart_venue?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2b8
# username: yingdd
# password: Yingdd2015
url: jdbc:mysql://127.0.0.1:3306/smart_venue?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2b8&useAffectedRows=true
url: jdbc:mysql://127.0.0.1:3306/smart_venue?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2b8&useAffectedRows=true&useSSL=false
username: root
password: 123456
redis:

View File

@@ -0,0 +1,21 @@
package com.sv.mapper;
import com.sv.entity.BarcodeEnterLog;
import com.sv.entity.BarcodeOffline;
public interface BarcodeEnterLogMapper {
int deleteByPrimaryKey(Integer id);
int insert(BarcodeEnterLog record);
int insertSelective(BarcodeEnterLog record);
BarcodeEnterLog selectByPrimaryKey(Integer id);
int updateByPrimaryKeySelective(BarcodeEnterLog record);
int updateByPrimaryKey(BarcodeEnterLog record);
BarcodeEnterLog findLastByBarcode(String barcode);
}

View File

@@ -0,0 +1,19 @@
package com.sv.mapper;
import com.sv.entity.BarcodeOffline;
public interface BarcodeOfflineMapper {
int deleteByPrimaryKey(Integer id);
int insert(BarcodeOffline record);
int insertSelective(BarcodeOffline record);
BarcodeOffline selectByPrimaryKey(Integer id);
int updateByPrimaryKeySelective(BarcodeOffline record);
int updateByPrimaryKey(BarcodeOffline record);
BarcodeOffline selectByBarcode(String barcode);
}

View File

@@ -294,7 +294,7 @@ public class VenueService extends BaseServiceImpl {
}
if (useCard != null) {
//使用会员卡入场
logger.info("用户" + member.getNickname() + "使用" + useCard.getCardType() + "入场");
logger.info("用户" + member.getNickname() + "使用" + useCard.getCardType() + "核销");
// 会员卡入场,增加记录
createMemberMoneyLog(MoneyLogEnum.JOIN.value, venue.getPrice(), member.getId(), member.getPlatformId(), PayTypeEnum.MEMBER_CARD.value, useCard.getCardType(),
venue.getId(), venue.getType());
@@ -305,21 +305,21 @@ public class VenueService extends BaseServiceImpl {
}
}else {
//查无可用会员卡
logger.info("用户" + member.getNickname() + "您好!请先购买会员卡再进场");
logger.info("用户" + member.getNickname() + "您好!请先购买会员卡再出场核销");
result.setFlg(1);
result.setMsg("未查询到会员卡,请先购买");
result.setMsg("未查询到会员卡,请先购买会员卡");
}
}else {
//判断余额是否够 TODO 应该从入场订单里面去取
//判断余额是否够
String time = DateUtilCard.nowTime().toString();
VenuePrice venuePrice = venuePriceService.findPrice(venueId, time);
if (memberService.isMoneyEnough(member.getId(), venuePrice.getPrice())) {
logger.info("用户" + member.getNickname() + "使用余额进场");
logger.info("用户" + member.getNickname() + "使用余额核销订单");
createMemberMoneyLog(MoneyLogEnum.JOIN.value, venuePrice.getPrice(), member.getId(), member.getPlatformId(), PayTypeEnum.BALANCE.value, null,
venue.getId(), venue.getType());
} else {
//余额不足
logger.error("用户" + member.getNickname() + "余额不足进场失败");
logger.error("用户" + member.getNickname() + "余额不足核销失败");
result.setFlg(1);
result.setMsg("余额不足,请先充值");
}

View File

@@ -0,0 +1,60 @@
package com.sv.service.common;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
@Component
public class DoorLockUtil {
private final static String DOOR_LOCK = "DOOR_LOCK_";
private final static String DOOR_BARCODE_LOCK = "DOOR_BARCODE_LOCK_";
private final static Integer LOCK_TIMEOUT = 30;
@Resource
RedisCache redisCache;
/**
* 门禁有人扫码之后需要锁定门禁30s
* @return
*/
public boolean checkDoorLock(String doorSn){
String doorKey = DOOR_LOCK + doorSn;
if (redisCache.getCacheObject(doorKey) == null){
return false;
}
return true;
}
/**
* 门禁有人扫码之后需要锁定门禁30s
* @param doorSn
*/
public void lockDoor(String doorSn){
String doorKey = DOOR_LOCK + doorSn;
redisCache.setCacheObject(doorKey,true,LOCK_TIMEOUT, TimeUnit.SECONDS);
}
/**
* 门禁有人扫码之后需要锁定门禁30s
* @return
*/
public boolean checkBarcode(String doorSn){
String doorKey = DOOR_BARCODE_LOCK + doorSn;
if (redisCache.getCacheObject(doorKey) == null){
return false;
}
return true;
}
/**
* 门禁有人扫码之后需要锁定门禁30s
* @param doorSn
*/
public void lockBarcode(String doorSn){
String doorKey = DOOR_BARCODE_LOCK + doorSn;
redisCache.setCacheObject(doorKey,true,LOCK_TIMEOUT, TimeUnit.SECONDS);
}
}

View File

@@ -0,0 +1,264 @@
package com.sv.service.common;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* spring redis 工具类
*
* @author quinn
**/
@Component
public class RedisCache
{
@Resource
public RedisTemplate redisTemplate;
/**
* 缓存基本的对象Integer、String、实体类等
*
* @param key 缓存的键值
* @param value 缓存的值
*/
public <T> void setCacheObject(final String key, final T value)
{
redisTemplate.opsForValue().set(key, value);
}
/**
* 缓存基本的对象Integer、String、实体类等
*
* @param key 缓存的键值
* @param value 缓存的值
* @param timeout 时间
* @param timeUnit 时间颗粒度
*/
public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit)
{
redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
}
/**
* 设置有效时间
*
* @param key Redis键
* @param timeout 超时时间
* @return true=设置成功false=设置失败
*/
public boolean expire(final String key, final long timeout)
{
return expire(key, timeout, TimeUnit.SECONDS);
}
/**
* 设置有效时间
*
* @param key Redis键
* @param timeout 超时时间
* @param unit 时间单位
* @return true=设置成功false=设置失败
*/
public boolean expire(final String key, final long timeout, final TimeUnit unit)
{
return redisTemplate.expire(key, timeout, unit);
}
/**
* 获取有效时间
*
* @param key Redis键
* @return 有效时间
*/
public long getExpire(final String key)
{
return redisTemplate.getExpire(key);
}
/**
* 判断 key是否存在
*
* @param key 键
* @return true 存在 false不存在
*/
public Boolean hasKey(String key)
{
return redisTemplate.hasKey(key);
}
/**
* 获得缓存的基本对象。
*
* @param key 缓存键值
* @return 缓存键值对应的数据
*/
public <T> T getCacheObject(final String key)
{
ValueOperations<String, T> operation = redisTemplate.opsForValue();
return operation.get(key);
}
/**
* 删除单个对象
*
* @param key
*/
public void deleteObject(final String key)
{
redisTemplate.delete(key);
}
/**
* 删除集合对象
*
* @param collection 多个对象
* @return
*/
public void deleteObject(final Collection collection)
{
redisTemplate.delete(collection);
}
/**
* 缓存List数据
*
* @param key 缓存的键值
* @param dataList 待缓存的List数据
* @return 缓存的对象
*/
public <T> long setCacheList(final String key, final List<T> dataList)
{
Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
return count == null ? 0 : count;
}
/**
* 获得缓存的list对象
*
* @param key 缓存的键值
* @return 缓存键值对应的数据
*/
public <T> List<T> getCacheList(final String key)
{
return redisTemplate.opsForList().range(key, 0, -1);
}
/**
* 缓存Set
*
* @param key 缓存键值
* @param dataSet 缓存的数据
* @return 缓存数据的对象
*/
public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet)
{
BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
Iterator<T> it = dataSet.iterator();
while (it.hasNext())
{
setOperation.add(it.next());
}
return setOperation;
}
/**
* 获得缓存的set
*
* @param key
* @return
*/
public <T> Set<T> getCacheSet(final String key)
{
return redisTemplate.opsForSet().members(key);
}
/**
* 缓存Map
*
* @param key
* @param dataMap
*/
public <T> void setCacheMap(final String key, final Map<String, T> dataMap)
{
if (dataMap != null) {
redisTemplate.opsForHash().putAll(key, dataMap);
}
}
/**
* 获得缓存的Map
*
* @param key
* @return
*/
public <T> Map<String, T> getCacheMap(final String key)
{
return redisTemplate.opsForHash().entries(key);
}
/**
* 往Hash中存入数据
*
* @param key Redis键
* @param hKey Hash键
* @param value 值
*/
public <T> void setCacheMapValue(final String key, final String hKey, final T value)
{
redisTemplate.opsForHash().put(key, hKey, value);
}
/**
* 获取Hash中的数据
*
* @param key Redis键
* @param hKey Hash键
* @return Hash中的对象
*/
public <T> T getCacheMapValue(final String key, final String hKey)
{
HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
return opsForHash.get(key, hKey);
}
/**
* 获取多个Hash中的数据
*
* @param key Redis键
* @param hKeys Hash键集合
* @return Hash对象集合
*/
public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys)
{
return redisTemplate.opsForHash().multiGet(key, hKeys);
}
/**
* 删除Hash中的某条数据
*
* @param key Redis键
* @param hKey Hash键
* @return 是否成功
*/
public boolean deleteCacheMapValue(final String key, final String hKey)
{
return redisTemplate.opsForHash().delete(key, hKey) > 0;
}
/**
* 获得缓存的基本对象列表
*
* @param pattern 字符串前缀
* @return 对象列表
*/
public Collection<String> keys(final String pattern)
{
return redisTemplate.keys(pattern);
}
}

View File

@@ -4,12 +4,16 @@ import com.common.DeviceDTO;
import com.enums.DeviceStatusEnum;
import com.enums.EnterEnum;
import com.github.pagehelper.PageHelper;
import com.sv.entity.BarcodeOffline;
import com.sv.entity.Device;
import com.sv.exception.oms.OmsException;
import com.sv.mapper.BarcodeOfflineMapper;
import com.sv.mapper.DeviceMapper;
import com.sv.service.api.util.DateUtilCard;
import com.ydd.framework.core.common.Pagination;
import com.ydd.framework.core.common.dto.ResponseDTO;
import com.ydd.framework.core.service.impl.BaseServiceImpl;
import org.apache.commons.lang.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
@@ -21,6 +25,7 @@ import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
/**
@@ -40,6 +45,9 @@ public class DeviceService extends BaseServiceImpl {
@Resource
private RestTemplate restTemplate;
@Resource
private BarcodeOfflineMapper barcodeOfflineMapper;
/**
* 创建门禁设备
@@ -206,7 +214,6 @@ public class DeviceService extends BaseServiceImpl {
}
}
/**
* find by DeviceName
*/
@@ -214,5 +221,16 @@ public class DeviceService extends BaseServiceImpl {
return deviceMapper.findByDevice(venueId);
}
public void makeDeviceBarcode(String deviceName, Integer venueId, String barcode) {
BarcodeOffline barcodeOffline = new BarcodeOffline();
Date startTime = new Date();
barcodeOffline.setStartTime(startTime);
barcodeOffline.setEndTime(DateUtils.addHours(startTime,2));
barcodeOffline.setVenueId(venueId);
barcodeOffline.setDeviceName(deviceName);
barcodeOffline.setBarcode(barcode);
barcodeOfflineMapper.insert(barcodeOffline);
}
}

View File

@@ -0,0 +1,109 @@
package com.sv.service.utils;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.ydd.framework.core.exception.ServiceException;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Hashtable;
public class VenueBarcodeUtil {
private static final int BLACK = 0xFF000000;
private static final int WHITE = 0xFFFFFFFF;
private static final int margin = 0;
public static String generateBarcode(String barcodeValue,String fileName) {
try {
String geneFilePath = "/Users/limqhz/home/test/" + fileName;
makeBarcode(geneFilePath,barcodeValue);
return geneFilePath;
}catch (WriterException e) {
throw new ServiceException("生成二维码图片文件有问题");
}
}
private static void makeBarcode(String path, String barcodeValue) throws WriterException {
//二维码内容
String content = barcodeValue;
String format = "jpg";
int width = 200; // 二维码宽度
int height = 200;// 二维码高度
// 设置二维码矩阵的信息
BitMatrix bitMatrix = setBitMatrix(content, width, height);
// 设置输出流
OutputStream outStream = null;
try {
outStream = new FileOutputStream(new File(path));
// 目前 针对容错等级为H reduceWhiteArea 二维码空白区域的大小 根据实际情况设置,如果二维码内容长度不固定的话 需要自己根据实际情况计算reduceWhiteArea的大小
writeToFile(bitMatrix, format, outStream, 5);
outStream.close();
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
outStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 设置生成二维码矩阵信息
* @param content 二维码图片内容
* @param width 二维码图片宽度
* @param height 二维码图片高度
* @throws WriterException
*/
private static BitMatrix setBitMatrix(String content, int width, int height) throws WriterException {
BitMatrix bitMatrix = null;
Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 指定编码方式,避免中文乱码
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 指定纠错等级 如果二维码里面的内容比较多的话推荐使用H 容错率30% 这样可以避免一些扫描不出来的问题
hints.put(EncodeHintType.MARGIN, margin); // 指定二维码四周白色区域大小 官方的这个方法目前没有没有作用默认设置为0
bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
return bitMatrix;
}
/**
* @param matrix
* @param format
* @param outStream
* @param reduceWhiteArea 二维码空白区域设置
* @throws IOException
*/
private static void writeToFile(BitMatrix matrix, String format, OutputStream outStream, int reduceWhiteArea) throws IOException {
BufferedImage image = toBufferedImage(matrix, reduceWhiteArea);
ImageIO.write(image, format, outStream);
}
/**
*
* @param matrix
* @param reduceWhiteArea
* @return
*/
private static BufferedImage toBufferedImage(BitMatrix matrix, int reduceWhiteArea) {
int width = matrix.getWidth();
int height = matrix.getHeight();
BufferedImage image = new BufferedImage(width - 2 * reduceWhiteArea, height - 2 * reduceWhiteArea, BufferedImage.TYPE_3BYTE_BGR);
for (int x = reduceWhiteArea; x < width - reduceWhiteArea; x++) {
for (int y = reduceWhiteArea; y < height - reduceWhiteArea; y++) {
image.setRGB(x - reduceWhiteArea, y - reduceWhiteArea, matrix.get(x, y) ? BLACK : WHITE);
}
}
return image;
}
}

View File

@@ -0,0 +1,152 @@
<?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.BarcodeEnterLogMapper" >
<resultMap id="BaseResultMap" type="com.sv.entity.BarcodeEnterLog" >
<constructor >
<idArg column="id" jdbcType="INTEGER" javaType="java.lang.Integer" />
<arg column="barcode" jdbcType="VARCHAR" javaType="java.lang.String" />
<arg column="venue_id" jdbcType="INTEGER" javaType="java.lang.Integer" />
<arg column="platform_id" 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" />
<arg column="type" jdbcType="INTEGER" javaType="java.lang.Integer" />
</constructor>
</resultMap>
<sql id="Base_Column_List" >
id, barcode, venue_id, platform_id, created_id, modified_id, created_time, modified_time,
type
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
select
<include refid="Base_Column_List" />
from sv_barcode_enter_venue_log
where id = #{id,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
delete from sv_barcode_enter_venue_log
where id = #{id,jdbcType=INTEGER}
</delete>
<insert id="insert" parameterType="com.sv.entity.BarcodeEnterLog" >
insert into sv_barcode_enter_venue_log (id, barcode, venue_id,
platform_id, created_id, modified_id,
created_time, modified_time, type
)
values (#{id,jdbcType=INTEGER}, #{barcode,jdbcType=VARCHAR}, #{venueId,jdbcType=INTEGER},
#{platformId,jdbcType=INTEGER}, #{createdId,jdbcType=INTEGER}, #{modifiedId,jdbcType=INTEGER},
#{createdTime,jdbcType=TIMESTAMP}, #{modifiedTime,jdbcType=TIMESTAMP}, #{type,jdbcType=INTEGER}
)
</insert>
<insert id="insertSelective" parameterType="com.sv.entity.BarcodeEnterLog" >
insert into sv_barcode_enter_venue_log
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="id != null" >
id,
</if>
<if test="barcode != null" >
barcode,
</if>
<if test="venueId != null" >
venue_id,
</if>
<if test="platformId != null" >
platform_id,
</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>
<if test="type != null" >
type,
</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="venueId != null" >
#{venueId,jdbcType=INTEGER},
</if>
<if test="platformId != null" >
#{platformId,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>
<if test="type != null" >
#{type,jdbcType=INTEGER},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.sv.entity.BarcodeEnterLog" >
update sv_barcode_enter_venue_log
<set >
<if test="barcode != null" >
barcode = #{barcode,jdbcType=VARCHAR},
</if>
<if test="venueId != null" >
venue_id = #{venueId,jdbcType=INTEGER},
</if>
<if test="platformId != null" >
platform_id = #{platformId,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>
<if test="type != null" >
type = #{type,jdbcType=INTEGER},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="com.sv.entity.BarcodeEnterLog" >
update sv_barcode_enter_venue_log
set barcode = #{barcode,jdbcType=VARCHAR},
venue_id = #{venueId,jdbcType=INTEGER},
platform_id = #{platformId,jdbcType=INTEGER},
created_id = #{createdId,jdbcType=INTEGER},
modified_id = #{modifiedId,jdbcType=INTEGER},
created_time = #{createdTime,jdbcType=TIMESTAMP},
modified_time = #{modifiedTime,jdbcType=TIMESTAMP},
type = #{type,jdbcType=INTEGER}
where id = #{id,jdbcType=INTEGER}
</update>
<select id="findLastByBarcode" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from sv_barcode_enter_venue_log
WHERE barcode = #{barcode,jdbcType=VARCHAR} order by created_time desc LIMIT 1
</select>
</mapper>

View File

@@ -0,0 +1,314 @@
<?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.BarcodeOfflineMapper">
<resultMap id="BaseResultMap" type="com.sv.entity.BarcodeOffline">
<constructor>
<idArg column="id" javaType="java.lang.Integer" jdbcType="INTEGER" />
<arg column="barcode" javaType="java.lang.String" jdbcType="VARCHAR" />
<arg column="start_time" javaType="java.util.Date" jdbcType="TIMESTAMP" />
<arg column="end_time" javaType="java.util.Date" jdbcType="TIMESTAMP" />
<arg column="venue_id" javaType="java.lang.Integer" jdbcType="INTEGER" />
<arg column="created_id" javaType="java.lang.Integer" jdbcType="INTEGER" />
<arg column="modified_id" javaType="java.lang.Integer" jdbcType="INTEGER" />
<arg column="created_time" javaType="java.util.Date" jdbcType="TIMESTAMP" />
<arg column="modified_time" javaType="java.util.Date" jdbcType="TIMESTAMP" />
<arg column="device_name" javaType="java.lang.String" jdbcType="VARCHAR" />
</constructor>
</resultMap>
<sql id="Base_Column_List">
id, barcode, start_time, end_time, venue_id, created_id, modified_id, created_time,
modified_time, device_name
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from sv_barcode_offline
where id = #{id,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
delete from sv_barcode_offline
where id = #{id,jdbcType=INTEGER}
</delete>
<insert id="insert" parameterType="com.sv.entity.BarcodeOffline">
insert into sv_barcode_offline (id, barcode, start_time,
end_time, venue_id, created_id,
modified_id, created_time, modified_time,
device_name)
values (#{id,jdbcType=INTEGER}, #{barcode,jdbcType=VARCHAR}, #{startTime,jdbcType=TIMESTAMP},
#{endTime,jdbcType=TIMESTAMP}, #{venueId,jdbcType=INTEGER}, #{createdId,jdbcType=INTEGER},
#{modifiedId,jdbcType=INTEGER}, #{createdTime,jdbcType=TIMESTAMP}, #{modifiedTime,jdbcType=TIMESTAMP},
#{deviceName,jdbcType=VARCHAR})
</insert>
<insert id="insertSelective" parameterType="com.sv.entity.BarcodeOffline">
insert into sv_barcode_offline
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="barcode != null">
barcode,
</if>
<if test="startTime != null">
start_time,
</if>
<if test="endTime != null">
end_time,
</if>
<if test="venueId != null">
venue_id,
</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>
<if test="deviceName != null">
device_name,
</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="startTime != null">
#{startTime,jdbcType=TIMESTAMP},
</if>
<if test="endTime != null">
#{endTime,jdbcType=TIMESTAMP},
</if>
<if test="venueId != null">
#{venueId,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>
<if test="deviceName != null">
#{deviceName,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.sv.entity.BarcodeOffline">
update sv_barcode_offline
<set>
<if test="barcode != null">
barcode = #{barcode,jdbcType=VARCHAR},
</if>
<if test="startTime != null">
start_time = #{startTime,jdbcType=TIMESTAMP},
</if>
<if test="endTime != null">
end_time = #{endTime,jdbcType=TIMESTAMP},
</if>
<if test="venueId != null">
venue_id = #{venueId,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>
<if test="deviceName != null">
device_name = #{deviceName,jdbcType=VARCHAR},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="com.sv.entity.BarcodeOffline">
update sv_barcode_offline
set barcode = #{barcode,jdbcType=VARCHAR},
start_time = #{startTime,jdbcType=TIMESTAMP},
end_time = #{endTime,jdbcType=TIMESTAMP},
venue_id = #{venueId,jdbcType=INTEGER},
created_id = #{createdId,jdbcType=INTEGER},
modified_id = #{modifiedId,jdbcType=INTEGER},
created_time = #{createdTime,jdbcType=TIMESTAMP},
modified_time = #{modifiedTime,jdbcType=TIMESTAMP},
device_name = #{deviceName,jdbcType=VARCHAR}
where id = #{id,jdbcType=INTEGER}
</update>
<resultMap id="BaseResultMap" type="com.sv.entity.BarcodeOffline">
<constructor>
<idArg column="id" javaType="java.lang.Integer" jdbcType="INTEGER" />
<arg column="barcode" javaType="java.lang.String" jdbcType="VARCHAR" />
<arg column="start_time" javaType="java.util.Date" jdbcType="TIMESTAMP" />
<arg column="end_time" javaType="java.util.Date" jdbcType="TIMESTAMP" />
<arg column="venue_id" javaType="java.lang.Integer" jdbcType="INTEGER" />
<arg column="created_id" javaType="java.lang.Integer" jdbcType="INTEGER" />
<arg column="modified_id" javaType="java.lang.Integer" jdbcType="INTEGER" />
<arg column="created_time" javaType="java.util.Date" jdbcType="TIMESTAMP" />
<arg column="modified_time" javaType="java.util.Date" jdbcType="TIMESTAMP" />
<arg column="device_name" javaType="java.lang.String" jdbcType="VARCHAR" />
</constructor>
</resultMap>
<sql id="Base_Column_List">
id, barcode, start_time, end_time, venue_id, created_id, modified_id, created_time,
modified_time, device_name
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from sv_barcode_offline
where id = #{id,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
delete from sv_barcode_offline
where id = #{id,jdbcType=INTEGER}
</delete>
<insert id="insert" parameterType="com.sv.entity.BarcodeOffline">
insert into sv_barcode_offline (id, barcode, start_time,
end_time, venue_id, created_id,
modified_id, created_time, modified_time,
device_name)
values (#{id,jdbcType=INTEGER}, #{barcode,jdbcType=VARCHAR}, #{startTime,jdbcType=TIMESTAMP},
#{endTime,jdbcType=TIMESTAMP}, #{venueId,jdbcType=INTEGER}, #{createdId,jdbcType=INTEGER},
#{modifiedId,jdbcType=INTEGER}, #{createdTime,jdbcType=TIMESTAMP}, #{modifiedTime,jdbcType=TIMESTAMP},
#{deviceName,jdbcType=VARCHAR})
</insert>
<insert id="insertSelective" parameterType="com.sv.entity.BarcodeOffline">
insert into sv_barcode_offline
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="barcode != null">
barcode,
</if>
<if test="startTime != null">
start_time,
</if>
<if test="endTime != null">
end_time,
</if>
<if test="venueId != null">
venue_id,
</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>
<if test="deviceName != null">
device_name,
</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="startTime != null">
#{startTime,jdbcType=TIMESTAMP},
</if>
<if test="endTime != null">
#{endTime,jdbcType=TIMESTAMP},
</if>
<if test="venueId != null">
#{venueId,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>
<if test="deviceName != null">
#{deviceName,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.sv.entity.BarcodeOffline">
update sv_barcode_offline
<set>
<if test="barcode != null">
barcode = #{barcode,jdbcType=VARCHAR},
</if>
<if test="startTime != null">
start_time = #{startTime,jdbcType=TIMESTAMP},
</if>
<if test="endTime != null">
end_time = #{endTime,jdbcType=TIMESTAMP},
</if>
<if test="venueId != null">
venue_id = #{venueId,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>
<if test="deviceName != null">
device_name = #{deviceName,jdbcType=VARCHAR},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="com.sv.entity.BarcodeOffline">
update sv_barcode_offline
set barcode = #{barcode,jdbcType=VARCHAR},
start_time = #{startTime,jdbcType=TIMESTAMP},
end_time = #{endTime,jdbcType=TIMESTAMP},
venue_id = #{venueId,jdbcType=INTEGER},
created_id = #{createdId,jdbcType=INTEGER},
modified_id = #{modifiedId,jdbcType=INTEGER},
created_time = #{createdTime,jdbcType=TIMESTAMP},
modified_time = #{modifiedTime,jdbcType=TIMESTAMP},
device_name = #{deviceName,jdbcType=VARCHAR}
where id = #{id,jdbcType=INTEGER}
</update>
<select id="selectByBarcode" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from sv_barcode_offline
where barcode = #{barcode,jdbcType=VARCHAR}
</select>
</mapper>

View File

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