修改:工程简单重构
This commit is contained in:
parent
ea8e9f70bd
commit
68f4e2b479
@ -24,7 +24,7 @@
|
|||||||
</response>
|
</response>
|
||||||
|
|
||||||
<servlets autoload="true" path=""/>
|
<servlets autoload="true" path=""/>
|
||||||
<render value="net.tccn.bbs.base.EnjoyRender"/>
|
<render value="net.tccn.bbs.base.TplRender"/>
|
||||||
</server>
|
</server>
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
238
doc/redbbs.sql
238
doc/redbbs.sql
File diff suppressed because one or more lines are too long
@ -426,16 +426,17 @@
|
|||||||
<li class="layui-hide-xs layui-hide-sm layui-show-md-inline-block"><span class="fly-mid"></span></li>
|
<li class="layui-hide-xs layui-hide-sm layui-show-md-inline-block"><span class="fly-mid"></span></li>
|
||||||
|
|
||||||
<!-- 用户登入后显示 -->
|
<!-- 用户登入后显示 -->
|
||||||
<li class="layui-hide-xs layui-hide-sm layui-show-md-inline-block"><a href="/user?#index">我的投稿</a></li>
|
<li class="layui-hide-xs layui-hide-sm layui-show-md-inline-block"><a href="/user?#index">我发表的贴</a>
|
||||||
|
</li>
|
||||||
<li class="layui-hide-xs layui-hide-sm layui-show-md-inline-block"><a href="/user?#collection">我收藏的贴</a></li>
|
<li class="layui-hide-xs layui-hide-sm layui-show-md-inline-block"><a href="/user?#collection">我收藏的贴</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="fly-column-right layui-hide-xs">
|
<div class="fly-column-right layui-hide-xs">
|
||||||
<span class="fly-search"><i class="layui-icon"></i></span>
|
<span class="fly-search"><i class="layui-icon"></i></span>
|
||||||
<a href="/jie/add" class="layui-btn">文章投稿</a>
|
<a href="/jie/add" class="layui-btn">发表新帖</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-hide-sm layui-show-xs-block" style="margin-top: -10px; padding-bottom: 10px; text-align: center;">
|
<div class="layui-hide-sm layui-show-xs-block" style="margin-top: -10px; padding-bottom: 10px; text-align: center;">
|
||||||
<a href="/jie/add" class="layui-btn">文章投稿</a>
|
<a href="/jie/add" class="layui-btn">发表新帖</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -15,7 +15,7 @@
|
|||||||
#for(x : top.rows??)
|
#for(x : top.rows??)
|
||||||
<li>
|
<li>
|
||||||
<a href="/user/#(x.userid)" class="fly-avatar">
|
<a href="/user/#(x.userid)" class="fly-avatar">
|
||||||
<img src="#(x.avatar)" alt="#(x.nickname)">
|
<img src="#(x.user.avatar)" alt="#(x.user.nickname)">
|
||||||
</a>
|
</a>
|
||||||
<h2 title="#(x.title)">
|
<h2 title="#(x.title)">
|
||||||
#if(x.status == 30)
|
#if(x.status == 30)
|
||||||
@ -33,7 +33,7 @@
|
|||||||
</h2>
|
</h2>
|
||||||
<div class="fly-list-info">
|
<div class="fly-list-info">
|
||||||
<a href="/user/#(x.userid)" link>
|
<a href="/user/#(x.userid)" link>
|
||||||
<cite>#(x.nickname)</cite>
|
<cite>#(x.user.nickname)</cite>
|
||||||
<!--<i class="iconfont icon-renzheng" title="认证信息:XXX"></i>
|
<!--<i class="iconfont icon-renzheng" title="认证信息:XXX"></i>
|
||||||
<i class="layui-badge fly-badge-vip">VIP3</i>-->
|
<i class="layui-badge fly-badge-vip">VIP3</i>-->
|
||||||
</a>
|
</a>
|
||||||
@ -80,7 +80,7 @@
|
|||||||
#for(x : contents.rows??)
|
#for(x : contents.rows??)
|
||||||
<li>
|
<li>
|
||||||
<a href="/user/#(x.userid)" class="fly-avatar">
|
<a href="/user/#(x.userid)" class="fly-avatar">
|
||||||
<img src="#(x.avatar)" alt="#(x.nickname)">
|
<img src="#(x.user.avatar)" alt="#(x.user.nickname)">
|
||||||
</a>
|
</a>
|
||||||
<h2 title="#(x.title)">
|
<h2 title="#(x.title)">
|
||||||
#if(x.status == 30)
|
#if(x.status == 30)
|
||||||
@ -92,7 +92,7 @@
|
|||||||
</h2>
|
</h2>
|
||||||
<div class="fly-list-info">
|
<div class="fly-list-info">
|
||||||
<a href="/user/#(x.userid)" link>
|
<a href="/user/#(x.userid)" link>
|
||||||
<cite>#(x.nickname)</cite>
|
<cite>#(x.user.nickname)</cite>
|
||||||
<!--
|
<!--
|
||||||
<i class="iconfont icon-renzheng" title="认证信息:XXX"></i>
|
<i class="iconfont icon-renzheng" title="认证信息:XXX"></i>
|
||||||
<i class="layui-badge fly-badge-vip">VIP3</i>
|
<i class="layui-badge fly-badge-vip">VIP3</i>
|
||||||
@ -175,13 +175,6 @@
|
|||||||
</div>
|
</div>
|
||||||
#end
|
#end
|
||||||
|
|
||||||
<div class="fly-panel fly-signin">
|
|
||||||
<div class="fly-panel-main fly-signin-main">
|
|
||||||
<div>Redbbs交流群:<cite>237626260</cite></div>
|
|
||||||
<div>Redkale技术交流群:<cite>237626260</cite></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--最新加入-->
|
<!--最新加入-->
|
||||||
<div class="fly-panel fly-rank fly-rank-reply" id="LAY_replyRank">
|
<div class="fly-panel fly-rank fly-rank-reply" id="LAY_replyRank">
|
||||||
<h3 class="fly-panel-title">
|
<h3 class="fly-panel-title">
|
||||||
@ -205,7 +198,7 @@
|
|||||||
#for(x : hotView.rows??)
|
#for(x : hotView.rows??)
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jie/detail/#(x.contentid)">#(x.title)</a>
|
<a href="/jie/detail/#(x.contentid)">#(x.title)</a>
|
||||||
<span><i class="iconfont"></i> #(x.viewnum)</span>
|
<span><i class="iconfont icon-pinglun1"></i> #(x.viewnum)</span>
|
||||||
</dd>
|
</dd>
|
||||||
#else
|
#else
|
||||||
<div class="fly-none">没有相关数据</div>
|
<div class="fly-none">没有相关数据</div>
|
||||||
|
@ -105,7 +105,7 @@
|
|||||||
<a name="item-1111111111"></a>
|
<a name="item-1111111111"></a>
|
||||||
<div class="detail-about detail-about-reply">
|
<div class="detail-about detail-about-reply">
|
||||||
<a class="fly-avatar" href="/user/#(x.userid)">
|
<a class="fly-avatar" href="/user/#(x.userid)">
|
||||||
<img src="#(x.avatar)" alt="#(x.nickname)">
|
<img src="#(x.user.avatar)" alt="#(x.user.nickname)">
|
||||||
</a>
|
</a>
|
||||||
<div class="fly-detail-user">
|
<div class="fly-detail-user">
|
||||||
<a href="" class="fly-link">
|
<a href="" class="fly-link">
|
||||||
@ -179,7 +179,7 @@
|
|||||||
#for(x : hotView.rows??)
|
#for(x : hotView.rows??)
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jie/detail/#(x.contentid)">#(x.title)</a>
|
<a href="/jie/detail/#(x.contentid)">#(x.title)</a>
|
||||||
<span><i class="iconfont"></i> #(x.viewnum)</span>
|
<span><i class="iconfont icon-pinglun1"></i> #(x.viewnum)</span>
|
||||||
</dd>
|
</dd>
|
||||||
#else
|
#else
|
||||||
<div class="fly-none">没有相关数据</div>
|
<div class="fly-none">没有相关数据</div>
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
<li>
|
<li>
|
||||||
|
|
||||||
<a href="/user/#(x.userid)" class="fly-avatar">
|
<a href="/user/#(x.userid)" class="fly-avatar">
|
||||||
<img src="#(x.avatar??)" alt="#(x.nickname)">
|
<img src="#(x.user.avatar??)" alt="#(x.user.nickname)">
|
||||||
</a>
|
</a>
|
||||||
<h2>
|
<h2>
|
||||||
#if(x.status == 30)
|
#if(x.status == 30)
|
||||||
@ -46,7 +46,7 @@
|
|||||||
</h2>
|
</h2>
|
||||||
<div class="fly-list-info">
|
<div class="fly-list-info">
|
||||||
<a href="/user/#(x.userid)" link>
|
<a href="/user/#(x.userid)" link>
|
||||||
<cite>#(x.nickname)</cite>
|
<cite>#(x.user.nickname)</cite>
|
||||||
<!--
|
<!--
|
||||||
<i class="iconfont icon-renzheng" title="认证信息:XXX"></i>
|
<i class="iconfont icon-renzheng" title="认证信息:XXX"></i>
|
||||||
<i class="layui-badge fly-badge-vip">VIP3</i>
|
<i class="layui-badge fly-badge-vip">VIP3</i>
|
||||||
@ -88,7 +88,7 @@
|
|||||||
#for(x : hotView.rows??)
|
#for(x : hotView.rows??)
|
||||||
<dd>
|
<dd>
|
||||||
<a href="/jie/detail/#(x.contentid)">#(x.title)</a>
|
<a href="/jie/detail/#(x.contentid)">#(x.title)</a>
|
||||||
<span><i class="iconfont"></i> #(x.viewnum)</span>
|
<span><i class="iconfont icon-pinglun1"></i> #(x.viewnum)</span>
|
||||||
</dd>
|
</dd>
|
||||||
#else
|
#else
|
||||||
<div class="fly-none">没有相关数据</div>
|
<div class="fly-none">没有相关数据</div>
|
||||||
|
@ -3,23 +3,11 @@
|
|||||||
#set(title=bean.title)
|
#set(title=bean.title)
|
||||||
#set(keywords=bean.title)
|
#set(keywords=bean.title)
|
||||||
#set(description=bean.title)
|
#set(description=bean.title)
|
||||||
#set(
|
|
||||||
project=["redbbs","redtimer", "JKit","jfly"]
|
|
||||||
)
|
|
||||||
|
|
||||||
#@layout()
|
#@layout()
|
||||||
#define css()
|
#define css()
|
||||||
<style>
|
<style>
|
||||||
.fly-panel{margin-right: 15px}
|
.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>
|
</style>
|
||||||
#end
|
#end
|
||||||
|
|
||||||
@ -27,16 +15,6 @@
|
|||||||
<div class="layui-container">
|
<div class="layui-container">
|
||||||
|
|
||||||
<div class="layui-row">
|
<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="layui-col-md8" style="padding-top: 20px;">
|
||||||
<!--内容-->
|
<!--内容-->
|
||||||
<div class="fly-panel detail-box">
|
<div class="fly-panel detail-box">
|
||||||
@ -69,11 +47,11 @@
|
|||||||
<a name="item-1111111111"></a>
|
<a name="item-1111111111"></a>
|
||||||
<div class="detail-about detail-about-reply">
|
<div class="detail-about detail-about-reply">
|
||||||
<a class="fly-avatar" href="/user/#(x.userid)">
|
<a class="fly-avatar" href="/user/#(x.userid)">
|
||||||
<img src="#(x.avatar)" alt="#(x.nickname)">
|
<img src="#(x.user.avatar)" alt="#(x.user.nickname)">
|
||||||
</a>
|
</a>
|
||||||
<div class="fly-detail-user">
|
<div class="fly-detail-user">
|
||||||
<a href="" class="fly-link">
|
<a href="" class="fly-link">
|
||||||
<cite>#(x.nickname)</cite>
|
<cite>#(x.user.nickname)</cite>
|
||||||
<!--<i class="iconfont icon-renzheng" title="认证信息:XXX"></i>
|
<!--<i class="iconfont icon-renzheng" title="认证信息:XXX"></i>
|
||||||
<i class="layui-badge fly-badge-vip">VIP3</i>-->
|
<i class="layui-badge fly-badge-vip">VIP3</i>-->
|
||||||
</a>
|
</a>
|
||||||
@ -141,11 +119,11 @@
|
|||||||
<div class="fly-panel detail-box">
|
<div class="fly-panel detail-box">
|
||||||
<div class="detail-about">
|
<div class="detail-about">
|
||||||
<a class="fly-avatar" href="/user/#(bean.userid)">
|
<a class="fly-avatar" href="/user/#(bean.userid)">
|
||||||
<img src="#(bean.avatar)" alt="#(bean.nickname)">
|
<img src="#(bean.user.avatar)" alt="#(bean.user.nickname)">
|
||||||
</a>
|
</a>
|
||||||
<div class="fly-detail-user">
|
<div class="fly-detail-user">
|
||||||
<a href="/user/#(bean.userid)" class="fly-link">
|
<a href="/user/#(bean.userid)" class="fly-link">
|
||||||
<cite>#(bean.nickname)</cite>
|
<cite>#(bean.user.nickname)</cite>
|
||||||
<!--
|
<!--
|
||||||
<i class="iconfont icon-renzheng" title="认证信息:{{ rows.user.approve }}"></i>
|
<i class="iconfont icon-renzheng" title="认证信息:{{ rows.user.approve }}"></i>
|
||||||
<i class="layui-badge fly-badge-vip">VIP3</i>
|
<i class="layui-badge fly-badge-vip">VIP3</i>
|
||||||
@ -244,8 +222,8 @@
|
|||||||
</div>-->
|
</div>-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
#end
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
#end
|
#end
|
||||||
|
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
package net.tccn.bbs.base;
|
|
||||||
|
|
||||||
import com.arangodb.ArangoCollection;
|
|
||||||
import com.arangodb.ArangoDB;
|
|
||||||
import com.arangodb.ArangoDatabase;
|
|
||||||
import net.tccn.bbs.base.entity.VisLog;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
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("abc123").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();
|
|
||||||
}
|
|
||||||
|
|
||||||
//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> 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,98 +0,0 @@
|
|||||||
package net.tccn.bbs.base;
|
|
||||||
|
|
||||||
import com.arangodb.ArangoCollection;
|
|
||||||
import com.arangodb.ArangoDB;
|
|
||||||
import com.arangodb.ArangoDatabase;
|
|
||||||
import net.tccn.bbs.base.entity.VisLog;
|
|
||||||
import org.redkale.net.http.RestMapping;
|
|
||||||
import org.redkale.net.http.RestService;
|
|
||||||
import org.redkale.util.AnyValue;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author: liangxianyou at 2018/11/18 9:02.
|
|
||||||
*/
|
|
||||||
@RestService(automapping = true, comment = "Arango服务")
|
|
||||||
public class ArangoService extends BaseService {
|
|
||||||
|
|
||||||
protected static final boolean winos = System.getProperty("os.name").contains("Window");
|
|
||||||
|
|
||||||
protected Function<String, String> chDev = (s) -> s + (isDev ? "_dev" : "");
|
|
||||||
|
|
||||||
@Resource(name = "property.arango.host")
|
|
||||||
private String arangoHost = "127.0.0.1";
|
|
||||||
@Resource(name = "property.arango.port")
|
|
||||||
private int port = 8529;
|
|
||||||
@Resource(name = "property.arango.database")
|
|
||||||
private String database = "redbbs";
|
|
||||||
@Resource(name = "property.arango.user")
|
|
||||||
private String user = "root";
|
|
||||||
@Resource(name = "property.arango.password")
|
|
||||||
private String password = "root";
|
|
||||||
|
|
||||||
//日志存放doc名称
|
|
||||||
private static final String VIS_LOG = "vis_log";
|
|
||||||
|
|
||||||
//Arango
|
|
||||||
protected static ArangoDB arangoDb;
|
|
||||||
protected static ArangoDatabase db;
|
|
||||||
protected static ArangoCollection colVisLog;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(AnyValue config) {
|
|
||||||
CompletableFuture.runAsync(() -> {
|
|
||||||
System.out.println("isDev :" + isDev);
|
|
||||||
|
|
||||||
arangoDb = new ArangoDB.Builder().host(arangoHost, port).user(user).password(password).build();
|
|
||||||
db = arangoDb.db(chDev.apply(database));
|
|
||||||
colVisLog = db.collection(chDev.apply(VIS_LOG));
|
|
||||||
|
|
||||||
if (!db.exists()) {
|
|
||||||
db.create();
|
|
||||||
}
|
|
||||||
if (!colVisLog.exists()) {
|
|
||||||
colVisLog.create();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@RestMapping(auth = false)
|
|
||||||
public List<Map> hi() {
|
|
||||||
System.out.println("colVisLog :" + colVisLog.exists());
|
|
||||||
String aql = String.format("for d in %s limit 10 return d", chDev.apply(VIS_LOG));
|
|
||||||
List<Map> visLogs = db.query(aql, Map.class).asListRemaining();
|
|
||||||
return visLogs;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 db.query(aql, long.class).first();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long findInt(String aql, Map para) {
|
|
||||||
return db.query(aql, long.class).first();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> List<T> find(String aql, Class<T> clazz) {
|
|
||||||
return db.query(aql, clazz).asListRemaining();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> List<T> find(String aql, Map para, Class<T> clazz) {
|
|
||||||
|
|
||||||
return db.query(aql, para, clazz).asListRemaining();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
14
src/net/tccn/bbs/base/BaseEntity.java
Normal file
14
src/net/tccn/bbs/base/BaseEntity.java
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package net.tccn.bbs.base;
|
||||||
|
|
||||||
|
import org.redkale.convert.json.JsonConvert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 所有 entity 上层类
|
||||||
|
*/
|
||||||
|
public abstract class BaseEntity {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JsonConvert.root().convertTo(this);
|
||||||
|
}
|
||||||
|
}
|
@ -1,16 +1,12 @@
|
|||||||
package net.tccn.bbs.base;
|
package net.tccn.bbs.base;
|
||||||
|
|
||||||
import com.arangodb.Predicate;
|
|
||||||
import org.redkale.net.http.RestMapping;
|
import org.redkale.net.http.RestMapping;
|
||||||
|
import org.redkale.service.RetResult;
|
||||||
import org.redkale.service.Service;
|
import org.redkale.service.Service;
|
||||||
import org.redkale.source.CacheSource;
|
import org.redkale.source.CacheSource;
|
||||||
import org.redkale.source.DataSource;
|
import org.redkale.source.DataSource;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.io.File;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Lxy at 2017/10/3 13:50.
|
* Created by Lxy at 2017/10/3 13:50.
|
||||||
@ -19,14 +15,13 @@ public class BaseService implements Service {
|
|||||||
|
|
||||||
protected final int sessionExpireSeconds = 7 * 24 * 60 * 60;
|
protected final int sessionExpireSeconds = 7 * 24 * 60 * 60;
|
||||||
|
|
||||||
@Resource(name = "property.isDev")
|
protected final static RetResult RET_SUCCESS = RetResult.success();
|
||||||
public boolean isDev = true;
|
|
||||||
|
|
||||||
@Resource(name = "SERVER_ROOT")
|
/*@Resource(name = "SERVER_ROOT")
|
||||||
protected File webroot;
|
protected File webroot;*/
|
||||||
|
|
||||||
@Resource(name = "redbbs")
|
@Resource(name = "redbbs")
|
||||||
protected DataSource source;
|
protected DataSource dataSource;
|
||||||
|
|
||||||
/* 使用redis 代码中配置此处即可
|
/* 使用redis 代码中配置此处即可
|
||||||
@Resource(name = "redis")*/
|
@Resource(name = "redis")*/
|
||||||
@ -38,35 +33,12 @@ public class BaseService implements Service {
|
|||||||
|
|
||||||
protected static final boolean winos = System.getProperty("os.name").contains("Window");
|
protected static final boolean winos = System.getProperty("os.name").contains("Window");
|
||||||
|
|
||||||
public static Predicate isEmpty = (x) -> {
|
|
||||||
if (x == null)
|
|
||||||
return true;
|
|
||||||
if (x instanceof List)
|
|
||||||
return ((List) x).isEmpty();
|
|
||||||
if (x instanceof String)
|
|
||||||
return ((String) x).isEmpty();
|
|
||||||
if (x instanceof Map)
|
|
||||||
return ((Map) x).isEmpty();
|
|
||||||
if (x instanceof Collection)
|
|
||||||
return ((Collection) x).isEmpty();
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
@RestMapping(ignore = true)
|
@RestMapping(ignore = true)
|
||||||
public DataSource getSource() {
|
public DataSource getSource() {
|
||||||
return source;
|
return dataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RestMapping(ignore = true)
|
protected RetResult retError(String info) {
|
||||||
public int currentUserid(String sessionid) {
|
return new RetResult<>(-1, info);
|
||||||
if (sessionid == null) return 0;
|
|
||||||
long userid = 0;
|
|
||||||
try {
|
|
||||||
userid = sessions.getLong(sessionid, 0);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return (int) userid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
package net.tccn.bbs.base;
|
package net.tccn.bbs.base;
|
||||||
|
|
||||||
import com.jfinal.kit.Kv;
|
import com.jfinal.kit.Kv;
|
||||||
import net.tccn.bbs.base.entity.VisLog;
|
import net.tccn.bbs.base.util.RetCodes;
|
||||||
import net.tccn.bbs.base.kit.RetCodes;
|
import net.tccn.bbs.base.util.TaskQueue;
|
||||||
import net.tccn.bbs.base.user.UserInfo;
|
|
||||||
import net.tccn.bbs.base.user.UserService;
|
|
||||||
import net.tccn.bbs.comment.CommentService;
|
import net.tccn.bbs.comment.CommentService;
|
||||||
import net.tccn.bbs.content.ContentService;
|
import net.tccn.bbs.content.ContentService;
|
||||||
|
import net.tccn.bbs.user.UserInfo;
|
||||||
|
import net.tccn.bbs.user.UserService;
|
||||||
|
import net.tccn.bbs.vislog.entity.VisLog;
|
||||||
import org.redkale.net.http.*;
|
import org.redkale.net.http.*;
|
||||||
import org.redkale.source.FilterExpress;
|
import org.redkale.source.FilterExpress;
|
||||||
import org.redkale.source.FilterNode;
|
import org.redkale.source.FilterNode;
|
||||||
@ -17,12 +18,11 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
import static net.tccn.bbs.base.kit.RetCodes.RET_USER_UNLOGIN;
|
import static net.tccn.bbs.base.util.RetCodes.RET_USER_UNLOGIN;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Lxy at 2017/10/3 13:39.
|
* Created by Lxy at 2017/10/3 13:39.
|
||||||
*/
|
*/
|
||||||
@HttpUserType(UserInfo.class)
|
|
||||||
public class BaseServlet extends HttpServlet {
|
public class BaseServlet extends HttpServlet {
|
||||||
|
|
||||||
protected static final boolean winos = System.getProperty("os.name").contains("Window");
|
protected static final boolean winos = System.getProperty("os.name").contains("Window");
|
||||||
@ -59,6 +59,7 @@ public class BaseServlet extends HttpServlet {
|
|||||||
if (sessionid != null) {
|
if (sessionid != null) {
|
||||||
request.setCurrentUser(userService.current(sessionid));
|
request.setCurrentUser(userService.current(sessionid));
|
||||||
currentid = userService.currentUserid(sessionid);
|
currentid = userService.currentUserid(sessionid);
|
||||||
|
request.setCurrentUserid(currentid);
|
||||||
}
|
}
|
||||||
|
|
||||||
String uri = request.getRequestURI();
|
String uri = request.getRequestURI();
|
||||||
@ -156,7 +157,9 @@ public class BaseServlet extends HttpServlet {
|
|||||||
public int getParaToInt(HttpRequest request, int index) {
|
public int getParaToInt(HttpRequest request, int index) {
|
||||||
int n = 0;
|
int n = 0;
|
||||||
String para = getPara(request, index);
|
String para = getPara(request, index);
|
||||||
if (para == null || "".equals(para)) n = 0;
|
if (para == null || "".equals(para)) {
|
||||||
|
n = 0;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
n = Integer.parseInt(para);
|
n = Integer.parseInt(para);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -3,8 +3,8 @@ package net.tccn.bbs.base;
|
|||||||
import com.jfinal.kit.Kv;
|
import com.jfinal.kit.Kv;
|
||||||
import com.jfinal.template.Engine;
|
import com.jfinal.template.Engine;
|
||||||
import com.jfinal.template.Template;
|
import com.jfinal.template.Template;
|
||||||
import net.tccn.bbs.base.kit.EJ;
|
import net.tccn.bbs.base.util.EJ;
|
||||||
import net.tccn.bbs.base.user.UserInfo;
|
import net.tccn.bbs.user.UserInfo;
|
||||||
import org.redkale.convert.Convert;
|
import org.redkale.convert.Convert;
|
||||||
import org.redkale.net.http.*;
|
import org.redkale.net.http.*;
|
||||||
import org.redkale.util.AnyValue;
|
import org.redkale.util.AnyValue;
|
||||||
@ -16,7 +16,7 @@ import java.util.Map;
|
|||||||
/**
|
/**
|
||||||
* Created by JUECHENG at 2018/1/30 0:18.
|
* Created by JUECHENG at 2018/1/30 0:18.
|
||||||
*/
|
*/
|
||||||
public class EnjoyRender implements HttpRender<HttpScope> {
|
public class TplRender implements HttpRender<HttpScope> {
|
||||||
|
|
||||||
@Resource(name = "SERVER_ROOT")
|
@Resource(name = "SERVER_ROOT")
|
||||||
protected File webroot;
|
protected File webroot;
|
||||||
@ -25,9 +25,10 @@ public class EnjoyRender implements HttpRender<HttpScope> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(HttpContext context, AnyValue config) {
|
public void init(HttpContext context, AnyValue config) {
|
||||||
|
engine.setDevMode(true);
|
||||||
engine.setBaseTemplatePath(webroot.getPath());
|
engine.setBaseTemplatePath(webroot.getPath());
|
||||||
engine.addSharedObject("EJ", new EJ());
|
engine.addSharedObject("EJ", new EJ());
|
||||||
engine.addSharedFunction("/_t/layout.html");
|
engine.addSharedFunction("/_tpl/layout.html");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@ -1,13 +0,0 @@
|
|||||||
package net.tccn.bbs.base;
|
|
||||||
|
|
||||||
import net.tccn.bbs.base.iface.UI;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* user foreign key (userId)
|
|
||||||
* Created by liangxianyou at 2018/6/9 14:50.
|
|
||||||
*/
|
|
||||||
public interface UF<I extends UI> {
|
|
||||||
int getUserid();
|
|
||||||
|
|
||||||
I createInfo();
|
|
||||||
}
|
|
750
src/net/tccn/bbs/base/Utils.java
Normal file
750
src/net/tccn/bbs/base/Utils.java
Normal file
@ -0,0 +1,750 @@
|
|||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package net.tccn.bbs.base;
|
||||||
|
|
||||||
|
import net.tccn.bbs.base.util.Kv;
|
||||||
|
import org.redkale.source.DataJdbcSource;
|
||||||
|
import org.redkale.source.DataSource;
|
||||||
|
import org.redkale.source.Flipper;
|
||||||
|
import org.redkale.util.Comment;
|
||||||
|
import org.redkale.util.Reproduce;
|
||||||
|
import org.redkale.util.Sheet;
|
||||||
|
import org.redkale.util.Utility;
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.ResultSetMetaData;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.time.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public final class Utils {
|
||||||
|
|
||||||
|
private Utils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String dateFmt(long time) {
|
||||||
|
/**
|
||||||
|
* 刚刚 60秒内 60 * 1000
|
||||||
|
* x分钟前 1小时候内 60 * 60*1000
|
||||||
|
* x小时前 1天内 24 * 60*60*1000
|
||||||
|
* x天前 1周内 7 * 24*60*60*1000
|
||||||
|
* 年-月-日 1周前
|
||||||
|
*/
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
|
||||||
|
long diff = now - time;
|
||||||
|
if (diff < 60 * 1000)
|
||||||
|
return "刚刚";
|
||||||
|
else if (diff < 60 * 60 * 1000)
|
||||||
|
return Math.floorDiv(diff, 60 * 1000) + "分钟前";
|
||||||
|
else if (diff < 24 * 60 * 60 * 1000)
|
||||||
|
return Math.floorDiv(diff, 60 * 60 * 1000) + "小时前";
|
||||||
|
else if (diff > 24 * 60 * 60 * 1000 && diff < 7 * 24 * 60 * 60 * 1000)
|
||||||
|
return Math.floorDiv(diff, 24 * 60 * 60 * 1000) + "天前";
|
||||||
|
else
|
||||||
|
return new SimpleDateFormat("yyyy-MM-dd").format(time);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String delHTMLTag(String htmlStr) {
|
||||||
|
String regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>"; //定义script的正则表达式
|
||||||
|
String regEx_style = "<style[^>]*?>[\\s\\S]*?<\\/style>"; //定义style的正则表达式
|
||||||
|
String regEx_html = "<[^>]+>"; //定义HTML标签的正则表达式
|
||||||
|
|
||||||
|
Pattern p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
|
||||||
|
Matcher m_script = p_script.matcher(htmlStr);
|
||||||
|
htmlStr = m_script.replaceAll(""); //过滤script标签
|
||||||
|
|
||||||
|
Pattern p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
|
||||||
|
Matcher m_style = p_style.matcher(htmlStr);
|
||||||
|
htmlStr = m_style.replaceAll(""); //过滤style标签
|
||||||
|
|
||||||
|
Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
|
||||||
|
Matcher m_html = p_html.matcher(htmlStr);
|
||||||
|
htmlStr = m_html.replaceAll(""); //过滤html标签
|
||||||
|
|
||||||
|
return htmlStr.trim(); //返回文本字符串
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T[] listToArray(List list, T[] ts) {
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
ts[0] = (T) list.get(i);
|
||||||
|
}
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int[] listToArray(List list, int[] ts) {
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
ts[0] = (int) list.get(i);
|
||||||
|
}
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断对象是否为空
|
||||||
|
*
|
||||||
|
* @param obj 待判断的对象
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean isEmpty(Object obj) {
|
||||||
|
if (obj == null) {
|
||||||
|
return true;
|
||||||
|
} else if (obj instanceof String) {
|
||||||
|
return ((String) obj).trim().isEmpty();
|
||||||
|
} else if (obj instanceof Collection) {
|
||||||
|
return ((Collection) obj).isEmpty();
|
||||||
|
} else if (obj instanceof Map) {
|
||||||
|
return ((Map) obj).isEmpty();
|
||||||
|
} else if (obj.getClass().isArray() && Array.getLength(obj) == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, Reproduce> reproduceMap = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param d 目标对象
|
||||||
|
* @param s 源对象
|
||||||
|
* @param <D> 目标对象的数据类型
|
||||||
|
* @param <S> 源对象的数据类型
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static <D, S> D copy(D d, S s) {
|
||||||
|
String reproductKey = d.getClass().getName() + "_" + s.getClass().getName();
|
||||||
|
|
||||||
|
Reproduce<D, S> reproduce = reproduceMap.get(reproductKey);
|
||||||
|
if (reproduce == null) {
|
||||||
|
if (reproduce == null) {
|
||||||
|
reproduceMap.put(reproductKey, reproduce = (Reproduce<D, S>) Reproduce.create(d.getClass(), s.getClass()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return reproduce.apply(d, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static List<String> parseHtmlImage(String html) {
|
||||||
|
Pattern pattern = Pattern.compile("(?<=(<img\\s?src\\s?=\\s?\"))\\S+\\.[A-Za-z]+");
|
||||||
|
Matcher match = pattern.matcher(html);
|
||||||
|
List<String> ls = new ArrayList<>();
|
||||||
|
while (match.find()) {
|
||||||
|
ls.add(match.group());
|
||||||
|
}
|
||||||
|
return ls;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param rs
|
||||||
|
* @param type
|
||||||
|
* @param <T>
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static <T> List<T> queryList(ResultSet rs, Class<T> type) {
|
||||||
|
try {
|
||||||
|
List list = new ArrayList();
|
||||||
|
ResultSetMetaData metaData = rs.getMetaData();
|
||||||
|
int count = metaData.getColumnCount();
|
||||||
|
while (rs.next()) {
|
||||||
|
Kv row = Kv.of();
|
||||||
|
for (int i = 1; i <= count; i++) {
|
||||||
|
String columnTypeName = metaData.getColumnTypeName(i);
|
||||||
|
//String columnName = metaData.getColumnName(i);
|
||||||
|
String columnLabel = metaData.getColumnLabel(i);
|
||||||
|
row.put(columnLabel, null);
|
||||||
|
|
||||||
|
if (rs.getObject(i) != null) {
|
||||||
|
switch (columnTypeName) {
|
||||||
|
case "DATETIME", "TIMESTAMP", "DATE" -> row.put(columnLabel, rs.getTimestamp(i).getTime());
|
||||||
|
default -> row.put(columnLabel, rs.getObject(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list.add((Map.class == type || Kv.class == type) ? row : Kv.toBean(row, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询 第一条的 第一列数据 值
|
||||||
|
*
|
||||||
|
* @param rs
|
||||||
|
* @param type
|
||||||
|
* @param <T>
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static <T> T findColumn(ResultSet rs, Class<T> type) {
|
||||||
|
try {
|
||||||
|
Object v = null;
|
||||||
|
while (rs.next()) {
|
||||||
|
ResultSetMetaData metaData = rs.getMetaData();
|
||||||
|
int count = metaData.getColumnCount();
|
||||||
|
|
||||||
|
for (int i = 1; i <= count; i++) {
|
||||||
|
String columnTypeName = metaData.getColumnTypeName(i);
|
||||||
|
if (rs.getObject(i) != null) {
|
||||||
|
switch (columnTypeName) {
|
||||||
|
case "DATETIME", "TIMESTAMP", "DATE" -> v = rs.getTimestamp(i).getTime();
|
||||||
|
default -> v = rs.getObject(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Kv.toAs(v, type);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List 混排
|
||||||
|
*
|
||||||
|
* @param list
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static <T> List<T> mix(List<T> list) {
|
||||||
|
int len = list.size();
|
||||||
|
Random random = new Random();
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
int r = random.nextInt(len);
|
||||||
|
if (i == r) continue;
|
||||||
|
|
||||||
|
T x = list.get(i);
|
||||||
|
list.set(i, list.get(r));
|
||||||
|
list.set(r, x);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Comment("获取集合随机元素")
|
||||||
|
public static <T> List<T> randomItems(List<T> list, int len) {
|
||||||
|
List<Integer> randoms = getRandoms(list.size(), len);
|
||||||
|
List<T> items = new ArrayList<>(randoms.size());
|
||||||
|
|
||||||
|
randoms.forEach(x -> items.add(list.get(x)));
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Comment("获取随机数字符")
|
||||||
|
public static String randomNumber(int len) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
Random random = new Random();
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
sb.append(random.nextInt(9));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Comment("获取随机数集合")
|
||||||
|
private static List<Integer> getRandoms(int max, int len) {
|
||||||
|
Set<Integer> randoms = new HashSet<>();
|
||||||
|
Random random = new Random();
|
||||||
|
while (randoms.size() < len && randoms.size() < max) {
|
||||||
|
randoms.add(random.nextInt(max));
|
||||||
|
}
|
||||||
|
List<Integer> list = randoms.stream().collect(Collectors.toList());
|
||||||
|
return mix(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unicode转中文
|
||||||
|
*
|
||||||
|
* @param str
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String unicodeToCn(String str) {
|
||||||
|
Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");
|
||||||
|
Matcher matcher = pattern.matcher(str);
|
||||||
|
char ch;
|
||||||
|
while (matcher.find()) {
|
||||||
|
ch = (char) Integer.parseInt(matcher.group(2), 16);
|
||||||
|
str = str.replace(matcher.group(1), ch + "");
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算字符串的字符长度
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static int strLength(String value) {
|
||||||
|
int valueLength = 0;
|
||||||
|
String chinese = "[\u4e00-\u9fa5]";
|
||||||
|
for (int i = 0; i < value.length(); i++) {
|
||||||
|
String temp = value.substring(i, i + 1);
|
||||||
|
if (temp.matches(chinese)) {
|
||||||
|
valueLength += 2;
|
||||||
|
} else {
|
||||||
|
valueLength += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return valueLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String randomIP() {
|
||||||
|
// aaa.aaa.aaa.aaa
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
|
Random r = new Random();
|
||||||
|
buf.append("x").append(".");
|
||||||
|
buf.append(r.nextInt(255)).append(".");
|
||||||
|
buf.append(r.nextInt(255)).append(".");
|
||||||
|
buf.append(r.nextInt(255));
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String fmt36(int n) {
|
||||||
|
return Integer.toString(n, 36);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String fmt36(long n) {
|
||||||
|
return Long.toString(n, 36);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T, V> Map<T, V> toMap(Collection<V> list, Function<V, T> fun) {
|
||||||
|
Map<T, V> map = new HashMap<>(list.size());
|
||||||
|
for (V v : list) {
|
||||||
|
if (v == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
map.put(fun.apply(v), v);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T, V, T2> Map<T, T2> toMap(Collection<V> list, Function<V, T> fun, Function<V, T2> fun2) {
|
||||||
|
Map<T, T2> map = new HashMap<>(list.size());
|
||||||
|
for (V v : list) {
|
||||||
|
if (v == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
map.put(fun.apply(v), fun2.apply(v));
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T, V> List<V> toList(Collection<T> list, Function<T, V> fun) {
|
||||||
|
if (list == null || list.isEmpty()) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
List<V> list1 = new ArrayList<>();
|
||||||
|
list.forEach(x -> list1.add(fun.apply(x)));
|
||||||
|
return list1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T, V> List<V> toList(Sheet<T> sheet, Function<T, V> fun) {
|
||||||
|
List<V> list = new ArrayList<>();
|
||||||
|
sheet.forEach(x -> list.add(fun.apply(x)));
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T, V> Set<V> toSet(Collection<T> list, Function<T, V> fun) {
|
||||||
|
if (list == null || list.isEmpty()) {
|
||||||
|
return new HashSet<>();
|
||||||
|
}
|
||||||
|
Set<V> set = new HashSet<>(list.size());
|
||||||
|
list.forEach(x -> set.add(fun.apply(x)));
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T, V> Set<V> toSet(Sheet<T> sheet, Function<T, V> fun) {
|
||||||
|
Set<V> set = new HashSet<>();
|
||||||
|
sheet.forEach(x -> set.add(fun.apply(x)));
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> List<T> filter(Collection<T> list, Predicate<T> predicate) {
|
||||||
|
if (list == null || list.isEmpty()) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
List<T> list1 = new ArrayList<>(list.size());
|
||||||
|
list.forEach(x -> {
|
||||||
|
if (!predicate.test(x)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
list1.add(x);
|
||||||
|
});
|
||||||
|
|
||||||
|
return list1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T, V> List<V> filterToList(Collection<T> list, Predicate<T> predicate, Function<T, V> fun) {
|
||||||
|
if (list == null || list.isEmpty()) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
List<V> list1 = new ArrayList<>(list.size());
|
||||||
|
|
||||||
|
list.forEach(x -> {
|
||||||
|
if (!predicate.test(x)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
list1.add(fun.apply(x));
|
||||||
|
});
|
||||||
|
|
||||||
|
return list1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T, V> Map<V, List<T>> group(Collection<T> list, Function<T, V> fun) {
|
||||||
|
if (list == null || list.isEmpty()) {
|
||||||
|
return new HashMap<>();
|
||||||
|
}
|
||||||
|
return list.stream().collect(Collectors.groupingBy(fun));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T, V, K> Map<V, List<K>> group(Collection<T> list, Function<T, V> fun, Function<T, K> fun2) {
|
||||||
|
if (list == null || list.isEmpty()) {
|
||||||
|
return new HashMap<>();
|
||||||
|
}
|
||||||
|
Map<V, List<T>> group = group(list, fun);
|
||||||
|
Map<V, List<K>> _group = new HashMap<>();
|
||||||
|
group.forEach((k, v) -> _group.put(k, toList(v, fun2)));
|
||||||
|
return _group;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getHtmlBody(String html) {
|
||||||
|
String s = html.replaceAll("\n", "");
|
||||||
|
int bodyIndex = s.indexOf("<body>");
|
||||||
|
if (bodyIndex > -1) {
|
||||||
|
bodyIndex = bodyIndex + 6;
|
||||||
|
int lastIndexOf = s.lastIndexOf("</body>");
|
||||||
|
if (lastIndexOf < bodyIndex) lastIndexOf = s.length();
|
||||||
|
s = s.substring(bodyIndex, lastIndexOf);
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getHtmlText(String html) {
|
||||||
|
return html.replaceAll("<([^ \\f\\n\\r\\t\\v<]| )+>", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取指定日期的 前/后 几天日期
|
||||||
|
public static long plusDays(long datetime, int daynum) {
|
||||||
|
if (daynum == 0 || datetime == 0) {
|
||||||
|
return datetime;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneId zoneId = ZoneId.systemDefault();
|
||||||
|
LocalDateTime time = LocalDateTime.ofInstant(Instant.ofEpochMilli(datetime), zoneId);
|
||||||
|
time = time.plusDays(daynum);
|
||||||
|
return time.toInstant(ZoneOffset.of("+8")).toEpochMilli();
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------
|
||||||
|
private static final MessageDigest sha1;
|
||||||
|
private static final MessageDigest md5;
|
||||||
|
private static final String AES_KEY = "HAOGAME_20200721";
|
||||||
|
private static final Cipher aesEncrypter; //加密
|
||||||
|
private static final Cipher aesDecrypter; //解密
|
||||||
|
|
||||||
|
static {
|
||||||
|
MessageDigest d = null;
|
||||||
|
try {
|
||||||
|
d = MessageDigest.getInstance("SHA-1");
|
||||||
|
} catch (NoSuchAlgorithmException ex) {
|
||||||
|
throw new Error(ex);
|
||||||
|
}
|
||||||
|
sha1 = d;
|
||||||
|
try {
|
||||||
|
d = MessageDigest.getInstance("MD5");
|
||||||
|
} catch (NoSuchAlgorithmException ex) {
|
||||||
|
throw new Error(ex);
|
||||||
|
}
|
||||||
|
md5 = d;
|
||||||
|
|
||||||
|
Cipher cipher = null;
|
||||||
|
final SecretKeySpec aesKey = new SecretKeySpec(AES_KEY.getBytes(), "AES");
|
||||||
|
try {
|
||||||
|
cipher = Cipher.getInstance("AES");
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, aesKey);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
aesEncrypter = cipher; //加密
|
||||||
|
try {
|
||||||
|
cipher = Cipher.getInstance("AES");
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, aesKey);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
aesDecrypter = cipher; //解密
|
||||||
|
}
|
||||||
|
|
||||||
|
//AES加密
|
||||||
|
public static String encryptAES(String value) {
|
||||||
|
if (value == null || value.isEmpty()) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
synchronized (aesEncrypter) {
|
||||||
|
return Utility.binToHexString(aesEncrypter.doFinal(value.getBytes()));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//AES解密
|
||||||
|
public static String decryptAES(String value) {
|
||||||
|
if (value == null || value.isEmpty()) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
byte[] hex = Utility.hexToBin(value);
|
||||||
|
try {
|
||||||
|
synchronized (aesEncrypter) {
|
||||||
|
return new String(aesDecrypter.doFinal(hex));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Comment("GET请求参数转换为字符,结果:p1=v1&p2=v2&p3=v3")
|
||||||
|
public static String convertHttpParams(Map map, boolean encode) {
|
||||||
|
if (map == null || map.isEmpty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
map.forEach((k, v) -> {
|
||||||
|
if (Utils.isEmpty(k) || Utils.isEmpty(v)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String value = String.valueOf(v);
|
||||||
|
if (encode) {
|
||||||
|
value = URLEncoder.encode(String.valueOf(v), StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
sb.append("&").append(k).append("=").append(value);
|
||||||
|
});
|
||||||
|
return sb.length() > 0 ? sb.substring(1) : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Comment("对象转GET请求参数转换为字符,结果:p1=v1&p2=v2&p3=v3")
|
||||||
|
public static String convertHttpParams(Object o, List<String> removeFields, boolean encode) {
|
||||||
|
Class<? extends Object> c = o.getClass();
|
||||||
|
Field[] fields = c.getDeclaredFields();
|
||||||
|
Map<String, Object> map = new TreeMap<String, Object>();
|
||||||
|
for (Field field : fields) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
String name = field.getName();
|
||||||
|
if (!Utils.isEmpty(removeFields) && removeFields.contains(name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Object value = null;
|
||||||
|
try {
|
||||||
|
value = field.get(o);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
if (value != null) {
|
||||||
|
map.put(name, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return convertHttpParams(map, encode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Comment("GET请求参数转换为字符,结果:p1=v1&p2=v2&p3=v3")
|
||||||
|
public static String convertHttpParams(Map<String, Object> map) {
|
||||||
|
if (map == null || map.isEmpty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
Set<String> sortSet = new TreeSet<String>();
|
||||||
|
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||||
|
sortSet.add(entry.getKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 参数名按ASCII码从小到大排序(字典序),然后使用( & )连接排好序的key=value集合
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
boolean isFirst = true;
|
||||||
|
for (String key : sortSet) {
|
||||||
|
if (isFirst) {
|
||||||
|
sb.append(key + "=" + URLEncoder.encode(String.valueOf(map.get(key)), StandardCharsets.UTF_8));
|
||||||
|
isFirst = false;
|
||||||
|
} else {
|
||||||
|
sb.append("&" + key + "=" + URLEncoder.encode(String.valueOf(map.get(key)), StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Comment("对象转map")
|
||||||
|
public static Map<String, Object> convertToMap(Object o, List<String> removeFields) {
|
||||||
|
Class<? extends Object> c = o.getClass();
|
||||||
|
List<Field> fields = Stream.of(c.getDeclaredFields()).collect(Collectors.toList());
|
||||||
|
if (c.getSuperclass() != null) {
|
||||||
|
Field[] superFields = c.getSuperclass().getDeclaredFields();
|
||||||
|
if (superFields.length > 0) {
|
||||||
|
fields.addAll(Arrays.asList(superFields));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> map = new TreeMap<>();
|
||||||
|
for (Field field : fields) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
String name = field.getName();
|
||||||
|
if (!Utils.isEmpty(removeFields) && removeFields.contains(name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Object value = null;
|
||||||
|
try {
|
||||||
|
value = field.get(o);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
if (value != null) {
|
||||||
|
map.put(name, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Comment("key字典排序")
|
||||||
|
public static LinkedHashMap sortedMap(Map<String, ?> map, String... excludeKeys) {
|
||||||
|
List<String> excludeList = List.of(excludeKeys);
|
||||||
|
LinkedHashMap<String, Object> linkedHashMap = new LinkedHashMap<>();
|
||||||
|
map.entrySet().stream()
|
||||||
|
.filter(f -> !excludeList.contains(f.getKey()))
|
||||||
|
.sorted(Map.Entry.comparingByKey())
|
||||||
|
.forEach(x -> linkedHashMap.put(x.getKey(), x.getValue()));
|
||||||
|
return linkedHashMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Comment(" string转化为jsonstring")
|
||||||
|
public static String convertParamStrToJsonStr(String paramStr) {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
Arrays.stream(paramStr.split("&")).forEach(x -> {
|
||||||
|
//防止有地址传参时造成的错误解析
|
||||||
|
x = URLDecoder.decode(x, StandardCharsets.UTF_8);
|
||||||
|
int index = x.indexOf("=");
|
||||||
|
char c = x.charAt(index + 1);
|
||||||
|
builder.append(String.format("\"%s\":\"%s\",", x.substring(0, index), c == '[' || c == '{' ? x.substring(index + 1).replaceAll("\"", "\\\\\"") : x.substring(index + 1)));
|
||||||
|
});
|
||||||
|
return String.format("{%s}", builder.deleteCharAt(builder.length() - 1).toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Sheet<T> querySheetBySql(DataSource dataSource, String sql, Flipper flipper, Class<T> type) {
|
||||||
|
DataJdbcSource jdbcSource = (DataJdbcSource) dataSource;
|
||||||
|
//总条数
|
||||||
|
int total = jdbcSource.directQuery("select count(0) c from (" + sql + ") c", rs -> {
|
||||||
|
int result = 0;
|
||||||
|
try {
|
||||||
|
while (rs.next()) {
|
||||||
|
result = rs.getInt(1);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (total == 0) {
|
||||||
|
return new Sheet<>(0, new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flipper != null) {
|
||||||
|
sql = String.format("%s %s limit %s,%s ", sql, Utils.isEmpty(flipper.getSort()) ? "" : "order by " + flipper.getSort(), flipper.getOffset(), flipper.getLimit());
|
||||||
|
}
|
||||||
|
List<T> dataList = jdbcSource.directQuery(sql, rs -> Utils.queryList(rs, type));
|
||||||
|
return new Sheet<>(total, dataList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Comment("获取次日0点0分0秒时间戳")
|
||||||
|
public static long getNextDayZero() {
|
||||||
|
LocalDate localDate = LocalDate.now();
|
||||||
|
localDate = localDate.plusDays(1);
|
||||||
|
LocalDateTime dateTime = LocalDateTime.of(localDate.getYear(), localDate.getMonth(), localDate.getDayOfMonth(), 0, 0, 0);
|
||||||
|
return dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String formatTime(long time, String pattern) {
|
||||||
|
if (Utils.isEmpty(pattern)) pattern = "yyyy-MM-dd";
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
|
||||||
|
return sdf.format(new Date(time));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Comment("获取字符串中某个字符的数量")
|
||||||
|
public static int strCountOfChar(String str, String code) {
|
||||||
|
int fromIndex = 0;
|
||||||
|
int count = 0;
|
||||||
|
while (true) {
|
||||||
|
int index = str.indexOf(code, fromIndex);
|
||||||
|
if (-1 != index) {
|
||||||
|
fromIndex = index + 1;
|
||||||
|
count++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Random random = new Random();
|
||||||
|
|
||||||
|
public static int randomNum(int len) {
|
||||||
|
int rs = random.nextInt(9);
|
||||||
|
if (rs == 0) rs = 1;
|
||||||
|
for (int i = 0; i < len - 1; i++) { //总长度为6
|
||||||
|
rs = rs * 10 + random.nextInt(9);
|
||||||
|
}
|
||||||
|
return rs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String genMd5(String info) {
|
||||||
|
MessageDigest md5 = null;
|
||||||
|
try {
|
||||||
|
md5 = MessageDigest.getInstance("MD5");
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
byte[] infoBytes = info.getBytes();
|
||||||
|
md5.update(infoBytes);
|
||||||
|
byte[] sign = md5.digest();
|
||||||
|
return byteArrayToHex(sign);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String byteArrayToHex(byte[] bytes) {
|
||||||
|
StringBuilder sign = new StringBuilder();
|
||||||
|
for (byte aByte : bytes) {
|
||||||
|
String hex = Integer.toHexString(aByte & 0xFF);
|
||||||
|
if (hex.length() == 1) {
|
||||||
|
sign.append("0");
|
||||||
|
}
|
||||||
|
sign.append(hex.toLowerCase());
|
||||||
|
}
|
||||||
|
return sign.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,43 +0,0 @@
|
|||||||
package net.tccn.bbs.base.bean;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.redkale.convert.json.JsonConvert;
|
|
||||||
import org.redkale.source.FilterBean;
|
|
||||||
|
|
||||||
import javax.persistence.Column;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author lxyer
|
|
||||||
*/
|
|
||||||
@Setter
|
|
||||||
@Getter
|
|
||||||
public class ActLogBean implements Serializable, FilterBean {
|
|
||||||
|
|
||||||
@Column(comment = "[日志id]")
|
|
||||||
private int logid;
|
|
||||||
|
|
||||||
@Column(comment = "[日志类型]")
|
|
||||||
private int cate;
|
|
||||||
|
|
||||||
@Column(comment = "[目标数据id]")
|
|
||||||
private int tid;
|
|
||||||
|
|
||||||
@Column(comment = "[用户id]")
|
|
||||||
private int userId;
|
|
||||||
|
|
||||||
@Column(comment = "[创建时间]")
|
|
||||||
private long createTime;
|
|
||||||
|
|
||||||
@Column(length = 128, comment = "[说明]")
|
|
||||||
private String remark = "";
|
|
||||||
|
|
||||||
@Column(comment = "[状态]-1删除 1正常")
|
|
||||||
private int status = 1;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return JsonConvert.root().convertTo(this);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
package net.tccn.bbs.base.iface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建信息
|
|
||||||
* Created by liangxianyou at 2018/6/16 17:43.
|
|
||||||
*/
|
|
||||||
public interface C<I extends CI> {
|
|
||||||
I createInfo();
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package net.tccn.bbs.base.iface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by liangxianyou at 2018/6/16 18:39.
|
|
||||||
*/
|
|
||||||
public interface CI<I extends CI> {
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
package net.tccn.bbs.base.iface;
|
|
||||||
|
|
||||||
import org.redkale.net.http.RestMapping;
|
|
||||||
import org.redkale.util.Sheet;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by liangxianyou at 2018/6/16 17:56.
|
|
||||||
*/
|
|
||||||
public interface CService<I extends UI> {
|
|
||||||
|
|
||||||
@RestMapping(ignore = true)
|
|
||||||
default <A extends C> Sheet<I> createInfo(Sheet<A> fSheet) {
|
|
||||||
Sheet<I> sheet = new Sheet<>();
|
|
||||||
|
|
||||||
if (fSheet == null || fSheet.getTotal() < 1) {
|
|
||||||
sheet.setTotal(0);
|
|
||||||
sheet.setRows(new ArrayList<>());
|
|
||||||
} else {
|
|
||||||
int total = (int) fSheet.getTotal();
|
|
||||||
List<I> rows = new ArrayList<>(total);
|
|
||||||
fSheet.forEach(x -> rows.add((I) x.createInfo()));
|
|
||||||
|
|
||||||
sheet.setTotal(total);
|
|
||||||
sheet.setRows(rows);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sheet;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
package net.tccn.bbs.base.iface;
|
|
||||||
|
|
||||||
import net.tccn.bbs.base.user.UserRecord;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by liangxianyou at 2018/6/9 13:45.
|
|
||||||
*/
|
|
||||||
public interface UI<I extends UI> {
|
|
||||||
|
|
||||||
//抽象方法
|
|
||||||
int getUserid();
|
|
||||||
|
|
||||||
UserRecord getUser();
|
|
||||||
|
|
||||||
I setUser(UserRecord user);
|
|
||||||
|
|
||||||
//默认实现方法
|
|
||||||
default String getRealname() {
|
|
||||||
return getUser() == null ? null : getUser().getRealname();
|
|
||||||
}
|
|
||||||
|
|
||||||
default String getNickname() {
|
|
||||||
return getUser() == null ? null : getUser().getNickname();
|
|
||||||
}
|
|
||||||
|
|
||||||
default String getSite() {
|
|
||||||
return getUser() == null ? "" : getUser().getSite();
|
|
||||||
}
|
|
||||||
|
|
||||||
default String getGit() {
|
|
||||||
return getUser() == null ? "" : getUser().getGit();
|
|
||||||
}
|
|
||||||
|
|
||||||
default String getAvatar() {
|
|
||||||
return getUser() == null ? null : getUser().getAvatar();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
package net.tccn.bbs.base.iface;
|
|
||||||
|
|
||||||
import net.tccn.bbs.base.user.UserRecord;
|
|
||||||
import org.redkale.net.http.RestMapping;
|
|
||||||
import org.redkale.source.DataSource;
|
|
||||||
import org.redkale.source.FilterExpress;
|
|
||||||
import org.redkale.source.FilterNode;
|
|
||||||
import org.redkale.util.Sheet;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by liangxianyou at 2018/6/16 18:25.
|
|
||||||
*/
|
|
||||||
public interface UIService<I extends UI> extends CService<I> {
|
|
||||||
|
|
||||||
DataSource getSource();
|
|
||||||
|
|
||||||
@RestMapping(ignore = true)
|
|
||||||
default Sheet<I> setIUser(Sheet<I> sheet) {
|
|
||||||
int[] userids = sheet.stream().mapToInt(I::getUserid).toArray();
|
|
||||||
|
|
||||||
List<UserRecord> users = getSource().queryList(UserRecord.class, FilterNode.create("userid", FilterExpress.IN, userids));
|
|
||||||
sheet.forEach(x -> {
|
|
||||||
UserRecord user = users.stream().filter(u -> u.getUserid() == x.getUserid()).findAny().orElse(null);
|
|
||||||
x.setUser(user);
|
|
||||||
});
|
|
||||||
return sheet;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RestMapping(ignore = true)
|
|
||||||
default I setIUser(I i) {
|
|
||||||
UserRecord user = getSource().find(UserRecord.class, i.getUserid());
|
|
||||||
|
|
||||||
return (I) i.setUser(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
package net.tccn.bbs.base.kit;
|
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Lxy at 2017/11/29 15:17.
|
|
||||||
*/
|
|
||||||
public final class LxyKit {
|
|
||||||
|
|
||||||
public static String dateFmt(long time) {
|
|
||||||
/**
|
|
||||||
* 刚刚 60秒内 60 * 1000
|
|
||||||
* x分钟前 1小时候内 60 * 60*1000
|
|
||||||
* x小时前 1天内 24 * 60*60*1000
|
|
||||||
* x天前 1周内 7 * 24*60*60*1000
|
|
||||||
* 年-月-日 1周前
|
|
||||||
*/
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
|
|
||||||
long diff = now - time;
|
|
||||||
if (diff < 60 * 1000)
|
|
||||||
return "刚刚";
|
|
||||||
else if (diff < 60 * 60 * 1000)
|
|
||||||
return Math.floorDiv(diff, 60 * 1000) + "分钟前";
|
|
||||||
else if (diff < 24 * 60 * 60 * 1000)
|
|
||||||
return Math.floorDiv(diff, 60 * 60 * 1000) + "小时前";
|
|
||||||
else if (diff > 24 * 60 * 60 * 1000 && diff < 7 * 24 * 60 * 60 * 1000)
|
|
||||||
return Math.floorDiv(diff, 24 * 60 * 60 * 1000) + "天前";
|
|
||||||
else
|
|
||||||
return new SimpleDateFormat("yyyy-MM-dd").format(time);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String delHTMLTag(String htmlStr) {
|
|
||||||
String regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>"; //定义script的正则表达式
|
|
||||||
String regEx_style = "<style[^>]*?>[\\s\\S]*?<\\/style>"; //定义style的正则表达式
|
|
||||||
String regEx_html = "<[^>]+>"; //定义HTML标签的正则表达式
|
|
||||||
|
|
||||||
Pattern p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
|
|
||||||
Matcher m_script = p_script.matcher(htmlStr);
|
|
||||||
htmlStr = m_script.replaceAll(""); //过滤script标签
|
|
||||||
|
|
||||||
Pattern p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
|
|
||||||
Matcher m_style = p_style.matcher(htmlStr);
|
|
||||||
htmlStr = m_style.replaceAll(""); //过滤style标签
|
|
||||||
|
|
||||||
Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
|
|
||||||
Matcher m_html = p_html.matcher(htmlStr);
|
|
||||||
htmlStr = m_html.replaceAll(""); //过滤html标签
|
|
||||||
|
|
||||||
return htmlStr.trim(); //返回文本字符串
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> T[] listToArray(List list, T[] ts) {
|
|
||||||
for (int i = 0; i < list.size(); i++) {
|
|
||||||
ts[0] = (T) list.get(i);
|
|
||||||
}
|
|
||||||
return ts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int[] listToArray(List list, int[] ts) {
|
|
||||||
for (int i = 0; i < list.size(); i++) {
|
|
||||||
ts[0] = (int) list.get(i);
|
|
||||||
}
|
|
||||||
return ts;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,181 +0,0 @@
|
|||||||
package net.tccn.bbs.base.user;
|
|
||||||
|
|
||||||
import com.jfinal.kit.Kv;
|
|
||||||
import net.tccn.bbs.base.BaseService;
|
|
||||||
import net.tccn.bbs.base.kit.LxyKit;
|
|
||||||
import net.tccn.bbs.base.kit.RetCodes;
|
|
||||||
import org.redkale.net.http.RestMapping;
|
|
||||||
import org.redkale.net.http.RestParam;
|
|
||||||
import org.redkale.net.http.RestService;
|
|
||||||
import org.redkale.net.http.RestSessionid;
|
|
||||||
import org.redkale.service.RetResult;
|
|
||||||
import org.redkale.source.FilterExpress;
|
|
||||||
import org.redkale.source.FilterFunc;
|
|
||||||
import org.redkale.source.FilterNode;
|
|
||||||
import org.redkale.source.Flipper;
|
|
||||||
import org.redkale.util.SelectColumn;
|
|
||||||
import org.redkale.util.Sheet;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import static net.tccn.bbs.base.kit.RetCodes.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Lxy at 2017/10/3 14:02.
|
|
||||||
*/
|
|
||||||
@RestService(automapping = true, comment = "用户服务")
|
|
||||||
public class UserService extends BaseService {
|
|
||||||
|
|
||||||
@RestMapping(auth = false, comment = "登录校验")
|
|
||||||
public RetResult<UserInfo> login(LoginBean bean) {
|
|
||||||
if (bean == null || bean.emptyUsername()) return RetCodes.retResult(RetCodes.RET_PARAMS_ILLEGAL, "参数错误");
|
|
||||||
|
|
||||||
final RetResult retResult = new RetResult();
|
|
||||||
|
|
||||||
UserRecord user = source.find(UserRecord.class, "username", bean.getUsername());
|
|
||||||
if (user == null || !Objects.equals(user.getPassword(), bean.getPassword())) {
|
|
||||||
//log(null, 0, "用户或密码错误");
|
|
||||||
return RetCodes.retResult(RetCodes.RET_USER_ACCOUNT_PWD_ILLEGAL, "用户名或密码错误");
|
|
||||||
}
|
|
||||||
sessions.setAsync(sessionExpireSeconds, bean.getSessionid(), (long) user.getUserid());
|
|
||||||
retResult.setRetcode(0);
|
|
||||||
retResult.setResult(Kv.by("token", bean.getSessionid()));
|
|
||||||
retResult.setRetinfo("登录成功.");
|
|
||||||
return retResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserInfo current(String sessionid) {
|
|
||||||
if (sessionid == null) return null;
|
|
||||||
|
|
||||||
long userid = 0;
|
|
||||||
try {
|
|
||||||
userid = sessions.getLong(sessionid, 0);
|
|
||||||
sessions.getAndRefresh(sessionid, sessionExpireSeconds);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return userid == 0 ? null : find((int) userid);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RestMapping(name = "info", comment = "用户信息")
|
|
||||||
public UserInfo find(int userid) {
|
|
||||||
UserRecord user = source.find(UserRecord.class, userid);
|
|
||||||
UserInfo bean = user.createUserInfo();
|
|
||||||
return bean;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RestMapping(name = "logout", auth = false, comment = "退出登录")
|
|
||||||
public RetResult logout(@RestSessionid String sessionid) {
|
|
||||||
sessions.remove(sessionid);
|
|
||||||
|
|
||||||
return RetResult.success();
|
|
||||||
//return new HttpResult().header("Location", "/").status(302);
|
|
||||||
}
|
|
||||||
|
|
||||||
@RestMapping(name = "query", auth = false, comment = "用户数据查询")
|
|
||||||
public Sheet<UserRecord> query(Flipper flipper, @RestParam(name = "bean", comment = "过滤条件") final UserBean userBean) {
|
|
||||||
Sheet<UserRecord> users = source.querySheet(UserRecord.class, flipper, userBean);
|
|
||||||
|
|
||||||
return users;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RestMapping(name = "changepwd", comment = "修改密码")
|
|
||||||
public RetResult updatePwd(@RestSessionid String sessionid, String pass, String nowpass) {
|
|
||||||
UserInfo userInfo = current(sessionid);//不会为空
|
|
||||||
|
|
||||||
if (!Objects.equals(userInfo.getPassword(), UserRecord.md5IfNeed(nowpass)))
|
|
||||||
return RetCodes.retResult(RET_USER_ACCOUNT_PWD_ILLEGAL, "密码错误");
|
|
||||||
if (pass == null || pass.length() < 6 || Objects.equals(pass, nowpass))
|
|
||||||
return RetCodes.retResult(RET_USER_PASSWORD_ILLEGAL, "密码设置无效");
|
|
||||||
source.updateColumn(UserRecord.class, userInfo.getUserid(), "password", UserRecord.md5IfNeed(pass));
|
|
||||||
return RetResult.success();
|
|
||||||
}
|
|
||||||
|
|
||||||
@RestMapping(name = "register", auth = false, comment = "用户注册")
|
|
||||||
public RetResult register(UserRecord bean) {
|
|
||||||
/*用户名、密码、邮箱*/
|
|
||||||
if (bean.getEmail() == null) return RetCodes.retResult(RET_USER_EMAIL_ILLEGAL, "邮件地址无效");
|
|
||||||
if (bean.getPassword() == null || bean.getPassword().length() < 6)
|
|
||||||
return RetCodes.retResult(RET_USER_PASSWORD_ILLEGAL, "密码设置无效");
|
|
||||||
|
|
||||||
UserRecord _user = source.find(UserRecord.class, FilterNode.create("email", bean.getEmail()));
|
|
||||||
if (_user != null) return RetCodes.retResult(RET_USER_USERNAME_EXISTS, "用户名已存在");
|
|
||||||
|
|
||||||
bean.setCreatetime(System.currentTimeMillis());
|
|
||||||
bean.setPassword(bean.passwordForMd5());
|
|
||||||
bean.setStatus((short) 10);
|
|
||||||
bean.setUsername(bean.getEmail());
|
|
||||||
bean.setAvatar("/res/images/avatar/" + new Random().nextInt(21) + ".jpg");//默认头像
|
|
||||||
|
|
||||||
int maxId = source.getNumberResult(UserRecord.class, FilterFunc.MAX, 10_0000, "userid").intValue();
|
|
||||||
if (maxId < 10_0000) maxId = 10_0000;
|
|
||||||
bean.setUserid(maxId + 1);
|
|
||||||
source.insert(bean);
|
|
||||||
|
|
||||||
//记录日志
|
|
||||||
return RetResult.success();
|
|
||||||
}
|
|
||||||
|
|
||||||
@RestMapping(name = "update", comment = "用户信息修改")
|
|
||||||
public RetResult userUpdate(UserInfo user, UserRecord bean, String[] columns) {
|
|
||||||
String nickname = bean.getNickname();
|
|
||||||
if (nickname == null && nickname.isEmpty())
|
|
||||||
return RetCodes.retResult(RET_USER_NICKNAME_ILLEGAL, "昵称无效");
|
|
||||||
|
|
||||||
nickname = nickname.replace(" ", "");
|
|
||||||
UserRecord _user = source.find(UserRecord.class, FilterNode.create("nickname", nickname));
|
|
||||||
if (_user != null && _user.getUserid() != user.getUserid())
|
|
||||||
return RetCodes.retResult(RET_USER_NICKNAME_EXISTS, "昵称已存在");
|
|
||||||
|
|
||||||
bean.setNickname(nickname);//去除昵称中的空格
|
|
||||||
source.updateColumn(bean
|
|
||||||
, FilterNode.create("userid", user.getUserid())
|
|
||||||
, SelectColumn.includes(columns)
|
|
||||||
);
|
|
||||||
return RetResult.success();
|
|
||||||
}
|
|
||||||
|
|
||||||
//最新加入
|
|
||||||
public Sheet<UserInfo> lastReg() {
|
|
||||||
Sheet<UserRecord> users = source.querySheet(UserRecord.class
|
|
||||||
, SelectColumn.includes("userid", "nickname", "avatar", "createtime")
|
|
||||||
, new Flipper().sort("createtime DESC").limit(8)
|
|
||||||
, FilterNode.create("status", 10));
|
|
||||||
|
|
||||||
Sheet<UserInfo> infos = new Sheet<>();
|
|
||||||
ArrayList<UserInfo> list = new ArrayList<>();
|
|
||||||
|
|
||||||
users.forEach(x -> {
|
|
||||||
UserInfo info = x.createUserInfo();
|
|
||||||
info.setTime(LxyKit.dateFmt(x.getCreatetime()));
|
|
||||||
list.add(info);
|
|
||||||
});
|
|
||||||
|
|
||||||
infos.setRows(list);
|
|
||||||
infos.setTotal(users.getTotal());
|
|
||||||
|
|
||||||
return infos;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RestMapping(name = "usercount", auth = false, comment = "用户数据统计")
|
|
||||||
public Number userCount() {
|
|
||||||
return source.getNumberResult(UserRecord.class, FilterFunc.COUNT, "userid", FilterNode.create("status", FilterExpress.NOTEQUAL, -10));
|
|
||||||
}
|
|
||||||
|
|
||||||
@RestMapping(ignore = true, comment = "判断用户是否是管理员")
|
|
||||||
public boolean isAdmin(int userid) {
|
|
||||||
if (userid <= 0) return false;
|
|
||||||
|
|
||||||
List<Integer> userIds = source.queryColumnList("userid", UserRecord.class, FilterNode.create("roleid", 1));
|
|
||||||
for (Integer x : userIds) {
|
|
||||||
if (userid == x) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
package net.tccn.bbs.base.kit;
|
package net.tccn.bbs.base.util;
|
||||||
|
|
||||||
import org.redkale.net.http.RestService;
|
import org.redkale.net.http.RestService;
|
||||||
|
|
352
src/net/tccn/bbs/base/util/Kv.java
Normal file
352
src/net/tccn/bbs/base/util/Kv.java
Normal file
@ -0,0 +1,352 @@
|
|||||||
|
package net.tccn.bbs.base.util;
|
||||||
|
|
||||||
|
import net.tccn.bbs.base.Utils;
|
||||||
|
import org.redkale.convert.json.JsonConvert;
|
||||||
|
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2018/3/12 14:17.
|
||||||
|
*/
|
||||||
|
public class Kv<K, V> extends LinkedHashMap<K, V> {
|
||||||
|
|
||||||
|
protected static final JsonConvert convert = JsonConvert.root();
|
||||||
|
|
||||||
|
public static Kv of() {
|
||||||
|
return new Kv();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Kv of(Object k, Object v) {
|
||||||
|
return new Kv().set(k, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Kv filter(Map<String, String> map, String... fields) {
|
||||||
|
Kv kv = Kv.of();
|
||||||
|
if (fields == null || fields.length == 0 || map == null) {
|
||||||
|
return kv;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String field : fields) {
|
||||||
|
if (field.contains("->")) {
|
||||||
|
String[] arr = field.split("->");
|
||||||
|
kv.put(arr[1], map.get(arr[0]));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
kv.put(field, map.get(field));
|
||||||
|
}
|
||||||
|
return kv;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Kv<K, V> set(K k, V v) {
|
||||||
|
put(k, v);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Kv<K, V> putAll(Kv<K, V> kv) {
|
||||||
|
kv.forEach((k, v) -> put(k, v));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将obj 属性映射到Kv 中
|
||||||
|
public static Kv toKv(Object m, String... fields) {
|
||||||
|
Kv kv = Kv.of();
|
||||||
|
if (m == null) {
|
||||||
|
return kv;
|
||||||
|
}
|
||||||
|
Stream.of(fields).forEach(field -> {
|
||||||
|
String filedT = field;
|
||||||
|
String filedS = field;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (field.contains("=")) {
|
||||||
|
String[] arr = field.split("=");
|
||||||
|
filedT = arr[0];
|
||||||
|
filedS = arr[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
Method method = m.getClass().getMethod("get" + toUpperCaseFirst(filedS));
|
||||||
|
if (method != null) {
|
||||||
|
kv.set(filedT, method.invoke(m));
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
||||||
|
new IllegalArgumentException(String.format("Kv.toKv获取 获取参数[]失败", field), e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return kv;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> List<Kv> toKv(Collection<T> datas, String... fields) {
|
||||||
|
return datas.stream().map(x -> toKv(x, fields)).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Kv toKv(Object m) {
|
||||||
|
return toKv(m, Kv.of(), m.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Kv toKv(Object m, Kv kv, Class clazz) {
|
||||||
|
Method[] methods = clazz.getMethods();
|
||||||
|
for (Method method : methods) {
|
||||||
|
if (!method.getName().startsWith("get") || method.getParameterCount() > 0 || "getClass".equals(method.getName()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
String k = toLowerCaseFirst(method.getName().replaceFirst("get", ""));
|
||||||
|
if (!kv.containsKey(k) || Utils.isEmpty(kv.get(k))) {
|
||||||
|
try {
|
||||||
|
kv.set(k, method.invoke(m));
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Field field : clazz.getDeclaredFields()) {
|
||||||
|
if (field.getAnnotation(Id.class) != null) {
|
||||||
|
try {
|
||||||
|
field.setAccessible(true);
|
||||||
|
kv.set("_id", field.get(m));
|
||||||
|
break;
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Class superclass = clazz.getSuperclass();
|
||||||
|
if (superclass != null) {
|
||||||
|
kv = toKv(m, kv, superclass);
|
||||||
|
}
|
||||||
|
return kv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将字符串第一个字母转大写
|
||||||
|
*
|
||||||
|
* @param str 待转换字符串
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static String toUpperCaseFirst(String str) {
|
||||||
|
Objects.requireNonNull(str);
|
||||||
|
return str.substring(0, 1).toUpperCase() + str.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将字符串第一个字母转小写
|
||||||
|
*
|
||||||
|
* @param str 待转换字符串
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static String toLowerCaseFirst(String str) {
|
||||||
|
Objects.requireNonNull(str);
|
||||||
|
return str.substring(0, 1).toLowerCase() + str.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T toBean(Class<T> type) {
|
||||||
|
return toBean(this, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 首字母大写
|
||||||
|
private static Function<String, String> upFirst = (s) -> {
|
||||||
|
return s.substring(0, 1).toUpperCase() + s.substring(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
private static Predicate<Class> isNumber = (t) -> {
|
||||||
|
return t == Integer.class || t == int.class
|
||||||
|
|| t == Long.class || t == long.class
|
||||||
|
|| t == Float.class || t == float.class
|
||||||
|
|| t == Double.class || t == double.class
|
||||||
|
|| t == Short.class || t == short.class
|
||||||
|
|| t == Byte.class || t == byte.class
|
||||||
|
;
|
||||||
|
};
|
||||||
|
|
||||||
|
public static <T> T toAs(Object v, Class<T> clazz) {
|
||||||
|
if (v == null) {
|
||||||
|
return null;
|
||||||
|
} else if (v.getClass() == clazz) {
|
||||||
|
return (T) v;
|
||||||
|
} else if (clazz == String.class) {
|
||||||
|
return (T) String.valueOf(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object v1 = v;
|
||||||
|
try {
|
||||||
|
|
||||||
|
if (v.getClass() == Long.class) {//多种数值类型的处理: Long => x
|
||||||
|
switch (clazz.getSimpleName()) {
|
||||||
|
case "int", "Integer" -> v1 = (int) (long) v;
|
||||||
|
case "short", "Short" -> v1 = (short) (long) v;
|
||||||
|
case "float", "Float" -> v1 = (float) (long) v;
|
||||||
|
case "byte", "Byte" -> v1 = (byte) (long) v;
|
||||||
|
}
|
||||||
|
} else if (v.getClass() == Double.class) {
|
||||||
|
if (isNumber.test(clazz)) {
|
||||||
|
switch (clazz.getSimpleName()) {
|
||||||
|
case "long", "Long" -> v1 = (long) (double) v;
|
||||||
|
case "int", "Integer" -> v1 = (int) (double) v;
|
||||||
|
case "short", "Short" -> v1 = (short) (double) v;
|
||||||
|
case "float", "Float" -> v1 = (float) (double) v;
|
||||||
|
case "byte", "Byte" -> v1 = (byte) (double) v;
|
||||||
|
}
|
||||||
|
} else if (clazz == String.class) {
|
||||||
|
v1 = String.valueOf(v);
|
||||||
|
}
|
||||||
|
} else if (v.getClass() == String.class) {
|
||||||
|
switch (clazz.getSimpleName()) {
|
||||||
|
case "Date" -> v1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse((String) v);
|
||||||
|
case "short", "Short" -> v1 = (short) Double.parseDouble((String) v);
|
||||||
|
case "float", "Float" -> v1 = (float) Double.parseDouble((String) v);
|
||||||
|
case "int", "Integer" -> v1 = (int) Double.parseDouble((String) v);
|
||||||
|
case "long", "Long" -> v1 = (long) Double.parseDouble((String) v);
|
||||||
|
case "double", "Double" -> v1 = Double.parseDouble((String) v);
|
||||||
|
case "byte", "Byte" -> v1 = Byte.parseByte((String) v);
|
||||||
|
}
|
||||||
|
} else if (v.getClass() == Integer.class) {
|
||||||
|
switch (clazz.getSimpleName()) {
|
||||||
|
case "long", "Long" -> v1 = (long) (int) v;
|
||||||
|
case "short", "Short" -> v1 = (short) (int) v;
|
||||||
|
case "float", "Float" -> v1 = (float) (int) v;
|
||||||
|
case "byte", "Byte" -> v1 = (byte) (int) v;
|
||||||
|
}
|
||||||
|
} else if (v.getClass() == Float.class) {
|
||||||
|
switch (clazz.getSimpleName()) {
|
||||||
|
case "long", "Long" -> v1 = (long) (float) v;
|
||||||
|
case "int", "Integer" -> v1 = (int) (float) v;
|
||||||
|
case "short", "Short" -> v1 = (short) (float) v;
|
||||||
|
case "byte", "Byte" -> v1 = (byte) (float) v;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
v1 = v;
|
||||||
|
}
|
||||||
|
} catch (ParseException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return (T) v1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T toBean(Map map, Class<T> clazz) {
|
||||||
|
//按照方法名 + 类型寻找,
|
||||||
|
//按照方法名 寻找
|
||||||
|
//+
|
||||||
|
Object obj = null;
|
||||||
|
try {
|
||||||
|
obj = clazz.getDeclaredConstructor().newInstance();
|
||||||
|
} catch (InstantiationException | IllegalAccessException | InvocationTargetException |
|
||||||
|
NoSuchMethodException e) {
|
||||||
|
new IllegalArgumentException("创建对象实列失败", e); // 检查clazz是否有无参构造
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String k : (Set<String>) map.keySet()) {
|
||||||
|
Object v = map.get(k);
|
||||||
|
if (v == null) continue;
|
||||||
|
//寻找method
|
||||||
|
try {
|
||||||
|
String methodName = "set" + upFirst.apply(k);
|
||||||
|
Class tClazz = null;
|
||||||
|
Method method = null;
|
||||||
|
try {
|
||||||
|
method = clazz.getMethod(methodName, tClazz = v.getClass());
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
//e.printStackTrace();
|
||||||
|
}
|
||||||
|
if (method == null) {
|
||||||
|
for (Method _method : clazz.getMethods()) {
|
||||||
|
if (methodName.equals(_method.getName()) && _method.getParameterCount() == 1) {
|
||||||
|
method = _method;
|
||||||
|
tClazz = _method.getParameterTypes()[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method == null) {
|
||||||
|
for (Method _method : clazz.getMethods()) {
|
||||||
|
if (methodName.equalsIgnoreCase(_method.getName()) && _method.getParameterCount() == 1) {
|
||||||
|
method = _method;
|
||||||
|
tClazz = _method.getParameterTypes()[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method != null) {
|
||||||
|
method.invoke(obj, toAs(v, tClazz));
|
||||||
|
}
|
||||||
|
|
||||||
|
//没有方法,找属性注解
|
||||||
|
/*if (method == null) {
|
||||||
|
Field field = null;
|
||||||
|
Field[] fields = clazz.getDeclaredFields();
|
||||||
|
for (Field _field : fields) {
|
||||||
|
To to = _field.getAnnotation(To.class);
|
||||||
|
if (to != null && k.equals(to.value())) {
|
||||||
|
field = _field;
|
||||||
|
tClazz = _field.getType();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (field != null) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(obj, toAs(v, tClazz));
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (T) obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return convert.convertTo(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInt(String key) {
|
||||||
|
return toAs(get(key), int.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInt(String key, int defaultValue) {
|
||||||
|
V v = get(key);
|
||||||
|
if (v == null) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
return toAs(v, int.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLong(String key) {
|
||||||
|
return toAs(get(key), Long.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLong(String key, long defaultValue) {
|
||||||
|
V v = get(key);
|
||||||
|
if (v == null) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
return toAs(v, long.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStr(String key) {
|
||||||
|
return toAs(get(key), String.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStr(String key, String defaultValue) {
|
||||||
|
V v = get(key);
|
||||||
|
if (v == null) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
return toAs(v, String.class);
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package net.tccn.bbs.base.kit;
|
package net.tccn.bbs.base.util;
|
||||||
|
|
||||||
import org.redkale.service.RetLabel;
|
import org.redkale.service.RetLabel;
|
||||||
import org.redkale.service.RetResult;
|
import org.redkale.service.RetResult;
|
@ -1,26 +1,19 @@
|
|||||||
package net.tccn.bbs.base;
|
package net.tccn.bbs.base.util;
|
||||||
|
|
||||||
import net.tccn.bbs.base.entity.Count;
|
import net.tccn.bbs.base.BaseService;
|
||||||
import net.tccn.bbs.base.entity.VisLog;
|
|
||||||
import net.tccn.bbs.base.user.UserInfo;
|
|
||||||
import net.tccn.bbs.base.user.UserService;
|
|
||||||
import net.tccn.bbs.content.Content;
|
|
||||||
import net.tccn.bbs.content.ContentInfo;
|
import net.tccn.bbs.content.ContentInfo;
|
||||||
import net.tccn.bbs.content.ContentService;
|
import net.tccn.bbs.content.ContentService;
|
||||||
|
import net.tccn.bbs.user.UserService;
|
||||||
|
import net.tccn.bbs.vislog.entity.VisLog;
|
||||||
import org.redkale.net.http.RestMapping;
|
import org.redkale.net.http.RestMapping;
|
||||||
import org.redkale.net.http.RestService;
|
import org.redkale.net.http.RestService;
|
||||||
import org.redkale.source.ColumnValue;
|
|
||||||
import org.redkale.source.FilterExpress;
|
|
||||||
import org.redkale.source.FilterNode;
|
|
||||||
import org.redkale.source.Flipper;
|
import org.redkale.source.Flipper;
|
||||||
import org.redkale.util.Comment;
|
import org.redkale.util.AnyValue;
|
||||||
import org.redkale.util.Sheet;
|
import org.redkale.util.Sheet;
|
||||||
import org.redkale.util.Utility;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.*;
|
import java.util.Map;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by liangxianyou at 2018/6/20 22:54.
|
* Created by liangxianyou at 2018/6/20 22:54.
|
||||||
@ -35,6 +28,25 @@ public class TaskQueue<T extends Object> extends BaseService implements Runnable
|
|||||||
|
|
||||||
protected static LinkedBlockingQueue queue = new LinkedBlockingQueue();
|
protected static LinkedBlockingQueue queue = new LinkedBlockingQueue();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(AnyValue config) {
|
||||||
|
|
||||||
|
// 独立线程,用户访问行为记录到数据库
|
||||||
|
new Thread(() -> {
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
T task = take();
|
||||||
|
//记录访问日志,如果是访问的文章详情:对文章访问数量更新
|
||||||
|
if (task instanceof VisLog) {
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
public TaskQueue() {
|
public TaskQueue() {
|
||||||
new Thread(this).start();
|
new Thread(this).start();
|
||||||
}
|
}
|
||||||
@ -50,32 +62,12 @@ 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 {
|
|
||||||
T task = take();
|
|
||||||
|
|
||||||
//记录访问日志,如果是访问的文章详情:对文章访问数量更新
|
|
||||||
if (task instanceof VisLog) {
|
|
||||||
//System.out.println(task);
|
|
||||||
ArangoService.save(task).thenAcceptAsync((_task) -> {
|
|
||||||
VisLog visLog = (VisLog) _task;
|
|
||||||
//[访问量]
|
|
||||||
String uri = visLog.getUri();
|
|
||||||
if (uri != null && uri.startsWith("/jie/detail/")) {
|
|
||||||
updateViewNum(visLog);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
} while (true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Comment("帖子阅读数处理")
|
/*@Comment("帖子阅读数处理")
|
||||||
private void updateViewNum(VisLog visLog) {
|
private void updateViewNum(VisLog visLog) {
|
||||||
|
|
||||||
String aql = String.format("for d in vis_log_dev\n" +
|
String aql = String.format("for d in vis_log_dev\n" +
|
||||||
@ -90,11 +82,11 @@ public class TaskQueue<T extends Object> extends BaseService implements Runnable
|
|||||||
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 = cacheSource.get(cacheKey);
|
||||||
if (isEmpty.test(ids)) {
|
if (isEmpty.test(ids)) {
|
||||||
@ -141,7 +133,9 @@ public class TaskQueue<T extends Object> extends BaseService implements Runnable
|
|||||||
} else if (!userService.isAdmin(userInfo.getUserid())) { //非管理员
|
} else if (!userService.isAdmin(userInfo.getUserid())) { //非管理员
|
||||||
node.and(FilterNode.create("status", FilterExpress.NOTEQUAL, 30).or(FilterNode.create("status", 30).and("userid", userInfo.getUserid())));
|
node.and(FilterNode.create("status", FilterExpress.NOTEQUAL, 30).or(FilterNode.create("status", 30).and("userid", userInfo.getUserid())));
|
||||||
}
|
}
|
||||||
return contentService.contentQuery(flipper, node);
|
return contentService.contentQuery(flipper, node);*/
|
||||||
|
|
||||||
|
return Sheet.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -166,10 +160,10 @@ public class TaskQueue<T extends Object> extends BaseService implements Runnable
|
|||||||
});
|
});
|
||||||
|
|
||||||
int[] userids = LxyKit.listToArray(uids, new int[uids.size()]);
|
int[] userids = LxyKit.listToArray(uids, new int[uids.size()]);
|
||||||
List<UserRecord> records = source.queryList(UserRecord.class, FilterNode.create("userid", FilterExpress.IN, userids));
|
List<UserDetail> records = source.queryList(UserDetail.class, FilterNode.create("userid", FilterExpress.IN, userids));
|
||||||
|
|
||||||
rows.forEach(x->{
|
rows.forEach(x->{
|
||||||
UserRecord record = records.stream().filter(y -> (Integer) x.get("userid") == y.getUserid()).findFirst().orElse(new UserRecord());
|
UserDetail record = records.stream().filter(y -> (Integer) x.get("userid") == y.getUserid()).findFirst().orElse(new UserDetail());
|
||||||
x.put("nickname", record.getRealname());
|
x.put("nickname", record.getRealname());
|
||||||
x.put("avatar", record.getAvatar());
|
x.put("avatar", record.getAvatar());
|
||||||
});
|
});
|
@ -1,71 +0,0 @@
|
|||||||
package net.tccn.bbs.comment;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import net.tccn.bbs.base.iface.C;
|
|
||||||
import net.tccn.bbs.base.kit.LxyKit;
|
|
||||||
import org.redkale.convert.json.JsonConvert;
|
|
||||||
|
|
||||||
import javax.persistence.Cacheable;
|
|
||||||
import javax.persistence.Column;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.Table;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author lxyer
|
|
||||||
*/
|
|
||||||
@Setter
|
|
||||||
@Getter
|
|
||||||
@Cacheable(interval = 5 * 60)
|
|
||||||
@Table(catalog = "redbbs", name = "sys_comment", comment = "[评论表]")
|
|
||||||
public class Comment implements Serializable, C<CommentInfo> {
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@Column(comment = "[评论id]")
|
|
||||||
private int commentid;
|
|
||||||
|
|
||||||
@Column(comment = "[评论用户id]")
|
|
||||||
private int userid;
|
|
||||||
|
|
||||||
@Column(comment = "[评论父id]")
|
|
||||||
private int pid;
|
|
||||||
|
|
||||||
@Column(comment = "[评论的类型]")
|
|
||||||
private short cate = 1;
|
|
||||||
|
|
||||||
@Column(comment = "[被评论内容的id]")
|
|
||||||
private int contentid;
|
|
||||||
|
|
||||||
@Column(comment = "[评论内容]")
|
|
||||||
private String content = "";
|
|
||||||
|
|
||||||
@Column(updatable = false, comment = "[创建时间]")
|
|
||||||
private long createtime;
|
|
||||||
|
|
||||||
@Column(comment = "[支持数]")
|
|
||||||
private int supportnum;
|
|
||||||
|
|
||||||
@Column(comment = "[状态]1正常,-1删除")
|
|
||||||
private short status = 10;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return JsonConvert.root().convertTo(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CommentInfo createInfo() {
|
|
||||||
CommentInfo info = new CommentInfo();
|
|
||||||
info.setCommentid(commentid);
|
|
||||||
info.setUserid(userid);
|
|
||||||
info.setPid(pid);
|
|
||||||
info.setCate(cate);
|
|
||||||
info.setContentid(contentid);
|
|
||||||
info.setContent(content);
|
|
||||||
info.setSupportnum(supportnum);
|
|
||||||
info.setStatus(status);
|
|
||||||
|
|
||||||
info.setCreatetime(LxyKit.dateFmt(createtime));
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,21 +2,21 @@ package net.tccn.bbs.comment;
|
|||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.tccn.bbs.base.iface.CI;
|
import net.tccn.bbs.base.BaseEntity;
|
||||||
import net.tccn.bbs.base.iface.UI;
|
import net.tccn.bbs.user.UserInfo;
|
||||||
import net.tccn.bbs.base.user.UserRecord;
|
|
||||||
import org.redkale.convert.json.JsonConvert;
|
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.*;
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author lxyer
|
* @author lxyer
|
||||||
*/
|
*/
|
||||||
@Setter
|
@Setter
|
||||||
@Getter
|
@Getter
|
||||||
public class CommentInfo implements UI<CommentInfo>, Serializable, CI<CommentInfo> {
|
@Cacheable(interval = 5 * 60)
|
||||||
|
@Table(catalog = "redbbs", name = "commentinfo", comment = "[评论表]")
|
||||||
|
public class CommentInfo extends BaseEntity {
|
||||||
|
|
||||||
|
@Id
|
||||||
@Column(comment = "[评论id]")
|
@Column(comment = "[评论id]")
|
||||||
private int commentid;
|
private int commentid;
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ public class CommentInfo implements UI<CommentInfo>, Serializable, CI<CommentInf
|
|||||||
private int pid;
|
private int pid;
|
||||||
|
|
||||||
@Column(comment = "[评论的类型]")
|
@Column(comment = "[评论的类型]")
|
||||||
private int cate;
|
private short cate = 1;
|
||||||
|
|
||||||
@Column(comment = "[被评论内容的id]")
|
@Column(comment = "[被评论内容的id]")
|
||||||
private int contentid;
|
private int contentid;
|
||||||
@ -35,36 +35,39 @@ public class CommentInfo implements UI<CommentInfo>, Serializable, CI<CommentInf
|
|||||||
@Column(comment = "[评论内容]")
|
@Column(comment = "[评论内容]")
|
||||||
private String content = "";
|
private String content = "";
|
||||||
|
|
||||||
|
@Column(updatable = false, comment = "[创建时间]")
|
||||||
|
private long createtime;
|
||||||
|
|
||||||
@Column(comment = "[支持数]")
|
@Column(comment = "[支持数]")
|
||||||
private int supportnum;
|
private int supportnum;
|
||||||
|
|
||||||
@Column(comment = "[状态]1正常,-1删除")
|
@Column(comment = "[状态]1正常,-1删除")
|
||||||
private int status = 1;
|
private short status = 10;
|
||||||
|
|
||||||
|
/*@Transient
|
||||||
|
private CommentBean pCommentInfo;*/
|
||||||
|
|
||||||
private String createtime;
|
@Transient
|
||||||
|
|
||||||
private CommentInfo pCommentInfo;
|
|
||||||
|
|
||||||
private String title;
|
private String title;
|
||||||
|
@Transient
|
||||||
private int hadsupport = -1;
|
private int hadsupport = -1;
|
||||||
|
|
||||||
@Override
|
@Transient
|
||||||
public String toString() {
|
private UserInfo user;
|
||||||
return JsonConvert.root().convertTo(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
//----
|
|
||||||
private UserRecord user;
|
|
||||||
|
|
||||||
@Override
|
/*public CommentBean createInfo() {
|
||||||
public UserRecord getUser() {
|
CommentBean info = new CommentBean();
|
||||||
return user;
|
info.setCommentid(commentid);
|
||||||
}
|
info.setUserid(userid);
|
||||||
|
info.setPid(pid);
|
||||||
|
info.setCate(cate);
|
||||||
|
info.setContentid(contentid);
|
||||||
|
info.setContent(content);
|
||||||
|
info.setSupportnum(supportnum);
|
||||||
|
info.setStatus(status);
|
||||||
|
|
||||||
@Override
|
info.setCreatetime(Utils.dateFmt(createtime));
|
||||||
public CommentInfo setUser(UserRecord user) {
|
return info;
|
||||||
this.user = user;
|
}*/
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,118 +1,138 @@
|
|||||||
package net.tccn.bbs.comment;
|
package net.tccn.bbs.comment;
|
||||||
|
|
||||||
import net.tccn.bbs.base.BaseService;
|
import net.tccn.bbs.base.BaseService;
|
||||||
import net.tccn.bbs.base.entity.ActLog;
|
import net.tccn.bbs.base.Utils;
|
||||||
import net.tccn.bbs.base.iface.UIService;
|
import net.tccn.bbs.base.util.RetCodes;
|
||||||
import net.tccn.bbs.base.kit.LxyKit;
|
import net.tccn.bbs.content.ContentInfo;
|
||||||
import net.tccn.bbs.base.kit.RetCodes;
|
import net.tccn.bbs.user.UserInfo;
|
||||||
import net.tccn.bbs.content.Content;
|
import net.tccn.bbs.user.UserService;
|
||||||
|
import net.tccn.bbs.vislog.entity.ActLog;
|
||||||
import org.redkale.net.http.RestMapping;
|
import org.redkale.net.http.RestMapping;
|
||||||
import org.redkale.net.http.RestParam;
|
import org.redkale.net.http.RestParam;
|
||||||
import org.redkale.net.http.RestService;
|
import org.redkale.net.http.RestService;
|
||||||
import org.redkale.net.http.RestSessionid;
|
import org.redkale.net.http.RestUserid;
|
||||||
import org.redkale.service.RetResult;
|
import org.redkale.service.RetResult;
|
||||||
import org.redkale.source.*;
|
import org.redkale.source.*;
|
||||||
|
import org.redkale.util.Comment;
|
||||||
import org.redkale.util.SelectColumn;
|
import org.redkale.util.SelectColumn;
|
||||||
import org.redkale.util.Sheet;
|
import org.redkale.util.Sheet;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import static net.tccn.bbs.base.kit.RetCodes.RET_COMMENT_CONTENT_ILLEGAL;
|
import static net.tccn.bbs.base.util.RetCodes.RET_COMMENT_CONTENT_ILLEGAL;
|
||||||
import static net.tccn.bbs.base.kit.RetCodes.RET_COMMENT_PARA_ILLEGAL;
|
import static org.redkale.source.FilterExpress.IN;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Lxy at 2017/11/29 10:00.
|
* Created by Lxy at 2017/11/29 10:00.
|
||||||
*/
|
*/
|
||||||
@RestService(name = "comment", comment = "评论服务")
|
@RestService(name = "comment", comment = "评论服务")
|
||||||
public class CommentService extends BaseService implements UIService<CommentInfo> {
|
public class CommentService extends BaseService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private UserService userService;
|
||||||
|
|
||||||
@RestMapping(name = "save", comment = "评论保存")
|
@RestMapping(name = "save", comment = "评论保存")
|
||||||
public RetResult save(@RestSessionid String sessionid, @RestParam(name = "bean") Comment comment) {
|
public RetResult save(@RestUserid int userid, @RestParam(name = "bean") CommentInfo comment) {
|
||||||
int contentid = comment.getContentid();
|
int contentid = comment.getContentid();
|
||||||
|
|
||||||
//数据校验
|
//数据校验
|
||||||
if (contentid < 1)
|
if (contentid < 1) {
|
||||||
return RetCodes.retResult(RET_COMMENT_PARA_ILLEGAL, "评论参数无效");
|
return retError("评论参数无效");
|
||||||
if (comment.getContent() == null)
|
}
|
||||||
return RetCodes.retResult(RET_COMMENT_CONTENT_ILLEGAL, "评论内容无效");
|
if (Utils.isEmpty(comment.getContent())) {
|
||||||
String content = LxyKit.delHTMLTag(comment.getContent());
|
return retError("评论内容无效");
|
||||||
if (content.isEmpty())
|
}
|
||||||
|
String content = Utils.delHTMLTag(comment.getContent());
|
||||||
|
if (content.isEmpty()) {
|
||||||
return RetCodes.retResult(RET_COMMENT_CONTENT_ILLEGAL, "评论内容无效");
|
return RetCodes.retResult(RET_COMMENT_CONTENT_ILLEGAL, "评论内容无效");
|
||||||
|
}
|
||||||
|
|
||||||
if (comment.getCommentid() < 1) {
|
if (comment.getCommentid() < 1) {
|
||||||
int userid = currentUserid(sessionid);
|
|
||||||
comment.setUserid(userid);
|
comment.setUserid(userid);
|
||||||
comment.setCreatetime(System.currentTimeMillis());
|
comment.setCreatetime(System.currentTimeMillis());
|
||||||
//todo:@用户处理
|
//todo:@用户处理
|
||||||
source.insert(comment);
|
dataSource.insert(comment);
|
||||||
|
|
||||||
//update replyNum
|
//update replyNum
|
||||||
int count = source.getNumberResult(Comment.class, FilterFunc.COUNT, "commentid", FilterNode.create("contentid", contentid)).intValue();
|
int count = dataSource.getNumberResult(CommentInfo.class, FilterFunc.COUNT, "commentid", FilterNode.create("contentid", contentid)).intValue();
|
||||||
source.updateColumn(Content.class, contentid, ColumnValue.create("replynum", count));
|
dataSource.updateColumn(ContentInfo.class, contentid, ColumnValue.create("replynum", count));
|
||||||
} else {
|
} else {
|
||||||
source.updateColumn(comment, SelectColumn.includes("content"));
|
dataSource.updateColumn(comment, SelectColumn.includes("content"));
|
||||||
}
|
}
|
||||||
return RetResult.success();
|
return RetResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
@RestMapping(name = "query", auth = false, comment = "查询评论")
|
@RestMapping(name = "query", auth = false, comment = "查询评论")
|
||||||
public Sheet<CommentInfo> query(@RestSessionid String sessionid, int contentId, Flipper flipper) {
|
public Sheet<CommentInfo> query(@RestUserid int userid, Flipper flipper, int contentid) {
|
||||||
int userid = currentUserid(sessionid);
|
flipper.setSort("supportnum DESC, commentid ASC"); // 按照 点赞数排序,相同点赞数按照 id(时间先后排序)
|
||||||
|
Sheet<CommentInfo> comments = dataSource.querySheet(CommentInfo.class, flipper, FilterNode.create("contentid", contentid));
|
||||||
|
|
||||||
flipper.setSort("supportnum DESC,commentid ASC");
|
// 设置用户信息
|
||||||
Sheet<Comment> comments = source.querySheet(Comment.class, flipper, FilterNode.create("contentid", contentId));
|
Set<Integer> userids = Utils.toSet(comments, x -> x.getUserid());
|
||||||
|
Map<Integer, UserInfo> userMap = userService.queryUserMap(userids);
|
||||||
|
comments.forEach(x -> x.setUser(userMap.get(x.getUserid())));
|
||||||
|
|
||||||
Sheet<CommentInfo> infos = createInfo(comments);
|
// 访客访问:不需要设置用户状态信息,返回
|
||||||
setIUser(infos);
|
if (userid == 0) {
|
||||||
|
return comments;
|
||||||
//用户点赞的评论
|
|
||||||
if (userid > 0) {
|
|
||||||
int[] commentids = comments.stream().mapToInt(Comment::getCommentid).toArray();
|
|
||||||
FilterNode node = FilterNode.create("cate", 10).and("status", 10).and("userid", userid).and("tid", FilterExpress.IN, commentids);
|
|
||||||
List<Integer> hadSupport = source.queryColumnList("tid", ActLog.class, node);
|
|
||||||
|
|
||||||
infos.forEach(x -> {
|
|
||||||
x.setHadsupport(hadSupport.contains(x.getCommentid()) ? 1 : -1);//
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return infos;
|
// 当前用户为登录用户:处理用户点赞状态
|
||||||
|
List<Integer> commentids = Utils.toList(comments, x -> x.getCommentid());
|
||||||
|
FilterNode node = FilterNode.create("cate", 10).and("status", 10).and("userid", userid).and("tid", IN, (Serializable) commentids);
|
||||||
|
List<Integer> supports = dataSource.queryColumnList("tid", ActLog.class, node);
|
||||||
|
comments.forEach(x -> {
|
||||||
|
x.setHadsupport(supports.contains(x.getCommentid()) ? 1 : 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
return comments;
|
||||||
}
|
}
|
||||||
|
|
||||||
@org.redkale.util.Comment("查询用户评论数据")
|
@Comment("查询用户评论数据")
|
||||||
public Sheet<CommentInfo> queryByUserid(int userid) {
|
public Sheet<CommentInfo> queryByUserid(int userid) {
|
||||||
Sheet<Comment> comments = source.querySheet(Comment.class, new Flipper().sort("createtime DESC"), FilterNode.create("userid", userid));
|
Sheet<CommentInfo> comments = dataSource.querySheet(CommentInfo.class, new Flipper("createtime DESC"), FilterNode.create("userid", userid));
|
||||||
|
|
||||||
int[] contentIds = comments.stream().mapToInt(x -> x.getCommentid()).toArray();
|
Set<Integer> contentids = Utils.toSet(comments, x -> x.getContentid());
|
||||||
List<Content> contents = source.queryList(Content.class, SelectColumn.includes("contentid", "title"), FilterNode.create("contentid", FilterExpress.IN, contentIds));
|
|
||||||
|
List<ContentInfo> contents = dataSource.queryList(ContentInfo.class, SelectColumn.includes("contentid", "title"), FilterNode.create("contentid", IN, (Serializable) contentids));
|
||||||
|
Map<Integer, ContentInfo> contentMap = Utils.toMap(contents, x -> x.getContentid());
|
||||||
|
|
||||||
|
// 设置用户信息
|
||||||
|
Set<Integer> userids = Utils.toSet(comments, x -> x.getUserid());
|
||||||
|
Map<Integer, UserInfo> userMap = userService.queryUserMap(userids);
|
||||||
|
comments.forEach(x -> x.setUser(userMap.get(x.getUserid())));
|
||||||
|
|
||||||
|
comments.forEach(x -> {
|
||||||
|
ContentInfo content = contentMap.get(x.getContentid());
|
||||||
|
if (content == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Sheet<CommentInfo> infos = createInfo(comments);
|
|
||||||
infos.forEach(x -> {
|
|
||||||
Content content = contents.stream().filter(k -> k.getContentid() == x.getContentid()).findFirst().orElse(new Content());
|
|
||||||
x.setTitle(content.getTitle());
|
x.setTitle(content.getTitle());
|
||||||
});
|
});
|
||||||
return infos;
|
return comments;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RestMapping(name = "support", comment = "点赞")
|
@RestMapping(name = "support", comment = "点赞")
|
||||||
public RetResult support(@RestSessionid String sessionid, int commentid, int ok) {
|
public RetResult support(@RestUserid int userid, int commentid, int ok) {
|
||||||
int userid = currentUserid(sessionid);
|
dataSource.findAsync(ActLog.class, FilterNode.create("userid", userid).and("tid", commentid).and("cate", 10)).thenAccept(actLog -> {
|
||||||
|
|
||||||
source.findAsync(ActLog.class, FilterNode.create("userid", userid).and("tid", commentid).and("cate", 10)).thenAccept(actLog -> {
|
|
||||||
if (actLog == null && ok == 1) {
|
if (actLog == null && ok == 1) {
|
||||||
actLog = new ActLog(10, commentid, userid);
|
actLog = new ActLog(10, commentid, userid);
|
||||||
actLog.setCreatetime(System.currentTimeMillis());
|
actLog.setCreatetime(System.currentTimeMillis());
|
||||||
source.insert(actLog);
|
dataSource.insert(actLog);
|
||||||
} else if (actLog != null && actLog.getStatus() != ok) {
|
} else if (actLog != null && actLog.getStatus() != ok) {
|
||||||
actLog.setStatus((short) -10);
|
actLog.setStatus((short) -10);
|
||||||
source.update(actLog);
|
dataSource.update(actLog);
|
||||||
}/*else {
|
}/*else {
|
||||||
return RetCodes.retResult(-1, ok == 1 ? "已赞" : "已取消赞");
|
return RetCodes.retResult(-1, ok == 1 ? "已赞" : "已取消赞");
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
int count = source.getNumberResult(ActLog.class, FilterFunc.COUNT, 0, "logid", FilterNode.create("tid", commentid).and("status", 10)).intValue();
|
int count = dataSource.getNumberResult(ActLog.class, FilterFunc.COUNT, 0, "logid", FilterNode.create("tid", commentid).and("status", 10)).intValue();
|
||||||
source.updateColumn(Comment.class, commentid, "supportnum", count);
|
dataSource.updateColumn(CommentInfo.class, commentid, "supportnum", count);
|
||||||
});
|
});
|
||||||
|
|
||||||
return RetResult.success();
|
return RetResult.success();
|
||||||
@ -123,12 +143,11 @@ public class CommentService extends BaseService implements UIService<CommentInfo
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@org.redkale.util.Comment("用户评论榜")
|
@Comment("用户评论榜")
|
||||||
public Map<String, Number> commentRank() {
|
public Map<String, Number> commentRank() {
|
||||||
Flipper flipper = new Flipper().limit(8);
|
dataSource.querySheet(CommentInfo.class, new Flipper(8), FilterNode.create("userid", IN));
|
||||||
source.querySheet(Comment.class, flipper, FilterNode.create("userid", FilterExpress.IN));
|
|
||||||
|
|
||||||
Map<String, Number> numberMap = source.getNumberMap(Comment.class, FilterFuncColumn.create(FilterFunc.DISTINCTCOUNT, "userid"));
|
Map<String, Number> numberMap = dataSource.getNumberMap(CommentInfo.class, FilterFuncColumn.create(FilterFunc.DISTINCTCOUNT, "userid"));
|
||||||
|
|
||||||
return numberMap;
|
return numberMap;
|
||||||
}
|
}
|
||||||
|
@ -1,95 +0,0 @@
|
|||||||
package net.tccn.bbs.content;
|
|
||||||
|
|
||||||
import com.jfinal.kit.Kv;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import net.tccn.bbs.base.iface.C;
|
|
||||||
import net.tccn.bbs.base.kit.LxyKit;
|
|
||||||
import org.redkale.convert.json.JsonConvert;
|
|
||||||
|
|
||||||
import javax.persistence.Cacheable;
|
|
||||||
import javax.persistence.Column;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.Table;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author lxyer
|
|
||||||
*/
|
|
||||||
@Setter
|
|
||||||
@Getter
|
|
||||||
@Cacheable(interval = 5 * 60)
|
|
||||||
@Table(catalog = "redbbs", name = "sys_content", comment = "[内容表]")
|
|
||||||
public class Content implements Serializable, C<ContentInfo> {
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@Column(comment = "[内容id]")
|
|
||||||
private int contentid;
|
|
||||||
|
|
||||||
@Column(comment = "[用户id]")
|
|
||||||
private int userid;
|
|
||||||
|
|
||||||
@Column(length = 64, comment = "[标题]")
|
|
||||||
private String title = "";
|
|
||||||
|
|
||||||
@Column(length = 256, comment = "[摘要]")
|
|
||||||
private String digest = "";
|
|
||||||
|
|
||||||
@Column(comment = "[内容]")
|
|
||||||
private String content = "";
|
|
||||||
|
|
||||||
@Column(updatable = false, comment = "[创建时间]")
|
|
||||||
private long createtime;
|
|
||||||
|
|
||||||
@Column(comment = "[类别]")
|
|
||||||
private short cate;
|
|
||||||
|
|
||||||
@Column(comment = "[内容栏目]10求助,20分享,30建议,40公告,50动态")
|
|
||||||
private short type;
|
|
||||||
|
|
||||||
@Column(comment = "[评论数]")
|
|
||||||
private int replynum;
|
|
||||||
|
|
||||||
@Column(comment = "[阅读量]")
|
|
||||||
private int viewnum;
|
|
||||||
|
|
||||||
@Column(comment = "[精] 10否,20是")
|
|
||||||
private short wonderful = 10;
|
|
||||||
|
|
||||||
@Column(comment = "[置顶]10否,20是")
|
|
||||||
private short top = 10;
|
|
||||||
|
|
||||||
@Column(comment = "[结帖]10否,20是")
|
|
||||||
private short solved = 10;
|
|
||||||
|
|
||||||
@Column(comment = "[状态] -10删除 10未结帖 20结帖 30私密")
|
|
||||||
private short status = 10;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return JsonConvert.root().convertTo(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Kv types = Kv.by(10, "求助").set(20, "分享").set(30, "讨论").set(40, "公告").set(50, "动态");
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ContentInfo createInfo() {
|
|
||||||
ContentInfo info = new ContentInfo();
|
|
||||||
info.setContentid(contentid);
|
|
||||||
info.setUserid(userid);
|
|
||||||
info.setTitle(title);
|
|
||||||
info.setContent(content);
|
|
||||||
info.setCate(cate);
|
|
||||||
info.setType(type);
|
|
||||||
info.setViewnum(viewnum);
|
|
||||||
info.setReplynum(replynum);
|
|
||||||
info.setWonderful(wonderful);
|
|
||||||
info.setTop(top);
|
|
||||||
info.setSolved(solved);
|
|
||||||
info.setStatus(status);
|
|
||||||
|
|
||||||
info.setTypename(types.getOrDefault((int) type, "其他").toString());
|
|
||||||
info.setCreatetime(LxyKit.dateFmt(createtime));
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
package net.tccn.bbs.content;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.redkale.convert.json.JsonConvert;
|
|
||||||
import org.redkale.source.FilterBean;
|
|
||||||
|
|
||||||
import javax.persistence.Column;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.Table;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author lxyer
|
|
||||||
*/
|
|
||||||
@Setter
|
|
||||||
@Getter
|
|
||||||
@Table(catalog = "db_redbbs", name = "content", comment = "[内容表]")
|
|
||||||
public class ContentBean implements FilterBean, java.io.Serializable {
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@Column(comment = "[内容id]")
|
|
||||||
private int contentid;
|
|
||||||
|
|
||||||
@Column(comment = "[用户id]")
|
|
||||||
private int userid;
|
|
||||||
|
|
||||||
@Column(length = 64, comment = "[标题]")
|
|
||||||
private String title = "";
|
|
||||||
|
|
||||||
@Column(length = 256, comment = "[摘要]")
|
|
||||||
private String digest = "";
|
|
||||||
|
|
||||||
@Column(comment = "[内容]")
|
|
||||||
private String content = "";
|
|
||||||
|
|
||||||
@Column(comment = "[创建时间]")
|
|
||||||
private long createtime;
|
|
||||||
|
|
||||||
@Column(comment = "[类别]")
|
|
||||||
private int cate;
|
|
||||||
|
|
||||||
@Column(comment = "[内容类型]1新闻,2作品")
|
|
||||||
private int type;
|
|
||||||
|
|
||||||
@Column(comment = "[评论数]")
|
|
||||||
private int replynum;
|
|
||||||
|
|
||||||
@Column(comment = "[阅读量]")
|
|
||||||
private int viewnum;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return JsonConvert.root().convertTo(this);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,50 +1,95 @@
|
|||||||
package net.tccn.bbs.content;
|
package net.tccn.bbs.content;
|
||||||
|
|
||||||
|
import com.jfinal.kit.Kv;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.tccn.bbs.base.iface.CI;
|
import net.tccn.bbs.base.BaseEntity;
|
||||||
import net.tccn.bbs.base.iface.UI;
|
import net.tccn.bbs.user.UserInfo;
|
||||||
import net.tccn.bbs.base.user.UserRecord;
|
|
||||||
import org.redkale.convert.ConvertColumn;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
import javax.persistence.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Lxy at 2017/11/26 20:52.
|
* @author lxyer
|
||||||
*/
|
*/
|
||||||
@Setter
|
@Setter
|
||||||
@Getter
|
@Getter
|
||||||
public class ContentInfo implements UI<ContentInfo>, Serializable, CI {
|
@Cacheable(interval = 5 * 60)
|
||||||
|
@Table(catalog = "redbbs", name = "contentinfo", comment = "[内容表]")
|
||||||
|
public class ContentInfo extends BaseEntity {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@Column(comment = "[内容id]")
|
||||||
private int contentid;
|
private int contentid;
|
||||||
|
|
||||||
|
@Column(comment = "[用户id]")
|
||||||
private int userid;
|
private int userid;
|
||||||
|
|
||||||
|
@Column(length = 64, comment = "[标题]")
|
||||||
private String title = "";
|
private String title = "";
|
||||||
|
|
||||||
|
@Column(length = 256, comment = "[摘要]")
|
||||||
private String digest = "";
|
private String digest = "";
|
||||||
|
|
||||||
|
@Column(comment = "[内容]")
|
||||||
private String content = "";
|
private String content = "";
|
||||||
private String createtime;
|
|
||||||
private int cate;
|
@Column(updatable = false, comment = "[创建时间]")
|
||||||
private int type;
|
private long createtime;
|
||||||
|
|
||||||
|
@Column(comment = "[类别]")
|
||||||
|
private short cate;
|
||||||
|
|
||||||
|
@Column(comment = "[内容栏目]10求助,20分享,30建议,40公告,50动态")
|
||||||
|
private short type;
|
||||||
|
|
||||||
|
@Column(comment = "[评论数]")
|
||||||
private int replynum;
|
private int replynum;
|
||||||
|
|
||||||
|
@Column(comment = "[阅读量]")
|
||||||
private int viewnum;
|
private int viewnum;
|
||||||
private int wonderful;
|
|
||||||
private int top;
|
|
||||||
private int solved;
|
|
||||||
private int status = 10;
|
|
||||||
|
|
||||||
private String typename;
|
@Column(comment = "[精] 10否,20是")
|
||||||
private int hadcollect = -1;
|
private short wonderful = 10;
|
||||||
//-----------
|
|
||||||
private UserRecord user;
|
|
||||||
|
|
||||||
@ConvertColumn(ignore = true)
|
@Column(comment = "[置顶]10否,20是")
|
||||||
@Override
|
private short top = 10;
|
||||||
public UserRecord getUser() {
|
|
||||||
return user;
|
@Column(comment = "[结帖]10否,20是")
|
||||||
|
private short solved = 10;
|
||||||
|
|
||||||
|
@Column(comment = "[状态] -10删除 10未结帖 20结帖 30私密")
|
||||||
|
private short status = 10;
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
private int collected;
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
private UserInfo user;
|
||||||
|
|
||||||
|
public String getTypename() {
|
||||||
|
return (String) types.getOrDefault((int) type, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ContentInfo setUser(UserRecord user) {
|
private static final Kv types = Kv.by(10, "求助").set(20, "分享").set(30, "讨论").set(40, "公告").set(50, "动态");
|
||||||
this.user = user;
|
|
||||||
return this;
|
/*public ContentInfo createInfo() {
|
||||||
}
|
ContentInfo info = new ContentInfo();
|
||||||
|
info.setContentid(contentid);
|
||||||
|
info.setUserid(userid);
|
||||||
|
info.setTitle(title);
|
||||||
|
info.setContent(content);
|
||||||
|
info.setCate(cate);
|
||||||
|
info.setType(type);
|
||||||
|
info.setViewnum(viewnum);
|
||||||
|
info.setReplynum(replynum);
|
||||||
|
info.setWonderful(wonderful);
|
||||||
|
info.setTop(top);
|
||||||
|
info.setSolved(solved);
|
||||||
|
info.setStatus(status);
|
||||||
|
|
||||||
|
info.setTypename(types.getOrDefault((int) type, "其他").toString());
|
||||||
|
info.setCreatetime(Utils.dateFmt(createtime));
|
||||||
|
return info;
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
@ -2,195 +2,194 @@ package net.tccn.bbs.content;
|
|||||||
|
|
||||||
import com.jfinal.kit.Kv;
|
import com.jfinal.kit.Kv;
|
||||||
import net.tccn.bbs.base.BaseService;
|
import net.tccn.bbs.base.BaseService;
|
||||||
import net.tccn.bbs.base.entity.ActLog;
|
import net.tccn.bbs.base.Utils;
|
||||||
import net.tccn.bbs.base.iface.UIService;
|
import net.tccn.bbs.base.util.RetCodes;
|
||||||
import net.tccn.bbs.base.kit.RetCodes;
|
import net.tccn.bbs.user.UserInfo;
|
||||||
import net.tccn.bbs.base.user.UserInfo;
|
import net.tccn.bbs.user.UserService;
|
||||||
import net.tccn.bbs.base.user.UserService;
|
import net.tccn.bbs.vislog.entity.ActLog;
|
||||||
import org.redkale.net.http.HttpScope;
|
import org.redkale.net.http.HttpScope;
|
||||||
import org.redkale.net.http.RestMapping;
|
import org.redkale.net.http.RestMapping;
|
||||||
import org.redkale.net.http.RestService;
|
import org.redkale.net.http.RestService;
|
||||||
import org.redkale.net.http.RestSessionid;
|
import org.redkale.net.http.RestUserid;
|
||||||
import org.redkale.service.RetResult;
|
import org.redkale.service.RetResult;
|
||||||
import org.redkale.source.FilterExpress;
|
import org.redkale.source.*;
|
||||||
import org.redkale.source.FilterFunc;
|
|
||||||
import org.redkale.source.FilterNode;
|
|
||||||
import org.redkale.source.Flipper;
|
|
||||||
import org.redkale.util.Comment;
|
import org.redkale.util.Comment;
|
||||||
import org.redkale.util.SelectColumn;
|
import org.redkale.util.SelectColumn;
|
||||||
import org.redkale.util.Sheet;
|
import org.redkale.util.Sheet;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.redkale.source.FilterExpress.GREATERTHANOREQUALTO;
|
||||||
|
import static org.redkale.source.FilterExpress.NOTEQUAL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Lxy at 2017/11/26 9:33.
|
* Created by Lxy at 2017/11/26 9:33.
|
||||||
*/
|
*/
|
||||||
@RestService(name = "content", comment = "文章帖子服务")
|
@RestService(name = "content", comment = "文章帖子服务")
|
||||||
public class ContentService extends BaseService implements UIService<ContentInfo> {
|
public class ContentService extends BaseService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
protected UserService userService;
|
private UserService userService;
|
||||||
|
|
||||||
@Comment("根据条件查询帖子数据")
|
@Comment("根据条件查询帖子数据")
|
||||||
public Sheet<ContentInfo> contentQuery(Flipper flipper, FilterNode filterNode) {
|
public Sheet<ContentInfo> contentQuery(Flipper flipper, FilterNode node) {
|
||||||
Sheet<Content> contents = source.querySheet(Content.class, flipper, filterNode);
|
Sheet<ContentInfo> contents = dataSource.querySheet(ContentInfo.class, flipper, node);
|
||||||
|
|
||||||
createInfo(contents);
|
// 设置用户信息
|
||||||
Sheet<ContentInfo> infos = createInfo(contents);
|
Set<Integer> userids = Utils.toSet(contents, x -> x.getUserid());
|
||||||
setIUser(infos);
|
Map<Integer, UserInfo> userMap = userService.queryUserMap(userids);
|
||||||
|
contents.forEach(x -> x.setUser(userMap.get(x.getUserid())));
|
||||||
|
|
||||||
return infos;
|
return contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RestMapping(name = "query", auth = false, comment = "内容列表")
|
@RestMapping(name = "query", auth = false, comment = "内容列表")
|
||||||
public Sheet<ContentInfo> query(Flipper flipper, String actived, String sessionid) {
|
public Sheet<ContentInfo> query(@RestUserid int userid, Flipper flipper, String actived) {
|
||||||
UserInfo current = userService.current(sessionid);
|
FilterNode node = FilterNode.create("status", NOTEQUAL, -10);
|
||||||
int currentid = current == null ? 0 : current.getUserid();
|
|
||||||
|
|
||||||
FilterNode filterNode = FilterNode.create("status", FilterExpress.NOTEQUAL, -10);
|
|
||||||
switch (actived) {
|
switch (actived) {
|
||||||
case "top":
|
case "top" -> node.and("top", GREATERTHANOREQUALTO, 20);
|
||||||
filterNode.and("top", FilterExpress.GREATERTHANOREQUALTO, 20);
|
case "untop" -> node.and("top", 10);
|
||||||
break;
|
case "unsolved" -> node.and("solved", 10);
|
||||||
case "untop":
|
case "solved" -> node.and("solved", 20);
|
||||||
filterNode.and("top", 10);
|
case "wonderful" -> node.and("wonderful", GREATERTHANOREQUALTO, 20);
|
||||||
break;
|
|
||||||
case "unsolved":
|
|
||||||
filterNode.and("solved", 10);
|
|
||||||
break;
|
|
||||||
case "solved":
|
|
||||||
filterNode.and("solved", 20);
|
|
||||||
break;
|
|
||||||
case "wonderful":
|
|
||||||
filterNode.and("wonderful", FilterExpress.GREATERTHANOREQUALTO, 20);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!userService.isAdmin(currentid)) {//私密贴:非管理员限制查看
|
if (!userService.isAdmin(userid)) {//私密贴:非管理员限制查看
|
||||||
filterNode.and(FilterNode.create("status", FilterExpress.NOTEQUAL, 30).or(FilterNode.create("status", 30).and("userid", currentid)));
|
node.and(FilterNode.create("status", NOTEQUAL, 30).or(FilterNode.create("status", 30).and("userid", userid)));
|
||||||
} else if (currentid <= 0) {//私密贴:未登录限制查看
|
} else if (userid <= 0) {//私密贴:未登录限制查看
|
||||||
filterNode.and("status", FilterExpress.NOTEQUAL, 30);
|
node.and("status", NOTEQUAL, 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
return contentQuery(flipper, filterNode);
|
return contentQuery(flipper, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@RestMapping(name = "save", comment = "帖子保存")
|
@RestMapping(name = "save", comment = "帖子保存")
|
||||||
public RetResult save(UserInfo user, Content bean) {
|
public RetResult save(@RestUserid int userid, ContentInfo info) {
|
||||||
//数据校验
|
//数据校验
|
||||||
if (bean.getTitle().isEmpty() || bean.getTitle().length() > 64) {
|
if (info.getTitle().isEmpty() || info.getTitle().length() > 64) {
|
||||||
return RetCodes.retResult(-1, "少年你的文章标题太长啦,精简化标题吧,为了更好的SEO长度请少于64个字节");
|
return retError("少年你的文章标题太长啦,精简化标题吧,为了更好的SEO长度请少于64个字节");
|
||||||
}
|
}
|
||||||
|
|
||||||
int userid = user.getUserid();
|
if (info.getContentid() < 1) {
|
||||||
|
synchronized (this) {
|
||||||
if (bean.getContentid() < 1) {
|
int maxid = dataSource.getNumberResult(ContentInfo.class, FilterFunc.MAX, 10_0000, "contentid").intValue();
|
||||||
int maxId = source.getNumberResult(Content.class, FilterFunc.MAX, 10_0000, "contentid").intValue();
|
info.setContentid(maxid + 1);
|
||||||
bean.setContentid(maxId + 1);
|
}
|
||||||
bean.setCreatetime(System.currentTimeMillis());
|
info.setCreatetime(System.currentTimeMillis());
|
||||||
bean.setUserid(userid);
|
info.setUserid(userid);
|
||||||
|
dataSource.insert(info);
|
||||||
source.insert(bean);
|
|
||||||
} else {
|
} else {
|
||||||
source.findAsync(Content.class, bean.getContentid()).thenAccept(x -> {
|
dataSource.findAsync(ContentInfo.class, info.getContentid()).thenAccept(x -> {
|
||||||
if (x.getUserid() == userid || userService.isAdmin(userid)) {//身份验证 后修改内容
|
if (x.getUserid() == userid || userService.isAdmin(userid)) {//身份验证 后修改内容
|
||||||
source.updateColumnAsync(bean, SelectColumn.includes("title", "digest", "content", "type", "status"));
|
dataSource.updateColumnAsync(info, SelectColumn.includes("title", "digest", "content", "type", "status"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return RetResult.success();
|
return RET_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RestMapping(name = "info", auth = false, comment = "帖子详情")
|
@RestMapping(name = "info", auth = false, comment = "帖子详情")
|
||||||
public ContentInfo info(UserInfo user, int contentid) {
|
public ContentInfo info(@RestUserid int userid, int contentid) {
|
||||||
int userId = user != null ? user.getUserid() : 0;
|
// 异步更新帖子阅读数
|
||||||
|
dataSource.updateColumnAsync(ContentInfo.class, contentid, ColumnValue.inc("viewnum", 1));
|
||||||
|
|
||||||
Content content = source.find(Content.class, contentid);
|
ContentInfo content = dataSource.find(ContentInfo.class, contentid);
|
||||||
if (content == null) return null;
|
if (content == null) {
|
||||||
|
return null;
|
||||||
ContentInfo contentInfo = setIUser(content.createInfo());
|
|
||||||
|
|
||||||
//收藏状态
|
|
||||||
if (userId > 0) {
|
|
||||||
ActLog actLog = source.find(ActLog.class, FilterNode.create("cate", 20).and("tid", contentid).and("status", 10));
|
|
||||||
if (actLog != null) contentInfo.setHadcollect(1);
|
|
||||||
}
|
}
|
||||||
return contentInfo;
|
|
||||||
|
// 设置用户信息
|
||||||
|
UserInfo user = userService.find(content.getUserid());
|
||||||
|
content.setUser(user);
|
||||||
|
|
||||||
|
// 访客访问,直接返回
|
||||||
|
if (userid == 0) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 登录用户:设置收藏状态
|
||||||
|
FilterNode node = FilterNode.create("cate", 20).and("tid", contentid).and("status", 10);
|
||||||
|
if (dataSource.exists(ActLog.class, node)) {
|
||||||
|
content.setCollected(1);
|
||||||
|
}
|
||||||
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RestMapping(name = "collect", comment = "帖子收藏")
|
@RestMapping(name = "collect", comment = "帖子收藏")
|
||||||
public RetResult collect(@RestSessionid String sessionid, int contentid, int ok) {
|
public RetResult collect(@RestUserid int userid, int contentid, int ok) {
|
||||||
int userid = userService.currentUserid(sessionid);//不会为空
|
|
||||||
|
|
||||||
ActLog actLog = source.find(ActLog.class, FilterNode.create("userid", userid).and("tid", contentid).and("cate", 20));
|
ActLog actLog = dataSource.find(ActLog.class, FilterNode.create("userid", userid).and("tid", contentid).and("cate", 20));
|
||||||
if (actLog == null && ok == 1) {
|
if (actLog == null && ok == 1) {
|
||||||
actLog = new ActLog(20, contentid, userid);//.cate(2).tid(contentId).userId(userId);
|
actLog = new ActLog(20, contentid, userid);//.cate(2).tid(contentId).userId(userId);
|
||||||
actLog.setCreatetime(System.currentTimeMillis());
|
actLog.setCreatetime(System.currentTimeMillis());
|
||||||
source.insert(actLog);
|
dataSource.insert(actLog);
|
||||||
} else if (actLog != null && actLog.getStatus() != ok) {
|
} else if (actLog != null && actLog.getStatus() != ok) {
|
||||||
actLog.setStatus((short) ok);
|
actLog.setStatus((short) ok);
|
||||||
actLog.setCreatetime(System.currentTimeMillis());
|
actLog.setCreatetime(System.currentTimeMillis());
|
||||||
source.update(actLog);
|
dataSource.update(actLog);
|
||||||
} else {
|
} else {
|
||||||
return RetCodes.retResult(-1, ok == 1 ? "已收藏" : "已取消收藏");
|
return RetCodes.retResult(-1, ok == 1 ? "已收藏" : "已取消收藏");
|
||||||
}
|
}
|
||||||
|
|
||||||
return RetResult.success();
|
return RET_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RestMapping(name = "collectquery", comment = "收藏列表")
|
@RestMapping(name = "collectquery", comment = "收藏列表")
|
||||||
public Sheet<ContentInfo> collectQuery(@RestSessionid String sessionid) {
|
public Sheet<ContentInfo> collectQuery(@RestUserid int userid) {
|
||||||
int userid = currentUserid(sessionid);
|
Flipper flipper = new Flipper("createtime DESC");
|
||||||
|
|
||||||
Flipper flipper = new Flipper().sort("createtime DESC");
|
|
||||||
FilterNode filterNode = FilterNode.create("cate", 20).and("status", 10).and("userid", userid);
|
FilterNode filterNode = FilterNode.create("cate", 20).and("status", 10).and("userid", userid);
|
||||||
Sheet<ActLog> actLogs = source.querySheet(ActLog.class, SelectColumn.includes("tid", "createtime"), flipper, filterNode);
|
Sheet<ActLog> actLogs = dataSource.querySheet(ActLog.class, SelectColumn.includes("tid", "createtime"), flipper, filterNode);
|
||||||
|
|
||||||
int[] contentids = actLogs.stream().mapToInt(x -> x.getTid()).toArray();
|
int[] contentids = actLogs.stream().mapToInt(x -> x.getTid()).toArray();
|
||||||
Sheet<Content> contents = source.querySheet(Content.class, SelectColumn.includes("contentid", "title"), flipper.sort(null), FilterNode.create("contentid", FilterExpress.IN, contentids));
|
Sheet<ContentInfo> contents = dataSource.querySheet(ContentInfo.class, SelectColumn.includes("contentid", "title"), flipper.sort(null), FilterNode.create("contentid", FilterExpress.IN, contentids));
|
||||||
|
|
||||||
Sheet<ContentInfo> infos = createInfo(contents);
|
// 设置用户信息
|
||||||
|
Set<Integer> userids = Utils.toSet(contents, x -> x.getUserid());
|
||||||
|
Map<Integer, UserInfo> userMap = userService.queryUserMap(userids);
|
||||||
|
contents.forEach(x -> x.setUser(userMap.get(x.getUserid())));
|
||||||
|
|
||||||
return infos;
|
return contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RestMapping(name = "set", comment = "便捷的修改内容")
|
@RestMapping(name = "set", comment = "便捷的修改内容")
|
||||||
public RetResult contentSet(@RestSessionid String sessionid,
|
public RetResult contentSet(UserInfo user,
|
||||||
@Comment("帖子id") int id,
|
@Comment("帖子id") int id,
|
||||||
@Comment("status|top|wonderful") String field,
|
@Comment("status|top|wonderful") String field,
|
||||||
@Comment("目标修改值") short v) {
|
@Comment("目标修改值") short v) {
|
||||||
//只有管理员可访问
|
int userid = user.getUserid();
|
||||||
int userid = currentUserid(sessionid);
|
|
||||||
//身份验证 后修改内容
|
//身份验证 后修改内容
|
||||||
source.findAsync(Content.class, id).thenAccept(content -> {
|
dataSource.findAsync(ContentInfo.class, id).thenAccept(content -> {
|
||||||
if (content.getUserid() == userid && userService.isAdmin(userid)) {//管理员可以做更多
|
if (userService.isAdmin(userid)) {//管理员可以做更多
|
||||||
//field: status|top|wonderful
|
//field: status|top|wonderful
|
||||||
// update content set {field}={v} where id={id}
|
// update content set {field}={v} where id={id}
|
||||||
source.updateColumn(Content.class, id, field, v);
|
dataSource.updateColumn(ContentInfo.class, id, field, v);
|
||||||
} else if (content.getUserid() == userid && ("status".equals(field))) {//非管理员只能修改状态
|
} else if (content.getUserid() == userid && ("status".equals(field))) {//非管理员只能修改状态
|
||||||
source.updateColumn(Content.class, id, field, v);
|
dataSource.updateColumn(ContentInfo.class, id, field, v);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return RetResult.success();
|
return RET_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RestMapping(name = "t", auth = false, comment = "测试HttpScope 模板使用")
|
@RestMapping(name = "t", auth = false, comment = "测试HttpScope 模板使用")
|
||||||
public HttpScope t(@RestSessionid String sessionid) {
|
public HttpScope t(@RestUserid int userid) {
|
||||||
ContentService contentService = this;
|
ContentService contentService = this;
|
||||||
Flipper flipper = new Flipper().limit(30).sort("top DESC,createtime DESC");
|
Flipper flipper = new Flipper(30).sort("top DESC,createtime DESC");
|
||||||
//置顶贴
|
//置顶贴
|
||||||
FilterNode topNode = FilterNode.create("status", FilterExpress.NOTEQUAL, -10).and("top", FilterExpress.GREATERTHANOREQUALTO, 20);
|
FilterNode topNode = FilterNode.create("status", NOTEQUAL, -10).and("top", GREATERTHANOREQUALTO, 20);
|
||||||
Sheet<ContentInfo> top = contentService.contentQuery(flipper, topNode);
|
Sheet<ContentInfo> top = contentService.contentQuery(flipper, topNode);
|
||||||
|
|
||||||
//非置顶贴
|
//非置顶贴
|
||||||
FilterNode untopNode = FilterNode.create("status", FilterExpress.NOTEQUAL, -10).and("top", 0);
|
FilterNode untopNode = FilterNode.create("status", NOTEQUAL, -10).and("top", 0);
|
||||||
Sheet<ContentInfo> contents = contentService.contentQuery(flipper, untopNode);
|
Sheet<ContentInfo> contents = contentService.contentQuery(flipper, untopNode);
|
||||||
|
|
||||||
//热议
|
//热议
|
||||||
Flipper flipper3 = new Flipper().limit(8).sort("replynum DESC");
|
Flipper flipper3 = new Flipper(8).sort("replynum DESC");
|
||||||
Sheet<ContentInfo> hotReply = contentService.query(flipper3, "", sessionid);
|
Sheet<ContentInfo> hotReply = contentService.query(userid, flipper3, "");
|
||||||
|
|
||||||
//最新加入
|
//最新加入
|
||||||
Sheet<UserInfo> lastReg = userService.lastReg();
|
Sheet<UserInfo> lastReg = userService.lastReg();
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
package net.tccn.bbs.base;
|
package net.tccn.bbs.file;
|
||||||
|
|
||||||
|
import net.tccn.bbs.base.BaseService;
|
||||||
import org.redkale.net.http.RestMapping;
|
import org.redkale.net.http.RestMapping;
|
||||||
import org.redkale.net.http.RestService;
|
import org.redkale.net.http.RestService;
|
||||||
import org.redkale.net.http.RestUploadFile;
|
import org.redkale.net.http.RestUploadFile;
|
||||||
import org.redkale.service.RetResult;
|
import org.redkale.service.RetResult;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
@ -16,16 +18,18 @@ import java.nio.file.StandardCopyOption;
|
|||||||
@RestService(automapping = true, comment = "文件服务")
|
@RestService(automapping = true, comment = "文件服务")
|
||||||
public class FileService extends BaseService {
|
public class FileService extends BaseService {
|
||||||
|
|
||||||
private static final String dir = "/var/www/upload/redbbs/";
|
@Resource(name = "property.file.upload_dir")
|
||||||
private static final String view = "http://img.1216.top/redbbs/";
|
private String dir = "";
|
||||||
private static final String format = "%1$tY%1$tm%1$td%1$tH%1$tM%1$tS";
|
@Resource(name = "property.file.view_path")
|
||||||
|
private String view = "";
|
||||||
|
private String format = "%1$tY%1$tm%1$td%1$tH%1$tM%1$tS";
|
||||||
|
|
||||||
@RestMapping(name = "upload", comment = "文件上传")
|
@RestMapping(name = "upload", comment = "文件上传")
|
||||||
public RetResult upload(@RestUploadFile File tmpFile) throws IOException {
|
public RetResult upload(@RestUploadFile File tmpFile) throws IOException {
|
||||||
String name = tmpFile.getName();
|
String name = tmpFile.getName();
|
||||||
String suffix = name.substring(name.lastIndexOf("."));
|
String suffix = name.substring(name.lastIndexOf("."));
|
||||||
String path = String.format(format, System.currentTimeMillis()) + suffix;
|
String path = String.format(format, System.currentTimeMillis()) + suffix;
|
||||||
File destFile = new File((winos ? "D:/wk/_own/redbbs/root/tem/" : dir) + path);
|
File destFile = new File(dir + path);
|
||||||
destFile.getParentFile().mkdir();
|
destFile.getParentFile().mkdir();
|
||||||
if (!tmpFile.renameTo(destFile)) {
|
if (!tmpFile.renameTo(destFile)) {
|
||||||
try {
|
try {
|
||||||
@ -35,7 +39,7 @@ public class FileService extends BaseService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
RetResult result = RetResult.success();
|
RetResult result = RetResult.success();
|
||||||
result.setRetinfo((winos ? "/tem/" : view) + path);
|
result.setRetinfo(view + path);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,7 +2,6 @@ package net.tccn.bbs.servlet;
|
|||||||
|
|
||||||
import com.jfinal.kit.Kv;
|
import com.jfinal.kit.Kv;
|
||||||
import net.tccn.bbs.base.BaseServlet;
|
import net.tccn.bbs.base.BaseServlet;
|
||||||
import net.tccn.bbs.base.user.UserInfo;
|
|
||||||
import net.tccn.bbs.comment.CommentInfo;
|
import net.tccn.bbs.comment.CommentInfo;
|
||||||
import net.tccn.bbs.content.ContentInfo;
|
import net.tccn.bbs.content.ContentInfo;
|
||||||
import org.redkale.net.http.*;
|
import org.redkale.net.http.*;
|
||||||
@ -20,12 +19,14 @@ import static org.redkale.source.FilterExpress.NOTEQUAL;
|
|||||||
public class ContentServlet extends BaseServlet {
|
public class ContentServlet extends BaseServlet {
|
||||||
@HttpMapping(url = "/jie", auth = false, comment = "问答列表")
|
@HttpMapping(url = "/jie", auth = false, comment = "问答列表")
|
||||||
public void jie(HttpRequest request, HttpResponse response) {
|
public void jie(HttpRequest request, HttpResponse response) {
|
||||||
|
Integer userid = request.currentUserid(int.class);
|
||||||
|
|
||||||
String actived = getPara(request, 0, "all");
|
String actived = getPara(request, 0, "all");
|
||||||
int curr = request.getIntParameter("curr", 1);
|
int curr = request.getIntParameter("curr", 1);
|
||||||
|
|
||||||
//分页帖子列表
|
//分页帖子列表
|
||||||
Flipper flipper = new Flipper().offset((curr - 1) * 15).limit(15).sort("top DESC,createtime DESC");
|
Flipper flipper = new Flipper().offset((curr - 1) * 15).limit(15).sort("top DESC,createtime DESC");
|
||||||
Sheet<ContentInfo> contents = contentService.query(flipper, actived, request.getSessionid(false));
|
Sheet<ContentInfo> contents = contentService.query(userid, flipper, actived);
|
||||||
|
|
||||||
Kv kv = Kv.by("contents", contents).set("url", request.getRequestURI())
|
Kv kv = Kv.by("contents", contents).set("url", request.getRequestURI())
|
||||||
.set("actived", actived).set("curr", curr);
|
.set("actived", actived).set("curr", curr);
|
||||||
@ -37,12 +38,10 @@ public class ContentServlet extends BaseServlet {
|
|||||||
@HttpParam(name = "#", type = int.class, comment = "内容ID")
|
@HttpParam(name = "#", type = int.class, comment = "内容ID")
|
||||||
public void add(HttpRequest request, HttpResponse response) {
|
public void add(HttpRequest request, HttpResponse response) {
|
||||||
int contentid = getParaToInt(request, 0);
|
int contentid = getParaToInt(request, 0);
|
||||||
String sessionid = request.getSessionid(false);
|
Integer userid = request.currentUserid(int.class);
|
||||||
UserInfo user = userService.current(sessionid);
|
|
||||||
|
|
||||||
ContentInfo contentInfo = null;
|
ContentInfo contentInfo = null;
|
||||||
if (contentid > 0) {
|
if (contentid > 0) {
|
||||||
contentInfo = contentService.info(user, contentid);
|
contentInfo = contentService.info(userid, contentid);
|
||||||
}
|
}
|
||||||
|
|
||||||
Kv kv = Kv.by("bean", contentInfo);
|
Kv kv = Kv.by("bean", contentInfo);
|
||||||
@ -53,10 +52,10 @@ public class ContentServlet extends BaseServlet {
|
|||||||
public void detail(HttpRequest request, HttpResponse response) {
|
public void detail(HttpRequest request, HttpResponse response) {
|
||||||
int contentid = getParaToInt(request, 0);
|
int contentid = getParaToInt(request, 0);
|
||||||
String sessionid = request.getSessionid(false);
|
String sessionid = request.getSessionid(false);
|
||||||
UserInfo user = userService.current(sessionid);
|
Integer userid = request.currentUserid(int.class);
|
||||||
|
|
||||||
ContentInfo content = contentService.info(user, contentid);
|
ContentInfo content = contentService.info(userid, contentid);
|
||||||
Sheet<CommentInfo> comments = commentService.query(sessionid, contentid, new Flipper().limit(30));
|
Sheet<CommentInfo> comments = commentService.query(userid, new Flipper(30), contentid);
|
||||||
|
|
||||||
//热帖
|
//热帖
|
||||||
//Flipper flipper2 = new Flipper().limit(8).sort("viewNum DESC");
|
//Flipper flipper2 = new Flipper().limit(8).sort("viewNum DESC");
|
||||||
|
@ -3,6 +3,7 @@ package net.tccn.bbs.servlet;
|
|||||||
import net.tccn.bbs.base.BaseServlet;
|
import net.tccn.bbs.base.BaseServlet;
|
||||||
import org.redkale.net.http.*;
|
import org.redkale.net.http.*;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -17,9 +18,11 @@ import java.util.Map;
|
|||||||
@WebServlet(value = {"/upload", "/upload/*"}, comment = "文件管理入口")
|
@WebServlet(value = {"/upload", "/upload/*"}, comment = "文件管理入口")
|
||||||
public class FileServlet extends BaseServlet {
|
public class FileServlet extends BaseServlet {
|
||||||
|
|
||||||
private static final String dir = "/var/www/upload/redbbs/";
|
@Resource(name = "property.file.upload_dir")
|
||||||
private static final String view = "http://img.1216.top/redbbs/";
|
private String dir = "";
|
||||||
private static final String format = "%1$tY%1$tm%1$td%1$tH%1$tM%1$tS";
|
@Resource(name = "property.file.view_path")
|
||||||
|
private String view = "";
|
||||||
|
private String format = "%1$tY%1$tm%1$td%1$tH%1$tM%1$tS";
|
||||||
|
|
||||||
@HttpMapping(url = "/upload/img", auth = false, comment = "图片上传")
|
@HttpMapping(url = "/upload/img", auth = false, comment = "图片上传")
|
||||||
public void uploadImg(HttpRequest request, HttpResponse response) {
|
public void uploadImg(HttpRequest request, HttpResponse response) {
|
||||||
@ -32,12 +35,12 @@ public class FileServlet extends BaseServlet {
|
|||||||
String name = part.getName();
|
String name = part.getName();
|
||||||
String suffix = name.substring(name.lastIndexOf("."));
|
String suffix = name.substring(name.lastIndexOf("."));
|
||||||
String path = String.format(format, System.currentTimeMillis()) + suffix;
|
String path = String.format(format, System.currentTimeMillis()) + suffix;
|
||||||
File destFile = new File((winos ? "E:/wk/own/redbbs/root/tem/" : dir) + path);
|
File destFile = new File(dir + path);
|
||||||
destFile.getParentFile().mkdir();
|
destFile.getParentFile().mkdir();
|
||||||
|
|
||||||
part.save(destFile);
|
part.save(destFile);
|
||||||
|
|
||||||
data.add((winos ? "/tem/" : view) + path);
|
data.add(view + path);
|
||||||
}
|
}
|
||||||
ret.put("data", data);
|
ret.put("data", data);
|
||||||
|
|
||||||
|
@ -2,9 +2,9 @@ package net.tccn.bbs.servlet;
|
|||||||
|
|
||||||
import com.jfinal.kit.Kv;
|
import com.jfinal.kit.Kv;
|
||||||
import net.tccn.bbs.base.BaseServlet;
|
import net.tccn.bbs.base.BaseServlet;
|
||||||
import net.tccn.bbs.base.user.UserInfo;
|
|
||||||
import net.tccn.bbs.comment.CommentInfo;
|
import net.tccn.bbs.comment.CommentInfo;
|
||||||
import net.tccn.bbs.content.ContentInfo;
|
import net.tccn.bbs.content.ContentInfo;
|
||||||
|
import net.tccn.bbs.user.UserInfo;
|
||||||
import org.redkale.net.http.*;
|
import org.redkale.net.http.*;
|
||||||
import org.redkale.source.FilterNode;
|
import org.redkale.source.FilterNode;
|
||||||
import org.redkale.source.Flipper;
|
import org.redkale.source.Flipper;
|
||||||
@ -17,15 +17,16 @@ import static org.redkale.source.FilterExpress.NOTEQUAL;
|
|||||||
/**
|
/**
|
||||||
* Created by Lxy at 2017/11/25 12:31.
|
* Created by Lxy at 2017/11/25 12:31.
|
||||||
*/
|
*/
|
||||||
@WebServlet(value = {"/", "/project" /* ,"/article","/article/*" */}, comment = "首页一级菜单入口")
|
@WebServlet(value = {"/", "/project"}, comment = "首页一级菜单入口")
|
||||||
public class IndexServlet extends BaseServlet {
|
public class IndexServlet extends BaseServlet {
|
||||||
|
|
||||||
|
|
||||||
@HttpMapping(url = "/", auth = false, comment = "社区首页")
|
@HttpMapping(url = "/", auth = false, comment = "社区首页")
|
||||||
public void abc(HttpRequest request, HttpResponse response) {
|
public void index(HttpRequest request, HttpResponse response) {
|
||||||
|
|
||||||
String sessionid = request.getSessionid(false);
|
String sessionid = request.getSessionid(false);
|
||||||
|
|
||||||
Flipper flipper = new Flipper().limit(15).sort("top DESC,createtime DESC");
|
Flipper flipper = new Flipper(15, "top DESC,createtime DESC");
|
||||||
//置顶贴
|
//置顶贴
|
||||||
FilterNode topNode = FilterNode.create("status", NOTEQUAL, -10).and("top", GREATERTHANOREQUALTO, 20);
|
FilterNode topNode = FilterNode.create("status", NOTEQUAL, -10).and("top", GREATERTHANOREQUALTO, 20);
|
||||||
Sheet<ContentInfo> top = contentService.contentQuery(flipper, setPrivate(request, topNode));
|
Sheet<ContentInfo> top = contentService.contentQuery(flipper, setPrivate(request, topNode));
|
||||||
@ -70,12 +71,11 @@ public class IndexServlet extends BaseServlet {
|
|||||||
//====================================项目相关====================================
|
//====================================项目相关====================================
|
||||||
@HttpMapping(url = "/project", auth = false, comment = "项目首页")
|
@HttpMapping(url = "/project", auth = false, comment = "项目首页")
|
||||||
public void project(HttpRequest request, HttpResponse response) {
|
public void project(HttpRequest request, HttpResponse response) {
|
||||||
String sessionid = request.getSessionid(false);
|
Integer userid = request.currentUserid(int.class);
|
||||||
UserInfo user = userService.current(sessionid);
|
|
||||||
int contentid = 22;
|
int contentid = 22;
|
||||||
|
|
||||||
ContentInfo content = contentService.info(user, contentid);
|
ContentInfo content = contentService.info(userid, contentid);
|
||||||
Sheet<CommentInfo> comments = commentService.query(sessionid, contentid, new Flipper().limit(30));
|
Sheet<CommentInfo> comments = commentService.query(userid, new Flipper(30), contentid);
|
||||||
|
|
||||||
Kv kv = Kv.by("bean", content).set("comments", comments);
|
Kv kv = Kv.by("bean", content).set("comments", comments);
|
||||||
response.finish(HttpScope.refer("/project/index.html").attr(kv));
|
response.finish(HttpScope.refer("/project/index.html").attr(kv));
|
||||||
|
@ -2,11 +2,11 @@ package net.tccn.bbs.servlet;
|
|||||||
|
|
||||||
import com.jfinal.kit.Kv;
|
import com.jfinal.kit.Kv;
|
||||||
import net.tccn.bbs.base.BaseServlet;
|
import net.tccn.bbs.base.BaseServlet;
|
||||||
import net.tccn.bbs.base.user.UserBean;
|
|
||||||
import net.tccn.bbs.base.user.UserInfo;
|
|
||||||
import net.tccn.bbs.base.user.UserRecord;
|
|
||||||
import net.tccn.bbs.comment.CommentInfo;
|
import net.tccn.bbs.comment.CommentInfo;
|
||||||
import net.tccn.bbs.content.ContentInfo;
|
import net.tccn.bbs.content.ContentInfo;
|
||||||
|
import net.tccn.bbs.user.UserBean;
|
||||||
|
import net.tccn.bbs.user.UserDetail;
|
||||||
|
import net.tccn.bbs.user.UserInfo;
|
||||||
import org.redkale.net.http.*;
|
import org.redkale.net.http.*;
|
||||||
import org.redkale.source.FilterExpress;
|
import org.redkale.source.FilterExpress;
|
||||||
import org.redkale.source.FilterNode;
|
import org.redkale.source.FilterNode;
|
||||||
@ -46,6 +46,7 @@ public class UserServlet extends BaseServlet {
|
|||||||
|
|
||||||
@HttpMapping(url = "/user", auth = false, comment = "用户首页")
|
@HttpMapping(url = "/user", auth = false, comment = "用户首页")
|
||||||
public void user(HttpRequest request, HttpResponse response) {
|
public void user(HttpRequest request, HttpResponse response) {
|
||||||
|
Integer userid = request.currentUserid(int.class);
|
||||||
String para = getPara(request);
|
String para = getPara(request);
|
||||||
|
|
||||||
//-------个人中心---------
|
//-------个人中心---------
|
||||||
@ -57,13 +58,13 @@ public class UserServlet extends BaseServlet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//创建的帖子
|
//创建的帖子
|
||||||
Flipper flipper = new Flipper().limit(8).sort("createtime DESC");
|
Flipper flipper = new Flipper(8, "createtime DESC");
|
||||||
|
|
||||||
FilterNode node = FilterNode.create("userid", user.getUserid()).and("status", FilterExpress.NOTEQUAL, -10);
|
FilterNode node = FilterNode.create("userid", user.getUserid()).and("status", FilterExpress.NOTEQUAL, -10);
|
||||||
Sheet<ContentInfo> contents = contentService.contentQuery(flipper, setPrivate(request, node));//queryByBean(flipper, bean);
|
Sheet<ContentInfo> contents = contentService.contentQuery(flipper, setPrivate(request, node));//queryByBean(flipper, bean);
|
||||||
|
|
||||||
//收藏的帖子
|
//收藏的帖子
|
||||||
Sheet<ContentInfo> collects = contentService.collectQuery(request.getSessionid(false));
|
Sheet<ContentInfo> collects = contentService.collectQuery(userid);
|
||||||
|
|
||||||
Kv kv = Kv.by("contents", contents).set("collects", collects);
|
Kv kv = Kv.by("contents", contents).set("collects", collects);
|
||||||
response.finish(HttpScope.refer("/user/index.html").attr(kv));
|
response.finish(HttpScope.refer("/user/index.html").attr(kv));
|
||||||
@ -71,12 +72,11 @@ public class UserServlet extends BaseServlet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//-------用户主页------
|
//-------用户主页------
|
||||||
int userid = 0;
|
|
||||||
if ("nick".equals(para)) {//通过@ 点击跳转
|
if ("nick".equals(para)) {//通过@ 点击跳转
|
||||||
String nickname = request.getParameter("nickname");
|
String nickname = request.getParameter("nickname");
|
||||||
UserBean userBean = new UserBean();
|
UserBean userBean = new UserBean();
|
||||||
userBean.setNickname(nickname);
|
userBean.setNickname(nickname);
|
||||||
Sheet<UserRecord> users = userService.query(new Flipper().limit(1), userBean);
|
Sheet<UserDetail> users = userService.query(new Flipper(1), userBean);
|
||||||
if (users.getTotal() > 0) {
|
if (users.getTotal() > 0) {
|
||||||
userid = users.stream().findFirst().orElse(null).getUserid();
|
userid = users.stream().findFirst().orElse(null).getUserid();
|
||||||
}
|
}
|
||||||
@ -88,7 +88,7 @@ public class UserServlet extends BaseServlet {
|
|||||||
UserInfo user = userService.find(userid);
|
UserInfo user = userService.find(userid);
|
||||||
|
|
||||||
//帖子
|
//帖子
|
||||||
Flipper flipper = new Flipper().limit(8).sort("createtime DESC");
|
Flipper flipper = new Flipper(8, "createtime DESC");
|
||||||
FilterNode node = FilterNode.create("userid", userid).and("status", FilterExpress.NOTEQUAL, -10);
|
FilterNode node = FilterNode.create("userid", userid).and("status", FilterExpress.NOTEQUAL, -10);
|
||||||
Sheet<ContentInfo> contents = contentService.contentQuery(flipper, setPrivate(request, node));
|
Sheet<ContentInfo> contents = contentService.contentQuery(flipper, setPrivate(request, node));
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package net.tccn.bbs.base.user;
|
package net.tccn.bbs.user;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
@ -1,4 +1,4 @@
|
|||||||
package net.tccn.bbs.base.user;
|
package net.tccn.bbs.user;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
@ -28,5 +28,4 @@ public class UserBean implements FilterBean {
|
|||||||
|
|
||||||
@Column(length = 32, comment = "[邮箱]")
|
@Column(length = 32, comment = "[邮箱]")
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package net.tccn.bbs.base.user;
|
package net.tccn.bbs.user;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
@ -16,8 +16,8 @@ import javax.persistence.Table;
|
|||||||
@Setter
|
@Setter
|
||||||
@Getter
|
@Getter
|
||||||
@Cacheable(interval = 5 * 60)
|
@Cacheable(interval = 5 * 60)
|
||||||
@Table(catalog = "redbbs", name = "sys_userrecord")
|
@Table(catalog = "redbbs", name = "userdetail")
|
||||||
public class UserRecord implements java.io.Serializable {
|
public class UserDetail implements java.io.Serializable {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@Column(comment = "[用户id]")
|
@Column(comment = "[用户id]")
|
||||||
@ -68,6 +68,7 @@ public class UserRecord implements java.io.Serializable {
|
|||||||
@Column(comment = "[状态]-10删除 10正常")
|
@Column(comment = "[状态]-10删除 10正常")
|
||||||
private short status = 10;
|
private short status = 10;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return JsonConvert.root().convertTo(this);
|
return JsonConvert.root().convertTo(this);
|
@ -1,8 +1,8 @@
|
|||||||
package net.tccn.bbs.base.user;
|
package net.tccn.bbs.user;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.redkale.convert.json.JsonConvert;
|
import net.tccn.bbs.base.BaseEntity;
|
||||||
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
@ -12,7 +12,7 @@ import javax.persistence.Id;
|
|||||||
*/
|
*/
|
||||||
@Setter
|
@Setter
|
||||||
@Getter
|
@Getter
|
||||||
public class UserInfo implements java.io.Serializable {
|
public class UserInfo extends BaseEntity {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@Column(comment = "[用户id]")
|
@Column(comment = "[用户id]")
|
||||||
@ -35,11 +35,6 @@ public class UserInfo implements java.io.Serializable {
|
|||||||
private int status = 1;
|
private int status = 1;
|
||||||
private String time = "";
|
private String time = "";
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return JsonConvert.root().convertTo(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查用户权限
|
* 检查用户权限
|
||||||
*
|
*
|
225
src/net/tccn/bbs/user/UserService.java
Normal file
225
src/net/tccn/bbs/user/UserService.java
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
package net.tccn.bbs.user;
|
||||||
|
|
||||||
|
import com.jfinal.kit.Kv;
|
||||||
|
import net.tccn.bbs.base.BaseService;
|
||||||
|
import net.tccn.bbs.base.Utils;
|
||||||
|
import net.tccn.bbs.base.util.RetCodes;
|
||||||
|
import org.redkale.net.http.*;
|
||||||
|
import org.redkale.service.RetResult;
|
||||||
|
import org.redkale.source.FilterExpress;
|
||||||
|
import org.redkale.source.FilterFunc;
|
||||||
|
import org.redkale.source.FilterNode;
|
||||||
|
import org.redkale.source.Flipper;
|
||||||
|
import org.redkale.util.Comment;
|
||||||
|
import org.redkale.util.SelectColumn;
|
||||||
|
import org.redkale.util.Sheet;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static net.tccn.bbs.base.util.RetCodes.RET_USER_ACCOUNT_PWD_ILLEGAL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Lxy at 2017/10/3 14:02.
|
||||||
|
*/
|
||||||
|
@RestService(comment = "用户服务")
|
||||||
|
public class UserService extends BaseService {
|
||||||
|
|
||||||
|
@RestMapping(name = "login", auth = false, comment = "登录校验")
|
||||||
|
public RetResult<UserInfo> login(LoginBean bean) {
|
||||||
|
if (bean == null || bean.emptyUsername()) {
|
||||||
|
return retError("参数错误");
|
||||||
|
}
|
||||||
|
|
||||||
|
RetResult retResult = new RetResult();
|
||||||
|
|
||||||
|
UserDetail user = dataSource.find(UserDetail.class, "username", bean.getUsername());
|
||||||
|
if (user == null || !Objects.equals(user.getPassword(), Utils.genMd5(bean.getPassword()))) {
|
||||||
|
//log(null, 0, "用户或密码错误");
|
||||||
|
return RetCodes.retResult(RET_USER_ACCOUNT_PWD_ILLEGAL, "用户名或密码错误");
|
||||||
|
}
|
||||||
|
sessions.setAsync(sessionExpireSeconds, bean.getSessionid(), (long) user.getUserid());
|
||||||
|
retResult.setRetcode(0);
|
||||||
|
retResult.setResult(Kv.by("token", bean.getSessionid()));
|
||||||
|
retResult.setRetinfo("登录成功.");
|
||||||
|
return retResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RestMapping(ignore = true)
|
||||||
|
public int currentUserid(String sessionid) {
|
||||||
|
if (sessionid == null) return 0;
|
||||||
|
long userid = 0;
|
||||||
|
try {
|
||||||
|
userid = sessions.getLong(sessionid, 0);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return (int) userid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserInfo current(String sessionid) {
|
||||||
|
if (sessionid == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
long userid = 0;
|
||||||
|
try {
|
||||||
|
userid = sessions.getLong(sessionid, 0);
|
||||||
|
sessions.getAndRefresh(sessionid, sessionExpireSeconds);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userid == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
UserInfo info = find((int) userid);
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RestMapping(name = "info", comment = "用户信息")
|
||||||
|
public UserInfo find(int userid) {
|
||||||
|
if (userid == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
UserDetail user = dataSource.find(UserDetail.class, userid);
|
||||||
|
UserInfo bean = user.createUserInfo();
|
||||||
|
return bean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Comment("根据用户ID, 批量查询一批用户信息")
|
||||||
|
public Map<Integer, UserInfo> queryUserMap(Collection<Integer> userids) {
|
||||||
|
if (Utils.isEmpty(userids)) {
|
||||||
|
return Map.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
FilterNode node = FilterNode.create("userid", (Serializable) userids);
|
||||||
|
List<UserDetail> records = dataSource.queryList(UserDetail.class, node);
|
||||||
|
Map<Integer, UserInfo> map = Utils.toMap(records, x -> x.getUserid(), x -> x.createUserInfo());
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RestMapping(name = "logout", auth = false, comment = "退出登录")
|
||||||
|
public RetResult logout(@RestSessionid String sessionid) {
|
||||||
|
sessions.remove(sessionid);
|
||||||
|
|
||||||
|
return RetResult.success();
|
||||||
|
//return new HttpResult().header("Location", "/").status(302);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RestMapping(name = "query", auth = false, comment = "用户数据查询")
|
||||||
|
public Sheet<UserDetail> query(Flipper flipper, @RestParam(name = "bean", comment = "过滤条件") final UserBean userBean) {
|
||||||
|
Sheet<UserDetail> users = dataSource.querySheet(UserDetail.class, flipper, userBean);
|
||||||
|
|
||||||
|
return users;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RestMapping(name = "changepwd", comment = "修改密码")
|
||||||
|
public RetResult updatePwd(@RestUserid int userid, String pass, String nowpass) {
|
||||||
|
UserInfo user = find(userid);
|
||||||
|
if (!Objects.equals(user.getPassword(), UserDetail.md5IfNeed(nowpass))) {
|
||||||
|
return retError("密码错误");
|
||||||
|
}
|
||||||
|
if (pass == null || pass.length() < 6 || Objects.equals(pass, nowpass)) {
|
||||||
|
return retError("密码设置无效");
|
||||||
|
}
|
||||||
|
dataSource.updateColumn(UserDetail.class, user.getUserid(), "password", UserDetail.md5IfNeed(pass));
|
||||||
|
return RetResult.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@RestMapping(name = "register", auth = false, comment = "用户注册")
|
||||||
|
public RetResult register(UserDetail bean) {
|
||||||
|
/*用户名、密码、邮箱*/
|
||||||
|
if (bean.getEmail() == null) {
|
||||||
|
return retError("邮件地址无效");
|
||||||
|
}
|
||||||
|
if (bean.getPassword() == null || bean.getPassword().length() < 6) {
|
||||||
|
return retError("密码设置无效");
|
||||||
|
}
|
||||||
|
if (dataSource.exists(UserDetail.class, FilterNode.create("email", bean.getEmail()))) {
|
||||||
|
return retError("用户名已存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
bean.setCreatetime(System.currentTimeMillis());
|
||||||
|
bean.setPassword(bean.passwordForMd5());
|
||||||
|
bean.setStatus((short) 10);
|
||||||
|
bean.setUsername(bean.getEmail());
|
||||||
|
bean.setAvatar("/res/images/avatar/" + new Random().nextInt(21) + ".jpg");//默认头像
|
||||||
|
|
||||||
|
synchronized (this) {
|
||||||
|
int maxid = dataSource.getNumberResult(UserDetail.class, FilterFunc.MAX, 10_0000, "userid").intValue();
|
||||||
|
if (maxid < 10_0000) {
|
||||||
|
maxid = 10_0000;
|
||||||
|
}
|
||||||
|
bean.setUserid(maxid + 1);
|
||||||
|
}
|
||||||
|
dataSource.insert(bean);
|
||||||
|
|
||||||
|
//记录日志
|
||||||
|
return RetResult.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@RestMapping(name = "update", comment = "用户信息修改")
|
||||||
|
public RetResult userUpdate(@RestUserid int userid, UserDetail bean, String[] columns) {
|
||||||
|
String nickname = bean.getNickname();
|
||||||
|
if (nickname == null && nickname.isEmpty()) {
|
||||||
|
return retError("昵称无效");
|
||||||
|
}
|
||||||
|
|
||||||
|
nickname = nickname.replace(" ", "");
|
||||||
|
FilterNode node = FilterNode.create("nickname", nickname).and("userid", FilterExpress.NOTEQUAL, userid);
|
||||||
|
if (dataSource.exists(UserDetail.class, node)) {
|
||||||
|
return retError("昵称已存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
bean.setNickname(nickname);//去除昵称中的空格
|
||||||
|
dataSource.updateColumn(bean
|
||||||
|
, FilterNode.create("userid", userid)
|
||||||
|
, SelectColumn.includes(columns)
|
||||||
|
);
|
||||||
|
return RetResult.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
//最新加入
|
||||||
|
public Sheet<UserInfo> lastReg() {
|
||||||
|
Sheet<UserDetail> users = dataSource.querySheet(UserDetail.class
|
||||||
|
, SelectColumn.includes("userid", "nickname", "avatar", "createtime")
|
||||||
|
, new Flipper(8, "createtime DESC")
|
||||||
|
, FilterNode.create("status", 10));
|
||||||
|
|
||||||
|
Sheet<UserInfo> infos = new Sheet<>();
|
||||||
|
ArrayList<UserInfo> list = new ArrayList<>();
|
||||||
|
|
||||||
|
users.forEach(x -> {
|
||||||
|
UserInfo info = x.createUserInfo();
|
||||||
|
info.setTime(Utils.dateFmt(x.getCreatetime()));
|
||||||
|
list.add(info);
|
||||||
|
});
|
||||||
|
|
||||||
|
infos.setRows(list);
|
||||||
|
infos.setTotal(users.getTotal());
|
||||||
|
|
||||||
|
return infos;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RestMapping(name = "usercount", auth = false, comment = "用户数据统计")
|
||||||
|
public Number userCount() {
|
||||||
|
return dataSource.getNumberResult(UserDetail.class, FilterFunc.COUNT, "userid", FilterNode.create("status", FilterExpress.NOTEQUAL, -10));
|
||||||
|
}
|
||||||
|
|
||||||
|
@RestMapping(ignore = true, comment = "判断用户是否是管理员")
|
||||||
|
public boolean isAdmin(int userid) {
|
||||||
|
if (userid <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Integer> userIds = dataSource.queryColumnList("userid", UserDetail.class, FilterNode.create("roleid", 1));
|
||||||
|
for (Integer x : userIds) {
|
||||||
|
if (userid == x) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
95
src/net/tccn/bbs/vislog/bean/ActLogBean.java
Normal file
95
src/net/tccn/bbs/vislog/bean/ActLogBean.java
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
package net.tccn.bbs.vislog.bean;
|
||||||
|
|
||||||
|
import org.redkale.convert.json.JsonConvert;
|
||||||
|
import org.redkale.source.FilterBean;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lxyer
|
||||||
|
*/
|
||||||
|
public class ActLogBean implements Serializable, FilterBean {
|
||||||
|
|
||||||
|
@Column(comment = "[日志id]")
|
||||||
|
private int logid;
|
||||||
|
|
||||||
|
@Column(comment = "[日志类型]")
|
||||||
|
private int cate;
|
||||||
|
|
||||||
|
@Column(comment = "[目标数据id]")
|
||||||
|
private int tid;
|
||||||
|
|
||||||
|
@Column(comment = "[用户id]")
|
||||||
|
private int userId;
|
||||||
|
|
||||||
|
@Column(comment = "[创建时间]")
|
||||||
|
private long createTime;
|
||||||
|
|
||||||
|
@Column(length = 128, comment = "[说明]")
|
||||||
|
private String remark = "";
|
||||||
|
|
||||||
|
@Column(comment = "[状态]-1删除 1正常")
|
||||||
|
private int status = 1;
|
||||||
|
|
||||||
|
public void setLogid(int logid) {
|
||||||
|
this.logid = logid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLogid() {
|
||||||
|
return this.logid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCate(int cate) {
|
||||||
|
this.cate = cate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCate() {
|
||||||
|
return this.cate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTid(int tid) {
|
||||||
|
this.tid = tid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTid() {
|
||||||
|
return this.tid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserId(int userId) {
|
||||||
|
this.userId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUserId() {
|
||||||
|
return this.userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateTime(long createTime) {
|
||||||
|
this.createTime = createTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCreateTime() {
|
||||||
|
return this.createTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemark(String remark) {
|
||||||
|
this.remark = remark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRemark() {
|
||||||
|
return this.remark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(int status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStatus() {
|
||||||
|
return this.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JsonConvert.root().convertTo(this);
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package net.tccn.bbs.base.entity;
|
package net.tccn.bbs.vislog.entity;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
@ -15,7 +15,7 @@ import javax.persistence.Table;
|
|||||||
@Setter
|
@Setter
|
||||||
@Getter
|
@Getter
|
||||||
@Cacheable(interval = 5 * 60)
|
@Cacheable(interval = 5 * 60)
|
||||||
@Table(catalog = "redbbs", name = "sys_actlog")
|
@Table(catalog = "redbbs", name = "actlog")
|
||||||
public class ActLog implements java.io.Serializable {
|
public class ActLog implements java.io.Serializable {
|
||||||
|
|
||||||
@Id
|
@Id
|
@ -1,4 +1,4 @@
|
|||||||
package net.tccn.bbs.base.entity;
|
package net.tccn.bbs.vislog.entity;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
@ -1,4 +1,4 @@
|
|||||||
package net.tccn.bbs.base.entity;
|
package net.tccn.bbs.vislog.entity;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
@ -1,4 +1,4 @@
|
|||||||
package net.tccn.bbs.base.entity;
|
package net.tccn.bbs.vislog.entity;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
@ -1,6 +1,7 @@
|
|||||||
package net.tccn.redim;
|
package net.tccn.redim;
|
||||||
|
|
||||||
import net.tccn.bbs.base.JBean;
|
import net.tccn.bbs.base.JBean;
|
||||||
|
import net.tccn.bbs.user.UserService;
|
||||||
import net.tccn.redim.entity.MsgRecord;
|
import net.tccn.redim.entity.MsgRecord;
|
||||||
import net.tccn.redim.info.MsgInfo;
|
import net.tccn.redim.info.MsgInfo;
|
||||||
import net.tccn.redim.service.ImFriendService;
|
import net.tccn.redim.service.ImFriendService;
|
||||||
@ -24,6 +25,9 @@ public class ChatWebSocket extends WebSocket {
|
|||||||
@Resource
|
@Resource
|
||||||
protected ImFriendService imFriendService;
|
protected ImFriendService imFriendService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
protected UserService userService;
|
||||||
|
|
||||||
protected Random random = new Random();
|
protected Random random = new Random();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -45,7 +49,7 @@ public class ChatWebSocket extends WebSocket {
|
|||||||
|
|
||||||
//fixme: 1、isyk => tour; 2、set cate to user global
|
//fixme: 1、isyk => tour; 2、set cate to user global
|
||||||
if (getAttribute("isyk") == null) {//tour
|
if (getAttribute("isyk") == null) {//tour
|
||||||
userid = imFriendService.currentUserid(getSessionid());
|
userid = userService.currentUserid(getSessionid());
|
||||||
setAttribute("isyk", true);
|
setAttribute("isyk", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,9 +3,9 @@ package net.tccn.redim.impl;
|
|||||||
import com.jfinal.kit.Kv;
|
import com.jfinal.kit.Kv;
|
||||||
import net.tccn.bbs.base.BaseService;
|
import net.tccn.bbs.base.BaseService;
|
||||||
import net.tccn.bbs.base.JBean;
|
import net.tccn.bbs.base.JBean;
|
||||||
import net.tccn.bbs.base.user.UserInfo;
|
import net.tccn.bbs.user.UserDetail;
|
||||||
import net.tccn.bbs.base.user.UserRecord;
|
import net.tccn.bbs.user.UserInfo;
|
||||||
import net.tccn.bbs.base.user.UserService;
|
import net.tccn.bbs.user.UserService;
|
||||||
import net.tccn.redim.service.ImFriendService;
|
import net.tccn.redim.service.ImFriendService;
|
||||||
import org.redkale.boot.Application;
|
import org.redkale.boot.Application;
|
||||||
import org.redkale.net.TransportFactory;
|
import org.redkale.net.TransportFactory;
|
||||||
@ -27,14 +27,14 @@ import java.util.stream.Collectors;
|
|||||||
public class ImFriendServiceImpl extends BaseService implements ImFriendService {
|
public class ImFriendServiceImpl extends BaseService implements ImFriendService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
UserService userService;
|
private UserService userService;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
public static Application application;
|
public static Application application;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JBean friends(String sessionid) {
|
public JBean friends(String sessionid) {
|
||||||
List<UserRecord> records = source.queryList(UserRecord.class, FilterNode.create("status", FilterExpress.NOTEQUAL, -10));
|
List<UserDetail> records = dataSource.queryList(UserDetail.class, FilterNode.create("status", FilterExpress.NOTEQUAL, -10));
|
||||||
|
|
||||||
Kv data = Kv.create();
|
Kv data = Kv.create();
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ package net.tccn.redim.impl;
|
|||||||
|
|
||||||
import net.tccn.bbs.base.BaseService;
|
import net.tccn.bbs.base.BaseService;
|
||||||
import net.tccn.bbs.base.JBean;
|
import net.tccn.bbs.base.JBean;
|
||||||
import net.tccn.bbs.base.user.UserRecord;
|
import net.tccn.bbs.user.UserDetail;
|
||||||
import net.tccn.redim.entity.MsgRecord;
|
import net.tccn.redim.entity.MsgRecord;
|
||||||
import net.tccn.redim.info.MsgInfo;
|
import net.tccn.redim.info.MsgInfo;
|
||||||
import net.tccn.redim.service.ImMsgService;
|
import net.tccn.redim.service.ImMsgService;
|
||||||
@ -15,7 +15,7 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* @author: liangxianyou at 2018/8/12 13:10.
|
* @author: liangxianyou at 2018/8/12 13:10.
|
||||||
*/
|
*/
|
||||||
@ResourceType(net.tccn.redim.service.ImMsgService.class)
|
@ResourceType(ImMsgService.class)
|
||||||
@RestService(name = "immsg", automapping = true, comment = "聊天记录管理")
|
@RestService(name = "immsg", automapping = true, comment = "聊天记录管理")
|
||||||
public class ImMsgServiceImpl extends BaseService implements ImMsgService {
|
public class ImMsgServiceImpl extends BaseService implements ImMsgService {
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ public class ImMsgServiceImpl extends BaseService implements ImMsgService {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public JBean insert(MsgRecord... msg) {
|
public JBean insert(MsgRecord... msg) {
|
||||||
source.insertAsync(msg);
|
dataSource.insertAsync(msg);
|
||||||
return JBean.ok();
|
return JBean.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ public class ImMsgServiceImpl extends BaseService implements ImMsgService {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public JBean update(MsgRecord... msg) {
|
public JBean update(MsgRecord... msg) {
|
||||||
source.updateAsync(msg);
|
dataSource.updateAsync(msg);
|
||||||
return JBean.ok();
|
return JBean.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,11 +61,11 @@ public class ImMsgServiceImpl extends BaseService implements ImMsgService {
|
|||||||
MsgInfo info = new MsgInfo();
|
MsgInfo info = new MsgInfo();
|
||||||
int fromuserid = msg.getFromuserid();
|
int fromuserid = msg.getFromuserid();
|
||||||
|
|
||||||
UserRecord userRecord;
|
UserDetail userDetail;
|
||||||
if (fromuserid > 0) {
|
if (fromuserid > 0) {
|
||||||
userRecord = source.find(UserRecord.class, fromuserid);
|
userDetail = dataSource.find(UserDetail.class, fromuserid);
|
||||||
info.setUsername(userRecord.getUsername());
|
info.setUsername(userDetail.getUsername());
|
||||||
info.setAvatar(userRecord.getAvatar());
|
info.setAvatar(userDetail.getAvatar());
|
||||||
info.setType("friend");
|
info.setType("friend");
|
||||||
} else {
|
} else {
|
||||||
info.setUsername("游客");
|
info.setUsername("游客");
|
||||||
@ -85,7 +85,7 @@ public class ImMsgServiceImpl extends BaseService implements ImMsgService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JBean<List<MsgRecord>> offlineMsg(int userid) {
|
public JBean<List<MsgRecord>> offlineMsg(int userid) {
|
||||||
List<MsgRecord> records = source.queryList(MsgRecord.class, FilterNode.create("touserid", userid).and("status", 10));
|
List<MsgRecord> records = dataSource.queryList(MsgRecord.class, FilterNode.create("touserid", userid).and("status", 10));
|
||||||
return JBean.by(records);
|
return JBean.by(records);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,5 +67,5 @@ public interface ImFriendService extends Service {
|
|||||||
* @param sessionid
|
* @param sessionid
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
int currentUserid(String sessionid);
|
//int currentUserid(String sessionid);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user