增加netty处理协议
This commit is contained in:
parent
a73d6457de
commit
0079beeac2
|
@ -7,6 +7,7 @@ import org.mybatis.spring.annotation.MapperScan;
|
|||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.web.servlet.ServletComponentScan;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
@ -15,6 +16,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
|
|||
@SpringBootApplication//(exclude = DataSourceAutoConfiguration.class)//排除DataSourceConfiguratrion
|
||||
@EnableCaching
|
||||
@EnableTransactionManagement
|
||||
@ServletComponentScan
|
||||
//@MapperScan("net.shapelight.modules.sys.dao")
|
||||
public class AdminApplication {
|
||||
|
||||
|
|
|
@ -90,5 +90,10 @@ public class GlobalValue {
|
|||
@Value("${global.wx.secret}")
|
||||
private String wxSecret;
|
||||
|
||||
@Value("${global.app.key}")
|
||||
private String appKey;
|
||||
@Value("${global.app.secret}")
|
||||
private String appSecret;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package net.shapelight.common.utils;
|
||||
import java.io.*;
|
||||
import java.util.Base64;
|
||||
import java.util.Date;
|
||||
|
||||
public class ImageUtils {
|
||||
/**
|
||||
|
@ -72,15 +73,17 @@ public class ImageUtils {
|
|||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
String imageStr = GetImageBase64Str("/home/shapelight/upload/1/header.jpg");
|
||||
System.out.println(imageStr);
|
||||
Base64StrToImage(imageStr, "/home/shapelight/upload/1/61.jpg");
|
||||
// String imageStr = GetImageBase64Str("d:/3.jpg");
|
||||
// System.out.println(imageStr);
|
||||
// Base64StrToImage(imageStr, "deviceEntity");
|
||||
|
||||
|
||||
|
||||
File img = new File("/home/shapelight/upload/1/header2.jpg");
|
||||
File img = new File("d:/3.jpg");
|
||||
if(img.exists()){
|
||||
String faceStr = ImageUtils.GetImageBase64Str("/home/shapelight/upload/1/header2.jpg");
|
||||
String faceStr = ImageUtils.GetImageBase64Str("d:/3.jpg");
|
||||
|
||||
long now = new Date().getTime();
|
||||
String a = faceStr;
|
||||
}else{
|
||||
String a = "";
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
package net.shapelight.modules.nettyapi.config;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.util.AttributeKey;
|
||||
import lombok.Data;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
@Component
|
||||
@Data
|
||||
public class ClientMap {
|
||||
|
||||
//用户id=>channel示例
|
||||
private final ConcurrentHashMap<String, Channel> channelMap = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* 判断一个通道是否有用户在使用
|
||||
* 可做信息转发时判断该通道是否合法
|
||||
* @param channel
|
||||
* @return
|
||||
*/
|
||||
public boolean hasUser(Channel channel) {
|
||||
AttributeKey<String> key = AttributeKey.valueOf("user");
|
||||
String kk = channel.attr(key).get();
|
||||
return (channel.hasAttr(key) && channel.attr(key).get() != null);//netty移除了这个map的remove方法,这里的判断谨慎一点
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 上线一个用户
|
||||
*
|
||||
* @param channel
|
||||
* @param userId
|
||||
*/
|
||||
public void online(Channel channel, String userId) {
|
||||
//先判断用户是否在web系统中登录?
|
||||
//这部分代码个人实现,参考上面redis中的验证
|
||||
|
||||
this.channelMap.put(userId, channel);
|
||||
AttributeKey<String> key = AttributeKey.valueOf("user");
|
||||
channel.attr(key).set(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下线一个用户
|
||||
*
|
||||
* @param channel
|
||||
*/
|
||||
public void offline(Channel channel) {
|
||||
Collection<Channel> col = this.channelMap.values();
|
||||
while(true == col.contains(channel)) {
|
||||
col.remove(channel);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户id获取该用户的通道
|
||||
*
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
public Channel getChannelByUserId(String userId) {
|
||||
return this.channelMap.get(userId);
|
||||
}
|
||||
|
||||
public String getUserIdByChannel(Channel channel) {
|
||||
AttributeKey<String> key = AttributeKey.valueOf("user");
|
||||
String kk = channel.attr(key).get();
|
||||
if (channel.hasAttr(key) && channel.attr(key).get() != null){
|
||||
return channel.attr(key).get();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断一个用户是否在线
|
||||
*
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
public Boolean isLogin(String userId) {
|
||||
return this.channelMap.containsKey(userId) && this.channelMap.get(userId) != null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
|
||||
|
||||
package net.shapelight.modules.nettyapi.config;
|
||||
|
||||
/**
|
||||
* 常量
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class CmdConstant {
|
||||
|
||||
public static final byte CMD_LOGIN = 0x01;
|
||||
public static final byte CMD_GETALL = 0x02;
|
||||
public static final byte CMD_GETONE = 0x03;
|
||||
public static final byte CMD_HART = 0x04;
|
||||
public static final byte CMD_UPRECORD = 0x05;
|
||||
public static final byte CMD_EXTRACT = 0x06;
|
||||
|
||||
public static final byte CMD_CONFIG = 0x50;
|
||||
public static final byte CMD_CHANGE = 0x51;
|
||||
public static final byte CMD_OPENDOOR = 0x52;
|
||||
public static final byte CMD_RESTART = 0x53;
|
||||
public static final byte CMD_APPUPDATE = 0x54;
|
||||
public static final byte CMD_CLEANDATA = 0x55;
|
||||
public static final byte CMD_ENABLE = 0x56;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
package net.shapelight.modules.nettyapi.config;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class HttpRequest {
|
||||
/**
|
||||
* 向指定URL发送GET方法的请求
|
||||
*
|
||||
* @param url
|
||||
* 发送请求的URL
|
||||
* @param param
|
||||
* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
|
||||
* @return URL 所代表远程资源的响应结果
|
||||
*/
|
||||
public static String sendGet(String url, String param) {
|
||||
String result = "";
|
||||
BufferedReader in = null;
|
||||
try {
|
||||
String urlNameString = url + "?" + param;
|
||||
URL realUrl = new URL(urlNameString);
|
||||
// 打开和URL之间的连接
|
||||
URLConnection connection = realUrl.openConnection();
|
||||
// 设置通用的请求属性
|
||||
connection.setRequestProperty("accept", "*/*");
|
||||
connection.setRequestProperty("connection", "Keep-Alive");
|
||||
connection.setRequestProperty("user-agent",
|
||||
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
|
||||
// 建立实际的连接
|
||||
connection.connect();
|
||||
// 获取所有响应头字段
|
||||
Map<String, List<String>> map = connection.getHeaderFields();
|
||||
// 遍历所有的响应头字段
|
||||
for (String key : map.keySet()) {
|
||||
// System.out.println(key + "--->" + map.get(key));
|
||||
}
|
||||
// 定义 BufferedReader输入流来读取URL的响应
|
||||
in = new BufferedReader(new InputStreamReader(
|
||||
connection.getInputStream()));
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
result += line;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// System.out.println("发送GET请求出现异常!" + e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 使用finally块来关闭输入流
|
||||
finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
} catch (Exception e2) {
|
||||
e2.printStackTrace();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 向指定 URL 发送POST方法的请求
|
||||
*
|
||||
* @param url
|
||||
* 发送请求的 URL
|
||||
* @param param
|
||||
* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
|
||||
* @return 所代表远程资源的响应结果
|
||||
*/
|
||||
public static String sendPost(String url, String param) {
|
||||
PrintWriter out = null;
|
||||
BufferedReader in = null;
|
||||
String result = "";
|
||||
try {
|
||||
URL realUrl = new URL(url);
|
||||
// 打开和URL之间的连接
|
||||
URLConnection conn = realUrl.openConnection();
|
||||
// 设置通用的请求属性
|
||||
conn.setRequestProperty("accept", "*/*");
|
||||
conn.setRequestProperty("connection", "Keep-Alive");
|
||||
conn.setRequestProperty("user-agent",
|
||||
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
|
||||
// 发送POST请求必须设置如下两行
|
||||
conn.setDoOutput(true);
|
||||
conn.setDoInput(true);
|
||||
// 获取URLConnection对象对应的输出流
|
||||
out = new PrintWriter(conn.getOutputStream());
|
||||
// 发送请求参数
|
||||
out.print(param);
|
||||
// flush输出流的缓冲
|
||||
out.flush();
|
||||
// 定义BufferedReader输入流来读取URL的响应
|
||||
in = new BufferedReader(
|
||||
new InputStreamReader(conn.getInputStream()));
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
result += line;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// System.out.println("发送 POST 请求出现异常!"+e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
//使用finally块来关闭输出流、输入流
|
||||
finally{
|
||||
try{
|
||||
if(out!=null){
|
||||
out.close();
|
||||
}
|
||||
if(in!=null){
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
catch(IOException ex){
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package net.shapelight.modules.nettyapi.config;
|
||||
|
||||
public class MyMessage {
|
||||
/*
|
||||
58 54 5A 47 //消息头 4字节 XTZG
|
||||
01 //版本号 1字节
|
||||
01 //数据类型 1字节 json
|
||||
03 //消息命令 1字节
|
||||
00 00 00 24 //数据长度 4字节 不包含以上头部数据
|
||||
58 23 47 4A //数据 json
|
||||
*/
|
||||
public static final byte[] HEAD = {(byte)0X58,(byte)0X49,(byte)0X54,(byte)0X55}; //4个字节
|
||||
public static final byte version = 0x01; //1个字节
|
||||
public static final byte dataType = 0x01; //1个字节type—负载数据格式,0x01为Json,0x02为xml,0x03为二进制数据;
|
||||
public final byte cmd; //1个字节
|
||||
public final int dataLength; //数据长度4字节
|
||||
public final byte[] content; //数据josn串
|
||||
|
||||
// public static final byte FOOT = (byte)0XFF;
|
||||
public byte[] data;//所有的数据转换为16进制的东东
|
||||
|
||||
public MyMessage(byte cmd,int dataLength,byte[] content) {//decoder用
|
||||
// this.data = data;
|
||||
this.cmd = cmd;
|
||||
this.dataLength = dataLength;
|
||||
this.content = content;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
package net.shapelight.modules.nettyapi.config;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Administrator
|
||||
*
|
||||
*/
|
||||
/*
|
||||
58 54 5A 47 //消息头 4字节 XTZG
|
||||
01 //版本号 1字节
|
||||
01 //数据类型 1字节 json
|
||||
03 //消息命令 1字节
|
||||
00 00 00 24 //数据长度 4字节 不包含以上头部数据
|
||||
54 34 27 8A //数据 json字符串
|
||||
*/
|
||||
@Slf4j
|
||||
public class MyMessageDecoder extends ByteToMessageDecoder {
|
||||
|
||||
private static final int HEAD_LENGTH = 11;//要通过proto_type和msg_type来确定长度的有效性
|
||||
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, ByteBuf in,
|
||||
List<Object> out) throws Exception {
|
||||
|
||||
if (in.readableBytes() < HEAD_LENGTH) {
|
||||
return;
|
||||
}
|
||||
in.markReaderIndex();
|
||||
|
||||
final byte c0 = in.readByte();
|
||||
if((c0&0xFF) != 0x58){
|
||||
in.resetReaderIndex();
|
||||
in.skipBytes(1);
|
||||
// log.debug(String.format("c0:is 0x%x",c0));
|
||||
return;
|
||||
}
|
||||
|
||||
final byte c1 = in.readByte();
|
||||
if((c1&0xFF) != 0x49){
|
||||
in.resetReaderIndex();
|
||||
in.skipBytes(1);
|
||||
// log.debug(String.format("c1:is 0x%x",c1));
|
||||
return;
|
||||
}
|
||||
|
||||
final byte c2 = in.readByte();
|
||||
if((c2&0xFF) != 0x54){
|
||||
in.resetReaderIndex();
|
||||
in.skipBytes(1);
|
||||
// log.debug(String.format("c2:is 0x%x",c2));
|
||||
return;
|
||||
}
|
||||
|
||||
final byte c3 = in.readByte();
|
||||
if((c3&0xFF) != 0x55){
|
||||
in.resetReaderIndex();
|
||||
in.skipBytes(1);
|
||||
// log.debug(String.format("c3:is 0x%x",c3));
|
||||
return;
|
||||
}
|
||||
|
||||
final byte version = in.readByte();
|
||||
final byte dataType = in.readByte();
|
||||
final byte cmd = in.readByte();
|
||||
final int dataLength = in.readInt();
|
||||
|
||||
if(in.readableBytes()<dataLength){
|
||||
in.resetReaderIndex();
|
||||
return;//数据不够,继续读
|
||||
}
|
||||
|
||||
byte[] contentBytes = new byte[dataLength];
|
||||
in.readBytes(contentBytes);
|
||||
|
||||
// if ( (0xff&contentBytes[dataLength - 1]) != 0x7d ){ //0x7d }
|
||||
// in.resetReaderIndex();
|
||||
// in.skipBytes(1);
|
||||
//// log.debug("数据结束符不是}");
|
||||
// return;//in.clear();
|
||||
// }
|
||||
|
||||
// String content = new String(contentBytes);
|
||||
// log.debug("收到数据:"+content);
|
||||
|
||||
final MyMessage o = new MyMessage(cmd,dataLength,contentBytes);// convertToObject(body);
|
||||
out.add(o);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package net.shapelight.modules.nettyapi.config;
|
||||
|
||||
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToByteEncoder;
|
||||
|
||||
public class MyMessageEncoder extends MessageToByteEncoder<MyMessage> {
|
||||
|
||||
@Override
|
||||
protected void encode(ChannelHandlerContext ctx, MyMessage msg, ByteBuf out)
|
||||
throws Exception {
|
||||
// if(msg.data!=null){//手动构建了data直接发就行了
|
||||
// byte[] body = msg.data;
|
||||
// out.writeBytes(body);//消息体中包含我们要发送的数据
|
||||
// return;
|
||||
// }
|
||||
|
||||
out.writeBytes(msg.HEAD);
|
||||
out.writeByte(msg.version);//4个字节,已经测试了
|
||||
out.writeByte(msg.dataType);
|
||||
out.writeByte(msg.cmd);
|
||||
out.writeInt(msg.dataLength);
|
||||
out.writeBytes(msg.content);
|
||||
// if( null != msg.content ){
|
||||
// out.writeBytes(msg.content.getBytes());
|
||||
// }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package net.shapelight.modules.nettyapi.config;
|
||||
|
||||
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.*;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.handler.timeout.IdleStateHandler;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class MyServer {
|
||||
|
||||
private Integer port = 9999;
|
||||
//private final int port = 9102;
|
||||
|
||||
private static EventLoopGroup bossGroup = null; // (1)
|
||||
private static EventLoopGroup workerGroup = null;//
|
||||
// private ChannelFuture cf;
|
||||
|
||||
// private final IMyServerHandler uiHandler;
|
||||
//
|
||||
public MyServer(Integer port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public void run() throws Exception {
|
||||
try {
|
||||
bossGroup = new NioEventLoopGroup(); // (1)
|
||||
workerGroup = new NioEventLoopGroup();
|
||||
ServerBootstrap b = new ServerBootstrap(); // (2)
|
||||
b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) // (3)
|
||||
.childHandler(new ChannelInitializer<SocketChannel>() { // (4)
|
||||
@Override
|
||||
public void initChannel(SocketChannel ch) throws Exception {
|
||||
final ChannelPipeline pipeline = ch.pipeline();
|
||||
// Decoders
|
||||
pipeline.addLast("decoder", new MyMessageDecoder());
|
||||
// Encoder
|
||||
pipeline.addLast("encoder", new MyMessageEncoder());
|
||||
//pipeline.addLast("idleStateHandler", new IdleStateHandler(6, 3, 0));//心跳机制
|
||||
pipeline.addLast("idleStateHandler", new IdleStateHandler(600, 600, 600));//心跳机制
|
||||
pipeline.addLast(new MyServerHandler());
|
||||
}
|
||||
}).option(ChannelOption.SO_BACKLOG, 128) // (5)//BACKLOG用于构造服务端套接字ServerSocket对象,标识当服务器请求处理线程全满时,用于临时存放已完成三次握手的请求的队列的最大长度。如果未设置或所设置的值小于1,Java将使用默认值50。
|
||||
.childOption(ChannelOption.SO_KEEPALIVE, true); // (6)
|
||||
|
||||
// Bind and start to accept incoming connections.
|
||||
ChannelFuture cf = b.bind(port).sync(); // (7)
|
||||
// cf = b.bind(port).sync(); // (7)
|
||||
log.info("Netty已启动正在监听: " + cf.channel().localAddress());
|
||||
// Wait until the server socket is closed.
|
||||
// In this example, this does not happen, but you can do that to gracefully
|
||||
// shut down your server.
|
||||
cf.channel().closeFuture().sync();//保证了服务一直启动,相当于一个死循环
|
||||
} finally {
|
||||
if (null != workerGroup) {
|
||||
workerGroup.shutdownGracefully();
|
||||
workerGroup = null;
|
||||
}
|
||||
if (null != bossGroup) {
|
||||
bossGroup.shutdownGracefully();
|
||||
bossGroup = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (workerGroup != null) {
|
||||
workerGroup.shutdownGracefully();
|
||||
workerGroup = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// public void destroy() {
|
||||
// log.info(MyServer.class + " netty服务监听关闭: " + cf.channel().localAddress());
|
||||
// try {
|
||||
// cf.channel().closeFuture().sync();// 关闭服务器通道
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }finally{
|
||||
// bossGroup.shutdownGracefully().syncUninterruptibly();
|
||||
// workerGroup.shutdownGracefully().syncUninterruptibly();
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
package net.shapelight.modules.nettyapi.config;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.channel.group.ChannelGroup;
|
||||
import io.netty.channel.group.DefaultChannelGroup;
|
||||
import io.netty.handler.timeout.IdleState;
|
||||
import io.netty.handler.timeout.IdleStateEvent;
|
||||
import io.netty.util.concurrent.GlobalEventExecutor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.shapelight.common.utils.SpringContextUtils;
|
||||
import net.shapelight.modules.nettyapi.service.MessageService;
|
||||
|
||||
|
||||
@Slf4j
|
||||
public class MyServerHandler extends SimpleChannelInboundHandler<MyMessage> {
|
||||
private ClientMap clientMap = SpringContextUtils.getBean("clientMap", ClientMap.class);
|
||||
private MessageService messageService = SpringContextUtils.getBean("messageService", MessageService.class);
|
||||
|
||||
private static ChannelGroup clients =new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
|
||||
|
||||
|
||||
// private final IMyServerHandler uiHandler;
|
||||
//
|
||||
// public MyServerHandler(IMyServerHandler uiHandler) {
|
||||
// super();
|
||||
// this.uiHandler = uiHandler;
|
||||
// }
|
||||
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, MyMessage msg)
|
||||
throws Exception {
|
||||
messageService.receive(ctx,msg);
|
||||
|
||||
// switch (msg.cmd) {
|
||||
// //登录
|
||||
// case 0x01: {
|
||||
// deviceLogin(ctx, msg.content);
|
||||
// log.debug("登录信息:" + msg.cmd);
|
||||
// break;
|
||||
// }
|
||||
// case 0x05: {
|
||||
// log.debug("设备注册:" + msg.cmd);
|
||||
// break;
|
||||
// }
|
||||
// case 0x07: {
|
||||
// log.debug("收到心跳:" + msg.cmd);
|
||||
// break;
|
||||
// }
|
||||
// default:
|
||||
// log.debug("unknown cmd type:" + msg.cmd);
|
||||
// break;
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
// 客户端连接之后获取客户端channel并放入group中管理
|
||||
@Override
|
||||
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
|
||||
clients.add(ctx.channel());
|
||||
}
|
||||
|
||||
// 移除对应客户端的channel
|
||||
@Override
|
||||
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
|
||||
// 长短id
|
||||
System.out.println(ctx.channel().id().asLongText());
|
||||
System.out.println(ctx.channel().id().asShortText());
|
||||
clients.remove(ctx.channel());
|
||||
clientMap.offline(ctx.channel());
|
||||
log.info("客户端断开");
|
||||
}
|
||||
|
||||
/**
|
||||
* 发生异常触发
|
||||
*/
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
cause.printStackTrace();
|
||||
ctx.close();
|
||||
clientMap.offline(ctx.channel());
|
||||
log.error("发生异常设备离线"+cause.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
|
||||
//心跳机制 配合ch.pipeline().addLast("idleStateHandler", new IdleStateHandler(60, 30, 0));使用
|
||||
super.userEventTriggered(ctx, evt);
|
||||
if (evt instanceof IdleStateEvent) {
|
||||
IdleStateEvent e = (IdleStateEvent) evt;
|
||||
if (e.state() == IdleState.READER_IDLE) {//没收到任何数据就关掉链接
|
||||
ctx.close();
|
||||
clientMap.offline(ctx.channel());
|
||||
log.info("无数据设备离线");
|
||||
} else if (e.state() == IdleState.WRITER_IDLE) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
package net.shapelight.modules.nettyapi.config;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.support.SpringBeanAutowiringSupport;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
import javax.servlet.annotation.WebListener;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@WebListener
|
||||
@Slf4j
|
||||
public class StartInit implements ServletContextListener {
|
||||
|
||||
@Value("${global.tcp_server.port}")
|
||||
private Integer port;//读取yml的配置:80
|
||||
|
||||
|
||||
//public static final int ASSERT_MAX_SIZE = 2*10*1000;
|
||||
public static final int ASSERT_MAX_SIZE = 10000;
|
||||
public static final int ASSERT_MAX_TIME = 10;//s
|
||||
|
||||
// private final List<PlcMacEntity> list = new ArrayList<PlcMacEntity>(ASSERT_MAX_SIZE);
|
||||
//
|
||||
// private final List<PlcUeEntity> syncUE = new ArrayList<PlcUeEntity>(1);
|
||||
private static final ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
|
||||
private static final ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
|
||||
|
||||
|
||||
//private PlcUeService plcUeSercice;
|
||||
// private IMyServerHandler handler = new IMyServerHandler() {
|
||||
//
|
||||
// @Override
|
||||
// public void do_receive() {
|
||||
//
|
||||
// cachedThreadPool.execute(new Runnable() {
|
||||
//
|
||||
// @Override
|
||||
// public void run() {
|
||||
//// synchronized (list) {
|
||||
//// list.add(mac);
|
||||
//// if(list.size()>ASSERT_MAX_SIZE) {
|
||||
//// final String tableName = plcMacDao.PREFIX+plcMacDao.SDF.format(new Date());
|
||||
//// //macMapper.tryCreateNewTable( tableName );
|
||||
//// //macMapper.insertList(list, tableName );
|
||||
////
|
||||
//// plcMacDao.tryCreateNewTable(tableName);
|
||||
//// plcMacDao.insertList(list, tableName);
|
||||
//// list.clear();
|
||||
//// }
|
||||
//// }
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// //HttpRequest.sendGet("http://127.0.0.1:8080/tl.web/common/macInsert",String.format( "mac=%s&rssi=%s&raw=%s", mac.getMac(),mac.getRssi(),mac.getRaw()));
|
||||
// log.debug("mac...insert...");
|
||||
// }
|
||||
// };
|
||||
|
||||
private MyServer server;
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent arg0) {
|
||||
server.close();
|
||||
// server.destroy();
|
||||
log.info("server closed");
|
||||
// synchronized (list) {
|
||||
// if(list.size()>0) {
|
||||
// final String tableName = plcMacDao.PREFIX+plcMacDao.SDF.format(new Date());
|
||||
// //macMapper.tryCreateNewTable( tableName );
|
||||
// //macMapper.insertList(list, tableName );
|
||||
// plcMacDao.tryCreateNewTable(tableName);
|
||||
// plcMacDao.insertList(list, tableName);
|
||||
// list.clear();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent servletContextEvent) {
|
||||
|
||||
|
||||
// System.out.println("Initialising listener...");
|
||||
// 加入下面的这行代码
|
||||
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
|
||||
// System.out.println("username:" + username + "password:" + password);
|
||||
|
||||
|
||||
WebApplicationContext webApplicationContext= WebApplicationContextUtils.getWebApplicationContext(servletContextEvent.getServletContext());
|
||||
// System.out.println("webApplicationContext:"+webApplicationContext);
|
||||
log.info("webApplicationContext"+webApplicationContext);
|
||||
if(webApplicationContext!=null) {
|
||||
log.info("not nul.....................................");
|
||||
}
|
||||
//macMapper =(MACMapper) webApplicationContext.getBean("macService");
|
||||
//ueMapper =(UEMapper) webApplicationContext.getBean("ueService");
|
||||
// plcMacDao = (PlcMacDao)webApplicationContext.getBean("plcMacDao");
|
||||
// plcUeDao = (PlcUeDao)webApplicationContext.getBean("plcUeDao");
|
||||
log.info("server will init ...");
|
||||
server = new MyServer(port);
|
||||
new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
server.run();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
|
||||
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// synchronized (list) {
|
||||
// if(list.size()<=0) return;
|
||||
// final String tableName = plcMacDao.PREFIX+plcMacDao.SDF.format(new Date());
|
||||
// //macMapper.tryCreateNewTable( tableName );
|
||||
// //macMapper.insertList(list, tableName );
|
||||
// plcMacDao.tryCreateNewTable(tableName);
|
||||
// plcMacDao.insertList(list, tableName);
|
||||
// list.clear();
|
||||
// }
|
||||
}
|
||||
},1, ASSERT_MAX_TIME, TimeUnit.SECONDS);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package net.shapelight.modules.nettyapi.service;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
|
||||
public interface DeviceApiService {
|
||||
|
||||
void login(Channel channel, String content);
|
||||
void getAllMember(Channel channel, String content);
|
||||
void getMemberInfo(Channel channel, String content);
|
||||
void heartbeat(Channel channel, String content);
|
||||
void saveRecord(Channel channel, String content);
|
||||
void extract(Channel channel, String content);
|
||||
|
||||
boolean isOnline(String sn);
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package net.shapelight.modules.nettyapi.service;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import net.shapelight.modules.nettyapi.config.MyMessage;
|
||||
|
||||
public interface MessageService {
|
||||
|
||||
void receive(ChannelHandlerContext ctx, MyMessage content);
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package net.shapelight.modules.nettyapi.service;
|
||||
|
||||
|
||||
import net.shapelight.modules.vo.TenAppVerison;
|
||||
import net.shapelight.modules.vo.TenDeviceConfig;
|
||||
|
||||
public interface ServerApiService {
|
||||
|
||||
int devConfig(String sn, TenDeviceConfig dc);
|
||||
|
||||
int restart(String sn);
|
||||
|
||||
int cleanData(String sn);
|
||||
|
||||
int openDoor(String sn, Long personId);
|
||||
|
||||
int enableDevice(String sn);
|
||||
|
||||
int appUpdate(String sn,TenAppVerison appVerison);
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,422 @@
|
|||
package net.shapelight.modules.nettyapi.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import io.netty.channel.Channel;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.shapelight.common.config.GlobalValue;
|
||||
import net.shapelight.common.utils.DateUtils;
|
||||
import net.shapelight.common.utils.ImageUtils;
|
||||
import net.shapelight.common.utils.TreeUtils;
|
||||
import net.shapelight.common.utils.UUIDUtil;
|
||||
import net.shapelight.modules.nettyapi.config.ClientMap;
|
||||
import net.shapelight.modules.nettyapi.config.CmdConstant;
|
||||
import net.shapelight.modules.nettyapi.config.MyMessage;
|
||||
import net.shapelight.modules.nettyapi.service.DeviceApiService;
|
||||
import net.shapelight.modules.nettyapi.service.ServerApiService;
|
||||
import net.shapelight.modules.nettyapi.utils.Result;
|
||||
import net.shapelight.modules.ten.entity.*;
|
||||
import net.shapelight.modules.ten.service.*;
|
||||
import net.shapelight.modules.vo.TenPersonIdUpdateAllVo;
|
||||
import net.shapelight.modules.vo.TenPersonIdUpdateVo;
|
||||
import net.shapelight.modules.vo.TenUserVo;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Service("deviceApiService")
|
||||
public class DeviceApiServiceImpl implements DeviceApiService {
|
||||
@Autowired
|
||||
ClientMap clientMap;
|
||||
@Autowired
|
||||
private TenDeviceService tenDeviceService;
|
||||
@Autowired
|
||||
private GlobalValue globalValue;
|
||||
@Autowired
|
||||
private TenRecordService tenRecordService;
|
||||
@Autowired
|
||||
private ServerApiService serverApiService;
|
||||
@Autowired
|
||||
private TenCellService tenCellService;
|
||||
@Autowired
|
||||
private TenPersonService tenPersonService;
|
||||
@Autowired
|
||||
private TenDeviceAlertService tenDeviceAlertService;
|
||||
@Autowired
|
||||
private TenPersonExtractService tenPersonExtractService;
|
||||
|
||||
|
||||
/*
|
||||
请求示例
|
||||
{
|
||||
"app_key": "0fksdjfkjd",
|
||||
"app_secret":"239i0r230ur0932u",
|
||||
"dev_id":"3cde32ef123"
|
||||
}
|
||||
返回示例
|
||||
|
||||
{
|
||||
"code": 200,
|
||||
"msg":"success",
|
||||
"data": {
|
||||
"area_id": "23948203",
|
||||
"area_name": "山海城,软件园,航城一小",
|
||||
"building_id": "123",
|
||||
"buiding_name": "3栋1单元,A2栋,1年级1班" ,
|
||||
"config":{
|
||||
"work_mode":0,
|
||||
"recognize_interval":3,
|
||||
"relay_suck_time":5,
|
||||
"support_liveness":true,
|
||||
"liveness_score":60,
|
||||
"recognize_score":65,
|
||||
"recognize_distance":2,
|
||||
"alert_temp_threshold":37.3,
|
||||
"upload_face_pic":true,
|
||||
"upload_pic_mode":0,
|
||||
"upload_http_url":"http://upload.face.com/face/pic/upload",
|
||||
"support_stranger":false
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
//0x01 0x02
|
||||
public void login(Channel channel, String content) {
|
||||
JSONObject loginJson = JSONObject.parseObject(content);
|
||||
|
||||
String gAppKey = globalValue.getAppKey();
|
||||
String gAppSecret = globalValue.getAppSecret();
|
||||
|
||||
String appKey = loginJson.getString("app_key");
|
||||
String appSecret = loginJson.getString("app_secret");
|
||||
String devId = loginJson.getString("dev_id");
|
||||
|
||||
if(appKey==null || appKey.length()==0 || appSecret == null || appSecret.length()==0
|
||||
|| !gAppKey.equals(appKey) || !gAppSecret.equals(appSecret)){
|
||||
Result res = Result.error(203, "App key or App Secret Error");
|
||||
String resContent = JSONObject.toJSONString(res);
|
||||
MyMessage message = new MyMessage(CmdConstant.CMD_LOGIN,resContent.length(),resContent.getBytes());
|
||||
channel.writeAndFlush(message);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//设备sn不能为空
|
||||
if (devId == null || devId.isEmpty()) {
|
||||
Result res = Result.error(201, "Device Is Not Bind");
|
||||
String resContent = JSONObject.toJSONString(res);
|
||||
MyMessage message = new MyMessage(CmdConstant.CMD_LOGIN,resContent.length(),resContent.getBytes());
|
||||
channel.writeAndFlush(message);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//1.判断sn是否存在 设备不存在1002
|
||||
|
||||
TenDeviceEntity deviceEntity = tenDeviceService.findBySn(devId);
|
||||
if(deviceEntity == null){
|
||||
Result res = Result.error(201, "Device Is Not Bind");
|
||||
String resContent = JSONObject.toJSONString(res);
|
||||
MyMessage message = new MyMessage(CmdConstant.CMD_LOGIN,resContent.length(),resContent.getBytes());
|
||||
channel.writeAndFlush(message);
|
||||
return;
|
||||
}
|
||||
|
||||
TenCellEntity cellEntity = tenCellService.getById(deviceEntity.getCellId());
|
||||
|
||||
Result res = new Result();
|
||||
Map<String,Object> dataMap = new HashMap<>();
|
||||
dataMap.put("area_id",cellEntity.getCellId().toString());
|
||||
dataMap.put("area_name",cellEntity.getName());
|
||||
dataMap.put("building_id",cellEntity.getCellId().toString());
|
||||
dataMap.put("building_name",cellEntity.getName());
|
||||
|
||||
Map<String,Object> configMap = new HashMap<>();
|
||||
configMap.put("work_mode",0);
|
||||
configMap.put("recognize_interval",3);
|
||||
configMap.put("relay_suck_time",5);
|
||||
configMap.put("support_liveness",true);
|
||||
configMap.put("liveness_score",60);
|
||||
configMap.put("recognize_score",65);
|
||||
configMap.put("recognize_distance",2);
|
||||
configMap.put("alert_temp_threshold",37.3);
|
||||
configMap.put("upload_face_pic",true);
|
||||
configMap.put("upload_pic_mode",0);
|
||||
configMap.put("upload_http_url","http://upload.face.com/face/pic/upload");
|
||||
configMap.put("support_stranger",false);
|
||||
|
||||
|
||||
dataMap.put("config",configMap);
|
||||
res.put("data",dataMap);
|
||||
String resContent = JSONObject.toJSONString(res);
|
||||
MyMessage message = new MyMessage(CmdConstant.CMD_LOGIN,resContent.getBytes().length,resContent.getBytes());
|
||||
channel.writeAndFlush(message);
|
||||
|
||||
|
||||
clientMap.online(channel, devId);
|
||||
tenDeviceService.updateById(deviceEntity);
|
||||
|
||||
log.debug("设备:" + devId + " 登录");
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {
|
||||
* "dev_id":"3cde32ef123"
|
||||
* }
|
||||
*/
|
||||
@Override
|
||||
public void getAllMember(Channel channel, String content) {
|
||||
JSONObject jsonContent = JSONObject.parseObject(content);
|
||||
String devId = jsonContent.getString("dev_id");
|
||||
TenDeviceEntity deviceEntity = tenDeviceService.findBySn(devId);
|
||||
if(deviceEntity == null){
|
||||
log.error("设备已删除");
|
||||
return;
|
||||
}
|
||||
|
||||
TenCellEntity cellEntity = tenCellService.getById(deviceEntity.getCellId());
|
||||
|
||||
List<TenPersonIdUpdateAllVo> all = tenPersonService.findAllPersonIdUpdateAll(cellEntity.getCellId(),null,null);
|
||||
|
||||
Result res = new Result();
|
||||
res.put("data",all);
|
||||
String resContent = JSONObject.toJSONString(res);
|
||||
MyMessage message = new MyMessage(CmdConstant.CMD_GETALL,resContent.getBytes().length,resContent.getBytes());
|
||||
channel.writeAndFlush(message);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
{
|
||||
"dev_id":"3cde32ef123",
|
||||
"uid":12000
|
||||
}
|
||||
*/
|
||||
@Override
|
||||
public void getMemberInfo(Channel channel, String content) {
|
||||
JSONObject jsonContent = JSONObject.parseObject(content);
|
||||
|
||||
String devId = jsonContent.getString("dev_id");
|
||||
Long uid = jsonContent.getLong("uid");
|
||||
|
||||
TenDeviceEntity deviceEntity = tenDeviceService.findBySn(devId);
|
||||
if(deviceEntity == null){
|
||||
log.error("设备已删除");
|
||||
return;
|
||||
}
|
||||
|
||||
TenCellEntity cellEntity = tenCellService.getById(deviceEntity.getCellId());
|
||||
|
||||
TenPersonEntity p = tenPersonService.getById(uid,cellEntity.getCellId());
|
||||
TenUserVo puser = new TenUserVo();
|
||||
|
||||
puser.setUid(p.getPersonId());
|
||||
puser.setUser_name(p.getName());
|
||||
puser.setUser_type(0);
|
||||
puser.setActive_start_time(0);
|
||||
puser.setActive_end_time(0);
|
||||
puser.setLast_update_stamp(p.getLastUpdateTime().getTime());
|
||||
puser.setCard_id("");
|
||||
puser.setFace_pic_download_url(globalValue.getMinioEndpoint()+"/"
|
||||
+ globalValue.getMinioBucketName()+"/"
|
||||
+ p.getOrgImage());
|
||||
puser.setFace_pic_base64("");
|
||||
|
||||
|
||||
Result res = new Result();
|
||||
res.put("data",puser);
|
||||
String resContent = JSONObject.toJSONString(res);
|
||||
MyMessage message = new MyMessage(CmdConstant.CMD_GETONE,resContent.getBytes().length,resContent.getBytes());
|
||||
channel.writeAndFlush(message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
{
|
||||
"dev_id":"3cde32ef123",
|
||||
"face_count":3232,
|
||||
"rgb_camera_status":0,
|
||||
"ir_camera_status":0
|
||||
"relay_status":0
|
||||
}
|
||||
*/
|
||||
@Override
|
||||
public void heartbeat(Channel channel, String content) {
|
||||
JSONObject jsonContent = JSONObject.parseObject(content);
|
||||
|
||||
String sn = jsonContent.getString("dev_id");
|
||||
|
||||
Integer faceCount = jsonContent.getIntValue("face_count");
|
||||
Integer rgbCameraStatus = jsonContent.getIntValue("rgb_camera_status");
|
||||
Integer irCameraStatus = jsonContent.getIntValue("ir_camera_status");
|
||||
Integer relayStatus = jsonContent.getIntValue("relay_status");
|
||||
|
||||
TenDeviceEntity deviceEntity = tenDeviceService.findBySn(sn);
|
||||
|
||||
if(deviceEntity == null){
|
||||
log.error("设备已删除");
|
||||
return;
|
||||
}
|
||||
|
||||
//保存人脸个数
|
||||
deviceEntity.setFaceCount(faceCount);
|
||||
tenDeviceService.updateById(deviceEntity);
|
||||
|
||||
TenCellEntity cellEntity = tenCellService.getById(deviceEntity.getCellId());
|
||||
|
||||
Date now = new Date();
|
||||
|
||||
//保存告警信息
|
||||
if(rgbCameraStatus.intValue() == 1){
|
||||
TenDeviceAlertEntity da = new TenDeviceAlertEntity();
|
||||
da.setSn(sn);
|
||||
da.setCellId(cellEntity.getCellId());
|
||||
da.setAlertLevel("严重");
|
||||
da.setAlertType("故障");
|
||||
da.setAlertTime(now);
|
||||
da.setErrorLog("RGB摄像头故障");
|
||||
tenDeviceAlertService.save(da);
|
||||
}
|
||||
|
||||
if(irCameraStatus.intValue() == 1){
|
||||
TenDeviceAlertEntity da = new TenDeviceAlertEntity();
|
||||
da.setSn(sn);
|
||||
da.setCellId(cellEntity.getCellId());
|
||||
da.setAlertLevel("严重");
|
||||
da.setAlertType("故障");
|
||||
da.setAlertTime(now);
|
||||
da.setErrorLog("红外摄像头故障");
|
||||
tenDeviceAlertService.save(da);
|
||||
}
|
||||
|
||||
if(relayStatus.intValue() == 1){
|
||||
TenDeviceAlertEntity da = new TenDeviceAlertEntity();
|
||||
da.setSn(sn);
|
||||
da.setCellId(cellEntity.getCellId());
|
||||
da.setAlertLevel("严重");
|
||||
da.setAlertType("故障");
|
||||
da.setAlertTime(now);
|
||||
da.setErrorLog("继电器故障");
|
||||
tenDeviceAlertService.save(da);
|
||||
}
|
||||
|
||||
Result res = new Result();
|
||||
String resContent = JSONObject.toJSONString(res);
|
||||
MyMessage message = new MyMessage(CmdConstant.CMD_HART,resContent.getBytes().length,resContent.getBytes());
|
||||
channel.writeAndFlush(message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
{
|
||||
"dev_id":"3cde32ef123",
|
||||
"uid":10003,
|
||||
"unlock_mode":0,
|
||||
"unlock_time":156002322,
|
||||
"capture_face_pic":"base64 image"
|
||||
}
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveRecord(Channel channel, String content) {
|
||||
JSONObject jsonContent = JSONObject.parseObject(content);
|
||||
String sn = jsonContent.getString("dev_id");
|
||||
|
||||
Long personId = jsonContent.getLongValue("uid");
|
||||
Integer unlockMode = jsonContent.getIntValue("unlock_mode");
|
||||
Long unlockTime = jsonContent.getLongValue("unlock_time");
|
||||
unlockTime = unlockTime*1000;
|
||||
String captureFacePic = jsonContent.getString("capture_face_pic");
|
||||
|
||||
TenDeviceEntity deviceEntity = tenDeviceService.findBySn(sn);
|
||||
|
||||
if(deviceEntity == null){
|
||||
log.error("设备已删除");
|
||||
return;
|
||||
}
|
||||
TenCellEntity cellEntity = tenCellService.getById(deviceEntity.getCellId());
|
||||
TenRecordEntity record = new TenRecordEntity();
|
||||
record.setDeviceSn(sn);
|
||||
record.setDeviceName(deviceEntity.getName());
|
||||
record.setCellId(deviceEntity.getCellId());
|
||||
record.setPersonId(personId);
|
||||
record.setOpenType(unlockMode);
|
||||
record.setRecordTime(new Date(unlockTime));
|
||||
record.setRecordFaceStr(captureFacePic);
|
||||
record.setTenantId(deviceEntity.getTenantId());
|
||||
|
||||
// log.info("保存记录:----------------------"+record.getRecordTime()+"-"+record.getMemberId().intValue());
|
||||
tenRecordService.saveForFace(record);
|
||||
|
||||
Result res = new Result();
|
||||
String resContent = JSONObject.toJSONString(res);
|
||||
MyMessage message = new MyMessage(CmdConstant.CMD_UPRECORD,resContent.getBytes().length,resContent.getBytes());
|
||||
channel.writeAndFlush(message);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
{
|
||||
"dev_id":"3cde32ef123",
|
||||
"uid":3232,
|
||||
"user_type":0,
|
||||
"state":0
|
||||
}
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void extract(Channel channel, String content) {
|
||||
JSONObject jsonContent = JSONObject.parseObject(content);
|
||||
String sn = jsonContent.getString("dev_id");
|
||||
|
||||
Long personId = jsonContent.getLongValue("uid");
|
||||
Integer userType = jsonContent.getIntValue("user_type");
|
||||
Integer state = jsonContent.getIntValue("state");
|
||||
|
||||
TenDeviceEntity deviceEntity = tenDeviceService.findBySn(sn);
|
||||
|
||||
if(deviceEntity == null){
|
||||
log.error("设备已删除");
|
||||
return;
|
||||
}
|
||||
TenCellEntity cellEntity = tenCellService.getById(deviceEntity.getCellId());
|
||||
|
||||
|
||||
TenPersonExtractEntity extract = new TenPersonExtractEntity();
|
||||
extract.setDeviceSn(sn);
|
||||
extract.setExtractTime(new Date());
|
||||
extract.setPersonId(personId);
|
||||
extract.setPersonType(userType);
|
||||
extract.setState(state);
|
||||
extract.setCellId(cellEntity.getCellId());
|
||||
extract.setTenantId(cellEntity.getTenantId());
|
||||
|
||||
tenPersonExtractService.save(extract);
|
||||
|
||||
Result res = new Result();
|
||||
String resContent = JSONObject.toJSONString(res);
|
||||
MyMessage message = new MyMessage(CmdConstant.CMD_EXTRACT,resContent.getBytes().length,resContent.getBytes());
|
||||
channel.writeAndFlush(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnline(String sn) {
|
||||
return clientMap.isLogin(sn);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
package net.shapelight.modules.nettyapi.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.shapelight.modules.nettyapi.config.ClientMap;
|
||||
import net.shapelight.modules.nettyapi.config.CmdConstant;
|
||||
import net.shapelight.modules.nettyapi.config.MyMessage;
|
||||
import net.shapelight.modules.nettyapi.service.DeviceApiService;
|
||||
import net.shapelight.modules.nettyapi.service.MessageService;
|
||||
import net.shapelight.modules.nettyapi.utils.Result;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
//import net.sf.ehcache.CacheManager;
|
||||
|
||||
@Slf4j
|
||||
@Service("messageService")
|
||||
public class MessageServiceImpl implements MessageService {
|
||||
@Autowired
|
||||
private DeviceApiService deviceApiService;
|
||||
@Autowired
|
||||
private ClientMap clientMap;
|
||||
@Autowired
|
||||
private CacheManager cacheManager;
|
||||
|
||||
@Override
|
||||
public void receive(ChannelHandlerContext ctx, MyMessage msg) {
|
||||
Channel channel = ctx.channel();
|
||||
String content = new String(msg.content);
|
||||
|
||||
|
||||
switch (msg.cmd) {
|
||||
//登录
|
||||
case CmdConstant.CMD_LOGIN: {
|
||||
// deviceLogin(ctx, msg.content);
|
||||
deviceApiService.login(channel,content);
|
||||
log.debug("登录信息:" + msg.cmd);
|
||||
break;
|
||||
}
|
||||
|
||||
case CmdConstant.CMD_GETALL: {
|
||||
log.debug("全量获取:" + msg.cmd);
|
||||
if(!clientMap.hasUser(channel)){
|
||||
Result res = Result.error(403,"No permission");
|
||||
String resContent = JSONObject.toJSONString(res);
|
||||
MyMessage message = new MyMessage(CmdConstant.CMD_GETALL,resContent.length(),resContent.getBytes());
|
||||
channel.writeAndFlush(message);
|
||||
return;
|
||||
}
|
||||
deviceApiService.getAllMember(channel,content);
|
||||
break;
|
||||
}
|
||||
case CmdConstant.CMD_GETONE: {
|
||||
log.debug("获取详情:" + msg.cmd);
|
||||
deviceApiService.getMemberInfo(channel,content);
|
||||
if(!clientMap.hasUser(channel)){
|
||||
Result res = Result.error(403,"No permission");
|
||||
String resContent = JSONObject.toJSONString(res);
|
||||
MyMessage message = new MyMessage(CmdConstant.CMD_GETONE,resContent.length(),resContent.getBytes());
|
||||
channel.writeAndFlush(message);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CmdConstant.CMD_HART: {
|
||||
log.debug("收到心跳:" + msg.cmd);
|
||||
if(!clientMap.hasUser(channel)){
|
||||
Result res = Result.error(403,"No permission");
|
||||
String resContent = JSONObject.toJSONString(res);
|
||||
MyMessage message = new MyMessage(CmdConstant.CMD_HART,resContent.length(),resContent.getBytes());
|
||||
channel.writeAndFlush(message);
|
||||
return;
|
||||
}
|
||||
deviceApiService.heartbeat(channel,content);
|
||||
break;
|
||||
}
|
||||
|
||||
case CmdConstant.CMD_UPRECORD: {
|
||||
log.debug("收到上传记录:" + msg.cmd);
|
||||
if(!clientMap.hasUser(channel)){
|
||||
Result res = Result.error(403,"No permission");
|
||||
String resContent = JSONObject.toJSONString(res);
|
||||
MyMessage message = new MyMessage(CmdConstant.CMD_UPRECORD,resContent.length(),resContent.getBytes());
|
||||
channel.writeAndFlush(message);
|
||||
return;
|
||||
}
|
||||
deviceApiService.saveRecord(channel,content);
|
||||
break;
|
||||
}
|
||||
|
||||
case CmdConstant.CMD_EXTRACT: {
|
||||
log.debug("提取失败log:" + msg.cmd);
|
||||
if(!clientMap.hasUser(channel)){
|
||||
Result res = Result.error(403,"No permission");
|
||||
String resContent = JSONObject.toJSONString(res);
|
||||
MyMessage message = new MyMessage(CmdConstant.CMD_EXTRACT,resContent.length(),resContent.getBytes());
|
||||
channel.writeAndFlush(message);
|
||||
return;
|
||||
}
|
||||
deviceApiService.extract(channel,content);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case CmdConstant.CMD_CONFIG: {
|
||||
log.debug("配置成功:" + msg.cmd);
|
||||
break;
|
||||
}
|
||||
|
||||
case CmdConstant.CMD_CHANGE: {
|
||||
log.debug("人员变更成功:" + msg.cmd);
|
||||
break;
|
||||
}
|
||||
|
||||
case CmdConstant.CMD_OPENDOOR: {
|
||||
log.debug("远程开门:" + msg.cmd);
|
||||
break;
|
||||
}
|
||||
|
||||
case CmdConstant.CMD_RESTART: {
|
||||
log.debug("重启设备:" + msg.cmd);
|
||||
break;
|
||||
}
|
||||
|
||||
case CmdConstant.CMD_APPUPDATE: {
|
||||
log.debug("app升级:" + msg.cmd);
|
||||
break;
|
||||
}
|
||||
|
||||
case CmdConstant.CMD_CLEANDATA: {
|
||||
log.debug("清除数据:" + msg.cmd);
|
||||
break;
|
||||
}
|
||||
|
||||
case CmdConstant.CMD_ENABLE: {
|
||||
log.debug("停用设备:" + msg.cmd);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
log.debug("unknown cmd type:" + msg.cmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
package net.shapelight.modules.nettyapi.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.netty.channel.Channel;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.shapelight.modules.nettyapi.config.ClientMap;
|
||||
import net.shapelight.modules.nettyapi.config.CmdConstant;
|
||||
import net.shapelight.modules.nettyapi.config.MyMessage;
|
||||
import net.shapelight.modules.nettyapi.service.ServerApiService;
|
||||
import net.shapelight.modules.ten.entity.TenDeviceEntity;
|
||||
import net.shapelight.modules.ten.service.TenDeviceService;
|
||||
import net.shapelight.modules.vo.TenAppVerison;
|
||||
import net.shapelight.modules.vo.TenDeviceConfig;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Service("serverApiService")
|
||||
public class ServerApiServiceImpl implements ServerApiService {
|
||||
@Autowired
|
||||
ClientMap clientMap;
|
||||
@Autowired
|
||||
private TenDeviceService tenDeviceService;
|
||||
|
||||
|
||||
@Override
|
||||
public int devConfig(String sn,TenDeviceConfig dc) {
|
||||
Channel channel = clientMap.getChannelByUserId(sn);
|
||||
if(channel == null){
|
||||
return -1;
|
||||
}
|
||||
// Map<String,Object> data = new HashMap<>();
|
||||
// data.put("data",data);
|
||||
String content = JSONObject.toJSONString(dc);
|
||||
MyMessage message = new MyMessage(CmdConstant.CMD_CONFIG,content.length(),content.getBytes());
|
||||
channel.writeAndFlush(message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int openDoor(String sn,Long personId) {
|
||||
Channel channel = clientMap.getChannelByUserId(sn);
|
||||
if(channel == null){
|
||||
return -1;
|
||||
}
|
||||
Map<String,Object> data = new HashMap<>();
|
||||
data.put("dev_id",sn);
|
||||
data.put("uid",personId);
|
||||
String content = JSONObject.toJSONString(data);
|
||||
MyMessage message = new MyMessage(CmdConstant.CMD_OPENDOOR,content.length(),content.getBytes());
|
||||
channel.writeAndFlush(message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int restart(String sn) {
|
||||
Channel channel = clientMap.getChannelByUserId(sn);
|
||||
if(channel == null){
|
||||
return -1;
|
||||
}
|
||||
Map<String,Object> data = new HashMap<>();
|
||||
data.put("dev_id",sn);
|
||||
String content = JSONObject.toJSONString(data);
|
||||
MyMessage message = new MyMessage(CmdConstant.CMD_RESTART,content.length(),content.getBytes());
|
||||
channel.writeAndFlush(message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int cleanData(String sn) {
|
||||
Channel channel = clientMap.getChannelByUserId(sn);
|
||||
if(channel == null){
|
||||
return -1;
|
||||
}
|
||||
Map<String,Object> data = new HashMap<>();
|
||||
data.put("dev_id",sn);
|
||||
String content = JSONObject.toJSONString(data);
|
||||
MyMessage message = new MyMessage(CmdConstant.CMD_CLEANDATA,content.length(),content.getBytes());
|
||||
channel.writeAndFlush(message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int enableDevice(String sn) {
|
||||
Channel channel = clientMap.getChannelByUserId(sn);
|
||||
if(channel == null){
|
||||
return -1;
|
||||
}
|
||||
Map<String,Object> data = new HashMap<>();
|
||||
data.put("dev_id",sn);
|
||||
String content = JSONObject.toJSONString(data);
|
||||
MyMessage message = new MyMessage(CmdConstant.CMD_ENABLE,content.length(),content.getBytes());
|
||||
channel.writeAndFlush(message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int appUpdate(String sn, TenAppVerison appVerison) {
|
||||
Channel channel = clientMap.getChannelByUserId(sn);
|
||||
if(channel == null){
|
||||
return -1;
|
||||
}
|
||||
// Map<String,Object> data = new HashMap<>();
|
||||
// data.put("data",data);
|
||||
String content = JSONObject.toJSONString(appVerison);
|
||||
MyMessage message = new MyMessage(CmdConstant.CMD_APPUPDATE,content.length(),content.getBytes());
|
||||
channel.writeAndFlush(message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
|
||||
|
||||
package net.shapelight.modules.nettyapi.utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 返回数据
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class Result extends HashMap<String, Object> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/*
|
||||
{
|
||||
"result": 200,
|
||||
"desc": "Success",
|
||||
"data":{}
|
||||
}
|
||||
*/
|
||||
|
||||
public Result() {
|
||||
put("code", 200);
|
||||
put("msg", "success");
|
||||
put("data", new HashMap<>());
|
||||
}
|
||||
|
||||
public static Result error() {
|
||||
return error(500, "未知异常,请联系管理员");
|
||||
}
|
||||
|
||||
public static Result error(String msg) {
|
||||
return error(500, msg);
|
||||
}
|
||||
|
||||
public static Result error(int code, String msg) {
|
||||
Result r = new Result();
|
||||
r.put("code", code);
|
||||
r.put("msg", msg);
|
||||
r.put("data",new HashMap<>());
|
||||
return r;
|
||||
}
|
||||
|
||||
public static Result ok(String desc) {
|
||||
Result r = new Result();
|
||||
r.put("msg", desc);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static Result ok(Map<String, Object> map) {
|
||||
Result r = new Result();
|
||||
r.putAll(map);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static Result ok() {
|
||||
return new Result();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result put(String key, Object value) {
|
||||
super.put(key, value);
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ import io.swagger.annotations.ApiOperation;
|
|||
import net.shapelight.common.utils.Constant;
|
||||
import net.shapelight.modules.dev.mqtt.CmdProcess;
|
||||
import net.shapelight.modules.dev.mqtt.EmqHttpApi;
|
||||
import net.shapelight.modules.nettyapi.service.ServerApiService;
|
||||
import net.shapelight.modules.sys.controller.AbstractController;
|
||||
import net.shapelight.modules.sys.entity.SysDeviceAppEntity;
|
||||
import net.shapelight.modules.sys.entity.SysDeviceEntity;
|
||||
|
@ -22,6 +23,8 @@ import net.shapelight.modules.sys.service.SysUserRoleService;
|
|||
import net.shapelight.modules.ten.entity.TenUserScopeEntity;
|
||||
import net.shapelight.modules.ten.service.TenCellService;
|
||||
import net.shapelight.modules.ten.service.TenUserScopeService;
|
||||
import net.shapelight.modules.vo.TenAppVerison;
|
||||
import net.shapelight.modules.vo.TenDeviceConfig;
|
||||
import net.shapelight.modules.vo.TenDeviceParamVo;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
@ -58,6 +61,8 @@ public class TenDeviceController extends AbstractController {
|
|||
private SysDeviceAppService sysDeviceAppService;
|
||||
@Autowired
|
||||
private EmqHttpApi emqHttpApi;
|
||||
@Autowired
|
||||
private ServerApiService serverApiService;
|
||||
|
||||
/**
|
||||
* 列表
|
||||
|
@ -154,6 +159,21 @@ public class TenDeviceController extends AbstractController {
|
|||
public R cleanPerson(@RequestBody Map<String, Object> deviceSn){
|
||||
String sn = (String)deviceSn.get("deviceSn");
|
||||
CmdProcess.publishCleanPerson(sn);
|
||||
//清除数据
|
||||
int r = serverApiService.cleanData(sn);
|
||||
|
||||
//配置参数
|
||||
TenDeviceConfig dc = new TenDeviceConfig();
|
||||
int s = serverApiService.devConfig(sn,dc);
|
||||
for(int i =0;i<1000;i++){
|
||||
|
||||
}
|
||||
//升级app
|
||||
TenAppVerison v = new TenAppVerison();
|
||||
int a = serverApiService.appUpdate(sn,v);
|
||||
if(r == -1){
|
||||
return R.error("设备离线");
|
||||
}
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
package net.shapelight.modules.ten.controller;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import net.shapelight.modules.ten.entity.TenPersonExtractEntity;
|
||||
import net.shapelight.modules.ten.service.TenPersonExtractService;
|
||||
import net.shapelight.common.utils.PageUtils;
|
||||
import net.shapelight.common.utils.R;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("ten/personextract")
|
||||
public class TenPersonExtractController {
|
||||
@Autowired
|
||||
private TenPersonExtractService tenPersonExtractService;
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
@RequiresPermissions("ten:personextract:list")
|
||||
public R list(@RequestParam Map<String, Object> params){
|
||||
PageUtils page = tenPersonExtractService.queryPage(params);
|
||||
|
||||
return R.ok().put("data", page);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 信息
|
||||
*/
|
||||
@GetMapping("/info/{extractId}")
|
||||
@RequiresPermissions("ten:personextract:info")
|
||||
public R info(@PathVariable("extractId") Long extractId){
|
||||
TenPersonExtractEntity tenPersonExtract = tenPersonExtractService.getById(extractId);
|
||||
|
||||
return R.ok().put("data", tenPersonExtract);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*/
|
||||
@PostMapping("/save")
|
||||
@RequiresPermissions("ten:personextract:save")
|
||||
public R save(@RequestBody TenPersonExtractEntity tenPersonExtract){
|
||||
tenPersonExtractService.save(tenPersonExtract);
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*/
|
||||
@PostMapping("/update")
|
||||
@RequiresPermissions("ten:personextract:update")
|
||||
public R update(@RequestBody TenPersonExtractEntity tenPersonExtract){
|
||||
tenPersonExtractService.updateById(tenPersonExtract);
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@PostMapping("/delete")
|
||||
@RequiresPermissions("ten:personextract:delete")
|
||||
public R delete(@RequestBody Long[] extractIds){
|
||||
tenPersonExtractService.removeByIds(Arrays.asList(extractIds));
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
}
|
|
@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
|
|||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import net.shapelight.modules.ten.entity.TenPersonEntity;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import net.shapelight.modules.vo.TenPersonIdUpdateAllVo;
|
||||
import net.shapelight.modules.vo.TenPersonIdUpdateVo;
|
||||
import net.shapelight.modules.vo.TenPersonVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
@ -52,6 +53,11 @@ public interface TenPersonDao {
|
|||
@Param("roomId")Long roomId
|
||||
);
|
||||
|
||||
List<TenPersonIdUpdateAllVo> findAllPersonIdUpdateAll(@Param("cellId")Long cellId,
|
||||
@Param("buildId")Long buildId,
|
||||
@Param("roomId")Long roomId
|
||||
);
|
||||
|
||||
List<TenPersonVo> findByLastUpdatePerson(@Param("cellId")Long cellId,
|
||||
@Param("buildId")Long buildId,
|
||||
@Param("roomId")Long roomId,
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package net.shapelight.modules.ten.dao;
|
||||
|
||||
import net.shapelight.modules.ten.entity.TenPersonExtractEntity;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Mapper
|
||||
public interface TenPersonExtractDao extends BaseMapper<TenPersonExtractEntity> {
|
||||
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package net.shapelight.modules.ten.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
@TableName("ten_person_extract")
|
||||
public class TenPersonExtractEntity implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId
|
||||
private Long extractId;
|
||||
/**
|
||||
* 提取时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date extractTime;
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
private Long personId;
|
||||
/**
|
||||
* 类型:业主,家属,物业,访客,白名单,黑名单
|
||||
*/
|
||||
private Integer personType;
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private String deviceSn;
|
||||
/**
|
||||
* 0:成功 ,1:解析人脸图片失败,2:算法调用失败,3:人脸检测失败,4:人脸质量未通过,5:人脸图片下载失败,6:没有图片
|
||||
*/
|
||||
private Integer state;
|
||||
/**
|
||||
* 小区ID
|
||||
*/
|
||||
private Long cellId;
|
||||
/**
|
||||
* 运营商ID
|
||||
*/
|
||||
private Long tenantId;
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package net.shapelight.modules.ten.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import net.shapelight.common.utils.PageUtils;
|
||||
import net.shapelight.modules.ten.entity.TenPersonExtractEntity;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
public interface TenPersonExtractService extends IService<TenPersonExtractEntity> {
|
||||
|
||||
PageUtils queryPage(Map<String, Object> params);
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ import net.shapelight.modules.ten.entity.TenBuildEntity;
|
|||
import net.shapelight.modules.ten.entity.TenCellEntity;
|
||||
import net.shapelight.modules.ten.entity.TenPersonEntity;
|
||||
import net.shapelight.modules.ten.entity.TenRoomEntity;
|
||||
import net.shapelight.modules.vo.TenPersonIdUpdateAllVo;
|
||||
import net.shapelight.modules.vo.TenPersonIdUpdateVo;
|
||||
import net.shapelight.modules.vo.TenPersonVo;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
@ -70,6 +71,8 @@ public interface TenPersonService {
|
|||
Long roomId
|
||||
);
|
||||
|
||||
List<TenPersonIdUpdateAllVo> findAllPersonIdUpdateAll(Long cellId, Long buildId, Long roomId);
|
||||
|
||||
List<TenPersonVo> findAllByCellId(Long cellId);
|
||||
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import net.shapelight.common.utils.Constant;
|
|||
import net.shapelight.common.utils.RedisUtils;
|
||||
import net.shapelight.modules.dev.mqtt.CmdProcess;
|
||||
import net.shapelight.modules.dev.mqtt.EmqHttpApi;
|
||||
import net.shapelight.modules.nettyapi.service.DeviceApiService;
|
||||
import net.shapelight.modules.ten.entity.*;
|
||||
import net.shapelight.modules.ten.service.*;
|
||||
import net.shapelight.modules.vo.TenDeviceVo;
|
||||
|
@ -54,6 +55,8 @@ public class TenDeviceServiceImpl extends ServiceImpl<TenDeviceDao, TenDeviceEnt
|
|||
private EmqHttpApi emqHttpApi;
|
||||
@Autowired
|
||||
private TenDeviceAlertService tenDeviceAlertService;
|
||||
@Autowired
|
||||
private DeviceApiService deviceApiService;
|
||||
|
||||
@Override
|
||||
public PageUtils queryPage(Map<String, Object> params) {
|
||||
|
@ -100,12 +103,22 @@ public class TenDeviceServiceImpl extends ServiceImpl<TenDeviceDao, TenDeviceEnt
|
|||
}
|
||||
dev.setScope(scope.toString());
|
||||
|
||||
boolean onlineFlag = emqHttpApi.getClient(dev.getSn());
|
||||
if(onlineFlag){
|
||||
// boolean onlineFlag = emqHttpApi.getClient(dev.getSn());
|
||||
// if(onlineFlag){
|
||||
// dev.setStatus(1);
|
||||
// }else{
|
||||
// dev.setStatus(0);
|
||||
// }
|
||||
|
||||
|
||||
Boolean flag = deviceApiService.isOnline(dev.getSn());
|
||||
if (flag) {
|
||||
dev.setStatus(1);
|
||||
}else{
|
||||
dev.setStatus(0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return new PageUtils(page);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package net.shapelight.modules.ten.service.impl;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import java.util.Map;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import net.shapelight.common.utils.PageUtils;
|
||||
import net.shapelight.common.utils.Query;
|
||||
|
||||
import net.shapelight.modules.ten.dao.TenPersonExtractDao;
|
||||
import net.shapelight.modules.ten.entity.TenPersonExtractEntity;
|
||||
import net.shapelight.modules.ten.service.TenPersonExtractService;
|
||||
|
||||
|
||||
@Service("tenPersonExtractService")
|
||||
public class TenPersonExtractServiceImpl extends ServiceImpl<TenPersonExtractDao, TenPersonExtractEntity> implements TenPersonExtractService {
|
||||
|
||||
@Override
|
||||
public PageUtils queryPage(Map<String, Object> params) {
|
||||
IPage<TenPersonExtractEntity> page = this.page(
|
||||
new Query<TenPersonExtractEntity>().getPage(params),
|
||||
new QueryWrapper<TenPersonExtractEntity>()
|
||||
);
|
||||
|
||||
return new PageUtils(page);
|
||||
}
|
||||
|
||||
}
|
|
@ -21,6 +21,7 @@ import net.shapelight.modules.excel.model.PersonModel;
|
|||
import net.shapelight.modules.ten.entity.*;
|
||||
import net.shapelight.modules.ten.service.*;
|
||||
import net.shapelight.modules.vo.TenDeviceVo;
|
||||
import net.shapelight.modules.vo.TenPersonIdUpdateAllVo;
|
||||
import net.shapelight.modules.vo.TenPersonIdUpdateVo;
|
||||
import net.shapelight.modules.vo.TenPersonVo;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
|
@ -1575,6 +1576,14 @@ public class TenPersonServiceImpl implements TenPersonService {
|
|||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<TenPersonIdUpdateAllVo> findAllPersonIdUpdateAll(Long cellId, Long buildId, Long roomId) {
|
||||
//升序排列
|
||||
List<TenPersonIdUpdateAllVo> list = tenPersonDao.findAllPersonIdUpdateAll(cellId, buildId, roomId);
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package net.shapelight.modules.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class TenAppVerison {
|
||||
/*
|
||||
{
|
||||
"dev_id":"3cde32ef123",
|
||||
"app_name":"GateBox",
|
||||
"latest_version":10,
|
||||
"apk_url":"http://ip:port/upgrade/app/GateBox-1.0.2.apk",
|
||||
“apk_file_size”:152001212,
|
||||
"desc":"版本描述"
|
||||
}
|
||||
*/
|
||||
|
||||
private String dev_id;
|
||||
private String app_name;
|
||||
private Integer latest_version;
|
||||
private String apk_url;
|
||||
private Integer apk_file_size;
|
||||
private String desc;
|
||||
|
||||
public TenAppVerison(){
|
||||
this.dev_id = "";
|
||||
this.app_name = "";
|
||||
this.latest_version = 0;
|
||||
this.apk_url = "";
|
||||
this.apk_file_size = 0;
|
||||
this.desc = "";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package net.shapelight.modules.vo;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class TenDeviceConfig {
|
||||
|
||||
/*
|
||||
{
|
||||
"work_mode":0,
|
||||
"recognize_interval":3,
|
||||
"relay_suck_time":5,
|
||||
"support_liveness":true,
|
||||
"liveness_score":60,
|
||||
"recognize_score":65,
|
||||
"recognize_distance":2,
|
||||
"alert_temp_threshold":37.3,
|
||||
"upload_face_pic":true,
|
||||
"upload_pic_mode":0,
|
||||
"upload_http_url":"http://upload.face.com/face/pic/upload",
|
||||
"support_stranger":false
|
||||
}
|
||||
*/
|
||||
|
||||
private Integer work_mode;
|
||||
private Integer recognize_interval;
|
||||
private Integer relay_suck_time;
|
||||
private Boolean support_liveness;
|
||||
private Integer liveness_score;
|
||||
private Integer recognize_score;
|
||||
private Integer recognize_distance;
|
||||
private Float alert_temp_threshold;
|
||||
private Boolean upload_face_pic;
|
||||
private Integer upload_pic_mode;
|
||||
private String upload_http_url;
|
||||
private Boolean support_stranger;
|
||||
|
||||
public TenDeviceConfig(){
|
||||
this.work_mode = 0;
|
||||
this.recognize_interval = 3;
|
||||
this.relay_suck_time = 5;
|
||||
this.support_liveness = true;
|
||||
this.liveness_score = 60;
|
||||
this.recognize_score = 65;
|
||||
this.recognize_distance = 1;
|
||||
this.alert_temp_threshold = 37.3f;
|
||||
this.upload_face_pic = true;
|
||||
this.upload_pic_mode = 0;
|
||||
this.upload_http_url = "";
|
||||
this.support_stranger = true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package net.shapelight.modules.vo;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
@Data
|
||||
public class TenPersonIdUpdateAllVo implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("人员ID")
|
||||
private Long uid;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@ApiModelProperty("更新时间")
|
||||
// @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
// @JSONField(format="yyyy-MM-dd HH:mm:ss")
|
||||
private Date last_update_stamp;
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package net.shapelight.modules.vo;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class TenUserVo {
|
||||
/*
|
||||
"uid": 10009,
|
||||
"last_update_stamp":156023023000,
|
||||
"user_type":0,
|
||||
"user_name":"张三",
|
||||
"face_pic_base64":"32423be30xefw",
|
||||
"face_pic_download_url":"http://example.com/download/face/234234.jpg",
|
||||
"active_start_time":1559090090,
|
||||
"active_end_time":156009090,
|
||||
"card_id":"4ef33423"
|
||||
*/
|
||||
private Long uid;
|
||||
private Long last_update_stamp;
|
||||
private Integer user_type;
|
||||
private String user_name;
|
||||
private String face_pic_base64;
|
||||
private String face_pic_download_url;
|
||||
private Integer active_start_time;
|
||||
private Integer active_end_time;
|
||||
private String card_id="";
|
||||
|
||||
|
||||
}
|
|
@ -3,7 +3,7 @@ spring:
|
|||
type: com.alibaba.druid.pool.DruidDataSource
|
||||
druid:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://192.168.50.232:3306/cell_db?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
|
||||
url: jdbc:mysql://192.168.50.232:3306/cell_db_tcp?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
|
||||
username: user
|
||||
password: user@server001
|
||||
initial-size: 10
|
||||
|
|
|
@ -100,7 +100,10 @@ global:
|
|||
appid: wxf59991f23f1f5500
|
||||
secret: 30b523b2bdd7b0739b7f06e9dc1519f8
|
||||
tcp_server:
|
||||
port: 8777
|
||||
port: 8086
|
||||
app:
|
||||
key: 9894480ac52e4
|
||||
secret: Mjk0ODUzNzA2Mzk3NzEzMjU2OTIwOTk1NzUzMDI5MTQwNDI
|
||||
|
||||
shapelight:
|
||||
cluster: false #集群配置 true集群环境 false单机环境,还需打开pom.xml里的spring-session-data-redis注释
|
||||
|
|
|
@ -92,6 +92,11 @@
|
|||
<result column="delete_flag" jdbcType="TINYINT" property="deleteFlag"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="idupdateMap" type="net.shapelight.modules.vo.TenPersonIdUpdateAllVo">
|
||||
<result column="person_id" jdbcType="BIGINT" property="uid"/>
|
||||
<result column="last_update_time" jdbcType="TIMESTAMP" property="last_update_stamp"/>
|
||||
</resultMap>
|
||||
|
||||
|
||||
<insert id="insert" parameterType="net.shapelight.modules.ten.entity.TenPersonEntity">
|
||||
insert into ten_person_${cellId}
|
||||
|
@ -664,6 +669,21 @@
|
|||
</select>
|
||||
|
||||
|
||||
<select id="findAllPersonIdUpdateAll" resultMap="idupdateMap">
|
||||
select person_id,last_update_time from ten_person_${cellId}
|
||||
where 1=1
|
||||
<if test="cellId != null and cellId!=''">
|
||||
and cell_id = #{cellId}
|
||||
</if>
|
||||
<if test="buildId != null and buildId!=''">
|
||||
and build_id = #{buildId}
|
||||
</if>
|
||||
<if test="roomId != null and roomId!=''">
|
||||
and room_id = #{roomId}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
|
||||
<select id="findByLastUpdatePerson" resultMap="updateMap">
|
||||
select * from ten_person_${cellId}
|
||||
where 1=1
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<?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="net.shapelight.modules.ten.dao.TenPersonExtractDao">
|
||||
|
||||
<!-- 可根据自己的需求,是否要使用 -->
|
||||
<!--<resultMap type="net.shapelight.modules.ten.entity.TenPersonExtractEntity" id="tenPersonExtractMap">-->
|
||||
<!--<result property="extractId" column="extract_id"/>-->
|
||||
<!--<result property="extractTime" column="extract_time"/>-->
|
||||
<!--<result property="personId" column="person_id"/>-->
|
||||
<!--<result property="personType" column="person_type"/>-->
|
||||
<!--<result property="deviceSn" column="deviceSn"/>-->
|
||||
<!--<result property="state" column="state"/>-->
|
||||
<!--<result property="cellId" column="cell_id"/>-->
|
||||
<!--<result property="tenantId" column="tenant_id"/>-->
|
||||
<!--</resultMap>-->
|
||||
|
||||
|
||||
</mapper>
|
Loading…
Reference in New Issue