1、修改帖子阅读数更新

2、修改热帖获取
This commit is contained in:
2018-11-19 00:10:34 +08:00
parent 0cf727bc8a
commit 6e3e277407
20 changed files with 141 additions and 71 deletions

Binary file not shown.

Binary file not shown.

BIN
lib/enjoy-3.5.jar Normal file

Binary file not shown.

BIN
lib/jackson-core-2.9.5.jar Normal file

Binary file not shown.

Binary file not shown.

BIN
lib/redkale-1.9.8.jar Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
lib/slf4j-api-1.7.13.jar Normal file

Binary file not shown.

BIN
lib/velocypack-1.4.1.jar Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -5,6 +5,9 @@ import com.arangodb.ArangoDB;
import com.arangodb.ArangoDatabase; import com.arangodb.ArangoDatabase;
import com.lxyer.bbs.base.entity.VisLog; import com.lxyer.bbs.base.entity.VisLog;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function; import java.util.function.Function;
/** /**
@@ -21,7 +24,6 @@ public class ArangoKit {
protected static ArangoDatabase dbDev = arangoDb.db(chDev.apply("redbbs")); protected static ArangoDatabase dbDev = arangoDb.db(chDev.apply("redbbs"));
protected static ArangoCollection colVisLog = dbDev.collection(chDev.apply("vis_log")); protected static ArangoCollection colVisLog = dbDev.collection(chDev.apply("vis_log"));
//check exists
static { static {
if (!dbDev.exists()) { if (!dbDev.exists()) {
dbDev.create(); dbDev.create();
@@ -30,12 +32,35 @@ public class ArangoKit {
if (!colVisLog.exists()) { if (!colVisLog.exists()) {
colVisLog.create(); colVisLog.create();
} }
//java.net.SocketTimeoutException: Read timed out 加入下面两行,观察是否正常
System.setProperty("sun.net.client.defaultConnectTimeout", String.valueOf(1000));
System.setProperty("sun.net.client.defaultReadTimeout", String.valueOf(1000));
} }
public static <T> void save(T t) { public static <T> CompletableFuture<T> save(T t) {
return CompletableFuture.supplyAsync(() -> {
if (t instanceof VisLog) { if (t instanceof VisLog) {
colVisLog.insertDocument(t); colVisLog.insertDocument(t);
} }
return t;
});
}
public static long findInt(String aql) {
return dbDev.query(aql, long.class).first();
}
public static long findInt(String aql, Map para) {
return dbDev.query(aql, long.class).first();
}
public static <T> List<T> find(String aql, Class<T> clazz) {
return dbDev.query(aql, clazz).asListRemaining();
}
public static <T> List<T> find(String aql, Map para, Class<T> clazz) {
return dbDev.query(aql, para, clazz).asListRemaining();
} }
} }

View File

@@ -86,6 +86,7 @@ public class BaseServlet extends HttpServlet {
VisLog visLog = new VisLog(); VisLog visLog = new VisLog();
visLog.setIp(request.getRemoteAddr()); visLog.setIp(request.getRemoteAddr());
visLog.setUri(request.getRequestURI());
visLog.setHeaders(headers); visLog.setHeaders(headers);
visLog.setPara(para); visLog.setPara(para);
visLog.setTime(System.currentTimeMillis()); visLog.setTime(System.currentTimeMillis());

View File

@@ -1,5 +1,6 @@
package com.lxyer.bbs.base; package com.lxyer.bbs.base;
import com.lxyer.bbs.base.entity.Count;
import com.lxyer.bbs.base.entity.VisLog; import com.lxyer.bbs.base.entity.VisLog;
import com.lxyer.bbs.base.kit.LxyKit; import com.lxyer.bbs.base.kit.LxyKit;
import com.lxyer.bbs.base.user.UserInfo; import com.lxyer.bbs.base.user.UserInfo;
@@ -8,14 +9,10 @@ import com.lxyer.bbs.base.user.UserService;
import com.lxyer.bbs.content.Content; import com.lxyer.bbs.content.Content;
import com.lxyer.bbs.content.ContentInfo; import com.lxyer.bbs.content.ContentInfo;
import com.lxyer.bbs.content.ContentService; import com.lxyer.bbs.content.ContentService;
import com.mongodb.Block;
import com.mongodb.MongoClient; import com.mongodb.MongoClient;
import com.mongodb.client.AggregateIterable;
import com.mongodb.client.FindIterable; import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase; import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Accumulators;
import com.mongodb.client.model.Aggregates;
import org.bson.Document; import org.bson.Document;
import org.bson.conversions.Bson; import org.bson.conversions.Bson;
import org.redkale.net.http.RestMapping; import org.redkale.net.http.RestMapping;
@@ -30,11 +27,11 @@ import org.redkale.util.Sheet;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.*; import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.function.Consumer;
import java.util.function.Function;
import static com.mongodb.client.model.Filters.*; import static com.mongodb.client.model.Filters.eq;
import static java.util.Arrays.asList;
/** /**
* Created by liangxianyou at 2018/6/20 22:54. * Created by liangxianyou at 2018/6/20 22:54.
@@ -82,81 +79,78 @@ public class TaskQueue<T extends Object> extends BaseService implements Runnable
@Override @Override
@RestMapping(ignore = true, comment = "独立线程,用户访问行为记录到数据库") @RestMapping(ignore = true, comment = "独立线程,用户访问行为记录到数据库")
public void run() { public void run() {
do {
try { try {
while (true){
T task = take(); T task = take();
//记录访问日志,如果是访问的文章详情:对文章访问数量更新
if (task instanceof VisLog) { if (task instanceof VisLog) {
ArangoKit.save(task); ArangoKit.save(task).thenAcceptAsync((_task) -> {
} VisLog visLog = (VisLog) _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));
//在这里处理日志数据
String uri = logData.get("uri")+"";
//[访问量] //[访问量]
if (uri.startsWith("/jie/detail/")){ String uri = visLog.getUri();
updateViewNumAsync(logData); if (uri != null && uri.startsWith("/jie/detail/")){
}*/ updateViewNum(visLog);
} }
});
}
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
} while (true);
} }
@Comment("帖子阅读数处理") @Comment("帖子阅读数处理")
private void updateViewNumAsync(Map logData) { private void updateViewNum(VisLog visLog) {
CompletableFuture.runAsync(()->{
Bson filter = and( String aql = String.format("for d in vis_log_dev\n" +
eq("uri", logData.get("uri"))//帖子 " filter d.uri == '%s' and d.ip == '%s' and (d.userid == %s or d.userid==0)\n" +
,eq("ip", logData.get("ip"))//IP " collect WITH COUNT INTO total\n" +
,or( " return total", visLog.getUri(), visLog.getIp(), visLog.getUserid());
eq("userid", logData.get("userid"))//登录人
,eq("userid", 0)//未登录userid=0 long total = ArangoKit.findInt(aql);
)
);
long count = visLog.count(filter); if (total <= 1) {
if (count <= 1){ String uri = visLog.getUri();
String uri = logData.get("uri") + "";
int contentid = Integer.parseInt(uri.replace("/jie/detail/", "")); int contentid = Integer.parseInt(uri.replace("/jie/detail/", ""));
source.updateColumn(Content.class, contentid, ColumnValue.inc("viewnum", 1)); source.updateColumn(Content.class, contentid, ColumnValue.inc("viewnum", 1));
} }
});
} }
@RestMapping(ignore = true, comment = "访问热帖数据") @RestMapping(ignore = true, comment = "访问热帖数据")
public Sheet<ContentInfo> hotView(String sessionid){ public Sheet<ContentInfo> hotView(String sessionid){
int limit = 8; int limit = 8;
String cacheKey = "hotView"; String cacheKey = "hotView";
Object ids = cacheSource.get(cacheKey); Object ids = null;//cacheSource.get(cacheKey);
if (ids == null){ if (ids == null){
Calendar cal = Calendar.getInstance(); Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, -7); cal.set(Calendar.DAY_OF_MONTH, -7);
Map para = new HashMap();
para.put("time", cal.getTimeInMillis());
//查询一周某热帖记录 //查询一周某热帖记录
Bson filter = and(ne("userid", 100001) List<Count> hotArticle = ArangoKit.find(
,regex("uri", "/jie/detail/*") "for d in vis_log_dev\n" +
,ne("ip", "") " filter d.uri =~ '^/jie/detail/[0-9]+$' and d.userid != 100001 and d.time > @time\n" +
,gt("time", cal.getTimeInMillis()) " COLLECT uri=d.uri WITH COUNT INTO total\n" +
); " sort total desc\n" +
List<Bson> list = asList( " limit 10\n" +
Aggregates.match(filter) " return {name: uri,total:total}",
,Aggregates.group("$uri", Accumulators.sum("count", 1)) Map.of("time", cal.getTimeInMillis()),
,Aggregates.sort(new Document("count", -1)) Count.class);
,Aggregates.limit(8)
);
AggregateIterable<Document> documents = visLog.aggregate(list, Document.class);
List<Integer> _ids = new ArrayList<>(limit); Function<List<Count>, List<Integer>> deal = (counts) -> {
documents.forEach((Block<? super Document>) x->{ List<Integer> _ids = new ArrayList<>();
String uri = x.getString("_id"); counts.forEach(x -> {
_ids.add(Integer.parseInt(uri.replace("/jie/detail/", ""))); _ids.add(Integer.parseInt(x.getName().replace("/jie/detail/", "")));
}); });
return _ids;
};
cacheSource.set(30 * 60, cacheKey, ids = _ids); ids = deal.apply(hotArticle);
cacheSource.set(30 * 60, cacheKey, ids);
} }
int[] contentids = new int[limit]; int[] contentids = new int[limit];
@@ -189,7 +183,7 @@ public class TaskQueue<T extends Object> extends BaseService implements Runnable
List<Map> rows = new ArrayList<>(); List<Map> rows = new ArrayList<>();
List<Integer> uids = new ArrayList<>(); List<Integer> uids = new ArrayList<>();
documents.forEach((Block<? super Document>) x->{ documents.forEach((Consumer<? super Document>) x->{
Integer userid = x.getInteger("userid"); Integer userid = x.getInteger("userid");
if (userid > 0) uids.add(userid); if (userid > 0) uids.add(userid);

View File

@@ -0,0 +1,37 @@
package com.lxyer.bbs.base.entity;
/**
* 用来计数用
*
* @author: liangxianyou at 2018/11/18 20:42.
*/
public class Count {
private String name;
private long total;
//-------------------
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getTotal() {
return total;
}
public void setTotal(long total) {
this.total = total;
}
@Override
public String toString() {
return "Count{" +
"name='" + name + '\'' +
", total=" + total +
'}';
}
}

View File

@@ -71,4 +71,17 @@ public class VisLog {
public void setHeaders(Map headers) { public void setHeaders(Map headers) {
this.headers = headers; this.headers = headers;
} }
@Override
public String toString() {
return "VisLog{" +
"ip='" + ip + '\'' +
", userid='" + userid + '\'' +
", ftime='" + ftime + '\'' +
", uri='" + uri + '\'' +
", time=" + time +
", para=" + para +
", headers=" + headers +
'}';
}
} }

View File

@@ -131,7 +131,7 @@ public class UserService extends BaseService {
user.setNickname(nickname);//去除昵称中的空格 user.setNickname(nickname);//去除昵称中的空格
source.updateColumn(user source.updateColumn(user
,FilterNode.create("userid", currentUserid(sessionid)) ,FilterNode.create("userid", currentUserid(sessionid))
,SelectColumn.createIncludes(columns) ,SelectColumn.includes(columns)
); );
return RetResult.success(); return RetResult.success();
} }
@@ -139,7 +139,7 @@ public class UserService extends BaseService {
//最新加入 //最新加入
public Sheet<UserInfo> lastReg(){ public Sheet<UserInfo> lastReg(){
Sheet<UserRecord> users = source.querySheet(UserRecord.class Sheet<UserRecord> users = source.querySheet(UserRecord.class
, SelectColumn.createIncludes("userid", "nickname", "avatar", "createtime") , SelectColumn.includes("userid", "nickname", "avatar", "createtime")
, new Flipper().sort("createtime DESC").limit(8) , new Flipper().sort("createtime DESC").limit(8)
, FilterNode.create("status", 10)); , FilterNode.create("status", 10));

View File

@@ -51,7 +51,7 @@ public class CommentService extends BaseService implements UIService<CommentInfo
int count = source.getNumberResult(Comment.class, FilterFunc.COUNT, "commentid", FilterNode.create("contentid", contentid)).intValue(); int count = source.getNumberResult(Comment.class, FilterFunc.COUNT, "commentid", FilterNode.create("contentid", contentid)).intValue();
source.updateColumn(Content.class, contentid, ColumnValue.create("replynum", count)); source.updateColumn(Content.class, contentid, ColumnValue.create("replynum", count));
}else { }else {
source.updateColumn(comment, SelectColumn.createIncludes("content")); source.updateColumn(comment, SelectColumn.includes("content"));
} }
return RetResult.success(); return RetResult.success();
} }
@@ -85,7 +85,7 @@ public class CommentService extends BaseService implements UIService<CommentInfo
Sheet<Comment> comments = source.querySheet(Comment.class, new Flipper().sort("createtime DESC"), FilterNode.create("userid", userid)); Sheet<Comment> comments = source.querySheet(Comment.class, new Flipper().sort("createtime DESC"), FilterNode.create("userid", userid));
int[] contentIds = comments.stream().mapToInt(x -> x.getCommentid()).toArray(); int[] contentIds = comments.stream().mapToInt(x -> x.getCommentid()).toArray();
List<Content> contents = source.queryList(Content.class, SelectColumn.createIncludes("contentid","title"), FilterNode.create("contentid", FilterExpress.IN, contentIds)); List<Content> contents = source.queryList(Content.class, SelectColumn.includes("contentid","title"), FilterNode.create("contentid", FilterExpress.IN, contentIds));
Sheet<CommentInfo> infos = createInfo(comments); Sheet<CommentInfo> infos = createInfo(comments);
infos.forEach(x->{ infos.forEach(x->{