1、【新增】添加IM

2、【新增】添加项目页面
2、【新增/修改】将日志写入到ArangoDb(原来MongoDb)
This commit is contained in:
lxyer 2018-11-18 10:27:27 +08:00
parent f87954899f
commit 7a86c47776
12 changed files with 518 additions and 27 deletions

26
pom.xml
View File

@ -14,8 +14,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>10</source>
<target>10</target>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
@ -25,12 +25,12 @@
<dependency>
<groupId>org.redkale</groupId>
<artifactId>redkale</artifactId>
<version>1.9.6</version>
<version>1.9.8</version>
</dependency>
<dependency>
<groupId>org.redkalex</groupId>
<artifactId>redkale-plugins</artifactId>
<version>1.9.5.2</version>
<version>1.9.8</version>
</dependency>
<dependency>
@ -41,17 +41,21 @@
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>enjoy</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver</artifactId>
<version>3.8.0</version>
<version>3.5</version>
</dependency>
<!-- mongodb支持 -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.8.0</version>
<version>3.9.0</version>
</dependency>
<!-- arangodb支持 -->
<dependency>
<groupId>com.arangodb</groupId>
<artifactId>arangodb-java-driver</artifactId>
<version>5.0.1</version>
</dependency>
<dependency>
<groupId>com.lxyer</groupId>

View File

@ -3,11 +3,23 @@
#set(title=bean.title)
#set(keywords=bean.title)
#set(description=bean.title)
#set(
project=["redbbs","redtimer", "ExcelUtil","jfly"]
)
#@layout()
#define css()
<style>
.fly-panel{margin-right: 15px}
.layui-col-md4{padding-top: 20px;}
.detail-box{min-height: 300px}
.pro_name a{color: #4183c4;}
.osc_git_title{background-color: #fff;}
.osc_git_box{background-color: #fff;}
.osc_git_box{border-color: #E3E9ED;}
.osc_git_info{color: #666;}
.osc_git_main a{color: #9B9B9B;}
</style>
#end
@ -15,6 +27,16 @@
<div class="layui-container">
<div class="layui-row">
#for(x : project)
<div class="layui-col-md4">
<div class="fly-panel detail-box">
<script src='https://gitee.com/tc608/#(x)/widget_preview'></script>
</div>
</div>
#end
#define xx()
<div class="layui-col-md8" style="padding-top: 20px;">
<!--内容-->
<div class="fly-panel detail-box">
@ -221,8 +243,8 @@
</div>
</div>-->
</div>
</div>
</div>
#end
</div>
#end

View File

@ -0,0 +1,40 @@
package com.lxyer.bbs.base;
import com.arangodb.ArangoCollection;
import com.arangodb.ArangoDB;
import com.arangodb.ArangoDatabase;
import com.lxyer.bbs.base.entity.VisLog;
import java.util.function.Function;
/**
* @author: liangxianyou at 2018/11/18 9:02.
*/
public class ArangoKit {
protected static final boolean winos = System.getProperty("os.name").contains("Window");
protected static Function<String, String> chDev = (s) -> s + (winos ? "_dev" : "");
//Arango
protected static ArangoDB arangoDb = new ArangoDB.Builder().host("120.24.230.60", 8529).user("root").password("root").build();
protected static ArangoDatabase dbDev = arangoDb.db(chDev.apply("redbbs"));
protected static ArangoCollection colVisLog = dbDev.collection(chDev.apply("vis_log"));
static {
if (!dbDev.exists()) {
dbDev.create();
}
if (!colVisLog.exists()) {
colVisLog.create();
}
}
public static <T> void save(T t) {
if (t instanceof VisLog) {
colVisLog.insertDocument(t);
}
}
}

View File

@ -86,9 +86,7 @@ public class BaseServlet extends HttpServlet {
VisLog visLog = new VisLog();
visLog.setIp(request.getRemoteAddr());
visLog.setUri(request.getRequestURI());
visLog.setHeaders(headers);
visLog.setUserid(userid);
visLog.setPara(para);
visLog.setTime(System.currentTimeMillis());
visLog.setFtime(String.format("%1$tY%1$tm%1$td%1$tH%1$tM%1$tS", visLog.getTime()));

View File

@ -1,5 +1,6 @@
package com.lxyer.bbs.base;
import com.lxyer.bbs.base.entity.VisLog;
import com.lxyer.bbs.base.kit.LxyKit;
import com.lxyer.bbs.base.user.UserInfo;
import com.lxyer.bbs.base.user.UserRecord;
@ -83,7 +84,12 @@ public class TaskQueue<T extends Object> extends BaseService implements Runnable
public void run() {
try {
while (true){
Map logData = (Map) take();
T task = take();
if (task instanceof VisLog) {
ArangoKit.save(task);
}
/*Map logData = (Map) take();
logData.put("ftime", String.format("%1$tY%1$tm%1$td%1$tH%1$tM%1$tS", logData.get("time")));
visLog.insertOne(new Document(logData));
@ -94,7 +100,7 @@ public class TaskQueue<T extends Object> extends BaseService implements Runnable
//[访问量]
if (uri.startsWith("/jie/detail/")){
updateViewNumAsync(logData);
}
}*/
}
} catch (InterruptedException e) {
e.printStackTrace();

View File

@ -1,7 +1,5 @@
package com.lxyer.bbs.base.entity;
import org.redkale.convert.json.JsonConvert;
import java.util.Map;
/**
@ -11,7 +9,7 @@ import java.util.Map;
*/
public class VisLog {
private String ip;
private int userid;
private String userid;
private String ftime;
private String uri;
private long time;
@ -26,11 +24,11 @@ public class VisLog {
this.ip = ip;
}
public int getUserid() {
public String getUserid() {
return userid;
}
public void setUserid(int userid) {
public void setUserid(String userid) {
this.userid = userid;
}
@ -73,9 +71,4 @@ public class VisLog {
public void setHeaders(Map headers) {
this.headers = headers;
}
@Override
public String toString() {
return JsonConvert.root().convertTo(this);
}
}

View File

@ -0,0 +1,108 @@
package com.lxyer.redim;
import com.lxyer.base.JBean;
import com.lxyer.redim.entity.MsgRecord;
import com.lxyer.redim.info.MsgInfo;
import com.lxyer.redim.service.ImFriendService;
import com.lxyer.redim.service.ImMsgService;
import org.redkale.net.http.*;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
/**
*
* Created by liangxianyou at 2018/7/8 22:51.
*/
@RestWebSocket(name = "chat", catalog = "ws", comment = "文字聊天", anyuser = true)
public class ChatWebSocket extends WebSocket {
@Resource
protected ImMsgService chatService;
@Resource
protected ImFriendService imFriendService;
protected Random random = new Random();
@Override
protected CompletableFuture<String> onOpen(HttpRequest request) {
String token = request.getParameter("token");
return CompletableFuture.supplyAsync(() -> {
if (token == null) {
setAttribute("isyk", true);
return request.getSessionid(false);
}
return token;
});
}
@Override
public CompletableFuture createUserid() {
return CompletableFuture.supplyAsync(()-> {
int userid = 0;
//fixme: 1isyk => tour; 2set cate to user global
if (getAttribute("isyk") == null){//tour
userid = imFriendService.currentUserid(getSessionid());
setAttribute("isyk", true);
}
//如果未获取登录信息使用token.hashCode 负值 作为登录用户
if (userid == 0){
//MsgInfo msgInfo = new MsgInfo();
userid = - Math.abs(getSessionid().hashCode());
}
//接收离线信息
int finalUserid = userid;
CompletableFuture.runAsync(()->{
JBean<List<MsgRecord>> list = chatService.offlineMsg(finalUserid);
List<MsgRecord> recordList = list.getResult();
if (recordList != null && recordList.size() > 0){
recordList.forEach(msgRecord->{
JBean<MsgInfo> msgInfo = chatService.createMsgInfo(msgRecord);
send(msgInfo.getResult()).thenAccept(x->{
if ((Integer)x == 0){//发送成功
msgRecord.setStatus((short) 20);
}
chatService.update(msgRecord);
});
});
}
});
return userid;
});
}
@Override
public void preOnMessage(String restmapping, WebSocketParam param, Runnable messageEvent) {
super.preOnMessage(restmapping, param, messageEvent);
}
@RestOnMessage(name = "text")
public void onChatMessage(MsgRecord msg, Map<String, String> extmap) {
msg.setFromuserid((Integer) getUserid());
JBean<MsgInfo> msgInfo = chatService.createMsgInfo(msg);
sendMessage(msgInfo.getResult(), msg.getTouserid()).thenAccept(x->{
if ((Integer)x == 0){//发送成功
msg.setStatus((short) 20);
}
chatService.insert(msg);
});
}
@Override
@RestOnMessage(name = "close")
public void onClose(int code, String reason) {
System.out.println("close!");
super.onClose(code, reason);
}
}

View File

@ -0,0 +1,87 @@
package com.lxyer.redim.entity;
import org.redkale.convert.json.JsonConvert;
import javax.persistence.*;
/**
*
* @author lxyer
*/
@Cacheable(interval = 5*60)
@Table(catalog = "redbbs", name = "im_msgrecord", comment = "[聊天记录表]")
public class MsgRecord implements java.io.Serializable {
@Id
@GeneratedValue
@Column(comment = "[主键id]")
private int msgid;
@Column(comment = "[发送人]")
private int fromuserid;
@Column(comment = "[接收人]")
private int touserid;
@Column(comment = "[内容]")
private String content = "";
@Column(updatable = false, comment = "[发送时间]")
private long createtime = System.currentTimeMillis();
@Column(comment = "[状态]-10删除10未发送 20已发送 30已读")
private short status = 10;
public void setMsgid(int msgid) {
this.msgid = msgid;
}
public int getMsgid() {
return this.msgid;
}
public void setFromuserid(int fromuserid) {
this.fromuserid = fromuserid;
}
public int getFromuserid() {
return this.fromuserid;
}
public void setTouserid(int touserid) {
this.touserid = touserid;
}
public int getTouserid() {
return this.touserid;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public void setCreatetime(long createtime) {
this.createtime = createtime;
}
public long getCreatetime() {
return this.createtime;
}
public void setStatus(short status) {
this.status = status;
}
public short getStatus() {
return this.status;
}
@Override
public String toString() {
return JsonConvert.root().convertTo(this);
}
}

View File

@ -0,0 +1,101 @@
package com.lxyer.redim.info;
/**
* @author: liangxianyou at 2018/8/12 15:04.
*/
public class MsgInfo {
private String username;
private String avatar;
private int id;
private String type;
private String content;
private int cid;
private boolean mine;
private int fromid;
private long timestamp;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public int getCid() {
return cid;
}
public void setCid(int cid) {
this.cid = cid;
}
public boolean isMine() {
return mine;
}
public void setMine(boolean mine) {
this.mine = mine;
}
public int getFromid() {
return fromid;
}
public void setFromid(int fromid) {
this.fromid = fromid;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
/*var message = {
username: "纸飞机" //消息来源用户名
,avatar: "http://tp1.sinaimg.cn/1571889140/180/40030060651/1" //消息来源用户头像
,id: "100000" //消息的来源ID如果是私聊则是用户id如果是群聊则是群组id
,type: "friend" //聊天窗口来源类型从发送消息传递的to里面获取
,content: "嗨,你好!本消息系离线消息。" //消息内容
,cid: 0 //消息id可不传除非你要对消息进行一些操作如撤回
,mine: false //是否我发送的消息如果为true则会显示在右方
,fromid: "100000" //消息的发送者id比如群组中的某个消息发送者可用于自动解决浏览器多窗口时的一些问题
,timestamp: 1467475443306 //服务端时间戳毫秒数注意如果你返回的是标准的 unix 时间戳记得要 *1000
}*/
}

View File

@ -0,0 +1,59 @@
package com.lxyer.redim.service;
import com.lxyer.base.JBean;
import org.redkale.service.Service;
public interface ImFriendService extends Service {
//================ 查询相关 =================
/**
* 分组好友数据
* @return
*/
JBean friends(String sessionid);
/**
* 根据条件查询好友
* @return
*/
JBean friendList(String sessionid);
/**
* 群组数据
* @return
*/
JBean groups(String sessionid);
//================ 操作好友相关 =================
/**
* 保存好友分组
* @return
*/
JBean itemSave(String sessionid);
/**
* 添加好友
* @return
*/
JBean addFriend(String sessionid);
//================ 操作群组相关 =================
/**
* 保存群组
* @return
*/
JBean groupSave(String sessionid);
/**
* 加入群组
* @return
*/
JBean addGroup(String sessionid);
/**
* 登录人用户id
* @param sessionid
* @return
*/
int currentUserid(String sessionid);
}

View File

@ -0,0 +1,43 @@
package com.lxyer.redim.service;
import com.lxyer.base.JBean;
import com.lxyer.redim.entity.MsgRecord;
import com.lxyer.redim.info.MsgInfo;
import org.redkale.service.Service;
import java.util.List;
public interface ImMsgService extends Service {
/**
* 消息入库
* @param msg
*/
JBean insert(MsgRecord... msg);
/**
* 消息修改
*/
JBean update(MsgRecord... msg);
/**
* 历史消息
* @return
*/
JBean list();
/**
* 创建消息体
*
* @param msg
*/
JBean<MsgInfo> createMsgInfo(MsgRecord msg);
/**
* 获取离线消息
* @param userid
* @return
*/
JBean<List<MsgRecord>> offlineMsg(int userid);
}

View File

@ -0,0 +1,30 @@
package com.lxyer.redim.servlet;
import com.lxyer.base.JBean;
import com.lxyer.redim.service.ImFriendService;
import org.redkale.net.http.*;
import javax.annotation.Resource;
import java.util.logging.Logger;
/**
* @author: liangxianyou at 2018/8/5 23:55.
*/
@WebServlet(value = {"/imx/*"}, comment = "测试servlet")
public class ImServlet extends HttpServlet {
public Logger log = Logger.getLogger(this.getClass().getSimpleName());
@Resource
ImFriendService imFriendService;
@HttpMapping(url = "/imx/friends", comment = "测试函数")
public void abc(HttpRequest request, HttpResponse response){
String token = request.getParameter("token");
JBean jBean = imFriendService.friends(token);
response.finish(jBean.getResult());
}
}