1、修改帖子阅读数更新
2、修改热帖获取
This commit is contained in:
parent
0cf727bc8a
commit
6e3e277407
BIN
lib/arangodb-java-driver-5.0.1.jar
Normal file
BIN
lib/arangodb-java-driver-5.0.1.jar
Normal file
Binary file not shown.
Binary file not shown.
BIN
lib/enjoy-3.5.jar
Normal file
BIN
lib/enjoy-3.5.jar
Normal file
Binary file not shown.
BIN
lib/jackson-core-2.9.5.jar
Normal file
BIN
lib/jackson-core-2.9.5.jar
Normal file
Binary file not shown.
Binary file not shown.
BIN
lib/netty-all-4.1.29.Final.jar
Normal file
BIN
lib/netty-all-4.1.29.Final.jar
Normal file
Binary file not shown.
BIN
lib/redkale-1.9.8.jar
Normal file
BIN
lib/redkale-1.9.8.jar
Normal file
Binary file not shown.
BIN
lib/redkale-plugins-1.9.8.jar
Normal file
BIN
lib/redkale-plugins-1.9.8.jar
Normal file
Binary file not shown.
Binary file not shown.
BIN
lib/redkale.jar
BIN
lib/redkale.jar
Binary file not shown.
BIN
lib/slf4j-api-1.7.13.jar
Normal file
BIN
lib/slf4j-api-1.7.13.jar
Normal file
Binary file not shown.
BIN
lib/velocypack-1.4.1.jar
Normal file
BIN
lib/velocypack-1.4.1.jar
Normal file
Binary file not shown.
BIN
libs/redbbs.jar
BIN
libs/redbbs.jar
Binary file not shown.
@ -5,6 +5,9 @@ import com.arangodb.ArangoDB;
|
||||
import com.arangodb.ArangoDatabase;
|
||||
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;
|
||||
|
||||
/**
|
||||
@ -21,7 +24,6 @@ public class ArangoKit {
|
||||
protected static ArangoDatabase dbDev = arangoDb.db(chDev.apply("redbbs"));
|
||||
protected static ArangoCollection colVisLog = dbDev.collection(chDev.apply("vis_log"));
|
||||
|
||||
//check exists
|
||||
static {
|
||||
if (!dbDev.exists()) {
|
||||
dbDev.create();
|
||||
@ -30,12 +32,35 @@ public class ArangoKit {
|
||||
if (!colVisLog.exists()) {
|
||||
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) {
|
||||
if (t instanceof VisLog) {
|
||||
colVisLog.insertDocument(t);
|
||||
}
|
||||
public static <T> CompletableFuture<T> save(T t) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
if (t instanceof VisLog) {
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -86,6 +86,7 @@ public class BaseServlet extends HttpServlet {
|
||||
|
||||
VisLog visLog = new VisLog();
|
||||
visLog.setIp(request.getRemoteAddr());
|
||||
visLog.setUri(request.getRequestURI());
|
||||
visLog.setHeaders(headers);
|
||||
visLog.setPara(para);
|
||||
visLog.setTime(System.currentTimeMillis());
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.lxyer.bbs.base;
|
||||
|
||||
import com.lxyer.bbs.base.entity.Count;
|
||||
import com.lxyer.bbs.base.entity.VisLog;
|
||||
import com.lxyer.bbs.base.kit.LxyKit;
|
||||
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.ContentInfo;
|
||||
import com.lxyer.bbs.content.ContentService;
|
||||
import com.mongodb.Block;
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.client.AggregateIterable;
|
||||
import com.mongodb.client.FindIterable;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import com.mongodb.client.model.Accumulators;
|
||||
import com.mongodb.client.model.Aggregates;
|
||||
import org.bson.Document;
|
||||
import org.bson.conversions.Bson;
|
||||
import org.redkale.net.http.RestMapping;
|
||||
@ -30,11 +27,11 @@ import org.redkale.util.Sheet;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static com.mongodb.client.model.Filters.*;
|
||||
import static java.util.Arrays.asList;
|
||||
import static com.mongodb.client.model.Filters.eq;
|
||||
|
||||
/**
|
||||
* Created by liangxianyou at 2018/6/20 22:54.
|
||||
@ -82,81 +79,78 @@ public class TaskQueue<T extends Object> extends BaseService implements Runnable
|
||||
@Override
|
||||
@RestMapping(ignore = true, comment = "独立线程,用户访问行为记录到数据库")
|
||||
public void run() {
|
||||
try {
|
||||
while (true){
|
||||
do {
|
||||
try {
|
||||
T task = take();
|
||||
|
||||
//记录访问日志,如果是访问的文章详情:对文章访问数量更新
|
||||
if (task instanceof VisLog) {
|
||||
ArangoKit.save(task);
|
||||
ArangoKit.save(task).thenAcceptAsync((_task) -> {
|
||||
VisLog visLog = (VisLog) _task;
|
||||
//[访问量]
|
||||
String uri = visLog.getUri();
|
||||
if (uri != null && uri.startsWith("/jie/detail/")){
|
||||
updateViewNum(visLog);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*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/")){
|
||||
updateViewNumAsync(logData);
|
||||
}*/
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
|
||||
@Comment("帖子阅读数处理")
|
||||
private void updateViewNumAsync(Map logData) {
|
||||
CompletableFuture.runAsync(()->{
|
||||
Bson filter = and(
|
||||
eq("uri", logData.get("uri"))//帖子
|
||||
,eq("ip", logData.get("ip"))//IP
|
||||
,or(
|
||||
eq("userid", logData.get("userid"))//登录人
|
||||
,eq("userid", 0)//未登录userid=0
|
||||
)
|
||||
);
|
||||
long count = visLog.count(filter);
|
||||
if (count <= 1){
|
||||
String uri = logData.get("uri") + "";
|
||||
int contentid = Integer.parseInt(uri.replace("/jie/detail/", ""));
|
||||
source.updateColumn(Content.class, contentid, ColumnValue.inc("viewnum", 1));
|
||||
}
|
||||
});
|
||||
private void updateViewNum(VisLog visLog) {
|
||||
|
||||
String aql = String.format("for d in vis_log_dev\n" +
|
||||
" filter d.uri == '%s' and d.ip == '%s' and (d.userid == %s or d.userid==0)\n" +
|
||||
" collect WITH COUNT INTO total\n" +
|
||||
" return total", visLog.getUri(), visLog.getIp(), visLog.getUserid());
|
||||
|
||||
long total = ArangoKit.findInt(aql);
|
||||
|
||||
|
||||
if (total <= 1) {
|
||||
String uri = visLog.getUri();
|
||||
int contentid = Integer.parseInt(uri.replace("/jie/detail/", ""));
|
||||
source.updateColumn(Content.class, contentid, ColumnValue.inc("viewnum", 1));
|
||||
}
|
||||
}
|
||||
|
||||
@RestMapping(ignore = true, comment = "访问热帖数据")
|
||||
public Sheet<ContentInfo> hotView(String sessionid){
|
||||
int limit = 8;
|
||||
String cacheKey = "hotView";
|
||||
Object ids = cacheSource.get(cacheKey);
|
||||
Object ids = null;//cacheSource.get(cacheKey);
|
||||
if (ids == null){
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.set(Calendar.DAY_OF_MONTH, -7);
|
||||
|
||||
Map para = new HashMap();
|
||||
para.put("time", cal.getTimeInMillis());
|
||||
//查询一周某热帖记录
|
||||
Bson filter = and(ne("userid", 100001)
|
||||
,regex("uri", "/jie/detail/*")
|
||||
,ne("ip", "")
|
||||
,gt("time", cal.getTimeInMillis())
|
||||
);
|
||||
List<Bson> list = asList(
|
||||
Aggregates.match(filter)
|
||||
,Aggregates.group("$uri", Accumulators.sum("count", 1))
|
||||
,Aggregates.sort(new Document("count", -1))
|
||||
,Aggregates.limit(8)
|
||||
);
|
||||
AggregateIterable<Document> documents = visLog.aggregate(list, Document.class);
|
||||
List<Count> hotArticle = ArangoKit.find(
|
||||
"for d in vis_log_dev\n" +
|
||||
" filter d.uri =~ '^/jie/detail/[0-9]+$' and d.userid != 100001 and d.time > @time\n" +
|
||||
" COLLECT uri=d.uri WITH COUNT INTO total\n" +
|
||||
" sort total desc\n" +
|
||||
" limit 10\n" +
|
||||
" return {name: uri,total:total}",
|
||||
Map.of("time", cal.getTimeInMillis()),
|
||||
Count.class);
|
||||
|
||||
List<Integer> _ids = new ArrayList<>(limit);
|
||||
documents.forEach((Block<? super Document>) x->{
|
||||
String uri = x.getString("_id");
|
||||
_ids.add(Integer.parseInt(uri.replace("/jie/detail/", "")));
|
||||
});
|
||||
Function<List<Count>, List<Integer>> deal = (counts) -> {
|
||||
List<Integer> _ids = new ArrayList<>();
|
||||
counts.forEach(x -> {
|
||||
_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];
|
||||
@ -189,7 +183,7 @@ public class TaskQueue<T extends Object> extends BaseService implements Runnable
|
||||
|
||||
List<Map> rows = new ArrayList<>();
|
||||
List<Integer> uids = new ArrayList<>();
|
||||
documents.forEach((Block<? super Document>) x->{
|
||||
documents.forEach((Consumer<? super Document>) x->{
|
||||
Integer userid = x.getInteger("userid");
|
||||
if (userid > 0) uids.add(userid);
|
||||
|
||||
|
37
src/com/lxyer/bbs/base/entity/Count.java
Normal file
37
src/com/lxyer/bbs/base/entity/Count.java
Normal 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 +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -71,4 +71,17 @@ public class VisLog {
|
||||
public void setHeaders(Map headers) {
|
||||
this.headers = headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VisLog{" +
|
||||
"ip='" + ip + '\'' +
|
||||
", userid='" + userid + '\'' +
|
||||
", ftime='" + ftime + '\'' +
|
||||
", uri='" + uri + '\'' +
|
||||
", time=" + time +
|
||||
", para=" + para +
|
||||
", headers=" + headers +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ public class UserService extends BaseService {
|
||||
user.setNickname(nickname);//去除昵称中的空格
|
||||
source.updateColumn(user
|
||||
,FilterNode.create("userid", currentUserid(sessionid))
|
||||
,SelectColumn.createIncludes(columns)
|
||||
,SelectColumn.includes(columns)
|
||||
);
|
||||
return RetResult.success();
|
||||
}
|
||||
@ -139,7 +139,7 @@ public class UserService extends BaseService {
|
||||
//最新加入
|
||||
public Sheet<UserInfo> lastReg(){
|
||||
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)
|
||||
, FilterNode.create("status", 10));
|
||||
|
||||
|
@ -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();
|
||||
source.updateColumn(Content.class, contentid, ColumnValue.create("replynum", count));
|
||||
}else {
|
||||
source.updateColumn(comment, SelectColumn.createIncludes("content"));
|
||||
source.updateColumn(comment, SelectColumn.includes("content"));
|
||||
}
|
||||
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));
|
||||
|
||||
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);
|
||||
infos.forEach(x->{
|
||||
|
Loading…
Reference in New Issue
Block a user