From 68f4e2b479fe6a07ab2de6ae9452bdb517c7c11a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E6=98=BE=E4=BC=98?= <237809796@qq.com> Date: Sat, 29 Apr 2023 23:30:44 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=EF=BC=9A=E5=B7=A5=E7=A8=8B?= =?UTF-8?q?=E7=AE=80=E5=8D=95=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- conf/application.xml | 2 +- doc/redbbs.sql | 238 ------ root/{_t => _tpl}/layout.html | 7 +- root/index.html | 17 +- root/jie/detail.html | 4 +- root/jie/index.html | 6 +- root/project/index.html | 34 +- src/net/tccn/bbs/base/ArangoKit.java | 67 -- src/net/tccn/bbs/base/ArangoService.java | 98 --- src/net/tccn/bbs/base/BaseEntity.java | 14 + src/net/tccn/bbs/base/BaseService.java | 44 +- src/net/tccn/bbs/base/BaseServlet.java | 17 +- .../base/{EnjoyRender.java => TplRender.java} | 9 +- src/net/tccn/bbs/base/UF.java | 13 - src/net/tccn/bbs/base/Utils.java | 750 ++++++++++++++++++ src/net/tccn/bbs/base/bean/ActLogBean.java | 43 - src/net/tccn/bbs/base/iface/C.java | 9 - src/net/tccn/bbs/base/iface/CI.java | 7 - src/net/tccn/bbs/base/iface/CService.java | 32 - src/net/tccn/bbs/base/iface/UI.java | 37 - src/net/tccn/bbs/base/iface/UIService.java | 38 - src/net/tccn/bbs/base/kit/LxyKit.java | 70 -- src/net/tccn/bbs/base/user/UserService.java | 181 ----- src/net/tccn/bbs/base/{kit => util}/EJ.java | 2 +- src/net/tccn/bbs/base/util/Kv.java | 352 ++++++++ .../tccn/bbs/base/{kit => util}/RetCodes.java | 2 +- .../tccn/bbs/base/{ => util}/TaskQueue.java | 74 +- src/net/tccn/bbs/comment/Comment.java | 71 -- src/net/tccn/bbs/comment/CommentInfo.java | 59 +- src/net/tccn/bbs/comment/CommentService.java | 135 ++-- src/net/tccn/bbs/content/Content.java | 95 --- src/net/tccn/bbs/content/ContentBean.java | 55 -- src/net/tccn/bbs/content/ContentInfo.java | 99 ++- src/net/tccn/bbs/content/ContentService.java | 195 +++-- .../tccn/bbs/{base => file}/FileService.java | 16 +- src/net/tccn/bbs/servlet/ContentServlet.java | 17 +- src/net/tccn/bbs/servlet/FileServlet.java | 13 +- src/net/tccn/bbs/servlet/IndexServlet.java | 16 +- src/net/tccn/bbs/servlet/UserServlet.java | 16 +- .../tccn/bbs/{base => }/user/LoginBean.java | 2 +- .../tccn/bbs/{base => }/user/UserBean.java | 3 +- .../UserRecord.java => user/UserDetail.java} | 7 +- .../tccn/bbs/{base => }/user/UserInfo.java | 11 +- src/net/tccn/bbs/user/UserService.java | 225 ++++++ src/net/tccn/bbs/vislog/bean/ActLogBean.java | 95 +++ .../bbs/{base => vislog}/entity/ActLog.java | 4 +- .../bbs/{base => vislog}/entity/Count.java | 2 +- .../bbs/{base => vislog}/entity/DynAttr.java | 2 +- .../bbs/{base => vislog}/entity/VisLog.java | 2 +- src/net/tccn/redim/ChatWebSocket.java | 6 +- .../tccn/redim/impl/ImFriendServiceImpl.java | 10 +- src/net/tccn/redim/impl/ImMsgServiceImpl.java | 18 +- .../tccn/redim/service/ImFriendService.java | 2 +- 53 files changed, 1869 insertions(+), 1474 deletions(-) delete mode 100644 doc/redbbs.sql rename root/{_t => _tpl}/layout.html (98%) delete mode 100644 src/net/tccn/bbs/base/ArangoKit.java delete mode 100644 src/net/tccn/bbs/base/ArangoService.java create mode 100644 src/net/tccn/bbs/base/BaseEntity.java rename src/net/tccn/bbs/base/{EnjoyRender.java => TplRender.java} (86%) delete mode 100644 src/net/tccn/bbs/base/UF.java create mode 100644 src/net/tccn/bbs/base/Utils.java delete mode 100644 src/net/tccn/bbs/base/bean/ActLogBean.java delete mode 100644 src/net/tccn/bbs/base/iface/C.java delete mode 100644 src/net/tccn/bbs/base/iface/CI.java delete mode 100644 src/net/tccn/bbs/base/iface/CService.java delete mode 100644 src/net/tccn/bbs/base/iface/UI.java delete mode 100644 src/net/tccn/bbs/base/iface/UIService.java delete mode 100644 src/net/tccn/bbs/base/kit/LxyKit.java delete mode 100644 src/net/tccn/bbs/base/user/UserService.java rename src/net/tccn/bbs/base/{kit => util}/EJ.java (93%) create mode 100644 src/net/tccn/bbs/base/util/Kv.java rename src/net/tccn/bbs/base/{kit => util}/RetCodes.java (98%) rename src/net/tccn/bbs/base/{ => util}/TaskQueue.java (77%) delete mode 100644 src/net/tccn/bbs/comment/Comment.java delete mode 100644 src/net/tccn/bbs/content/Content.java delete mode 100644 src/net/tccn/bbs/content/ContentBean.java rename src/net/tccn/bbs/{base => file}/FileService.java (73%) rename src/net/tccn/bbs/{base => }/user/LoginBean.java (94%) rename src/net/tccn/bbs/{base => }/user/UserBean.java (94%) rename src/net/tccn/bbs/{base/user/UserRecord.java => user/UserDetail.java} (94%) rename src/net/tccn/bbs/{base => }/user/UserInfo.java (79%) create mode 100644 src/net/tccn/bbs/user/UserService.java create mode 100644 src/net/tccn/bbs/vislog/bean/ActLogBean.java rename src/net/tccn/bbs/{base => vislog}/entity/ActLog.java (93%) rename src/net/tccn/bbs/{base => vislog}/entity/Count.java (92%) rename src/net/tccn/bbs/{base => vislog}/entity/DynAttr.java (95%) rename src/net/tccn/bbs/{base => vislog}/entity/VisLog.java (93%) diff --git a/conf/application.xml b/conf/application.xml index 6734711..5b42737 100644 --- a/conf/application.xml +++ b/conf/application.xml @@ -24,7 +24,7 @@ - + diff --git a/doc/redbbs.sql b/doc/redbbs.sql deleted file mode 100644 index 201874a..0000000 --- a/doc/redbbs.sql +++ /dev/null @@ -1,238 +0,0 @@ --- MySQL dump 10.13 Distrib 5.7.21, for Linux (x86_64) --- --- Host: localhost Database: redbbs --- ------------------------------------------------------ --- Server version 5.7.21 - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - --- --- Table structure for table `im_imgroup` --- - -DROP TABLE IF EXISTS `im_imgroup`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `im_imgroup` ( - `groupid` int(11) NOT NULL AUTO_INCREMENT, - `groupname` varchar(32) DEFAULT NULL, - `ownuserid` int(11) NOT NULL COMMENT '[所属用户]', - `userids` varchar(256) DEFAULT '' COMMENT '[好友id]', - PRIMARY KEY (`groupid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='[好友分组]'; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `im_imgroup` --- - -LOCK TABLES `im_imgroup` WRITE; -/*!40000 ALTER TABLE `im_imgroup` DISABLE KEYS */; -/*!40000 ALTER TABLE `im_imgroup` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `im_partner` --- - -DROP TABLE IF EXISTS `im_partner`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `im_partner` ( - `partnerid` int(11) NOT NULL AUTO_INCREMENT, - `partnername` varchar(32) DEFAULT NULL, - `ownuserid` int(11) DEFAULT NULL COMMENT '[所属人]', - `createtime` bigint(20) DEFAULT NULL, - `userids` varchar(256) NOT NULL DEFAULT '' COMMENT '[群成员id]', - PRIMARY KEY (`partnerid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='[群组]'; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `im_partner` --- - -LOCK TABLES `im_partner` WRITE; -/*!40000 ALTER TABLE `im_partner` DISABLE KEYS */; -/*!40000 ALTER TABLE `im_partner` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `sys_actlog` --- - -DROP TABLE IF EXISTS `sys_actlog`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `sys_actlog` ( - `logid` int(11) NOT NULL AUTO_INCREMENT COMMENT '[日志id]', - `cate` smallint(6) NOT NULL COMMENT '[日志类型] 10点赞 20收藏', - `tid` int(11) DEFAULT NULL COMMENT '[目标数据id]', - `userid` int(11) NOT NULL DEFAULT '0' COMMENT '[用户id]', - `createtime` bigint(20) DEFAULT NULL COMMENT '[创建时间]', - `remark` varchar(128) DEFAULT NULL COMMENT '[说明]', - `status` smallint(6) DEFAULT '10' COMMENT '[状态]-10删除 10正常', - PRIMARY KEY (`logid`) -) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `sys_actlog` --- - -LOCK TABLES `sys_actlog` WRITE; -/*!40000 ALTER TABLE `sys_actlog` DISABLE KEYS */; -INSERT INTO `sys_actlog` VALUES (1,10,13,100003,1512025122957,'',10),(2,10,13,100003,1512025740325,'',10),(3,10,13,100003,1512025795043,'',10),(4,10,13,100003,1512025901312,'',10),(5,10,13,100003,1512025965326,'',10),(6,10,13,100003,1512026040433,'',10),(7,10,2,100003,1512028418702,'',10),(8,10,8,100003,1512028432175,'',10),(9,10,4,100003,1512028464602,'',10),(10,20,3,100003,1512034501549,'',-10),(11,20,2,100003,1512032642934,'',-10),(12,20,1,100003,1512032796896,'',10),(13,10,11,100003,1512032884321,'',10),(14,10,10,100003,1512032895493,'',10),(15,20,8,100003,1512034565868,'',10),(16,10,12,100002,1512045337969,'',10),(17,20,9,100001,1512101602962,'',10),(18,10,111,100001,1512914577786,'',10),(19,10,18,100001,1512915224895,'',10),(20,10,20,100003,1521166811155,'',10); -/*!40000 ALTER TABLE `sys_actlog` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `sys_comment` --- - -DROP TABLE IF EXISTS `sys_comment`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `sys_comment` ( - `commentid` int(11) NOT NULL AUTO_INCREMENT COMMENT '[评论id]', - `userid` int(11) NOT NULL COMMENT '[评论用户id]', - `pid` int(11) NOT NULL DEFAULT '0' COMMENT '[评论父id]', - `cate` smallint(6) NOT NULL DEFAULT '1' COMMENT '[评论的类型]', - `contentid` int(11) NOT NULL COMMENT '[被评论内容的id]', - `content` text COMMENT '[评论内容]', - `createtime` bigint(20) DEFAULT NULL COMMENT '[创建时间]', - `supportnum` int(11) DEFAULT '0' COMMENT '[支持数]', - `status` smallint(6) NOT NULL DEFAULT '10' COMMENT '[状态]-10删除 10正常', - PRIMARY KEY (`commentid`) -) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8 COMMENT='[评论表]'; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `sys_comment` --- - -LOCK TABLES `sys_comment` WRITE; -/*!40000 ALTER TABLE `sys_comment` DISABLE KEYS */; -INSERT INTO `sys_comment` VALUES (1,100003,0,10,1,'face[围观] face[围观] ',1511939728047,0,10),(2,100003,0,10,2,'face[嘻嘻] face[可怜] ',1511940602654,1,10),(3,100003,13,10,1,'@nick face[哈哈] ',1511940625623,0,10),(4,100003,13,10,1,'@nickface[白眼] ',1511940683270,1,10),(5,100003,13,10,1,'@nick1111',1511940700471,0,10),(6,100003,0,10,1,'img[/tem/20171129162348.jpg] ',1511943836477,0,10),(7,100003,0,10,2,'img[/tem/20171129163431.jpg] ',1511944482613,0,10),(8,100003,0,10,2,'face[生病] ',1511944517640,1,10),(9,100003,0,10,1,'face[太开心] ',1511944551078,0,10),(10,100003,0,10,1,'face[哈哈] face[哈哈] face[哈哈] ',1511944648519,1,10),(11,100003,0,10,1,'face[哈哈] ',1511944795212,1,10),(12,100002,0,10,1,'gfd d',1512045330899,1,10),(13,100002,12,10,1,'@荣培晓fg hr',1512045347046,0,10),(14,100002,3,10,1,'@nick htr yt',1512045359531,0,10),(15,100003,7,10,2,'@nick ',1512098913721,0,10),(16,100003,0,10,8,'img[http://img.1216.top/bbs/20171201120132.gif] ',1512100903683,0,10),(17,100003,0,10,2,'face[哈哈] img[/tem/20171203113715.png] ',1512272244158,0,10),(18,100001,0,10,8,'123',1512914569848,1,10),(19,100001,0,10,15,'

\"[污]\"

',1519814792066,0,10),(20,100003,0,10,12,'

\"[污]\"评论一个

',1521166738268,1,10),(21,100003,0,10,15,'


',1521210812583,0,10),(22,100003,0,10,15,'

 

',1521211118233,0,10),(23,100003,22,10,15,'

@nick 

',1521212557156,0,10),(24,100003,23,10,15,'

@nick \"[舔屏]\"

',1521212576515,0,10),(25,100003,0,10,18,'

查看官方demo里面有,https://gitee.com/redkale/redkale-oss

',1524015328722,0,10); -/*!40000 ALTER TABLE `sys_comment` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `sys_content` --- - -DROP TABLE IF EXISTS `sys_content`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `sys_content` ( - `contentid` int(11) NOT NULL AUTO_INCREMENT COMMENT '[内容id]', - `userid` int(11) NOT NULL COMMENT '[用户id]', - `title` varchar(64) NOT NULL COMMENT '[标题]', - `digest` varchar(256) DEFAULT '' COMMENT '[摘要]', - `content` text COMMENT '[内容]', - `createtime` bigint(20) NOT NULL COMMENT '[创建时间]', - `cate` smallint(6) DEFAULT NULL COMMENT '[类别]', - `type` int(11) NOT NULL COMMENT '[内容栏目]10求助,20分享,30建议,40公告,50动态', - `replynum` int(11) NOT NULL DEFAULT '0' COMMENT '[评论数]', - `viewnum` int(11) NOT NULL DEFAULT '0' COMMENT '[阅读量]', - `wonderful` smallint(6) NOT NULL DEFAULT '10' COMMENT '[精] 10否,20是', - `top` smallint(6) NOT NULL DEFAULT '10' COMMENT '[置顶]10否,20是', - `solved` smallint(6) NOT NULL DEFAULT '10' COMMENT '[结帖]10否,20是', - `status` smallint(6) NOT NULL DEFAULT '10' COMMENT '[状态]-10删除 10未结帖 20结帖 30私密', - PRIMARY KEY (`contentid`) -) ENGINE=InnoDB AUTO_INCREMENT=43 DEFAULT CHARSET=utf8 COMMENT='[内容表]'; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `sys_content` --- - -LOCK TABLES `sys_content` WRITE; -/*!40000 ALTER TABLE `sys_content` DISABLE KEYS */; -INSERT INTO `sys_content` VALUES (1,100001,'被历史误判!时间还其公道','','

\"[哈哈]\"\"[坏笑]\"\"[偷笑]\"


',1505031204000,9,50,11,522,10,10,0,-10),(2,100001,'故宫武英殿举行赵孟頫书画特展','','img[/tem/20171203231840.jpg]\r\n',1505042514000,2,0,5,167,10,10,0,-10),(3,100001,'Redkale 技术详解 01 -- 双亲委托模型','',' Redkale 里大量使用了双亲委托模型,序列化的ConvertFactory、依赖注入的ResourceFactory、服务管理的WatchFactory均采用双亲委托模型。用于优先加载自定义的处理类,同时也保证两个同级的子Factory不会相互干扰。
\r\n',1511682960591,1,0,0,95,20,10,0,-10),(4,100003,'回收木头打造彩色鸟屋 让鸟儿找到栖息之地','','\r\nimg[http://www.shouyihuo.com/uploads/allimg/171128/4_171128095818_1.jpg]\r\n\r\nface[浮云]\r\nimg[http://www.shouyihuo.com/uploads/allimg/171128/4_171128095832_2.jpg]',1511858330764,9,20,0,170,10,10,0,-10),(5,100003,'2017-11-29','','img[/tem/20171129232304.png] ',1511968992737,1,0,0,30,10,10,0,-10),(6,100003,'儿童画','','img[/tem/20171130173239.jpg] ',1512034378751,3,0,0,1,10,10,0,-10),(7,100003,'儿童画','','img[/tem/20171130173239.jpg] ',1512034389038,3,0,0,2,10,10,0,-10),(8,100003,'儿童画-九岁','','img[http://img.1216.top/bbs/20171201120301.jpg] ',1512034430071,9,20,2,145,10,10,0,-10),(9,100001,'全家福-培晓作','','img[http://img.1216.top/bbs/20171201120447.jpg] ',1512054964558,9,0,0,125,20,10,0,-10),(10,100002,'培晓艺术','','\r\nimg[http://img.1216.top/bbs/20171204184735.png] ',1512384522858,9,0,0,41,20,20,0,-10),(11,100001,'社区功能进一步完善,已可以投入使用','','
\n 进一步完善,加入 求助/分享/...各个栏目\n[pre]\n社区基本功能已完成,可以简单的投入使用了\n欢迎围观、欢迎注册体验\"[太开心]\"


',1512921121862,0,50,0,212,10,10,0,10),(12,100002,'阿狸日常','','




 

',1512923899949,0,20,1,185,20,10,0,10),(13,100003,'现在版本nginx支不支持TCP的SSL','','
不知道现在版本nginx支不支持TCP的SSL, 如果支持的话那就不考虑实现SSL了  



',1514916271430,0,30,0,57,10,10,0,10),(14,100003,'http协议基本认证 Authorization','','

阅读目录
什么是HTTP基本认证
HTTP基本认证的过程
HTTP基本认证的优点
每次都要进行认证
HTTP基本认证和HTTPS一起使用就很安全
HTTP OAuth认证
其他认证
客户端的使用
 >>>http协议基本认证 Authorization 

',1514917144371,0,20,0,54,10,10,0,10),(15,100003,'redkale1.8.9 内存进一步优化','','

\n

\n

同样的请求,50线程请求2000次, redkale1.8.8占内存最高值750M, 1.8.9降到500M  

【1.8.8】  



  【1.8.9】




',1514917498015,0,20,5,140,20,10,0,10),(16,100003,'系统思维--读书笔记','','

《系统架构》 复杂系统的产品设计与开发

-----------------------------------------

什么是系统思维?

    简单说,就是把某个疑问、状态、难题等明确的视为一个系统,是为一组相互关联的实体。(与 批判、分析、创新思维  思维模式并列)

如果完成一次系统思维的过程?

  1.     1、确定系统及其形式与功能
  2.     2、确定系统中的实体 及其形式与功能,以及系统所处的环境系统的边界
  3.     3、确定各个实体间的关系位于边界处的关系,并确定这些关系的形式和功能
  4.     4、确定系统的涌现属性

系统的定义:

    系统是由一组实体和这些实体之间的关系所构成的集合,其功能要大于这些实体各自功能之和。

架构定义:

    对系统中的实体和实体间的关系所进行的抽象描述

涌现是什么

    -系统运作时所表现、呈现或浮现出的东西

    -各实体拼合成一个系统时,实体间的交互会把功能、行为、性能和其他内在属性涌现出来;系统的价值来源于涌现物的赋予,能够涌现预期属性的系统是成功的系统,反之亦然;另外除了性能外系统涌现涌现的属性包括:可靠性、可维护性、可操作性、安全性、健壮性等;

涌现原则:

    整体大于其各部分之和。 ——亚里士多德


。。。。未完



',1522378656136,0,20,0,56,10,10,0,10),(17,100013,'Idea在已经存在的mavn项目建立子模块遇到的问题','','

idea 提示:\'F:/workspace/xxxx/pom.xml\' already exists in VFS

尝试方法:

    1,查看A项目下是否已经xxx.xml或xxx.iml文件,将其删除

    2,打开Project Structure 查看是否已经存在其子模块,将其删除

    3,点击项目右键,选择Show in Exploer 在本地文件夹里打开,查看是否存在其子模块文件夹,将其删除。

    4,点击File 选择 Invalidate Caches /Restarts... 选项,清理一缓存。

  

导致问题原因:

    可能由于在建立 了模块时,选择了与其父模块一样的文件夹导致。


',1523503127379,0,20,0,63,10,10,0,10),(18,100014,'redkale处理session','','

redkale在作为http服务器使用时,是如何处理session这块内容的?还是采用token方式验证,去掉session呢

',1523549060544,0,10,1,60,10,10,0,10),(19,100013,'maven将某个子模块下的资源移到到其它子模块下','','

描述:

    如何使用maven将A模块下的资源文件在打包时复制到B模块下。

配置信息:

    需要在B模块下的pom.xml文件配置如下信息:

<build>
<resources>
<resource>
<directory>../A模块项目名称/src/main/resources</directory>
<filtering>true</filtering>
<includes> <!-- 包含的文件 -->
<include>*</include>
<include>*/*</include>
</includes>
<excludes><!-- 排除某些文件 -->
<exclude>*.properties</exclude>
</excludes>
</resource>
</resources>
</build>


',1523841741041,0,20,0,51,10,10,0,10),(20,100013,'vmware中启动FreeDos进入BIOS系统','','

找到FreeDos系统在硬盘上的虚拟文件的目录。修改后辍为.vmxf配置文件。添加如下内容:

bios.forceSetupOnce = \"TRUE\" 

bios.bootDelay = \"10000\" 

保存重启。注:每次启动完后,添加得这两个配置会消失,需要重新添加。

',1524128820960,0,20,0,54,10,10,0,10),(21,100013,'MongoDB提示:not master and slaveOk=false','','
出现的原因:mongo集群,你连接到了某一个SECONDARY主机上,然后此主机没有读取权限导致的。
解决办法:
1、在mongo shell中执行rs.slaveOk() 来获取读取的权限。https://docs.mongodb.com/manual/reference/method/rs.slaveOk/
2、在连接时使用指定PRIMARY主机(使用集群方式连接)。如果使用MongoDB管理软件请查看是否有相关配置信息。如果使用命令行方式可以如下命令格式进行连接:
mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
                 
如:mongo mongodb://192.168.176.133:27018,192.168.176.135:27017/database?replicaSet=repset2


其中:192.168.176.133和192.168.176.135这两个ip是SECONDARY主机地址,连接后会自动切换到PRIMARY主机上(在连接时会自动查询配置信息,然后连接到PRIMARY主机上)replicaSet是集群名。

链接地址:https://docs.mongodb.com/manual/reference/connection-string/index.html

            注:如果在连接过程中出现host2或某个域名出现未知主机异常UnknownHostException时。请确定此集群在配置时进是否使用主机名映射。也就是否需要在本地修改hosts文件来添加映射关系。

 

   


',1526022672039,0,20,0,43,10,10,0,10),(22,100001,'社区功能更新记录--社区建议评论此贴','','


2018-06-12更新
1. 用户资料加入[个人博客地址、码云/GitHub地址](部分用户开放设置)
2. 加入用户信息接口UF/UI,优化用户信息设置代码


2018-06-10更新
1. 个人中心-收藏数据不对
2. 管理员查询不到用户未公开帖子
3. 注册/资料修改 成功后未提示
4. 首页帖子用户头像链接地址错误


2018-05-12更新
1. 文章编辑加入未保存浏览器缓存
2. 文章编辑标题加入长度检查


',1526140381293,0,30,0,160,20,30,0,10),(23,100013,'maven web工程添加本地类库的方式','','

方式一:

    在webapp/WEB-INF目录下建立 一个lib文件,直接将jar复制到里面。然后修改pom.xml文件。

<dependency>  \n    <groupId>com.alipay.api</groupId>  \n    <artifactId>alipay-sdk-java20170324180803</artifactId>
<version>20170324180803</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/alipay-sdk-java20170324180803.jar</systemPath>
</dependency>

其中<scope><systemPath>标签最为重要,<scope>其值必须为system,<systemPath>为jar的位置。其它标签内容可自行定义。

方式二:使用maven-war-plugin插件

<dependency>
<groupId>com.alipay.api</groupId>
<artifactId>alipay-sdk-java20170324180803</artifactId>
<version>20170324180803</version>
<scope>system</scope>
<systemPath>${project.basedir}/local-lib/alipay-sdk-java20170324180803.jar</systemPath>
</dependency>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<warName>${project.artifactId}</warName>
<webResources>
<resource>
<directory>local-lib/</directory>
<targetPath>WEB-INF/lib</targetPath>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>

注:local-lib文件夹是在项目的根目录建立的。


方式三:使用resource标签,将jar移动到指定的目录

<dependency>
<groupId>com.alipay.api</groupId>
<artifactId>alipay-sdk-java20170324180803</artifactId>
<version>20170324180803</version>
<scope>system</scope>
<systemPath>${project.basedir}/local-lib/alipay-sdk-java20170324180803.jar</systemPath>
</dependency>

<resource>
<directory>${basedir}/local-lib</directory>
<includes>
<include>*.jar</include>
</includes>
<targetPath>${build.directory}/${build.finalName}/WEB-INF/lib</targetPath>
</resource>

注:其中<targetPath>标签内容占主要。也需要将方式一中的<dependency>标签内容添加到pom中。

说明:${变量名}这种是mave内置的一些变量。直接使用即可。其主要目标就是将jar移动到编译后的WEB-INF/lib目录下即可

',1527130015404,0,20,0,19,10,10,0,10),(24,100013,'mavn多工程只打包某一个工程','','

命令:

maven package -DskipTests -pl sub-model-proejct -ad

说明:

    1,执行命令的目录为父目录。

    2,选项说明

            -DskipTests:跳过测试

            -pl:构建指定的反应堆项目而不是所有项目,后期跟项目名。也就是要构建项目中的pom文件中的<artifactId>标签中的内容

            -am:如果指定了项目列表,还可以建立列表所需的项目(就是如果项目依赖于其它子项目也会一起构建)

     3,maven版本在2.1版本以上。

     4,maven相关更多命令可以查看mvn --help或到官网查看。

     5,如果使用mvn package 命令来打包如果某一个项目模块下出现问题后,其实同级模块也无法进行打包。而这种方式只有在其依赖的项目模块出现问题后才会失败。

   


',1527130651108,0,20,0,26,10,10,0,10),(25,100003,'fastJson 处理含有下划线字段的坑','','

fastJson 处理含有下划线字段的坑

场景:

    在ES或者mongodb数据库中,存入数据后,数据库会自动为我们的数据创建_id
字段,但是如果在查询的时候使用fastjson做数据解析,

问题:

“_id”会被映射到“id”  

解决办法:

将JavaBean中的字段多加一个“_”  也就是“__
',1527225649538,0,20,0,39,10,10,0,10),(26,100003,'Java的poi实现Excel导入导出【导出支持多个sheet,导入支持高低版本的excel】','','

本贴类型:
        工具源码分享

场景:
        在很多企业管理系统中都会碰到,excel的poi导入导出功能;需求很大,解决方案也很多,(不过我没用过别人的,喜欢用自己写的^_^,没毛病),

工具源码:

        1、Excel导出支持多sheet:    >>>快速使用<<<<  
       
2、excel简单导入代码 [支持2007前后版本]  >>>快速使用<<<<


功能描述:  

        导出:支持多sheet ,支持导出list<bean> list<Map> 写的比较糙,有相关需求的随便看看,参考着自己个儿改改用
        导入:根据配置,导入得到List<Map>数据,可以自己实现List<JavaBean>的扩展(比如使用反射),支持2007前后版本Excel的处理

 


如有使用不明白的地方,可联系本人qq:168_52_537 (去掉下划线)


',1527226866587,0,20,0,50,20,20,0,10),(27,100003,'Redkale 序列教程汇总','','

Redkale 入门教程:

    02 -- REST敏捷开发     01 -- Hello Word! 

Redkale 技术详解:

03 -- Convert高性能序列化 

02 -- Creator构建对象 

01 -- 双亲委托模型 


',1527388626376,0,20,0,34,10,20,0,10),(28,100003,'读取项目配置文件,JDK自带方法【JDK】','','

配置文件内容如下:

user=lxy
pwd=123

非常简单的Java代码(一看就会有木有):

Properties prop = new Properties();
File file = new File(\"conf/cfg.txt\");
prop.load(new FileInputStream(file));

prop.forEach((k,v)->{
System.out.println(k+ \"==\"+ v);
});

配置文件是我们项目中必不可少的东西,
在设计的代码结构的过程中,公共部分通常封装、抽取为方法;
其他部分呢,要么来源数据库,要么来源用户输入,要么来源于文件(配置文件),运行代码再加载配置;这时候这段代码就能为我们很好的工作 

作者:lxy
QQ  :168_52_537


',1527439605223,0,20,0,49,10,20,0,10),(29,100013,'idea下的vim插件配置文件','','

windows:当前用户目录下的_ideavimrc

Linux::当前用户目录下的.ideavimrc


',1528422298022,0,20,0,13,10,10,0,10),(30,100018,'Java学习 set classpath的小结','','

Java学习 set classpath的小结
2018年05月24日 13:52:15
阅读数:5
我们知道javac命令在编译的时候查找类是按照classpath的路径去寻找,如果找不到,就在当前路径下寻找,如果还是找不到,就会报错。

我们可以使用set classpath来查看我们的路径是什么



这其中有三个路径,第一个是‘.’就是当前路径,后两个都是系统类包路径

如果我们临时需要设置一个路径,我们可以开启一个命令行窗口

使用set classpath = 路径名就修改了。



如果我们只是想在原有路径基础上,再加上一个路径我们可以这样:



%classpath%就是原有的路径,前面加上分号与追加的路径隔开。

注意:

我们所使用的set classpath=路径名

是临时设置的,只在当前的黑屏幕cmd有用,一旦退出,恢复以往路径。

个人分类: java






D:\\hao zun cheng\\Documents\\java演示操作>cd/

D:\\>java Hello
Hello World!

D:\\>c:

C:\\>set classpath=d:

C:\\>java hello
错误: 找不到或无法加载主类 hello

C:\\>set classpath
CLASSPATH=d:

C:\\>java Hello
Hello World!

C:\\>

',1528569052027,0,30,0,4,10,10,0,30),(31,100018,'java基础','','

111.0

java基础
软件开发
软件:一序列按照特殊顺序组织的计算机数据和指令的集合。软件;系统软件(windos,linux,Dos),应用软件(qq,扫雷)
开发:软件的开发,制作软件
。 软件实现了人机交互
人机交互
图形化界面
命令行方式(需要一个控制台,输入特定的指令来完成操作
计算机语言
人机沟通的方式c,,,c++,,,java...
java语言是面向internet的编程语言。

java语言的三种技术架构(技术分支):java EE java SE java ME .


java语言的关键特性:1 简洁有效 2 可移植性 3 面向对象 4 解释型 5 适合分布式运算


java的跨平台性:

java可以在不同的平台运行(windois linux mac [苹果系统])
通过JVM(java虚拟机)jvm不能跨平台,不同的系统装不同的jvm.

JVM是JAVA虚拟机,它将.class字节码文件编译成机器语言,以便机器识别!


JDK与JRE(JDK开发工具包,JRE运行方式)



dos中常用的命令:[help]
dir:
md: rd: del: cd: cd.. cd\\ exit cls(清屏)

环境变量的配置
Hello World 的演示
set classpath的使用

',1528569113683,0,30,0,3,10,10,0,30),(32,100018,'java语言基础','','

111.1
java语言基础
组成 :段 大括号 主体

public class TestJava{ //public:表示该类公有,整个程序的可以访问
如果将一个类声明成public,则文件名和这个类名要一致
在一个java文件里,最多只能有一个public类,否则.java的文件便无法命名。

public static void main(String[]args){ //程序运行的起点,主函数main() main()method主方法
int num = 3;// 声明变量num,赋值为3. 使用变量前必须先声明
System.out.println(num);//标准输出 打印到标准输出设备-显示器

}


}




1.关键字

2.标识符
在程序中定义的一些名称。
由26个英文字母大小写,数字:0—9,符号:_$ 组成。
定义标识符的规则:1 数字不可以开头2 不可以使用关键字

3.注释
java中的注释格式:
单行注释://

多行注释:/* * /

文档注释:/** */


操作: HEllo WOrld! 的演示


可用于程序的检测


语法错误 语义错误



提高程序的可读性:注释 缩进

',1528569196783,0,30,0,3,10,10,0,30),(33,100018,'java基础 常量与变量','','

111.2
java基础 常量与变量


1.常量
代表不能改变的数值。

常量的分类:
1 整数常量 所有整数

2小数常量 所有小数

3布尔(boolean)型常量 两个 true false(真假)

4字符常量 将一个数字,字母或符号用单引号(\'\')标识。

5字符串常量 一个或多个字符 用双引号(“”)标识。

6 null常量(空常量) 一个 null

对于整数有四种表现形式: (进制表示计数方式)

二进制 八进制(用0开头) 十进制 十六进制(用0x开头表示)


进制的转换,运算



2. 变量
内存中的一个存储区域。
该区域有自己的名称(变量名)和类型(数据类型)。
该区域的数据可以在同一类型范围内不断变化。

定义变量是为了用来不断的存放同一类型的常量,并可重复使用。

使用变量注意:
变量的作用范围(一对{}之间有效)
初始化值

定义变量的格式: 数据类型 变量名=初始化值

▲ 声明一个变量,并给这个变量赋值。▼先声明才能使用!

变量的三种设置方式:

在声明变量时设置/ int num = 3;
声明后在设置 / int num ; num = 3;
在程序的任何位置声明并设置 /





数据类型:


基本数据类型 数值型:整型(byte int short long ) 浮点型(double双精度浮点型 folate)
布尔型boolean: true false
字符型 char

引用数据类型 类(class) 数组 接口(interface)

整数默认 int 小数默认 double

',1528569270573,0,30,0,6,10,10,0,30),(34,100018,'运算符','','

111.3
运算符
1.算术运算符 + - * / %(取余,模运算)( + 字符串之间的+,用于连接作用:\"a+b=\"+(a+b)+\",b=\"+b , 3+\"2\" ) a++ a--:递增递减


2.赋值运算

3.比较运算 == !=
比较运算符,运算完后的结果必须是true或false。

4.逻辑运算
用于连接两个boolean类型的表达式。(2<x<5, x>2 & x<5)

&:与 |:或
&运算特点:只要有一边为false,结果为false
只有两边都为true,结果才为true. true & true= true


|运算特点:只要有一边为true,结果为true
只有两边都为false,结果才为false.



^ 异或,true^true=false,和或有点不同

^的运算特点:^符号的两边结果如果相同,结果是false
两边的结果不同,结果是true.

!非运算,判断事物的另一面。

!true=false; !false=true.

&& 双与与 运算,左边为false 右边不在做运算(和&相比更高效)
||



5.位运算 用于二进制运算的符号(6&3 6^3^3=6 一个数异或同一个数两次,结果还是这个数)

&运算 |运算 ^运算 反码运算~6=-7(-7+1=-6)

移位运算 <<左移 >>右移 >>>无符号右移
3<<2 3左移两位3*2*2(移几位就这个数乘以二的几次方)右移改除 同理 》》:对于高位出现的
空位,是什么就用什么补,负数还是负数



>>>:无符号右移,数据进行右移时,高位出现的空位,无论原高位是什么,空位的用0补。负数变正数。



6.三元运算

格式 (条件表达式)?表达式1:表达式2;

如果条件为true,运算结果为表达式1.
如果条件为false,运算结果为表达式2.




表达式:
由操作数与运算符组成。操作数可以是常量 ,变量,也可以是方法。











',1528569322974,0,30,0,4,10,10,0,30),(35,100018,'if','','

111.4 程序流程控制 ---判断结构 选择结构 循环结构 顺序结构
判断结构 If语句 三种格式:if(条件表达式)
{执行语句}

if(条件表达式)     if(条件表达式)
{执行语句};              {执行语句};
else                     else if(条件表达式)
{执行语句};               {执行语句};
.....
else (条件表达式)
{执行语句};


局部代码块可以定义一个局部变量的生命周期。

',1528569488211,0,30,0,6,10,10,0,30),(36,100013,'Idea的设置','','

一,开启自动导入包功能

    

',1528699074773,0,20,0,16,10,10,0,10),(37,100001,'这些设计模式你都知道吗','','


一、六大设计原则
1. 单一职责原则
2. 里氏替换原则
3. 依赖倒置原则
4. 接口隔离原则
5. 迪米特法则
6. 开闭原则

二、设计模式
7. 单列模式
8. 工厂方法模式
9. 抽象工厂模式
10. 模板方法模式
11. 建造者模式
12. 代理模式
13. 原型模式
14. 中介者模式
15. 命令模式
16. 责任链模式
17. 装饰模式
18. 策略模式
19. 适配器模式
20. 迭代器模式
21. 组合模式
22. 观察者模式
23. 门面模式
24. 备忘录模式
25. 访问者模式
26. 状态模式
27. 解释器模式
28. 享元模式
29. 桥梁模式

',1528777827596,0,20,0,20,10,10,0,10),(38,100001,'数据库表设计的一些改进思路整理在此,收益很多,','','

以下内容来源<redkale 技术交流群>

整理下来逐一领会,感谢张老师(redkale作者)的指导

\nRedkale<redkale@qq.com> 8:58:13
表命名最好能让人一目了然, 除了表现出内容还要能表的数据模型
-----------
Redkale<redkale@qq.com> 9:04:07
比如我的设计习惯:
xxxrecord表示流水型的数据, 数据量会很大, 通常需要分库分表, 如:payrecord、loginrecord
xxxinfo,xxxdetail表示内容型数据, 数据量可大可小(中短期内不会分表),如:userdetail(用户表)、orderinfo(订单表)
xxxconfig 表示配置型数据,数据量有限。
\n

-----------

Redkale<redkale@qq.com> 9:06:54\n

而且你的表名也体现不出所属模块来
这些设计细节其实很重要, 比文档重要得多,   只要你能做到别人看你表结构就能读懂业务逻辑就说明合格了
\n\n-----------\nRedkale<redkale@qq.com> 9:08:57\n

你看redkale-demo、redkale-oss, 每个表名的前缀就是模块名, 这样别人看表名就知道这个表在哪个模块,被哪个Service调用\n------

\n\n

Redkale<redkale@qq.com> 9:11:19
状态字段最好都用smallint  也就是short
Redkale<redkale@qq.com> 9:11:59
别人一看short字段就知道是状态字段或者枚举值字段

\n\n



Redkale<redkale@qq.com> 8:58:13
表命名最好能让人一目了然, 除了表现出内容还要能表的数据模型

Redkale<redkale@qq.com> 9:04:07
比如我的设计习惯:
xxxrecord表示流水型的数据, 数据量会很大, 通常需要分库分表, 如:payrecord、loginrecord
xxxinfo,xxxdetail表示内容型数据, 数据量可大可小(中短期内不会分表),如:userdetail(用户表)、orderinfo(订单表)
xxxconfig 表示配置型数据,数据量有限。


Redkale<redkale@qq.com> 9:06:54
而且你的表名也体现不出所属模块来
这些设计细节其实很重要, 比文档重要得多, 只要你能做到别人看你表结构就能读懂业务逻辑就说明合格了

绝尘(237809796) 9:07:46
好,从表结构 表名开始再加强升级
绝尘(237809796) 9:08:50
最好能不用文档,每个人都能看懂入门redkale
Redkale<redkale@qq.com> 9:08:57
你看redkale-demo、redkale-oss, 每个表名的前缀就是模块名, 这样别人看表名就知道这个表在哪个模块,被哪个Service调用
绝尘(237809796) 9:09:50

Redkale<redkale@qq.com> 9:11:19
状态字段最好都用smallint 也就是short
Redkale<redkale@qq.com> 9:11:59
别人一看short字段就知道是状态字段或者枚举值字段
绝尘(237809796) 9:13:03
@Redkale 好,认真改善
绝尘(237809796) 9:13:19
Redkale<redkale@qq.com> 9:13:37
还有主键, 一个表里最重要的就是主键字段, 应该注释更详细点
Redkale<redkale@qq.com> 9:13:51


Redkale<redkale@qq.com> 9:15:38
这样以后如果要分库分表, 别人一看注释就知道这个表的数据能按什么维度分表
Redkale<redkale@qq.com> 9:16:10
比如这个回合表, 就只能按日期时间、userid、nodeid分表, 不能分其他维度了


Redkale<redkale@qq.com> 9:17:32

这样新人上手成本很低,  只要将一遍所以的设计规范就知道了, 不用每个功能对着数据表、代码看, 而且每个人的风格不一样, 看起来更头大

Redkale<redkale@qq.com> 9:19:19
你的`createTime`, 一会 bigint、一会date 一会 timestamp 
Redkale<redkale@qq.com> 9:20:58
状态字段禁止使用0表示由意义的值
Redkale<redkale@qq.com> 9:21:12
你这样过滤查询会很蛋疼
Redkale<redkale@qq.com> 9:21:35
传0,redkale会认为不过滤
绝尘(237809796) 9:21:49
确实有这个痛点
文(1101001213) 9:22:25
0一般都是初始值  
Redkale<redkale@qq.com> 9:22:27
你是不是觉得存0比存1少占硬盘空间  
追梦(40839292) 9:22:29
对于枚举,状态等,通常0保留
绝尘(237809796) 9:22:29
从1开始,这样就解决了吧
绝尘(237809796) 9:22:46
@Redkale 一样的吧
IT小萌新(373038132) 9:22:56
主要是int的初始值是0
立立✌️(853089986) 9:23:09
你们在做什么项目啊
文(1101001213) 9:23:14

Redkale<redkale@qq.com> 9:23:37
用short, 有3万多,  你就不能大方点, 用 10 20, 非要1/2    
IT小萌新(373038132) 9:23:37
不过老大设计表的时候确实很讲究
IT小萌新(373038132) 9:23:39
厉害
文(1101001213) 9:23:54
我喜欢
文(1101001213) 9:23:57
10 20
Redkale<redkale@qq.com> 9:24:24
用10 20 ,这样中间还可以穿插意义相近的状态
文(1101001213) 9:24:26
因为动不动业务变更   才好往里面加
追梦(40839292) 9:24:39
群主一看,就是带头做过项目的
绝尘(237809796) 9:24:46
有个地方我也用上10 20了
文(1101001213) 9:24:58
跟分配菜单排序一样的道理
IT小萌新(373038132) 9:25:33
嗯 受教了
绝尘(237809796) 9:26:10
群主是干 CTO的,才赖得带项目呢
Redkale<redkale@qq.com> 9:26:19
比如你设计 1:正常、2:删除;   以后业务发展,加其他几个状态。 3:审批、4冻结   你看这值顺序不觉得别扭了
用10, 20.      10:正常; 20:删除;   以后加: 12:审批; 14:冻结, 这样后续还可以再扩展
文(1101001213) 9:26:58
对的   
绝尘(237809796) 9:27:00
嗯,信息量好大,得好好吸收
绝尘(237809796) 9:27:24
回头一一改进
追梦(40839292) 9:27:27
马屁拍的响@绝尘 \"[污]\"
文(1101001213) 9:27:30
但是要是用上流程引擎的话  就是另一回事

追梦(40839292) 9:27:47
群主受用的啊

Redkale<redkale@qq.com> 9:28:56
用户没输入的信息最好都为空,  你默认为男,  以后数据分析, 你根本不知道用户是真的设置为男,还是系统默认赋值的
绝尘(237809796) 9:29:18
我是发自内心的好不好,@追梦 
IT小萌新(373038132) 9:29:49
群主思维很缜密
绝尘(237809796) 9:29:51

IT小萌新(373038132) 9:29:58
不愧是数学常年满分的\"[神马]\"
中国-虾米(1462996820) 9:30:05
布尔的 列 为啥不用 true/false。
文(1101001213) 9:30:07
空的话 null建议不要
Redkale<redkale@qq.com> 9:30:49
除了text、blob, 其他常规字段都不能为null, 特别是number字段
绝尘(237809796) 9:30:52
@中国-虾米 布亇只有两个值
追梦(40839292) 9:30:56
嗯,不要用null,处理起来麻烦
绝尘(237809796) 9:31:09
扩展就废了
Redkale<redkale@qq.com> 9:31:20
我的表结构里没有boolean类型, 都是short
中国-虾米(1462996820) 9:31:40
只能是 0和1
文(1101001213) 9:31:41
特别是 统计查询 还有数据分析时  null的时候 你会发现好烦
中国-虾米(1462996820) 9:31:50
要是 short 还可以其他
中国-虾米(1462996820) 9:32:01
为啥 不用 bit\n


\nRedkale<redkale@qq.com> 9:32:14
如果是可叠加的状态值, 最好设计成1/2/4/8/16 这样 位运算可以叠加
文(1101001213) 9:33:26
get了
Redkale<redkale@qq.com> 9:34:26
以前有些表字段,  isHide、isDel、isRead, 看着都急死
文(1101001213) 9:34:54
条件太多 有时自己都乱
Redkale<redkale@qq.com> 9:35:12
初级感扑面而来
绝尘(237809796) 9:35:16
感觉被扒光了,站在大街,但这些都是老大青春换来的经验,值得认真思考和学习 \"[污]\"
绝尘(237809796) 9:35:30
很爽

Redkale<redkale@qq.com> 9:35:42
还没看你代码呢
追梦(40839292) 9:35:43
群主,现在在干嘛?
龙飞在天(121156) 9:35:51
@Redkale 老大,为啥不建议用tinyint呢?
文(1101001213) 9:36:20
他在给他分析  数据库设计  代码规范@追梦 @绝尘 

Redkale<redkale@qq.com> 9:37:35
tinyint 对应  byte,   现在什么年代了, 还计较1个字节和2个字节的差距吗, 统一short最简单

Redkale<redkale@qq.com> 9:38:57
现在数据库很多类型我都忘了,  只需要知道常见的类型就够用了
mysql8 没到生产环境的量 也不知道性能好在哪些地方
Redkale<redkale@qq.com> 9:41:48
装过mysql8, 又还原5.7了, jdbc驱动变动太大了

Redkale<redkale@qq.com> 9:44:16
然后呢, 你很需要这个特性吗

Redkale<redkale@qq.com> 9:45:38
目前没碰到常规关系型数据库设计搞不定的数据类型
Redkale<redkale@qq.com> 9:50:24
做后台要多花时间思考表设计, 这个层面是很少变化的,  如果用大量时间在花哨的API层面,过两年不流行了就得跟着新框架屁股后面跑

Redkale<redkale@qq.com> 9:52:15
特别是通才后台开发者, 表、代码、页面都一个人做。    如果是专长的另当别论

Redkale<redkale@qq.com> 10:03:07
表名和类名是一样的吗

表名通常与业务领域模型一致
Redkale<redkale@qq.com> 10:08:01
类名本身就要有模块前缀


',1528904275202,0,30,0,57,20,30,0,10),(39,100001,'处理一个查询参数,实现mysql的高级复合查询','','

背景需求:

一个查询参数,查询全站数据

场景一:网站首页的搜索,一个搜索框要查询整个网站中相关的数据,

处理这个需求有两个步骤:

  1. 1、给输入的内容做分词
  2. 2、使用分词模糊查询数据库

场景二:管理后台,一个输入框输入一个自己的表达式,精确匹配出相关数据,

这种场景的数据处理流程:

  1. 1、根据需求制定 查询表达式
  2. 2、解析参数,生成相应的sql或者查询条件(其实都是废话,和场景一没什么不一样)


下面主要介绍的是一个场景二的代码案例:

查询字符串: 

String str = \"字符1 && 字符2 && 字符3 || 字符4 && 字符5 || 字符6\";

处理得到结果:

and ((title=? and title=? and title=?) or(title=? and title=?) or(title=?))
[\"字符1\",\"字符2\",\"字符3\",\"字符4\",\"字符5\",\"字符6\"]

Java字符串处理:

public static String r(String str){

StringBuffer sql = new StringBuffer();
List<String> para = new ArrayList<>();
sql.append(\" and (\");
for (String x : str.split(\"[|][|]\")) {
sql.append(\"(\");
for (String t : x.split(\"&&\")) {
sql.append(\"title=? and \");
para.add(t.trim());
}
sql.delete(sql.length()-5, sql.length());
sql.append(\") or\");
}
sql.delete(sql.length()-3,sql.length());
sql.append(\")\");

Gson gson = new Gson();
System.out.println(sql.toString());
System.out.println(gson.toJson(para));

return sql.toString();
}


另外注意,Java中的 竖线分割应该如下使用

str.split(\"[|]\") 或者 str.split(\"[|][|]\")


更多个性查询规则,可相应定制,  


',1528969122975,0,20,0,12,10,10,0,10),(40,100001,'Java 打包zip压缩文件','','

Java打包压缩包,简单代码如下:


//文件压缩到zip
public static void run_a() throws IOException {

ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(new File(\"hello.zip\")));
BufferedOutputStream bos = new BufferedOutputStream(zos);

List<String> files = asList(\"log.txt\");//文件列表

for (String fileName : files) {
File file = new File(fileName);
ZipEntry zipEntry = new ZipEntry(\"file/\" + file.getName());
zos.putNextEntry(zipEntry);//设置即将用来写的文件

FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);

int read;
while ((read = bis.read()) != -1){
bos.write(read);
bos.flush();
}
}
zos.close();
}

可拷贝到自己代码中,main方法中运行,看看效果,
更多个性化使用,自行定制,

源码可到  我的gitee 账号下 demo---> jdk-demo---> zip 查看


',1529053122762,0,20,0,12,10,10,0,10),(41,100001,'“积木编程”','','

        端午假期,好多人都去旅游了;对于我旅游并不抱着多大的兴趣,唯爱写代码,以构思程序写代码为生活最大的快乐;这就像我中学时候喜欢物理,学习物理,思考物理现象就是最好的休息,一去想那些宇宙世界奥妙的奇特就感觉特别爽,特别能找到感觉;这可能和我对事的态度有关吧,总想把自己所做的事情,做的很好(很有感觉),做的很有感觉,犹如厨房里面切菜,犹如玻璃厂苦累的不抱怨,犹如电子厂装配车间装配零件,。。。;

        我用心思索,我努力前进,最后就是要找到一个感觉;成就感,操控欲,亦或者更大的成功;这个说不清道不明的感觉;




',1529169086235,0,50,0,13,10,10,0,30),(42,100018,'计数器','','

/*1~100之间六的倍数出现的次数

x%6=0,六的倍数


*/
public class WhileTest1{
    public static void main(String[] args){
        int x = 1;
        int num = 0;
        while(x<=100){
            if(x%6==0){
                num++;
                System.out.println(x);

            }
            x++;
        }
        System.out.println(\"num=\"+num);
    }
}


',1529200957645,0,30,0,12,10,10,0,30); -/*!40000 ALTER TABLE `sys_content` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `sys_dynattr` --- - -DROP TABLE IF EXISTS `sys_dynattr`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `sys_dynattr` ( - `tid` int(11) NOT NULL COMMENT '[目标数据id]', - `cate` smallint(6) NOT NULL COMMENT '[类型]1文章, 2xx, 3...,', - `attr` varchar(32) NOT NULL, - `value` text COMMENT '[属性值]', - PRIMARY KEY (`tid`,`cate`,`attr`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='[动态属性表]'; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `sys_dynattr` --- - -LOCK TABLES `sys_dynattr` WRITE; -/*!40000 ALTER TABLE `sys_dynattr` DISABLE KEYS */; -INSERT INTO `sys_dynattr` VALUES (1,1,'content','格列柯作品\r\n“矫饰”一词源于意大利语Maniera,意为“风格”,在中文翻译上很容易让人与“矫情”等负面词汇联系到一起,因此很多人对这个画派产生了误解。\r\n事实上,这个画派也的确很长一段时间内在西方美术史上饱受非议,它曾被认为是文艺复兴渐趋衰落后出现的一种故意追求造作形式的画派。直至后来经过很长一段时间的研究,矫饰主义才被客观地界定为是一个全新、独立且有着很大影响力的流派。'),(1,1,'cover','http://upload.art.ifeng.com/2017/0908/thumb_320_200_1504838478153.png'),(2,1,'content','

在文艺复兴和巴洛克风格之间,有一个容易被忽视的流派,他们追求变化和夸张,突破了作品一定要“完美、优雅”的限制,它被称为矫饰主义。

何为矫饰主义

14-17世纪的文艺复兴时期,在一般大众心目中,它几乎一度成为了西方艺术的代名词,《蒙娜丽莎》《最后的晚餐》《大卫》……这些名作都出自这个时期,它崇尚的是一种均衡稳定、优雅和谐之美。

达·芬奇《最后的晚餐》

在文艺复兴晚期,画家们对这种理性美感到了“审美疲劳”,且觉得在这种画法上很难再超越文艺复兴的那些大师们,根本无法施展自己的拳脚、展现自己的才华。于是,他们便有意识地创造新风格,组成了一个新的画派,创作那些惊人的、富有幻想的作品——“矫饰主义”就由此出现了。

格列柯作品

“矫饰”一词源于意大利语Maniera,意为“风格”,在中文翻译上很容易让人与“矫情”等负面词汇联系到一起,因此很多人对这个画派产生了误解。

事实上,这个画派也的确很长一段时间内在西方美术史上饱受非议,它曾被认为是文艺复兴渐趋衰落后出现的一种故意追求造作形式的画派。直至后来经过很长一段时间的研究,矫饰主义才被客观地界定为是一个全新、独立且有着很大影响力的流派。

布龙齐诺《托雷多的肖像》,1560年

矫饰主义的特征十分明显,主要表现为拉长的人体比例、不平衡的姿势、丰富夸张的表情,以及缺乏清晰的透视。在绘画的色彩上,矫饰主义一改文艺复兴时期的沉闷色调,色彩更加丰富、艳丽,还常常有一些怪异的光影效果。除此之外,在绘画题材上也多是偷窥、阴谋等相对晦涩的话题。

总的来说,矫饰主义就是毫无章法地去创造和追求一种“视觉的惊奇”。

帕米贾尼诺《圣保罗的皈依》

布龙齐诺作品

画家帕米贾尼诺的这幅《长颈圣母》可以说是矫饰主义画作的典范之一。在这幅画中,我们依旧可以感受到拉斐尔式圣母的优美,却又有着截然不同的艺术处理。

帕米贾尼诺《长颈圣母》

画面中人物的肢体都被拉长,即使是圣母手中的婴儿,也被拉到了4、5岁儿童身高的长度。艺术史家贡布里希认为,帕米贾尼诺故意加长了圣母的脖子,以形成优雅的姿态。画家似乎有意阻止我们用日常经验的标准去衡量画中的一切。

帕米贾尼诺《长颈圣母》局部

其实,在拉斐尔和米开朗基罗的中后期作品中,我们也可以看到矫饰主义的影子。他们在绘画、雕塑中追求更多的肢体动作上的变化和夸大的情绪反应,这些都与早期的矫饰主义艺术家的作品有着很高的相似之处。

米开朗基罗《昼》

说到矫饰主义,就不得不提到艺术家蓬托尔莫。他于1494年出生在意大利,是一位虔诚的宗教画家,他曾前往佛罗伦萨学画。起初,在他的早期作品中还可以看到达·芬奇、米开朗基罗等大师的影子。在他遗留下来的日记中人们发现,他对自己的工作充满着热情,但是内心呈现的状态却是十分孤独、敏感的。

蓬托尔莫《Madonna and Child with the Young St John the Baptist》

1512年,蓬托尔莫在画家沙托的门下工作时,遇到了画家罗索,由于年龄和兴趣爱好都相仿,二人很快便成为了朋友。

蓬托尔莫作品

罗索也曾在佛罗伦萨等城市工作,且艺术上受到米开朗基罗很大的影响。但是后来,罗索和蓬托尔莫二人都背离了文艺复兴兴盛时期的艺术原则,共同转向了对矫饰主义作品的创作。

罗索作品

蓬托尔莫的作品《基督被接下十字架》被誉为矫饰主义发展的核心之作。在这幅作品中,虽然表达的主题十分神圣,但是人物塞满了整个画面,人物的比例被明显拉长,且蓬托尔莫刻意压缩了画面的透视深度。画中人物的神情,每个人的脸上都带有一种焦虑感和紧张感。可以说,整幅作品与古典主义那种稳重、理性的风格完全迥异。

蓬托尔莫《基督下十字架》

但不可否认的是,蓬托尔莫的画作在色彩和设计上总能给人留下深刻的印象,比如下面这幅著名的油画《在埃及的约瑟夫》。

《在埃及的约瑟夫(Joseph in Egypt)》,1515-1518年

另外一位被称作现代绘画之父——格列柯,也同样是矫饰主义的代表人物。他的画作以弯曲瘦长的身形为特色,用色怪诞而变幻无常。在作品《天使报喜》中,人物同样遵循了矫饰主义一贯的风格——即身体被拉长。除此之外,人物背后的光影表现也一反传统绘画,明暗对比强烈,使画面充满了神秘的光芒。

埃尔·格列柯《天使报喜》,布面油画,66.5×91cm,1595年

风格影响

矫饰主义风格不仅仅体现在绘画上,作为一种风潮,它在建筑和雕塑中也同样有所体现。文艺复兴时期的建筑讲究秩序和比例,拥有严谨的立面和平面构图以及从古典建筑中继承下来的柱式系统。当时的建筑师们认为,古典柱式构图体现着和谐与理性,并同人体美有着相通之处。

维琴察圆厅别墅

矫饰主义建筑中最典型的一个例子就是位于罗马郊区的法尔尼斯别墅。

我们可以明显地看出,矫饰主义建筑追求的是一种怪诞的效果,不求整体的宏伟和雄壮,且有意地与建筑周围简陋的环境形成鲜明的对比。

法尔尼斯别墅

矫饰主义从16世纪下半叶至17世纪初,总共持续了仅仅半个世纪,无论是与前面的文艺复兴相比,还是与后面的巴洛克风格相比,都好像“差点意思”。但正是因为有矫饰主义艺术家们对突破和超越的追求,才为巴洛克风格搭建了一个稳固的阶梯。这世界上,没有绝对的稳定优雅之美,那些“矫揉造作”或许更能带来新的灵感。

有盐APP给大家送福利啦,现在加入“有盐1001种生活”微信群,就可以:

随时抢到DIY、插花、陶艺、音乐、戏剧、亲子等活动优惠券和大红包哦!!

第一时间Get各种好玩又不贵的活动!!

'),(2,1,'cover','http://upload.art.ifeng.com/2017/0908/1504837717810.jpg'),(100001,1,'abc','def'); -/*!40000 ALTER TABLE `sys_dynattr` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `sys_userrecord` --- - -DROP TABLE IF EXISTS `sys_userrecord`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `sys_userrecord` ( - `userid` int(11) NOT NULL COMMENT '[用户id]', - `username` varchar(32) NOT NULL COMMENT '[登录名]', - `password` varchar(64) NOT NULL COMMENT '[密码]', - `sex` smallint(6) DEFAULT NULL COMMENT '[性别] 10男,20女', - `phone` varchar(32) NOT NULL COMMENT '[电话号码]', - `nickname` varchar(64) DEFAULT '' COMMENT '[昵称]', - `avatar` varchar(128) DEFAULT '' COMMENT '[头像地址]', - `realname` varchar(32) DEFAULT '' COMMENT '[真实姓名]', - `email` varchar(32) DEFAULT '' COMMENT '[邮箱]', - `roleid` int(2) NOT NULL DEFAULT '0', - `site` varchar(128) DEFAULT '' COMMENT '[个人博客地址]', - `git` varchar(128) DEFAULT '' COMMENT '[码云/GitHub]', - `createtime` bigint(20) NOT NULL COMMENT '[创建时间]', - `sign` varchar(256) NOT NULL DEFAULT '' COMMENT '[签名]', - `city` varchar(64) NOT NULL DEFAULT '' COMMENT '[所在城市]', - `status` smallint(6) NOT NULL DEFAULT '10' COMMENT '[状态]-10删除 10正常', - PRIMARY KEY (`userid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `sys_userrecord` --- - -LOCK TABLES `sys_userrecord` WRITE; -/*!40000 ALTER TABLE `sys_userrecord` DISABLE KEYS */; -INSERT INTO `sys_userrecord` VALUES (100001,'@1216.top','fcea920f7412b5da7be0cf42b8c93759',10,'18515190967','绝尘','http://img.1216.top/art/u93.png','','admin@1216.top',1,'http://1216.top','https://gitee.com/tc608',1507677533071,'','云南',10),(100002,'237809797@qq.com','fcea920f7412b5da7be0cf42b8c93759',20,'13121880915','晓','http://img.1216.top/art/u36.png','','237809797@qq.com',0,NULL,'',1509196823551,'','',10),(100003,'237809796@qq.com','fcea920f7412b5da7be0cf42b8c93759',10,'','nick','http://img.1216.top/bbs/20171203103651.gif','','237809796@qq.com',1,NULL,'',1511851218332,'态度决定高度。','',10),(100004,'vip@qq.com','25d55ad283aa400af464c76d713c07ad',10,'','qq','/res/images/avatar/3.jpg','','vip@qq.com',0,NULL,'',1512954927558,'','',10),(100005,'12@qq.com','e10adc3949ba59abbe56e057f20f883e',10,'','123','/res/images/avatar/13.jpg','','12@qq.com',0,NULL,'',1512957064362,'','',10),(100006,'10000@qq.com','0d124d13699173f26a6519631cfe6e52',10,'','na','/res/images/avatar/9.jpg','','10000@qq.com',0,NULL,'',1512987234013,'','',10),(100007,'syy@qq.com','6fb327cfe8bd8268d7e1a8468d88e8d2',10,'','syy','/res/images/avatar/13.jpg','','syy@qq.com',0,NULL,'',1513305537321,'','',10),(100008,'555@qq.com','5b1b68a9abf4d2cd155c81a9225fd158',10,'','555','/res/images/avatar/19.jpg','','555@qq.com',0,NULL,'',1513355350396,'','',10),(100009,'2442669938@qq.com','25f9e794323b453885f5181f1b624d0b',10,'','iLvc','/res/images/avatar/10.jpg','','2442669938@qq.com',0,NULL,'',1513512637440,'','',10),(100010,'316034712@qq.com','af73fabc0e20d29ce37ad7bb66e7a4ff',10,'','OoxiaobinoO','/res/images/avatar/4.jpg','','316034712@qq.com',0,NULL,'',1513840912828,'','',10),(100011,'dsfds@qq.com','614ac7c72e24ff3f38f9f3fc7bdb85ad',10,'','znm','/res/images/avatar/0.jpg','','dsfds@qq.com',0,NULL,'',1519973503109,'','',10),(100012,'aaa@qq.com','d9f6e636e369552839e7bb8057aeb8da',10,'','aaa','/res/images/avatar/11.jpg','','aaa@qq.com',0,NULL,'',1519973543625,'','',10),(100013,'ceilingsliuce@163.com','09528b3dc71191355493ffdc7d2ad592',10,'','darkleo','http://img.1216.top/redbbs/20180416092232.jpg','','ceilingsliuce@163.com',1,NULL,'',1523251835728,'原本安静的环境,突然变得喧闹了。','帝都',10),(100014,'qkmc@outlook.com','f0dc2ec24679fae04aeb9b2c86b5ffdf',10,'','mrruan','http://img.1216.top/redbbs/20180413000231.jpg','','qkmc@outlook.com',0,NULL,'',1523548897975,'','',10),(100015,'540825202@qq.com','d2f30ddd1f6c85aca59040a1c9d62cc4',10,'','欧夏晴','/res/images/avatar/8.jpg','','540825202@qq.com',0,NULL,'',1525757972569,'','',10),(100016,'yjikai@163.com','c9993d00fd9a06389e4339c8ace53c14',10,'','JiMoer','/res/images/avatar/16.jpg','','yjikai@163.com',0,NULL,'',1526123922579,'','',10),(100017,'1403852318@qq.com','6132f7de6ec97fe73bb18db72116c40a',10,'','孟人二','/res/images/avatar/2.jpg','','1403852318@qq.com',0,'','',1528180576775,'','',10),(100018,'1015336092@qq.com','4607e782c4d86fd5364d7e4508bb10d9',10,'','cheng','/res/images/avatar/1.jpg','','1015336092@qq.com',0,'','',1528567851030,'以夢为馬,不负韶华。','',10); -/*!40000 ALTER TABLE `sys_userrecord` ENABLE KEYS */; -UNLOCK TABLES; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - --- Dump completed on 2018-06-17 20:22:11 diff --git a/root/_t/layout.html b/root/_tpl/layout.html similarity index 98% rename from root/_t/layout.html rename to root/_tpl/layout.html index d0f3e8d..ddacb35 100644 --- a/root/_t/layout.html +++ b/root/_tpl/layout.html @@ -426,16 +426,17 @@
  • -
  • 我的投稿
  • +
  • 我发表的贴 +
  • 我收藏的贴
  • diff --git a/root/index.html b/root/index.html index 300ac77..53de7d8 100644 --- a/root/index.html +++ b/root/index.html @@ -15,7 +15,7 @@ #for(x : top.rows??)
  • - #(x.nickname) + #(x.user.nickname)

    #if(x.status == 30) @@ -33,7 +33,7 @@

    - #(x.nickname) + #(x.user.nickname) @@ -80,7 +80,7 @@ #for(x : contents.rows??)
  • - #(x.nickname) + #(x.user.nickname)

    #if(x.status == 30) @@ -92,7 +92,7 @@

    - #(x.nickname) + #(x.user.nickname)

    @@ -205,7 +198,7 @@ #for(x : hotView.rows??)
    #(x.title) - #(x.viewnum) + #(x.viewnum)
    #else
    没有相关数据
    diff --git a/root/jie/detail.html b/root/jie/detail.html index d8086e2..07bdbfe 100644 --- a/root/jie/detail.html +++ b/root/jie/detail.html @@ -105,7 +105,7 @@
    - #(x.nickname) + #(x.user.nickname)
    @@ -179,7 +179,7 @@ #for(x : hotView.rows??)
    #(x.title) - #(x.viewnum) + #(x.viewnum)
    #else
    没有相关数据
    diff --git a/root/jie/index.html b/root/jie/index.html index 8b2bfa4..5320462 100644 --- a/root/jie/index.html +++ b/root/jie/index.html @@ -34,7 +34,7 @@
  • - #(x.nickname) + #(x.user.nickname)

    #if(x.status == 30) @@ -46,7 +46,7 @@

    - #(x.nickname) + #(x.user.nickname)
    @@ -69,11 +47,11 @@
    - #(x.nickname) + #(x.user.nickname) #end diff --git a/src/net/tccn/bbs/base/ArangoKit.java b/src/net/tccn/bbs/base/ArangoKit.java deleted file mode 100644 index 7d51e20..0000000 --- a/src/net/tccn/bbs/base/ArangoKit.java +++ /dev/null @@ -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 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 CompletableFuture 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 List find(String aql, Class clazz) { - return dbDev.query(aql, clazz).asListRemaining(); - } - - public static List find(String aql, Map para, Class clazz) { - - return dbDev.query(aql, para, clazz).asListRemaining(); - } - -} diff --git a/src/net/tccn/bbs/base/ArangoService.java b/src/net/tccn/bbs/base/ArangoService.java deleted file mode 100644 index 2543b43..0000000 --- a/src/net/tccn/bbs/base/ArangoService.java +++ /dev/null @@ -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 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 hi() { - System.out.println("colVisLog :" + colVisLog.exists()); - String aql = String.format("for d in %s limit 10 return d", chDev.apply(VIS_LOG)); - List visLogs = db.query(aql, Map.class).asListRemaining(); - return visLogs; - } - - public static CompletableFuture 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 List find(String aql, Class clazz) { - return db.query(aql, clazz).asListRemaining(); - } - - public static List find(String aql, Map para, Class clazz) { - - return db.query(aql, para, clazz).asListRemaining(); - } - -} diff --git a/src/net/tccn/bbs/base/BaseEntity.java b/src/net/tccn/bbs/base/BaseEntity.java new file mode 100644 index 0000000..1870f9b --- /dev/null +++ b/src/net/tccn/bbs/base/BaseEntity.java @@ -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); + } +} diff --git a/src/net/tccn/bbs/base/BaseService.java b/src/net/tccn/bbs/base/BaseService.java index dbd2de8..bb67e80 100644 --- a/src/net/tccn/bbs/base/BaseService.java +++ b/src/net/tccn/bbs/base/BaseService.java @@ -1,16 +1,12 @@ package net.tccn.bbs.base; -import com.arangodb.Predicate; import org.redkale.net.http.RestMapping; +import org.redkale.service.RetResult; import org.redkale.service.Service; import org.redkale.source.CacheSource; import org.redkale.source.DataSource; 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. @@ -19,14 +15,13 @@ public class BaseService implements Service { protected final int sessionExpireSeconds = 7 * 24 * 60 * 60; - @Resource(name = "property.isDev") - public boolean isDev = true; + protected final static RetResult RET_SUCCESS = RetResult.success(); - @Resource(name = "SERVER_ROOT") - protected File webroot; + /*@Resource(name = "SERVER_ROOT") + protected File webroot;*/ @Resource(name = "redbbs") - protected DataSource source; + protected DataSource dataSource; /* 使用redis 代码中配置此处即可 @Resource(name = "redis")*/ @@ -38,35 +33,12 @@ public class BaseService implements Service { 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) public DataSource getSource() { - return source; + return dataSource; } - @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; + protected RetResult retError(String info) { + return new RetResult<>(-1, info); } - } diff --git a/src/net/tccn/bbs/base/BaseServlet.java b/src/net/tccn/bbs/base/BaseServlet.java index 51db0ee..ddf0aa3 100644 --- a/src/net/tccn/bbs/base/BaseServlet.java +++ b/src/net/tccn/bbs/base/BaseServlet.java @@ -1,12 +1,13 @@ package net.tccn.bbs.base; import com.jfinal.kit.Kv; -import net.tccn.bbs.base.entity.VisLog; -import net.tccn.bbs.base.kit.RetCodes; -import net.tccn.bbs.base.user.UserInfo; -import net.tccn.bbs.base.user.UserService; +import net.tccn.bbs.base.util.RetCodes; +import net.tccn.bbs.base.util.TaskQueue; import net.tccn.bbs.comment.CommentService; 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.source.FilterExpress; import org.redkale.source.FilterNode; @@ -17,12 +18,11 @@ import java.io.File; import java.io.IOException; 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. */ -@HttpUserType(UserInfo.class) public class BaseServlet extends HttpServlet { protected static final boolean winos = System.getProperty("os.name").contains("Window"); @@ -59,6 +59,7 @@ public class BaseServlet extends HttpServlet { if (sessionid != null) { request.setCurrentUser(userService.current(sessionid)); currentid = userService.currentUserid(sessionid); + request.setCurrentUserid(currentid); } String uri = request.getRequestURI(); @@ -156,7 +157,9 @@ public class BaseServlet extends HttpServlet { public int getParaToInt(HttpRequest request, int index) { int n = 0; String para = getPara(request, index); - if (para == null || "".equals(para)) n = 0; + if (para == null || "".equals(para)) { + n = 0; + } try { n = Integer.parseInt(para); } catch (Exception e) { diff --git a/src/net/tccn/bbs/base/EnjoyRender.java b/src/net/tccn/bbs/base/TplRender.java similarity index 86% rename from src/net/tccn/bbs/base/EnjoyRender.java rename to src/net/tccn/bbs/base/TplRender.java index 41a0a65..8d67fd5 100644 --- a/src/net/tccn/bbs/base/EnjoyRender.java +++ b/src/net/tccn/bbs/base/TplRender.java @@ -3,8 +3,8 @@ package net.tccn.bbs.base; import com.jfinal.kit.Kv; import com.jfinal.template.Engine; import com.jfinal.template.Template; -import net.tccn.bbs.base.kit.EJ; -import net.tccn.bbs.base.user.UserInfo; +import net.tccn.bbs.base.util.EJ; +import net.tccn.bbs.user.UserInfo; import org.redkale.convert.Convert; import org.redkale.net.http.*; import org.redkale.util.AnyValue; @@ -16,7 +16,7 @@ import java.util.Map; /** * Created by JUECHENG at 2018/1/30 0:18. */ -public class EnjoyRender implements HttpRender { +public class TplRender implements HttpRender { @Resource(name = "SERVER_ROOT") protected File webroot; @@ -25,9 +25,10 @@ public class EnjoyRender implements HttpRender { @Override public void init(HttpContext context, AnyValue config) { + engine.setDevMode(true); engine.setBaseTemplatePath(webroot.getPath()); engine.addSharedObject("EJ", new EJ()); - engine.addSharedFunction("/_t/layout.html"); + engine.addSharedFunction("/_tpl/layout.html"); } @Override diff --git a/src/net/tccn/bbs/base/UF.java b/src/net/tccn/bbs/base/UF.java deleted file mode 100644 index 5148f4e..0000000 --- a/src/net/tccn/bbs/base/UF.java +++ /dev/null @@ -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 { - int getUserid(); - - I createInfo(); -} diff --git a/src/net/tccn/bbs/base/Utils.java b/src/net/tccn/bbs/base/Utils.java new file mode 100644 index 0000000..14455be --- /dev/null +++ b/src/net/tccn/bbs/base/Utils.java @@ -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 = "]*?>[\\s\\S]*?<\\/script>"; //定义script的正则表达式 + String regEx_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[] 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 reproduceMap = new HashMap<>(); + + /** + * @param d 目标对象 + * @param s 源对象 + * @param 目标对象的数据类型 + * @param 源对象的数据类型 + * @return + */ + public static D copy(D d, S s) { + String reproductKey = d.getClass().getName() + "_" + s.getClass().getName(); + + Reproduce reproduce = reproduceMap.get(reproductKey); + if (reproduce == null) { + if (reproduce == null) { + reproduceMap.put(reproductKey, reproduce = (Reproduce) Reproduce.create(d.getClass(), s.getClass())); + } + } + + return reproduce.apply(d, s); + } + + + public static List parseHtmlImage(String html) { + Pattern pattern = Pattern.compile("(?<=( ls = new ArrayList<>(); + while (match.find()) { + ls.add(match.group()); + } + return ls; + } + + /** + * @param rs + * @param type + * @param + * @return + */ + public static List queryList(ResultSet rs, Class 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 + * @return + */ + public static T findColumn(ResultSet rs, Class 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 List mix(List 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 List randomItems(List list, int len) { + List randoms = getRandoms(list.size(), len); + List 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 getRandoms(int max, int len) { + Set randoms = new HashSet<>(); + Random random = new Random(); + while (randoms.size() < len && randoms.size() < max) { + randoms.add(random.nextInt(max)); + } + List 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 Map toMap(Collection list, Function fun) { + Map map = new HashMap<>(list.size()); + for (V v : list) { + if (v == null) { + continue; + } + map.put(fun.apply(v), v); + } + return map; + } + + public static Map toMap(Collection list, Function fun, Function fun2) { + Map 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 List toList(Collection list, Function fun) { + if (list == null || list.isEmpty()) { + return new ArrayList<>(); + } + List list1 = new ArrayList<>(); + list.forEach(x -> list1.add(fun.apply(x))); + return list1; + } + + public static List toList(Sheet sheet, Function fun) { + List list = new ArrayList<>(); + sheet.forEach(x -> list.add(fun.apply(x))); + return list; + } + + public static Set toSet(Collection list, Function fun) { + if (list == null || list.isEmpty()) { + return new HashSet<>(); + } + Set set = new HashSet<>(list.size()); + list.forEach(x -> set.add(fun.apply(x))); + return set; + } + + public static Set toSet(Sheet sheet, Function fun) { + Set set = new HashSet<>(); + sheet.forEach(x -> set.add(fun.apply(x))); + return set; + } + + public static List filter(Collection list, Predicate predicate) { + if (list == null || list.isEmpty()) { + return new ArrayList<>(); + } + List list1 = new ArrayList<>(list.size()); + list.forEach(x -> { + if (!predicate.test(x)) { + return; + } + + list1.add(x); + }); + + return list1; + } + + public static List filterToList(Collection list, Predicate predicate, Function fun) { + if (list == null || list.isEmpty()) { + return new ArrayList<>(); + } + List list1 = new ArrayList<>(list.size()); + + list.forEach(x -> { + if (!predicate.test(x)) { + return; + } + + list1.add(fun.apply(x)); + }); + + return list1; + } + + public static Map> group(Collection list, Function fun) { + if (list == null || list.isEmpty()) { + return new HashMap<>(); + } + return list.stream().collect(Collectors.groupingBy(fun)); + } + + public static Map> group(Collection list, Function fun, Function fun2) { + if (list == null || list.isEmpty()) { + return new HashMap<>(); + } + Map> group = group(list, fun); + Map> _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(""); + if (bodyIndex > -1) { + bodyIndex = bodyIndex + 6; + int lastIndexOf = s.lastIndexOf(""); + 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 removeFields, boolean encode) { + Class c = o.getClass(); + Field[] fields = c.getDeclaredFields(); + Map 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 convertHttpParams(map, encode); + } + + @Comment("GET请求参数转换为字符,结果:p1=v1&p2=v2&p3=v3") + public static String convertHttpParams(Map map) { + if (map == null || map.isEmpty()) { + return ""; + } + Set sortSet = new TreeSet(); + for (Map.Entry 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 convertToMap(Object o, List removeFields) { + Class c = o.getClass(); + List 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 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 map, String... excludeKeys) { + List excludeList = List.of(excludeKeys); + LinkedHashMap 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 Sheet querySheetBySql(DataSource dataSource, String sql, Flipper flipper, Class 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 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(); + } + +} diff --git a/src/net/tccn/bbs/base/bean/ActLogBean.java b/src/net/tccn/bbs/base/bean/ActLogBean.java deleted file mode 100644 index eca8eb8..0000000 --- a/src/net/tccn/bbs/base/bean/ActLogBean.java +++ /dev/null @@ -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); - } -} diff --git a/src/net/tccn/bbs/base/iface/C.java b/src/net/tccn/bbs/base/iface/C.java deleted file mode 100644 index c70fcca..0000000 --- a/src/net/tccn/bbs/base/iface/C.java +++ /dev/null @@ -1,9 +0,0 @@ -package net.tccn.bbs.base.iface; - -/** - * 创建信息 - * Created by liangxianyou at 2018/6/16 17:43. - */ -public interface C { - I createInfo(); -} diff --git a/src/net/tccn/bbs/base/iface/CI.java b/src/net/tccn/bbs/base/iface/CI.java deleted file mode 100644 index a3acf03..0000000 --- a/src/net/tccn/bbs/base/iface/CI.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.tccn.bbs.base.iface; - -/** - * Created by liangxianyou at 2018/6/16 18:39. - */ -public interface CI { -} diff --git a/src/net/tccn/bbs/base/iface/CService.java b/src/net/tccn/bbs/base/iface/CService.java deleted file mode 100644 index 0a7ed91..0000000 --- a/src/net/tccn/bbs/base/iface/CService.java +++ /dev/null @@ -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 { - - @RestMapping(ignore = true) - default Sheet createInfo(Sheet fSheet) { - Sheet sheet = new Sheet<>(); - - if (fSheet == null || fSheet.getTotal() < 1) { - sheet.setTotal(0); - sheet.setRows(new ArrayList<>()); - } else { - int total = (int) fSheet.getTotal(); - List rows = new ArrayList<>(total); - fSheet.forEach(x -> rows.add((I) x.createInfo())); - - sheet.setTotal(total); - sheet.setRows(rows); - } - - return sheet; - } -} diff --git a/src/net/tccn/bbs/base/iface/UI.java b/src/net/tccn/bbs/base/iface/UI.java deleted file mode 100644 index d91e65d..0000000 --- a/src/net/tccn/bbs/base/iface/UI.java +++ /dev/null @@ -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 { - - //抽象方法 - 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(); - } -} diff --git a/src/net/tccn/bbs/base/iface/UIService.java b/src/net/tccn/bbs/base/iface/UIService.java deleted file mode 100644 index 8ae0f6f..0000000 --- a/src/net/tccn/bbs/base/iface/UIService.java +++ /dev/null @@ -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 extends CService { - - DataSource getSource(); - - @RestMapping(ignore = true) - default Sheet setIUser(Sheet sheet) { - int[] userids = sheet.stream().mapToInt(I::getUserid).toArray(); - - List 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); - } - -} diff --git a/src/net/tccn/bbs/base/kit/LxyKit.java b/src/net/tccn/bbs/base/kit/LxyKit.java deleted file mode 100644 index d209efa..0000000 --- a/src/net/tccn/bbs/base/kit/LxyKit.java +++ /dev/null @@ -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 = "]*?>[\\s\\S]*?<\\/script>"; //定义script的正则表达式 - String regEx_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[] 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; - } -} diff --git a/src/net/tccn/bbs/base/user/UserService.java b/src/net/tccn/bbs/base/user/UserService.java deleted file mode 100644 index 478d9a9..0000000 --- a/src/net/tccn/bbs/base/user/UserService.java +++ /dev/null @@ -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 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 query(Flipper flipper, @RestParam(name = "bean", comment = "过滤条件") final UserBean userBean) { - Sheet 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 lastReg() { - Sheet users = source.querySheet(UserRecord.class - , SelectColumn.includes("userid", "nickname", "avatar", "createtime") - , new Flipper().sort("createtime DESC").limit(8) - , FilterNode.create("status", 10)); - - Sheet infos = new Sheet<>(); - ArrayList 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 userIds = source.queryColumnList("userid", UserRecord.class, FilterNode.create("roleid", 1)); - for (Integer x : userIds) { - if (userid == x) { - return true; - } - } - - return false; - } -} diff --git a/src/net/tccn/bbs/base/kit/EJ.java b/src/net/tccn/bbs/base/util/EJ.java similarity index 93% rename from src/net/tccn/bbs/base/kit/EJ.java rename to src/net/tccn/bbs/base/util/EJ.java index 9b0eff4..95de62c 100644 --- a/src/net/tccn/bbs/base/kit/EJ.java +++ b/src/net/tccn/bbs/base/util/EJ.java @@ -1,4 +1,4 @@ -package net.tccn.bbs.base.kit; +package net.tccn.bbs.base.util; import org.redkale.net.http.RestService; diff --git a/src/net/tccn/bbs/base/util/Kv.java b/src/net/tccn/bbs/base/util/Kv.java new file mode 100644 index 0000000..1db9553 --- /dev/null +++ b/src/net/tccn/bbs/base/util/Kv.java @@ -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 extends LinkedHashMap { + + 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 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 set(K k, V v) { + put(k, v); + return this; + } + + public Kv putAll(Kv 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 List toKv(Collection 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 toBean(Class type) { + return toBean(this, type); + } + + // 首字母大写 + private static Function upFirst = (s) -> { + return s.substring(0, 1).toUpperCase() + s.substring(1); + }; + + private static Predicate 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 toAs(Object v, Class 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 toBean(Map map, Class clazz) { + //按照方法名 + 类型寻找, + //按照方法名 寻找 + //+ + Object obj = null; + try { + obj = clazz.getDeclaredConstructor().newInstance(); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | + NoSuchMethodException e) { + new IllegalArgumentException("创建对象实列失败", e); // 检查clazz是否有无参构造 + } + + for (String k : (Set) 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); + } +} \ No newline at end of file diff --git a/src/net/tccn/bbs/base/kit/RetCodes.java b/src/net/tccn/bbs/base/util/RetCodes.java similarity index 98% rename from src/net/tccn/bbs/base/kit/RetCodes.java rename to src/net/tccn/bbs/base/util/RetCodes.java index ca13d5f..cf73b44 100644 --- a/src/net/tccn/bbs/base/kit/RetCodes.java +++ b/src/net/tccn/bbs/base/util/RetCodes.java @@ -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.RetResult; diff --git a/src/net/tccn/bbs/base/TaskQueue.java b/src/net/tccn/bbs/base/util/TaskQueue.java similarity index 77% rename from src/net/tccn/bbs/base/TaskQueue.java rename to src/net/tccn/bbs/base/util/TaskQueue.java index 2526ebc..344d444 100644 --- a/src/net/tccn/bbs/base/TaskQueue.java +++ b/src/net/tccn/bbs/base/util/TaskQueue.java @@ -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.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.base.BaseService; import net.tccn.bbs.content.ContentInfo; 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.RestService; -import org.redkale.source.ColumnValue; -import org.redkale.source.FilterExpress; -import org.redkale.source.FilterNode; import org.redkale.source.Flipper; -import org.redkale.util.Comment; +import org.redkale.util.AnyValue; import org.redkale.util.Sheet; -import org.redkale.util.Utility; import javax.annotation.Resource; -import java.util.*; +import java.util.Map; import java.util.concurrent.LinkedBlockingQueue; -import java.util.function.Function; /** * Created by liangxianyou at 2018/6/20 22:54. @@ -35,6 +28,25 @@ public class TaskQueue extends BaseService implements Runnable 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() { new Thread(this).start(); } @@ -50,32 +62,12 @@ public class TaskQueue extends BaseService implements Runnable } @Override - @RestMapping(ignore = true, comment = "独立线程,用户访问行为记录到数据库") + @RestMapping(ignore = true, comment = "") 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) { String aql = String.format("for d in vis_log_dev\n" + @@ -90,11 +82,11 @@ public class TaskQueue extends BaseService implements Runnable int contentid = Integer.parseInt(uri.replace("/jie/detail/", "")); source.updateColumn(Content.class, contentid, ColumnValue.inc("viewnum", 1)); } - } + }*/ @RestMapping(ignore = true, comment = "访问热帖数据") public Sheet hotView(String sessionid) { - int limit = 8; + /*int limit = 8; String cacheKey = "hotView"; Object ids = cacheSource.get(cacheKey); if (isEmpty.test(ids)) { @@ -141,7 +133,9 @@ public class TaskQueue extends BaseService implements Runnable } else if (!userService.isAdmin(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 extends BaseService implements Runnable }); int[] userids = LxyKit.listToArray(uids, new int[uids.size()]); - List records = source.queryList(UserRecord.class, FilterNode.create("userid", FilterExpress.IN, userids)); + List records = source.queryList(UserDetail.class, FilterNode.create("userid", FilterExpress.IN, userids)); 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("avatar", record.getAvatar()); }); diff --git a/src/net/tccn/bbs/comment/Comment.java b/src/net/tccn/bbs/comment/Comment.java deleted file mode 100644 index 858173d..0000000 --- a/src/net/tccn/bbs/comment/Comment.java +++ /dev/null @@ -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 { - - @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; - } -} diff --git a/src/net/tccn/bbs/comment/CommentInfo.java b/src/net/tccn/bbs/comment/CommentInfo.java index 476b90f..598dfe4 100644 --- a/src/net/tccn/bbs/comment/CommentInfo.java +++ b/src/net/tccn/bbs/comment/CommentInfo.java @@ -2,21 +2,21 @@ package net.tccn.bbs.comment; import lombok.Getter; import lombok.Setter; -import net.tccn.bbs.base.iface.CI; -import net.tccn.bbs.base.iface.UI; -import net.tccn.bbs.base.user.UserRecord; -import org.redkale.convert.json.JsonConvert; +import net.tccn.bbs.base.BaseEntity; +import net.tccn.bbs.user.UserInfo; -import javax.persistence.Column; -import java.io.Serializable; +import javax.persistence.*; /** * @author lxyer */ @Setter @Getter -public class CommentInfo implements UI, Serializable, CI { +@Cacheable(interval = 5 * 60) +@Table(catalog = "redbbs", name = "commentinfo", comment = "[评论表]") +public class CommentInfo extends BaseEntity { + @Id @Column(comment = "[评论id]") private int commentid; @@ -27,7 +27,7 @@ public class CommentInfo implements UI, Serializable, CI, Serializable, CI { +public class CommentService extends BaseService { + + @Resource + private UserService userService; @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(); //数据校验 - if (contentid < 1) - return RetCodes.retResult(RET_COMMENT_PARA_ILLEGAL, "评论参数无效"); - if (comment.getContent() == null) - return RetCodes.retResult(RET_COMMENT_CONTENT_ILLEGAL, "评论内容无效"); - String content = LxyKit.delHTMLTag(comment.getContent()); - if (content.isEmpty()) + if (contentid < 1) { + return retError("评论参数无效"); + } + if (Utils.isEmpty(comment.getContent())) { + return retError("评论内容无效"); + } + String content = Utils.delHTMLTag(comment.getContent()); + if (content.isEmpty()) { return RetCodes.retResult(RET_COMMENT_CONTENT_ILLEGAL, "评论内容无效"); + } if (comment.getCommentid() < 1) { - int userid = currentUserid(sessionid); comment.setUserid(userid); comment.setCreatetime(System.currentTimeMillis()); //todo:@用户处理 - source.insert(comment); + dataSource.insert(comment); //update replyNum - int count = source.getNumberResult(Comment.class, FilterFunc.COUNT, "commentid", FilterNode.create("contentid", contentid)).intValue(); - source.updateColumn(Content.class, contentid, ColumnValue.create("replynum", count)); + int count = dataSource.getNumberResult(CommentInfo.class, FilterFunc.COUNT, "commentid", FilterNode.create("contentid", contentid)).intValue(); + dataSource.updateColumn(ContentInfo.class, contentid, ColumnValue.create("replynum", count)); } else { - source.updateColumn(comment, SelectColumn.includes("content")); + dataSource.updateColumn(comment, SelectColumn.includes("content")); } return RetResult.success(); } @RestMapping(name = "query", auth = false, comment = "查询评论") - public Sheet query(@RestSessionid String sessionid, int contentId, Flipper flipper) { - int userid = currentUserid(sessionid); + public Sheet query(@RestUserid int userid, Flipper flipper, int contentid) { + flipper.setSort("supportnum DESC, commentid ASC"); // 按照 点赞数排序,相同点赞数按照 id(时间先后排序) + Sheet comments = dataSource.querySheet(CommentInfo.class, flipper, FilterNode.create("contentid", contentid)); - flipper.setSort("supportnum DESC,commentid ASC"); - Sheet comments = source.querySheet(Comment.class, flipper, FilterNode.create("contentid", contentId)); + // 设置用户信息 + Set userids = Utils.toSet(comments, x -> x.getUserid()); + Map userMap = userService.queryUserMap(userids); + comments.forEach(x -> x.setUser(userMap.get(x.getUserid()))); - Sheet infos = createInfo(comments); - setIUser(infos); - - //用户点赞的评论 - 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 hadSupport = source.queryColumnList("tid", ActLog.class, node); - - infos.forEach(x -> { - x.setHadsupport(hadSupport.contains(x.getCommentid()) ? 1 : -1);// - }); + // 访客访问:不需要设置用户状态信息,返回 + if (userid == 0) { + return comments; } - return infos; + // 当前用户为登录用户:处理用户点赞状态 + List 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 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 queryByUserid(int userid) { - Sheet comments = source.querySheet(Comment.class, new Flipper().sort("createtime DESC"), FilterNode.create("userid", userid)); + Sheet comments = dataSource.querySheet(CommentInfo.class, new Flipper("createtime DESC"), FilterNode.create("userid", userid)); - int[] contentIds = comments.stream().mapToInt(x -> x.getCommentid()).toArray(); - List contents = source.queryList(Content.class, SelectColumn.includes("contentid", "title"), FilterNode.create("contentid", FilterExpress.IN, contentIds)); + Set contentids = Utils.toSet(comments, x -> x.getContentid()); + + List contents = dataSource.queryList(ContentInfo.class, SelectColumn.includes("contentid", "title"), FilterNode.create("contentid", IN, (Serializable) contentids)); + Map contentMap = Utils.toMap(contents, x -> x.getContentid()); + + // 设置用户信息 + Set userids = Utils.toSet(comments, x -> x.getUserid()); + Map 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 infos = createInfo(comments); - infos.forEach(x -> { - Content content = contents.stream().filter(k -> k.getContentid() == x.getContentid()).findFirst().orElse(new Content()); x.setTitle(content.getTitle()); }); - return infos; + return comments; } @RestMapping(name = "support", comment = "点赞") - public RetResult support(@RestSessionid String sessionid, int commentid, int ok) { - int userid = currentUserid(sessionid); - - source.findAsync(ActLog.class, FilterNode.create("userid", userid).and("tid", commentid).and("cate", 10)).thenAccept(actLog -> { + public RetResult support(@RestUserid int userid, int commentid, int ok) { + dataSource.findAsync(ActLog.class, FilterNode.create("userid", userid).and("tid", commentid).and("cate", 10)).thenAccept(actLog -> { if (actLog == null && ok == 1) { actLog = new ActLog(10, commentid, userid); actLog.setCreatetime(System.currentTimeMillis()); - source.insert(actLog); + dataSource.insert(actLog); } else if (actLog != null && actLog.getStatus() != ok) { actLog.setStatus((short) -10); - source.update(actLog); + dataSource.update(actLog); }/*else { return RetCodes.retResult(-1, ok == 1 ? "已赞" : "已取消赞"); }*/ - int count = source.getNumberResult(ActLog.class, FilterFunc.COUNT, 0, "logid", FilterNode.create("tid", commentid).and("status", 10)).intValue(); - source.updateColumn(Comment.class, commentid, "supportnum", count); + int count = dataSource.getNumberResult(ActLog.class, FilterFunc.COUNT, 0, "logid", FilterNode.create("tid", commentid).and("status", 10)).intValue(); + dataSource.updateColumn(CommentInfo.class, commentid, "supportnum", count); }); return RetResult.success(); @@ -123,12 +143,11 @@ public class CommentService extends BaseService implements UIService commentRank() { - Flipper flipper = new Flipper().limit(8); - source.querySheet(Comment.class, flipper, FilterNode.create("userid", FilterExpress.IN)); + dataSource.querySheet(CommentInfo.class, new Flipper(8), FilterNode.create("userid", IN)); - Map numberMap = source.getNumberMap(Comment.class, FilterFuncColumn.create(FilterFunc.DISTINCTCOUNT, "userid")); + Map numberMap = dataSource.getNumberMap(CommentInfo.class, FilterFuncColumn.create(FilterFunc.DISTINCTCOUNT, "userid")); return numberMap; } diff --git a/src/net/tccn/bbs/content/Content.java b/src/net/tccn/bbs/content/Content.java deleted file mode 100644 index 17d779d..0000000 --- a/src/net/tccn/bbs/content/Content.java +++ /dev/null @@ -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 { - - @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; - } -} diff --git a/src/net/tccn/bbs/content/ContentBean.java b/src/net/tccn/bbs/content/ContentBean.java deleted file mode 100644 index 3a7752c..0000000 --- a/src/net/tccn/bbs/content/ContentBean.java +++ /dev/null @@ -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); - } -} diff --git a/src/net/tccn/bbs/content/ContentInfo.java b/src/net/tccn/bbs/content/ContentInfo.java index 5524bc5..41d508f 100644 --- a/src/net/tccn/bbs/content/ContentInfo.java +++ b/src/net/tccn/bbs/content/ContentInfo.java @@ -1,50 +1,95 @@ package net.tccn.bbs.content; +import com.jfinal.kit.Kv; import lombok.Getter; import lombok.Setter; -import net.tccn.bbs.base.iface.CI; -import net.tccn.bbs.base.iface.UI; -import net.tccn.bbs.base.user.UserRecord; -import org.redkale.convert.ConvertColumn; +import net.tccn.bbs.base.BaseEntity; +import net.tccn.bbs.user.UserInfo; -import java.io.Serializable; +import javax.persistence.*; /** - * Created by Lxy at 2017/11/26 20:52. + * @author lxyer */ @Setter @Getter -public class ContentInfo implements UI, Serializable, CI { +@Cacheable(interval = 5 * 60) +@Table(catalog = "redbbs", name = "contentinfo", comment = "[内容表]") +public class ContentInfo extends BaseEntity { + @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 = ""; - private String createtime; - private int cate; - private int type; + + @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; - private int wonderful; - private int top; - private int solved; - private int status = 10; - private String typename; - private int hadcollect = -1; - //----------- - private UserRecord user; + @Column(comment = "[精] 10否,20是") + private short wonderful = 10; - @ConvertColumn(ignore = true) - @Override - public UserRecord getUser() { - return user; + @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; + + @Transient + private int collected; + + @Transient + private UserInfo user; + + public String getTypename() { + return (String) types.getOrDefault((int) type, ""); } - @Override - public ContentInfo setUser(UserRecord user) { - this.user = user; - return this; - } + + private static final Kv types = Kv.by(10, "求助").set(20, "分享").set(30, "讨论").set(40, "公告").set(50, "动态"); + + /*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; + }*/ } diff --git a/src/net/tccn/bbs/content/ContentService.java b/src/net/tccn/bbs/content/ContentService.java index 0ccada4..7d56aaa 100644 --- a/src/net/tccn/bbs/content/ContentService.java +++ b/src/net/tccn/bbs/content/ContentService.java @@ -2,195 +2,194 @@ package net.tccn.bbs.content; import com.jfinal.kit.Kv; import net.tccn.bbs.base.BaseService; -import net.tccn.bbs.base.entity.ActLog; -import net.tccn.bbs.base.iface.UIService; -import net.tccn.bbs.base.kit.RetCodes; -import net.tccn.bbs.base.user.UserInfo; -import net.tccn.bbs.base.user.UserService; +import net.tccn.bbs.base.Utils; +import net.tccn.bbs.base.util.RetCodes; +import net.tccn.bbs.user.UserInfo; +import net.tccn.bbs.user.UserService; +import net.tccn.bbs.vislog.entity.ActLog; import org.redkale.net.http.HttpScope; import org.redkale.net.http.RestMapping; 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.source.FilterExpress; -import org.redkale.source.FilterFunc; -import org.redkale.source.FilterNode; -import org.redkale.source.Flipper; +import org.redkale.source.*; import org.redkale.util.Comment; import org.redkale.util.SelectColumn; import org.redkale.util.Sheet; 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. */ @RestService(name = "content", comment = "文章帖子服务") -public class ContentService extends BaseService implements UIService { +public class ContentService extends BaseService { @Resource - protected UserService userService; + private UserService userService; @Comment("根据条件查询帖子数据") - public Sheet contentQuery(Flipper flipper, FilterNode filterNode) { - Sheet contents = source.querySheet(Content.class, flipper, filterNode); + public Sheet contentQuery(Flipper flipper, FilterNode node) { + Sheet contents = dataSource.querySheet(ContentInfo.class, flipper, node); - createInfo(contents); - Sheet infos = createInfo(contents); - setIUser(infos); + // 设置用户信息 + Set userids = Utils.toSet(contents, x -> x.getUserid()); + Map userMap = userService.queryUserMap(userids); + contents.forEach(x -> x.setUser(userMap.get(x.getUserid()))); - return infos; + return contents; } @RestMapping(name = "query", auth = false, comment = "内容列表") - public Sheet query(Flipper flipper, String actived, String sessionid) { - UserInfo current = userService.current(sessionid); - int currentid = current == null ? 0 : current.getUserid(); - - FilterNode filterNode = FilterNode.create("status", FilterExpress.NOTEQUAL, -10); + public Sheet query(@RestUserid int userid, Flipper flipper, String actived) { + FilterNode node = FilterNode.create("status", NOTEQUAL, -10); switch (actived) { - case "top": - filterNode.and("top", FilterExpress.GREATERTHANOREQUALTO, 20); - break; - case "untop": - filterNode.and("top", 10); - break; - case "unsolved": - filterNode.and("solved", 10); - break; - case "solved": - filterNode.and("solved", 20); - break; - case "wonderful": - filterNode.and("wonderful", FilterExpress.GREATERTHANOREQUALTO, 20); - break; + case "top" -> node.and("top", GREATERTHANOREQUALTO, 20); + case "untop" -> node.and("top", 10); + case "unsolved" -> node.and("solved", 10); + case "solved" -> node.and("solved", 20); + case "wonderful" -> node.and("wonderful", GREATERTHANOREQUALTO, 20); } - if (!userService.isAdmin(currentid)) {//私密贴:非管理员限制查看 - filterNode.and(FilterNode.create("status", FilterExpress.NOTEQUAL, 30).or(FilterNode.create("status", 30).and("userid", currentid))); - } else if (currentid <= 0) {//私密贴:未登录限制查看 - filterNode.and("status", FilterExpress.NOTEQUAL, 30); + if (!userService.isAdmin(userid)) {//私密贴:非管理员限制查看 + node.and(FilterNode.create("status", NOTEQUAL, 30).or(FilterNode.create("status", 30).and("userid", userid))); + } else if (userid <= 0) {//私密贴:未登录限制查看 + node.and("status", NOTEQUAL, 30); } - return contentQuery(flipper, filterNode); + return contentQuery(flipper, node); } @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) { - return RetCodes.retResult(-1, "少年你的文章标题太长啦,精简化标题吧,为了更好的SEO长度请少于64个字节"); + if (info.getTitle().isEmpty() || info.getTitle().length() > 64) { + return retError("少年你的文章标题太长啦,精简化标题吧,为了更好的SEO长度请少于64个字节"); } - int userid = user.getUserid(); - - if (bean.getContentid() < 1) { - int maxId = source.getNumberResult(Content.class, FilterFunc.MAX, 10_0000, "contentid").intValue(); - bean.setContentid(maxId + 1); - bean.setCreatetime(System.currentTimeMillis()); - bean.setUserid(userid); - - source.insert(bean); + if (info.getContentid() < 1) { + synchronized (this) { + int maxid = dataSource.getNumberResult(ContentInfo.class, FilterFunc.MAX, 10_0000, "contentid").intValue(); + info.setContentid(maxid + 1); + } + info.setCreatetime(System.currentTimeMillis()); + info.setUserid(userid); + dataSource.insert(info); } else { - source.findAsync(Content.class, bean.getContentid()).thenAccept(x -> { + dataSource.findAsync(ContentInfo.class, info.getContentid()).thenAccept(x -> { 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 = "帖子详情") - public ContentInfo info(UserInfo user, int contentid) { - int userId = user != null ? user.getUserid() : 0; + public ContentInfo info(@RestUserid int userid, int contentid) { + // 异步更新帖子阅读数 + dataSource.updateColumnAsync(ContentInfo.class, contentid, ColumnValue.inc("viewnum", 1)); - Content content = source.find(Content.class, contentid); - 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); + ContentInfo content = dataSource.find(ContentInfo.class, contentid); + if (content == null) { + return null; } - 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 = "帖子收藏") - public RetResult collect(@RestSessionid String sessionid, int contentid, int ok) { - int userid = userService.currentUserid(sessionid);//不会为空 + public RetResult collect(@RestUserid int userid, int contentid, int ok) { - 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) { actLog = new ActLog(20, contentid, userid);//.cate(2).tid(contentId).userId(userId); actLog.setCreatetime(System.currentTimeMillis()); - source.insert(actLog); + dataSource.insert(actLog); } else if (actLog != null && actLog.getStatus() != ok) { actLog.setStatus((short) ok); actLog.setCreatetime(System.currentTimeMillis()); - source.update(actLog); + dataSource.update(actLog); } else { return RetCodes.retResult(-1, ok == 1 ? "已收藏" : "已取消收藏"); } - return RetResult.success(); + return RET_SUCCESS; } @RestMapping(name = "collectquery", comment = "收藏列表") - public Sheet collectQuery(@RestSessionid String sessionid) { - int userid = currentUserid(sessionid); - - Flipper flipper = new Flipper().sort("createtime DESC"); + public Sheet collectQuery(@RestUserid int userid) { + Flipper flipper = new Flipper("createtime DESC"); FilterNode filterNode = FilterNode.create("cate", 20).and("status", 10).and("userid", userid); - Sheet actLogs = source.querySheet(ActLog.class, SelectColumn.includes("tid", "createtime"), flipper, filterNode); + Sheet actLogs = dataSource.querySheet(ActLog.class, SelectColumn.includes("tid", "createtime"), flipper, filterNode); int[] contentids = actLogs.stream().mapToInt(x -> x.getTid()).toArray(); - Sheet contents = source.querySheet(Content.class, SelectColumn.includes("contentid", "title"), flipper.sort(null), FilterNode.create("contentid", FilterExpress.IN, contentids)); + Sheet contents = dataSource.querySheet(ContentInfo.class, SelectColumn.includes("contentid", "title"), flipper.sort(null), FilterNode.create("contentid", FilterExpress.IN, contentids)); - Sheet infos = createInfo(contents); + // 设置用户信息 + Set userids = Utils.toSet(contents, x -> x.getUserid()); + Map userMap = userService.queryUserMap(userids); + contents.forEach(x -> x.setUser(userMap.get(x.getUserid()))); - return infos; + return contents; } @RestMapping(name = "set", comment = "便捷的修改内容") - public RetResult contentSet(@RestSessionid String sessionid, + public RetResult contentSet(UserInfo user, @Comment("帖子id") int id, @Comment("status|top|wonderful") String field, @Comment("目标修改值") short v) { - //只有管理员可访问 - int userid = currentUserid(sessionid); + int userid = user.getUserid(); + //身份验证 后修改内容 - source.findAsync(Content.class, id).thenAccept(content -> { - if (content.getUserid() == userid && userService.isAdmin(userid)) {//管理员可以做更多 + dataSource.findAsync(ContentInfo.class, id).thenAccept(content -> { + if (userService.isAdmin(userid)) {//管理员可以做更多 //field: status|top|wonderful // 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))) {//非管理员只能修改状态 - 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 模板使用") - public HttpScope t(@RestSessionid String sessionid) { + public HttpScope t(@RestUserid int userid) { 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 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 contents = contentService.contentQuery(flipper, untopNode); //热议 - Flipper flipper3 = new Flipper().limit(8).sort("replynum DESC"); - Sheet hotReply = contentService.query(flipper3, "", sessionid); + Flipper flipper3 = new Flipper(8).sort("replynum DESC"); + Sheet hotReply = contentService.query(userid, flipper3, ""); //最新加入 Sheet lastReg = userService.lastReg(); diff --git a/src/net/tccn/bbs/base/FileService.java b/src/net/tccn/bbs/file/FileService.java similarity index 73% rename from src/net/tccn/bbs/base/FileService.java rename to src/net/tccn/bbs/file/FileService.java index 604ab1c..8eea394 100644 --- a/src/net/tccn/bbs/base/FileService.java +++ b/src/net/tccn/bbs/file/FileService.java @@ -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.RestService; import org.redkale.net.http.RestUploadFile; import org.redkale.service.RetResult; +import javax.annotation.Resource; import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -16,16 +18,18 @@ import java.nio.file.StandardCopyOption; @RestService(automapping = true, comment = "文件服务") public class FileService extends BaseService { - private static final String dir = "/var/www/upload/redbbs/"; - private static final String view = "http://img.1216.top/redbbs/"; - private static final String format = "%1$tY%1$tm%1$td%1$tH%1$tM%1$tS"; + @Resource(name = "property.file.upload_dir") + private String dir = ""; + @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 = "文件上传") public RetResult upload(@RestUploadFile File tmpFile) throws IOException { String name = tmpFile.getName(); String suffix = name.substring(name.lastIndexOf(".")); 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(); if (!tmpFile.renameTo(destFile)) { try { @@ -35,7 +39,7 @@ public class FileService extends BaseService { } } RetResult result = RetResult.success(); - result.setRetinfo((winos ? "/tem/" : view) + path); + result.setRetinfo(view + path); return result; } } diff --git a/src/net/tccn/bbs/servlet/ContentServlet.java b/src/net/tccn/bbs/servlet/ContentServlet.java index 72329a4..ce76ffe 100644 --- a/src/net/tccn/bbs/servlet/ContentServlet.java +++ b/src/net/tccn/bbs/servlet/ContentServlet.java @@ -2,7 +2,6 @@ package net.tccn.bbs.servlet; import com.jfinal.kit.Kv; import net.tccn.bbs.base.BaseServlet; -import net.tccn.bbs.base.user.UserInfo; import net.tccn.bbs.comment.CommentInfo; import net.tccn.bbs.content.ContentInfo; import org.redkale.net.http.*; @@ -20,12 +19,14 @@ import static org.redkale.source.FilterExpress.NOTEQUAL; public class ContentServlet extends BaseServlet { @HttpMapping(url = "/jie", auth = false, comment = "问答列表") public void jie(HttpRequest request, HttpResponse response) { + Integer userid = request.currentUserid(int.class); + String actived = getPara(request, 0, "all"); int curr = request.getIntParameter("curr", 1); //分页帖子列表 Flipper flipper = new Flipper().offset((curr - 1) * 15).limit(15).sort("top DESC,createtime DESC"); - Sheet contents = contentService.query(flipper, actived, request.getSessionid(false)); + Sheet contents = contentService.query(userid, flipper, actived); Kv kv = Kv.by("contents", contents).set("url", request.getRequestURI()) .set("actived", actived).set("curr", curr); @@ -37,12 +38,10 @@ public class ContentServlet extends BaseServlet { @HttpParam(name = "#", type = int.class, comment = "内容ID") public void add(HttpRequest request, HttpResponse response) { int contentid = getParaToInt(request, 0); - String sessionid = request.getSessionid(false); - UserInfo user = userService.current(sessionid); - + Integer userid = request.currentUserid(int.class); ContentInfo contentInfo = null; if (contentid > 0) { - contentInfo = contentService.info(user, contentid); + contentInfo = contentService.info(userid, contentid); } Kv kv = Kv.by("bean", contentInfo); @@ -53,10 +52,10 @@ public class ContentServlet extends BaseServlet { public void detail(HttpRequest request, HttpResponse response) { int contentid = getParaToInt(request, 0); String sessionid = request.getSessionid(false); - UserInfo user = userService.current(sessionid); + Integer userid = request.currentUserid(int.class); - ContentInfo content = contentService.info(user, contentid); - Sheet comments = commentService.query(sessionid, contentid, new Flipper().limit(30)); + ContentInfo content = contentService.info(userid, contentid); + Sheet comments = commentService.query(userid, new Flipper(30), contentid); //热帖 //Flipper flipper2 = new Flipper().limit(8).sort("viewNum DESC"); diff --git a/src/net/tccn/bbs/servlet/FileServlet.java b/src/net/tccn/bbs/servlet/FileServlet.java index 584e53c..ffed7f3 100644 --- a/src/net/tccn/bbs/servlet/FileServlet.java +++ b/src/net/tccn/bbs/servlet/FileServlet.java @@ -3,6 +3,7 @@ package net.tccn.bbs.servlet; import net.tccn.bbs.base.BaseServlet; import org.redkale.net.http.*; +import javax.annotation.Resource; import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -17,9 +18,11 @@ import java.util.Map; @WebServlet(value = {"/upload", "/upload/*"}, comment = "文件管理入口") public class FileServlet extends BaseServlet { - private static final String dir = "/var/www/upload/redbbs/"; - private static final String view = "http://img.1216.top/redbbs/"; - private static final String format = "%1$tY%1$tm%1$td%1$tH%1$tM%1$tS"; + @Resource(name = "property.file.upload_dir") + private String dir = ""; + @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 = "图片上传") public void uploadImg(HttpRequest request, HttpResponse response) { @@ -32,12 +35,12 @@ public class FileServlet extends BaseServlet { String name = part.getName(); String suffix = name.substring(name.lastIndexOf(".")); 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(); part.save(destFile); - data.add((winos ? "/tem/" : view) + path); + data.add(view + path); } ret.put("data", data); diff --git a/src/net/tccn/bbs/servlet/IndexServlet.java b/src/net/tccn/bbs/servlet/IndexServlet.java index 24aecb1..177a85b 100644 --- a/src/net/tccn/bbs/servlet/IndexServlet.java +++ b/src/net/tccn/bbs/servlet/IndexServlet.java @@ -2,9 +2,9 @@ package net.tccn.bbs.servlet; import com.jfinal.kit.Kv; import net.tccn.bbs.base.BaseServlet; -import net.tccn.bbs.base.user.UserInfo; import net.tccn.bbs.comment.CommentInfo; import net.tccn.bbs.content.ContentInfo; +import net.tccn.bbs.user.UserInfo; import org.redkale.net.http.*; import org.redkale.source.FilterNode; 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. */ -@WebServlet(value = {"/", "/project" /* ,"/article","/article/*" */}, comment = "首页一级菜单入口") +@WebServlet(value = {"/", "/project"}, comment = "首页一级菜单入口") public class IndexServlet extends BaseServlet { + @HttpMapping(url = "/", auth = false, comment = "社区首页") - public void abc(HttpRequest request, HttpResponse response) { + public void index(HttpRequest request, HttpResponse response) { 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); Sheet top = contentService.contentQuery(flipper, setPrivate(request, topNode)); @@ -70,12 +71,11 @@ public class IndexServlet extends BaseServlet { //====================================项目相关==================================== @HttpMapping(url = "/project", auth = false, comment = "项目首页") public void project(HttpRequest request, HttpResponse response) { - String sessionid = request.getSessionid(false); - UserInfo user = userService.current(sessionid); + Integer userid = request.currentUserid(int.class); int contentid = 22; - ContentInfo content = contentService.info(user, contentid); - Sheet comments = commentService.query(sessionid, contentid, new Flipper().limit(30)); + ContentInfo content = contentService.info(userid, contentid); + Sheet comments = commentService.query(userid, new Flipper(30), contentid); Kv kv = Kv.by("bean", content).set("comments", comments); response.finish(HttpScope.refer("/project/index.html").attr(kv)); diff --git a/src/net/tccn/bbs/servlet/UserServlet.java b/src/net/tccn/bbs/servlet/UserServlet.java index d5f8558..25a19ff 100644 --- a/src/net/tccn/bbs/servlet/UserServlet.java +++ b/src/net/tccn/bbs/servlet/UserServlet.java @@ -2,11 +2,11 @@ package net.tccn.bbs.servlet; import com.jfinal.kit.Kv; 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.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.source.FilterExpress; import org.redkale.source.FilterNode; @@ -46,6 +46,7 @@ public class UserServlet extends BaseServlet { @HttpMapping(url = "/user", auth = false, comment = "用户首页") public void user(HttpRequest request, HttpResponse response) { + Integer userid = request.currentUserid(int.class); 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); Sheet contents = contentService.contentQuery(flipper, setPrivate(request, node));//queryByBean(flipper, bean); //收藏的帖子 - Sheet collects = contentService.collectQuery(request.getSessionid(false)); + Sheet collects = contentService.collectQuery(userid); Kv kv = Kv.by("contents", contents).set("collects", collects); 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)) {//通过@ 点击跳转 String nickname = request.getParameter("nickname"); UserBean userBean = new UserBean(); userBean.setNickname(nickname); - Sheet users = userService.query(new Flipper().limit(1), userBean); + Sheet users = userService.query(new Flipper(1), userBean); if (users.getTotal() > 0) { userid = users.stream().findFirst().orElse(null).getUserid(); } @@ -88,7 +88,7 @@ public class UserServlet extends BaseServlet { 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); Sheet contents = contentService.contentQuery(flipper, setPrivate(request, node)); diff --git a/src/net/tccn/bbs/base/user/LoginBean.java b/src/net/tccn/bbs/user/LoginBean.java similarity index 94% rename from src/net/tccn/bbs/base/user/LoginBean.java rename to src/net/tccn/bbs/user/LoginBean.java index c16bcea..4015842 100644 --- a/src/net/tccn/bbs/base/user/LoginBean.java +++ b/src/net/tccn/bbs/user/LoginBean.java @@ -1,4 +1,4 @@ -package net.tccn.bbs.base.user; +package net.tccn.bbs.user; import lombok.Getter; import lombok.Setter; diff --git a/src/net/tccn/bbs/base/user/UserBean.java b/src/net/tccn/bbs/user/UserBean.java similarity index 94% rename from src/net/tccn/bbs/base/user/UserBean.java rename to src/net/tccn/bbs/user/UserBean.java index dd33bb0..3eed1a4 100644 --- a/src/net/tccn/bbs/base/user/UserBean.java +++ b/src/net/tccn/bbs/user/UserBean.java @@ -1,4 +1,4 @@ -package net.tccn.bbs.base.user; +package net.tccn.bbs.user; import lombok.Getter; import lombok.Setter; @@ -28,5 +28,4 @@ public class UserBean implements FilterBean { @Column(length = 32, comment = "[邮箱]") private String email; - } diff --git a/src/net/tccn/bbs/base/user/UserRecord.java b/src/net/tccn/bbs/user/UserDetail.java similarity index 94% rename from src/net/tccn/bbs/base/user/UserRecord.java rename to src/net/tccn/bbs/user/UserDetail.java index 6d9cd12..8fbd3f4 100644 --- a/src/net/tccn/bbs/base/user/UserRecord.java +++ b/src/net/tccn/bbs/user/UserDetail.java @@ -1,4 +1,4 @@ -package net.tccn.bbs.base.user; +package net.tccn.bbs.user; import lombok.Getter; import lombok.Setter; @@ -16,8 +16,8 @@ import javax.persistence.Table; @Setter @Getter @Cacheable(interval = 5 * 60) -@Table(catalog = "redbbs", name = "sys_userrecord") -public class UserRecord implements java.io.Serializable { +@Table(catalog = "redbbs", name = "userdetail") +public class UserDetail implements java.io.Serializable { @Id @Column(comment = "[用户id]") @@ -68,6 +68,7 @@ public class UserRecord implements java.io.Serializable { @Column(comment = "[状态]-10删除 10正常") private short status = 10; + @Override public String toString() { return JsonConvert.root().convertTo(this); diff --git a/src/net/tccn/bbs/base/user/UserInfo.java b/src/net/tccn/bbs/user/UserInfo.java similarity index 79% rename from src/net/tccn/bbs/base/user/UserInfo.java rename to src/net/tccn/bbs/user/UserInfo.java index d9880f9..4408034 100644 --- a/src/net/tccn/bbs/base/user/UserInfo.java +++ b/src/net/tccn/bbs/user/UserInfo.java @@ -1,8 +1,8 @@ -package net.tccn.bbs.base.user; +package net.tccn.bbs.user; import lombok.Getter; import lombok.Setter; -import org.redkale.convert.json.JsonConvert; +import net.tccn.bbs.base.BaseEntity; import javax.persistence.Column; import javax.persistence.Id; @@ -12,7 +12,7 @@ import javax.persistence.Id; */ @Setter @Getter -public class UserInfo implements java.io.Serializable { +public class UserInfo extends BaseEntity { @Id @Column(comment = "[用户id]") @@ -35,11 +35,6 @@ public class UserInfo implements java.io.Serializable { private int status = 1; private String time = ""; - @Override - public String toString() { - return JsonConvert.root().convertTo(this); - } - /** * 检查用户权限 * diff --git a/src/net/tccn/bbs/user/UserService.java b/src/net/tccn/bbs/user/UserService.java new file mode 100644 index 0000000..81aae45 --- /dev/null +++ b/src/net/tccn/bbs/user/UserService.java @@ -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 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 queryUserMap(Collection userids) { + if (Utils.isEmpty(userids)) { + return Map.of(); + } + + FilterNode node = FilterNode.create("userid", (Serializable) userids); + List records = dataSource.queryList(UserDetail.class, node); + Map 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 query(Flipper flipper, @RestParam(name = "bean", comment = "过滤条件") final UserBean userBean) { + Sheet 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 lastReg() { + Sheet users = dataSource.querySheet(UserDetail.class + , SelectColumn.includes("userid", "nickname", "avatar", "createtime") + , new Flipper(8, "createtime DESC") + , FilterNode.create("status", 10)); + + Sheet infos = new Sheet<>(); + ArrayList 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 userIds = dataSource.queryColumnList("userid", UserDetail.class, FilterNode.create("roleid", 1)); + for (Integer x : userIds) { + if (userid == x) { + return true; + } + } + + return false; + } +} diff --git a/src/net/tccn/bbs/vislog/bean/ActLogBean.java b/src/net/tccn/bbs/vislog/bean/ActLogBean.java new file mode 100644 index 0000000..4fafa56 --- /dev/null +++ b/src/net/tccn/bbs/vislog/bean/ActLogBean.java @@ -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); + } +} diff --git a/src/net/tccn/bbs/base/entity/ActLog.java b/src/net/tccn/bbs/vislog/entity/ActLog.java similarity index 93% rename from src/net/tccn/bbs/base/entity/ActLog.java rename to src/net/tccn/bbs/vislog/entity/ActLog.java index 8871a17..599da80 100644 --- a/src/net/tccn/bbs/base/entity/ActLog.java +++ b/src/net/tccn/bbs/vislog/entity/ActLog.java @@ -1,4 +1,4 @@ -package net.tccn.bbs.base.entity; +package net.tccn.bbs.vislog.entity; import lombok.Getter; import lombok.Setter; @@ -15,7 +15,7 @@ import javax.persistence.Table; @Setter @Getter @Cacheable(interval = 5 * 60) -@Table(catalog = "redbbs", name = "sys_actlog") +@Table(catalog = "redbbs", name = "actlog") public class ActLog implements java.io.Serializable { @Id diff --git a/src/net/tccn/bbs/base/entity/Count.java b/src/net/tccn/bbs/vislog/entity/Count.java similarity index 92% rename from src/net/tccn/bbs/base/entity/Count.java rename to src/net/tccn/bbs/vislog/entity/Count.java index 4bb4979..ba098d3 100644 --- a/src/net/tccn/bbs/base/entity/Count.java +++ b/src/net/tccn/bbs/vislog/entity/Count.java @@ -1,4 +1,4 @@ -package net.tccn.bbs.base.entity; +package net.tccn.bbs.vislog.entity; import lombok.Getter; import lombok.Setter; diff --git a/src/net/tccn/bbs/base/entity/DynAttr.java b/src/net/tccn/bbs/vislog/entity/DynAttr.java similarity index 95% rename from src/net/tccn/bbs/base/entity/DynAttr.java rename to src/net/tccn/bbs/vislog/entity/DynAttr.java index 51912b1..7261f58 100644 --- a/src/net/tccn/bbs/base/entity/DynAttr.java +++ b/src/net/tccn/bbs/vislog/entity/DynAttr.java @@ -1,4 +1,4 @@ -package net.tccn.bbs.base.entity; +package net.tccn.bbs.vislog.entity; import lombok.Getter; import lombok.Setter; diff --git a/src/net/tccn/bbs/base/entity/VisLog.java b/src/net/tccn/bbs/vislog/entity/VisLog.java similarity index 93% rename from src/net/tccn/bbs/base/entity/VisLog.java rename to src/net/tccn/bbs/vislog/entity/VisLog.java index 70585b0..a7dcc3b 100644 --- a/src/net/tccn/bbs/base/entity/VisLog.java +++ b/src/net/tccn/bbs/vislog/entity/VisLog.java @@ -1,4 +1,4 @@ -package net.tccn.bbs.base.entity; +package net.tccn.bbs.vislog.entity; import lombok.Getter; import lombok.Setter; diff --git a/src/net/tccn/redim/ChatWebSocket.java b/src/net/tccn/redim/ChatWebSocket.java index daa0aea..cd2406a 100644 --- a/src/net/tccn/redim/ChatWebSocket.java +++ b/src/net/tccn/redim/ChatWebSocket.java @@ -1,6 +1,7 @@ package net.tccn.redim; import net.tccn.bbs.base.JBean; +import net.tccn.bbs.user.UserService; import net.tccn.redim.entity.MsgRecord; import net.tccn.redim.info.MsgInfo; import net.tccn.redim.service.ImFriendService; @@ -24,6 +25,9 @@ public class ChatWebSocket extends WebSocket { @Resource protected ImFriendService imFriendService; + @Resource + protected UserService userService; + protected Random random = new Random(); @Override @@ -45,7 +49,7 @@ public class ChatWebSocket extends WebSocket { //fixme: 1、isyk => tour; 2、set cate to user global if (getAttribute("isyk") == null) {//tour - userid = imFriendService.currentUserid(getSessionid()); + userid = userService.currentUserid(getSessionid()); setAttribute("isyk", true); } diff --git a/src/net/tccn/redim/impl/ImFriendServiceImpl.java b/src/net/tccn/redim/impl/ImFriendServiceImpl.java index b3a938b..ee08868 100644 --- a/src/net/tccn/redim/impl/ImFriendServiceImpl.java +++ b/src/net/tccn/redim/impl/ImFriendServiceImpl.java @@ -3,9 +3,9 @@ package net.tccn.redim.impl; import com.jfinal.kit.Kv; import net.tccn.bbs.base.BaseService; import net.tccn.bbs.base.JBean; -import net.tccn.bbs.base.user.UserInfo; -import net.tccn.bbs.base.user.UserRecord; -import net.tccn.bbs.base.user.UserService; +import net.tccn.bbs.user.UserDetail; +import net.tccn.bbs.user.UserInfo; +import net.tccn.bbs.user.UserService; import net.tccn.redim.service.ImFriendService; import org.redkale.boot.Application; import org.redkale.net.TransportFactory; @@ -27,14 +27,14 @@ import java.util.stream.Collectors; public class ImFriendServiceImpl extends BaseService implements ImFriendService { @Resource - UserService userService; + private UserService userService; @Resource public static Application application; @Override public JBean friends(String sessionid) { - List records = source.queryList(UserRecord.class, FilterNode.create("status", FilterExpress.NOTEQUAL, -10)); + List records = dataSource.queryList(UserDetail.class, FilterNode.create("status", FilterExpress.NOTEQUAL, -10)); Kv data = Kv.create(); diff --git a/src/net/tccn/redim/impl/ImMsgServiceImpl.java b/src/net/tccn/redim/impl/ImMsgServiceImpl.java index 0ab3c0f..b7f6771 100644 --- a/src/net/tccn/redim/impl/ImMsgServiceImpl.java +++ b/src/net/tccn/redim/impl/ImMsgServiceImpl.java @@ -2,7 +2,7 @@ package net.tccn.redim.impl; import net.tccn.bbs.base.BaseService; 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.info.MsgInfo; import net.tccn.redim.service.ImMsgService; @@ -15,7 +15,7 @@ import java.util.List; /** * @author: liangxianyou at 2018/8/12 13:10. */ -@ResourceType(net.tccn.redim.service.ImMsgService.class) +@ResourceType(ImMsgService.class) @RestService(name = "immsg", automapping = true, comment = "聊天记录管理") public class ImMsgServiceImpl extends BaseService implements ImMsgService { @@ -26,7 +26,7 @@ public class ImMsgServiceImpl extends BaseService implements ImMsgService { */ @Override public JBean insert(MsgRecord... msg) { - source.insertAsync(msg); + dataSource.insertAsync(msg); return JBean.ok(); } @@ -37,7 +37,7 @@ public class ImMsgServiceImpl extends BaseService implements ImMsgService { */ @Override public JBean update(MsgRecord... msg) { - source.updateAsync(msg); + dataSource.updateAsync(msg); return JBean.ok(); } @@ -61,11 +61,11 @@ public class ImMsgServiceImpl extends BaseService implements ImMsgService { MsgInfo info = new MsgInfo(); int fromuserid = msg.getFromuserid(); - UserRecord userRecord; + UserDetail userDetail; if (fromuserid > 0) { - userRecord = source.find(UserRecord.class, fromuserid); - info.setUsername(userRecord.getUsername()); - info.setAvatar(userRecord.getAvatar()); + userDetail = dataSource.find(UserDetail.class, fromuserid); + info.setUsername(userDetail.getUsername()); + info.setAvatar(userDetail.getAvatar()); info.setType("friend"); } else { info.setUsername("游客"); @@ -85,7 +85,7 @@ public class ImMsgServiceImpl extends BaseService implements ImMsgService { @Override public JBean> offlineMsg(int userid) { - List records = source.queryList(MsgRecord.class, FilterNode.create("touserid", userid).and("status", 10)); + List records = dataSource.queryList(MsgRecord.class, FilterNode.create("touserid", userid).and("status", 10)); return JBean.by(records); } diff --git a/src/net/tccn/redim/service/ImFriendService.java b/src/net/tccn/redim/service/ImFriendService.java index b9a8dec..c80364b 100644 --- a/src/net/tccn/redim/service/ImFriendService.java +++ b/src/net/tccn/redim/service/ImFriendService.java @@ -67,5 +67,5 @@ public interface ImFriendService extends Service { * @param sessionid * @return */ - int currentUserid(String sessionid); + //int currentUserid(String sessionid); }