From d74d470597c89de9d35114f01e1ea3dfeaa1bbd3 Mon Sep 17 00:00:00 2001 From: ronger Date: Mon, 30 Mar 2020 16:20:49 +0800 Subject: [PATCH 01/36] =?UTF-8?q?Revert=20"=E6=96=B0=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=8F=91=E5=B8=83,=E7=BC=BA=E9=99=B7=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D,=E7=94=A8=E6=88=B7=E4=BD=93=E9=AA=8C?= =?UTF-8?q?=E6=8F=90=E5=8D=87"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/constant/NotificationConstant.java | 2 - .../core/constant/ProjectConstant.java | 29 ++--- .../com/rymcu/vertical/dto/ArticleDTO.java | 4 - .../com/rymcu/vertical/dto/ArticleTagDTO.java | 5 - .../java/com/rymcu/vertical/dto/Author.java | 3 - .../com/rymcu/vertical/dto/CommentDTO.java | 41 ------- .../com/rymcu/vertical/entity/Article.java | 2 - .../com/rymcu/vertical/entity/Comment.java | 2 +- .../rymcu/vertical/mapper/ArticleMapper.java | 83 +------------ .../rymcu/vertical/mapper/CommentMapper.java | 36 ------ .../vertical/service/ArticleService.java | 13 -- .../vertical/service/CommentService.java | 16 --- .../service/impl/ArticleServiceImpl.java | 60 ++------- .../service/impl/CommentServiceImpl.java | 114 ------------------ .../vertical/service/impl/TagServiceImpl.java | 14 --- .../com/rymcu/vertical/util/BaiDuUtils.java | 27 +---- .../vertical/util/NotificationUtils.java | 2 +- .../web/api/article/ArticleController.java | 31 ----- .../web/api/comment/CommentController.java | 34 ------ src/main/java/mapper/ArticleMapper.xml | 26 ++-- src/main/java/mapper/CommentMapper.xml | 49 -------- src/main/java/mapper/RoleMapper.xml | 2 +- 22 files changed, 31 insertions(+), 564 deletions(-) delete mode 100644 src/main/java/com/rymcu/vertical/dto/CommentDTO.java delete mode 100644 src/main/java/com/rymcu/vertical/mapper/CommentMapper.java delete mode 100644 src/main/java/com/rymcu/vertical/service/CommentService.java delete mode 100644 src/main/java/com/rymcu/vertical/service/impl/CommentServiceImpl.java delete mode 100644 src/main/java/com/rymcu/vertical/web/api/comment/CommentController.java delete mode 100644 src/main/java/mapper/CommentMapper.xml diff --git a/src/main/java/com/rymcu/vertical/core/constant/NotificationConstant.java b/src/main/java/com/rymcu/vertical/core/constant/NotificationConstant.java index 19bbb61..41e53a1 100644 --- a/src/main/java/com/rymcu/vertical/core/constant/NotificationConstant.java +++ b/src/main/java/com/rymcu/vertical/core/constant/NotificationConstant.java @@ -10,6 +10,4 @@ public class NotificationConstant { public static String Follow = "1"; - public static String Comment = "2"; - } diff --git a/src/main/java/com/rymcu/vertical/core/constant/ProjectConstant.java b/src/main/java/com/rymcu/vertical/core/constant/ProjectConstant.java index db5d098..96eb072 100644 --- a/src/main/java/com/rymcu/vertical/core/constant/ProjectConstant.java +++ b/src/main/java/com/rymcu/vertical/core/constant/ProjectConstant.java @@ -2,25 +2,16 @@ package com.rymcu.vertical.core.constant; /** * 项目常量 - * @author ronger */ public final class ProjectConstant { - /**当前环境*/ - public static final String ENV = "dev"; - /**项目基础包名称,根据自己公司的项目修改*/ - public static final String BASE_PACKAGE = "com.rymcu.vertical"; - /**DTO所在包*/ - public static final String DTO_PACKAGE = BASE_PACKAGE + ".dto"; - /**Model所在包*/ - public static final String MODEL_PACKAGE = BASE_PACKAGE + ".entity"; - /**Mapper所在包*/ - public static final String MAPPER_PACKAGE = BASE_PACKAGE + ".mapper"; - /**Service所在包*/ - public static final String SERVICE_PACKAGE = BASE_PACKAGE + ".service"; - /**ServiceImpl所在包*/ - public static final String SERVICE_IMPL_PACKAGE = SERVICE_PACKAGE + ".impl"; - /**Controller所在包*/ - public static final String CONTROLLER_PACKAGE = BASE_PACKAGE + ".web"; - /**Mapper插件基础接口的完全限定名*/ - public static final String MAPPER_INTERFACE_REFERENCE = BASE_PACKAGE + ".core.mapper.Mapper"; + public static final String BASE_PACKAGE = "com.rymcu.vertical";//项目基础包名称,根据自己公司的项目修改 + + public static final String DTO_PACKAGE = BASE_PACKAGE + ".dto";//DTO所在包 + public static final String MODEL_PACKAGE = BASE_PACKAGE + ".entity";//Model所在包 + public static final String MAPPER_PACKAGE = BASE_PACKAGE + ".mapper";//Mapper所在包 + public static final String SERVICE_PACKAGE = BASE_PACKAGE + ".service";//Service所在包 + public static final String SERVICE_IMPL_PACKAGE = SERVICE_PACKAGE + ".impl";//ServiceImpl所在包 + public static final String CONTROLLER_PACKAGE = BASE_PACKAGE + ".web";//Controller所在包 + + public static final String MAPPER_INTERFACE_REFERENCE = BASE_PACKAGE + ".core.mapper.Mapper";//Mapper插件基础接口的完全限定名 } diff --git a/src/main/java/com/rymcu/vertical/dto/ArticleDTO.java b/src/main/java/com/rymcu/vertical/dto/ArticleDTO.java index 60aa8c2..ce315ea 100644 --- a/src/main/java/com/rymcu/vertical/dto/ArticleDTO.java +++ b/src/main/java/com/rymcu/vertical/dto/ArticleDTO.java @@ -41,14 +41,10 @@ public class ArticleDTO { private String articlePermalink; /** 站内链接 */ private String articleLink; - /** 文章状态 */ - private String articleStatus; /** 更新时间 */ private Date updatedTime; private Author articleAuthor; private List tags; - - private List articleComments; } diff --git a/src/main/java/com/rymcu/vertical/dto/ArticleTagDTO.java b/src/main/java/com/rymcu/vertical/dto/ArticleTagDTO.java index ed69468..7eb15f7 100644 --- a/src/main/java/com/rymcu/vertical/dto/ArticleTagDTO.java +++ b/src/main/java/com/rymcu/vertical/dto/ArticleTagDTO.java @@ -7,13 +7,8 @@ import lombok.Data; */ @Data public class ArticleTagDTO { - - private Integer idArticleTag; - private Integer idTag; - private Integer idArticle; - private String tagTitle; private String tagUri; diff --git a/src/main/java/com/rymcu/vertical/dto/Author.java b/src/main/java/com/rymcu/vertical/dto/Author.java index 1f6a567..49105d7 100644 --- a/src/main/java/com/rymcu/vertical/dto/Author.java +++ b/src/main/java/com/rymcu/vertical/dto/Author.java @@ -2,9 +2,6 @@ package com.rymcu.vertical.dto; import lombok.Data; -/** - * @author ronger - */ @Data public class Author { diff --git a/src/main/java/com/rymcu/vertical/dto/CommentDTO.java b/src/main/java/com/rymcu/vertical/dto/CommentDTO.java deleted file mode 100644 index a3d2563..0000000 --- a/src/main/java/com/rymcu/vertical/dto/CommentDTO.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.rymcu.vertical.dto; - -import lombok.Data; - -import java.util.Date; - -/** - * @author ronger - */ -@Data -public class CommentDTO { - private Integer idComment; - /** 评论内容 */ - private String commentContent; - /** 作者 id */ - private Integer commentAuthorId; - /** 文章 id */ - private Integer commentArticleId; - /** 锚点 url */ - private String commentSharpUrl; - /** 父评论 id */ - private Integer commentOriginalCommentId; - /** 父评论作者头像 */ - private String commentOriginalAuthorThumbnailURL; - /** 父评论作者昵称 */ - private String commentOriginalAuthorNickname; - /** 状态 */ - private String commentStatus; - /** 0:公开回帖,1:匿名回帖 */ - private String commentAnonymous; - /** 回帖计数 */ - private Integer commentReplyCount; - /** 0:所有人可见,1:仅楼主和自己可见 */ - private String commentVisible; - /** 创建时间 */ - private Date createdTime; - - private Author commenter; - - private String timeAgo; -} diff --git a/src/main/java/com/rymcu/vertical/entity/Article.java b/src/main/java/com/rymcu/vertical/entity/Article.java index 6aefb49..e389d2c 100644 --- a/src/main/java/com/rymcu/vertical/entity/Article.java +++ b/src/main/java/com/rymcu/vertical/entity/Article.java @@ -46,6 +46,4 @@ public class Article implements Serializable,Cloneable { private Date createdTime; /** 更新时间 */ private Date updatedTime; - /** 文章状态 */ - private String articleStatus; } diff --git a/src/main/java/com/rymcu/vertical/entity/Comment.java b/src/main/java/com/rymcu/vertical/entity/Comment.java index d9b71cc..e8fb312 100644 --- a/src/main/java/com/rymcu/vertical/entity/Comment.java +++ b/src/main/java/com/rymcu/vertical/entity/Comment.java @@ -19,7 +19,7 @@ public class Comment implements Serializable,Cloneable { @Id @GeneratedValue(generator = "JDBC") @Column(name = "id") - private Integer idComment; + private Integer id; /** 评论内容 */ @Column(name = "comment_content") private String commentContent; diff --git a/src/main/java/com/rymcu/vertical/mapper/ArticleMapper.java b/src/main/java/com/rymcu/vertical/mapper/ArticleMapper.java index 959525f..71b036c 100644 --- a/src/main/java/com/rymcu/vertical/mapper/ArticleMapper.java +++ b/src/main/java/com/rymcu/vertical/mapper/ArticleMapper.java @@ -10,113 +10,34 @@ import org.apache.ibatis.annotations.Param; import java.util.List; -/** - * @author ronger - */ public interface ArticleMapper extends Mapper
{ - - /** - * 获取文章列表 - * @param searchText - * @param tag - * @return - */ List selectArticles(@Param("searchText") String searchText, @Param("tag") String tag); - /** - * 根据用户 ID 获取作者信息 - * @param id - * @return - */ Author selectAuthor(@Param("id") Integer id); - /** - * 根据文章 ID 查询文章 - * @param id - * @param type - * @return - */ - ArticleDTO selectArticleDTOById(@Param("id") Integer id, @Param("type") int type); + ArticleDTO selectArticleDTOById(@Param("id") Integer id); - /** - * 保存文章内容 - * @param idArticle - * @param articleContent - * @param articleContentHtml - * @return - */ Integer insertArticleContent(@Param("idArticle") Integer idArticle, @Param("articleContent") String articleContent, @Param("articleContentHtml") String articleContentHtml); - /** - * 更新文章内容 - * @param idArticle - * @param articleContent - * @param articleContentHtml - * @return - */ Integer updateArticleContent(@Param("idArticle") Integer idArticle, @Param("articleContent") String articleContent, @Param("articleContentHtml") String articleContentHtml); - /** - * 获取文章正文内容 - * @param idArticle - * @return - */ ArticleContent selectArticleContent(@Param("idArticle") Integer idArticle); - /** - * 获取主题下文章列表 - * @param topicName - * @return - */ List selectArticlesByTopicUri(@Param("topicName") String topicName); - /** - * 获取标签下文章列表 - * @param tagName - * @return - */ List selectArticlesByTagName(@Param("tagName") String tagName); - /** - * 获取用户文章列表 - * @param idUser - * @return - */ List selectUserArticles(@Param("idUser") Integer idUser); - /** - * 删除文章标签 - * @param id - * @return - */ Integer deleteTagArticle(@Param("id") Integer id); - /** - * 获取文章标签列表 - * @param idArticle - * @return - */ List selectTags(@Param("idArticle") Integer idArticle); /** - * 更新文章浏览数 + * * @param id * @param articleViewCount * @return */ Integer updateArticleViewCount(@Param("id") Integer id, @Param("articleViewCount") Integer articleViewCount); - - /** - * 获取草稿列表 - * @param idUser - * @return - */ - List selectDrafts(@Param("idUser") Integer idUser); - - /** - * 删除未使用的文章标签 - * @param idArticleTag - * @return - */ - Integer deleteUnusedArticleTag(@Param("idArticleTag") Integer idArticleTag); } diff --git a/src/main/java/com/rymcu/vertical/mapper/CommentMapper.java b/src/main/java/com/rymcu/vertical/mapper/CommentMapper.java deleted file mode 100644 index fba4a79..0000000 --- a/src/main/java/com/rymcu/vertical/mapper/CommentMapper.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.rymcu.vertical.mapper; - -import com.rymcu.vertical.core.mapper.Mapper; -import com.rymcu.vertical.dto.Author; -import com.rymcu.vertical.dto.CommentDTO; -import com.rymcu.vertical.entity.Comment; -import org.apache.ibatis.annotations.Param; - -import java.util.List; - -public interface CommentMapper extends Mapper { - /** - * @param idArticle - * @return - */ - List selectArticleComments(@Param("idArticle") Integer idArticle); - - /** - * @param commentAuthorId - * @return - */ - Author selectAuthor(@Param("commentAuthorId") Integer commentAuthorId); - - /** - * @param commentOriginalCommentId - * @return - */ - Author selectCommentOriginalAuthor(@Param("commentOriginalCommentId") Integer commentOriginalCommentId); - - /** - * @param idComment - * @param toString - * @return - */ - Integer updateCommentSharpUrl(@Param("idComment") Integer idComment, @Param("commentSharpUrl") String commentSharpUrl); -} diff --git a/src/main/java/com/rymcu/vertical/service/ArticleService.java b/src/main/java/com/rymcu/vertical/service/ArticleService.java index 541bf57..a901362 100644 --- a/src/main/java/com/rymcu/vertical/service/ArticleService.java +++ b/src/main/java/com/rymcu/vertical/service/ArticleService.java @@ -74,17 +74,4 @@ public interface ArticleService extends Service
{ * @param id */ void incrementArticleViewCount(Integer id); - - /** - * 获取分享链接数据 - * @param id - * @return - */ - Map share(Integer id) throws BaseApiException; - - /** - * 查询草稿文章类别 - * @return - */ - List findDrafts() throws BaseApiException; } diff --git a/src/main/java/com/rymcu/vertical/service/CommentService.java b/src/main/java/com/rymcu/vertical/service/CommentService.java deleted file mode 100644 index 5324a42..0000000 --- a/src/main/java/com/rymcu/vertical/service/CommentService.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.rymcu.vertical.service; - -import com.rymcu.vertical.core.service.Service; -import com.rymcu.vertical.dto.CommentDTO; -import com.rymcu.vertical.entity.Comment; - -import javax.servlet.http.HttpServletRequest; -import java.util.List; -import java.util.Map; - -public interface CommentService extends Service { - - List getArticleComments(Integer idArticle); - - Map postComment(Comment comment, HttpServletRequest request); -} diff --git a/src/main/java/com/rymcu/vertical/service/impl/ArticleServiceImpl.java b/src/main/java/com/rymcu/vertical/service/impl/ArticleServiceImpl.java index f451556..1178ab0 100644 --- a/src/main/java/com/rymcu/vertical/service/impl/ArticleServiceImpl.java +++ b/src/main/java/com/rymcu/vertical/service/impl/ArticleServiceImpl.java @@ -1,19 +1,16 @@ package com.rymcu.vertical.service.impl; import com.rymcu.vertical.core.constant.NotificationConstant; -import com.rymcu.vertical.core.constant.ProjectConstant; import com.rymcu.vertical.core.service.AbstractService; import com.rymcu.vertical.dto.ArticleDTO; import com.rymcu.vertical.dto.ArticleTagDTO; import com.rymcu.vertical.dto.Author; -import com.rymcu.vertical.dto.CommentDTO; import com.rymcu.vertical.entity.Article; import com.rymcu.vertical.entity.ArticleContent; import com.rymcu.vertical.entity.Tag; import com.rymcu.vertical.entity.User; import com.rymcu.vertical.mapper.ArticleMapper; import com.rymcu.vertical.service.ArticleService; -import com.rymcu.vertical.service.CommentService; import com.rymcu.vertical.service.TagService; import com.rymcu.vertical.service.UserService; import com.rymcu.vertical.util.*; @@ -45,16 +42,11 @@ public class ArticleServiceImpl extends AbstractService
implements Arti private TagService tagService; @Resource private UserService userService; - @Resource - private CommentService commentService; @Value("${resource.domain}") - private String domain; - @Value("${env}") - private String env; + private static String domain; private static final int MAX_PREVIEW = 200; - private static final String defaultStatus = "0"; @Override public List findArticles(String searchText, String tag) { @@ -67,10 +59,7 @@ public class ArticleServiceImpl extends AbstractService
implements Arti @Override public ArticleDTO findArticleDTOById(Integer id, int type) { - ArticleDTO articleDTO = articleMapper.selectArticleDTOById(id,type); - if (articleDTO == null) { - return null; - } + ArticleDTO articleDTO = articleMapper.selectArticleDTOById(id); articleDTO = genArticle(articleDTO,type); return articleDTO; } @@ -132,12 +121,11 @@ public class ArticleServiceImpl extends AbstractService
implements Arti newArticle.setArticleTags(articleTags); newArticle.setCreatedTime(new Date()); newArticle.setUpdatedTime(newArticle.getCreatedTime()); - newArticle.setArticleStatus(article.getArticleStatus()); articleMapper.insertSelective(newArticle); + newArticle.setArticlePermalink(domain + "/article/"+newArticle.getIdArticle()); + newArticle.setArticleLink("/article/"+newArticle.getIdArticle()); articleMapper.insertArticleContent(newArticle.getIdArticle(),articleContent,articleContentHtml); - if (!ProjectConstant.ENV.equals(env) && defaultStatus.equals(newArticle.getArticleStatus())) { - BaiDuUtils.sendSEOData(newArticle.getArticlePermalink()); - } + BaiDuUtils.sendSEOData(newArticle.getArticlePermalink()); } else { newArticle = articleMapper.selectByPrimaryKey(article.getIdArticle()); if(!user.getIdUser().equals(newArticle.getArticleAuthorId())){ @@ -154,27 +142,16 @@ public class ArticleServiceImpl extends AbstractService
implements Arti String articlePreviewContent = articleContentHtml.substring(0,length); newArticle.setArticlePreviewContent(Html2TextUtil.getContent(articlePreviewContent)); } - newArticle.setArticleStatus(article.getArticleStatus()); newArticle.setUpdatedTime(new Date()); articleMapper.updateArticleContent(newArticle.getIdArticle(),articleContent,articleContentHtml); - if (!ProjectConstant.ENV.equals(env) && defaultStatus.equals(newArticle.getArticleStatus())) { - BaiDuUtils.updateSEOData(newArticle.getArticlePermalink()); - } + BaiDuUtils.updateSEOData(newArticle.getArticlePermalink()); } - if (notification && defaultStatus.equals(newArticle.getArticleStatus())) { + if (notification) { NotificationUtils.sendAnnouncement(newArticle.getIdArticle(), NotificationConstant.Article, newArticle.getArticleTitle()); } tagService.saveTagArticle(newArticle); - - if (defaultStatus.equals(newArticle.getArticleStatus())) { - newArticle.setArticlePermalink(domain + "/article/" + newArticle.getIdArticle()); - newArticle.setArticleLink("/article/" + newArticle.getIdArticle()); - } else { - newArticle.setArticlePermalink(domain + "/draft/" + newArticle.getIdArticle()); - newArticle.setArticleLink("/draft/" + newArticle.getIdArticle()); - } articleMapper.updateByPrimaryKeySelective(newArticle); map.put("id", newArticle.getIdArticle()); @@ -239,27 +216,6 @@ public class ArticleServiceImpl extends AbstractService
implements Arti articleMapper.updateArticleViewCount(article.getIdArticle(), articleViewCount); } - @Override - public Map share(Integer id) throws BaseApiException { - Article article = articleMapper.selectByPrimaryKey(id); - User user = UserUtils.getWxCurrentUser(); - StringBuilder shareUrl = new StringBuilder(article.getArticlePermalink()); - shareUrl.append("?s=").append(user.getNickname()); - Map map = new HashMap(1); - map.put("shareUrl", shareUrl); - return map; - } - - @Override - public List findDrafts() throws BaseApiException { - User user = UserUtils.getWxCurrentUser(); - List list = articleMapper.selectDrafts(user.getIdUser()); - list.forEach(article->{ - genArticle(article,0); - }); - return list; - } - private ArticleDTO genArticle(ArticleDTO article,Integer type) { Author author = articleMapper.selectAuthor(article.getArticleAuthorId()); article.setArticleAuthor(author); @@ -283,8 +239,6 @@ public class ArticleServiceImpl extends AbstractService
implements Arti String articlePreviewContent = articleContent.getArticleContentHtml().substring(0,length); article.setArticlePreviewContent(Html2TextUtil.getContent(articlePreviewContent)); } - List commentDTOList = commentService.getArticleComments(article.getIdArticle()); - article.setArticleComments(commentDTOList); return article; } } diff --git a/src/main/java/com/rymcu/vertical/service/impl/CommentServiceImpl.java b/src/main/java/com/rymcu/vertical/service/impl/CommentServiceImpl.java deleted file mode 100644 index f7268e1..0000000 --- a/src/main/java/com/rymcu/vertical/service/impl/CommentServiceImpl.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.rymcu.vertical.service.impl; - -import com.rymcu.vertical.core.constant.NotificationConstant; -import com.rymcu.vertical.core.service.AbstractService; -import com.rymcu.vertical.dto.Author; -import com.rymcu.vertical.dto.CommentDTO; -import com.rymcu.vertical.entity.Article; -import com.rymcu.vertical.entity.Comment; -import com.rymcu.vertical.mapper.CommentMapper; -import com.rymcu.vertical.service.ArticleService; -import com.rymcu.vertical.service.CommentService; -import com.rymcu.vertical.util.Html2TextUtil; -import com.rymcu.vertical.util.NotificationUtils; -import com.rymcu.vertical.util.Utils; -import org.apache.commons.lang.StringUtils; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; -import java.util.*; - -/** - * @author ronger - */ -@Service -public class CommentServiceImpl extends AbstractService implements CommentService { - - @Resource - private CommentMapper commentMapper; - @Resource - private ArticleService articleService; - - private static final int MAX_PREVIEW = 200; - - @Override - public List getArticleComments(Integer idArticle) { - List commentDTOList = commentMapper.selectArticleComments(idArticle); - commentDTOList.forEach(commentDTO -> { - commentDTO.setTimeAgo(Utils.getTimeAgo(commentDTO.getCreatedTime())); - if (commentDTO.getCommentAuthorId() != null) { - Author author = commentMapper.selectAuthor(commentDTO.getCommentAuthorId()); - if (author != null) { - commentDTO.setCommenter(author); - } - } - if (commentDTO.getCommentOriginalCommentId() != null) { - Author commentOriginalAuthor = commentMapper.selectCommentOriginalAuthor(commentDTO.getCommentOriginalCommentId()); - if (commentOriginalAuthor != null) { - commentDTO.setCommentOriginalAuthorThumbnailURL(commentOriginalAuthor.getUserAvatarURL()); - commentDTO.setCommentOriginalAuthorNickname(commentOriginalAuthor.getUserNickname()); - } - } - }); - return commentDTOList; - } - - @Override - @Transactional(rollbackFor = Exception.class) - public Map postComment(Comment comment, HttpServletRequest request) { - Map map = new HashMap(1); - if(comment.getCommentArticleId() == null){ - map.put("message","非法访问,文章主键异常!"); - return map; - } - if(comment.getCommentAuthorId() == null){ - map.put("message","非法访问,用户未登录!"); - return map; - } - if(StringUtils.isBlank(comment.getCommentContent())){ - map.put("message","回帖内容不能为空!"); - return map; - } - Article article = articleService.findById(comment.getCommentArticleId().toString()); - if (article == null) { - map.put("message","文章不存在!"); - return map; - } - String ip = Utils.getIpAddress(request); - String ua = request.getHeader("user-agent"); - comment.setCommentIP(ip); - comment.setCommentUA(ua); - comment.setCreatedTime(new Date()); - commentMapper.insertSelective(comment); - StringBuilder commentSharpUrl = new StringBuilder(article.getArticlePermalink()); - commentSharpUrl.append("/comment/").append(comment.getIdComment()); - commentMapper.updateCommentSharpUrl(comment.getIdComment(), commentSharpUrl.toString()); - - String commentContent = comment.getCommentContent(); - if(StringUtils.isNotBlank(commentContent)){ - Integer length = commentContent.length(); - if(length > MAX_PREVIEW){ - length = 200; - } - String commentPreviewContent = commentContent.substring(0,length); - commentContent = Html2TextUtil.getContent(commentPreviewContent); - // 评论者不是作者本人则进行消息通知 - if (!article.getArticleAuthorId().equals(comment.getCommentAuthorId())) { - NotificationUtils.saveNotification(article.getArticleAuthorId(),comment.getIdComment(), NotificationConstant.Comment, commentContent); - } - // 判断是否是回复消息 - if (comment.getCommentOriginalCommentId() != null && comment.getCommentOriginalCommentId() != 0) { - Comment originalComment = commentMapper.selectByPrimaryKey(comment.getCommentOriginalCommentId()); - // 回复消息时,评论者不是上级评论作者则进行消息通知 - if (!comment.getCommentAuthorId().equals(originalComment.getCommentAuthorId())) { - NotificationUtils.saveNotification(originalComment.getCommentAuthorId(),comment.getIdComment(), NotificationConstant.Comment, commentContent); - } - } - } - - - return map; - } -} diff --git a/src/main/java/com/rymcu/vertical/service/impl/TagServiceImpl.java b/src/main/java/com/rymcu/vertical/service/impl/TagServiceImpl.java index d58eed3..4c02be0 100644 --- a/src/main/java/com/rymcu/vertical/service/impl/TagServiceImpl.java +++ b/src/main/java/com/rymcu/vertical/service/impl/TagServiceImpl.java @@ -1,11 +1,9 @@ package com.rymcu.vertical.service.impl; import com.rymcu.vertical.core.service.AbstractService; -import com.rymcu.vertical.dto.ArticleTagDTO; import com.rymcu.vertical.entity.Article; import com.rymcu.vertical.entity.Tag; import com.rymcu.vertical.entity.User; -import com.rymcu.vertical.mapper.ArticleMapper; import com.rymcu.vertical.mapper.TagMapper; import com.rymcu.vertical.service.TagService; import com.rymcu.vertical.util.UserUtils; @@ -31,8 +29,6 @@ public class TagServiceImpl extends AbstractService implements TagService { @Resource private TagMapper tagMapper; - @Resource - private ArticleMapper articleMapper; @Override @Transactional(rollbackFor = { UnsupportedEncodingException.class,BaseApiException.class }) @@ -41,7 +37,6 @@ public class TagServiceImpl extends AbstractService implements TagService { String articleTags = article.getArticleTags(); if(StringUtils.isNotBlank(articleTags)){ String[] tags = articleTags.split(","); - List articleTagDTOList = articleMapper.selectTags(article.getIdArticle()); for (int i = 0; i < tags.length; i++) { boolean addTagArticle = false; boolean addUserTag = false; @@ -59,12 +54,6 @@ public class TagServiceImpl extends AbstractService implements TagService { addTagArticle = true; addUserTag = true; } else { - for(int m=0,n=articleTagDTOList.size()-1;m implements TagService { addUserTag = true; } } - articleTagDTOList.forEach(articleTagDTO -> { - articleMapper.deleteUnusedArticleTag(articleTagDTO.getIdArticleTag()); - }); if(addTagArticle){ tagMapper.insertTagArticle(tag.getIdTag(),article.getIdArticle()); } diff --git a/src/main/java/com/rymcu/vertical/util/BaiDuUtils.java b/src/main/java/com/rymcu/vertical/util/BaiDuUtils.java index 83e015f..5e83cd0 100644 --- a/src/main/java/com/rymcu/vertical/util/BaiDuUtils.java +++ b/src/main/java/com/rymcu/vertical/util/BaiDuUtils.java @@ -33,29 +33,6 @@ public class BaiDuUtils { } return 0; },executor); - return; - } - - public static void sendUpdateSEOData(String permalink) { - if (StringUtils.isBlank(permalink) || StringUtils.isBlank(token)) { - return; - } - ExecutorService executor= new ThreadPoolExecutor(1,1,0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); - CompletableFuture.supplyAsync(()-> { - try { - HttpResponse response = HttpRequest.post("http://data.zz.baidu.com/update?site=" + site + "&token=" + token). - header("User-Agent", "curl/7.12.1"). - header("Host", "data.zz.baidu.com"). - header("Content-Type", "text/plain"). - header("Connection", "close").body(permalink.getBytes(), "text/plain").timeout(30000).send(); - response.charset("UTF-8"); - System.out.println(response.bodyText()); - } catch (Exception e){ - e.printStackTrace(); - } - return 0; - },executor); - return; } public static void updateSEOData(String permalink) { @@ -100,7 +77,7 @@ public class BaiDuUtils { },executor); } - public static void main(){ - sendUpdateSEOData("https://rymcu.com"); + public static void main(String agrs[]){ + sendSEOData("https://rymcu.com/article/31"); } } diff --git a/src/main/java/com/rymcu/vertical/util/NotificationUtils.java b/src/main/java/com/rymcu/vertical/util/NotificationUtils.java index 7a42c0c..112f20b 100644 --- a/src/main/java/com/rymcu/vertical/util/NotificationUtils.java +++ b/src/main/java/com/rymcu/vertical/util/NotificationUtils.java @@ -42,7 +42,7 @@ public class NotificationUtils { },executor); } - public static void saveNotification(Integer idUser, Integer dataId, String dataType, String dataSummary) { + private static void saveNotification(Integer idUser, Integer dataId, String dataType, String dataSummary) { ExecutorService executor= new ThreadPoolExecutor(1,1,0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); CompletableFuture.supplyAsync(()-> { try { diff --git a/src/main/java/com/rymcu/vertical/web/api/article/ArticleController.java b/src/main/java/com/rymcu/vertical/web/api/article/ArticleController.java index 8fa3f41..631e1c5 100644 --- a/src/main/java/com/rymcu/vertical/web/api/article/ArticleController.java +++ b/src/main/java/com/rymcu/vertical/web/api/article/ArticleController.java @@ -1,14 +1,9 @@ package com.rymcu.vertical.web.api.article; -import com.github.pagehelper.PageHelper; -import com.github.pagehelper.PageInfo; import com.rymcu.vertical.core.result.GlobalResult; import com.rymcu.vertical.core.result.GlobalResultGenerator; import com.rymcu.vertical.dto.ArticleDTO; -import com.rymcu.vertical.dto.CommentDTO; import com.rymcu.vertical.service.ArticleService; -import com.rymcu.vertical.service.CommentService; -import com.rymcu.vertical.util.Utils; import com.rymcu.vertical.web.api.exception.BaseApiException; import org.springframework.web.bind.annotation.*; @@ -16,7 +11,6 @@ import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.io.UnsupportedEncodingException; import java.util.HashMap; -import java.util.List; import java.util.Map; /** @@ -28,8 +22,6 @@ public class ArticleController { @Resource private ArticleService articleService; - @Resource - private CommentService commentService; @@ -59,27 +51,4 @@ public class ArticleController { return GlobalResultGenerator.genSuccessResult(map); } - @GetMapping("/{id}/comments") - public GlobalResult> commons(@PathVariable Integer id){ - List commentDTOList = commentService.getArticleComments(id); - Map map = new HashMap<>(1); - map.put("comments", commentDTOList); - return GlobalResultGenerator.genSuccessResult(map); - } - - @GetMapping("/drafts") - public GlobalResult drafts(@RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "10") Integer rows) throws BaseApiException { - PageHelper.startPage(page, rows); - List list = articleService.findDrafts(); - PageInfo pageInfo = new PageInfo(list); - Map map = Utils.getArticlesGlobalResult(pageInfo); - return GlobalResultGenerator.genSuccessResult(map); - } - - @GetMapping("/{id}/share") - public GlobalResult share(@PathVariable Integer id) throws BaseApiException { - Map map = articleService.share(id); - return GlobalResultGenerator.genSuccessResult(map); - } - } diff --git a/src/main/java/com/rymcu/vertical/web/api/comment/CommentController.java b/src/main/java/com/rymcu/vertical/web/api/comment/CommentController.java deleted file mode 100644 index 814b625..0000000 --- a/src/main/java/com/rymcu/vertical/web/api/comment/CommentController.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.rymcu.vertical.web.api.comment; - -import com.rymcu.vertical.core.result.GlobalResult; -import com.rymcu.vertical.core.result.GlobalResultGenerator; -import com.rymcu.vertical.dto.ArticleDTO; -import com.rymcu.vertical.entity.Comment; -import com.rymcu.vertical.service.CommentService; -import com.rymcu.vertical.web.api.exception.BaseApiException; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; -import java.io.UnsupportedEncodingException; -import java.util.Map; - -/** - * @author ronger - */ -@RestController -@RequestMapping("/api/v1/comment") -public class CommentController { - - @Resource - private CommentService commentService; - - @PostMapping("/post") - public GlobalResult postComment(@RequestBody Comment comment, HttpServletRequest request) throws BaseApiException, UnsupportedEncodingException { - Map map = commentService.postComment(comment,request); - return GlobalResultGenerator.genSuccessResult(map); - } -} diff --git a/src/main/java/mapper/ArticleMapper.xml b/src/main/java/mapper/ArticleMapper.xml index e315b78..65d0423 100644 --- a/src/main/java/mapper/ArticleMapper.xml +++ b/src/main/java/mapper/ArticleMapper.xml @@ -35,7 +35,6 @@ - @@ -51,13 +50,11 @@ - - - - - - - + + + + + insert into vertical_article_content (id_article,article_content,article_content_html,created_time,updated_time) @@ -72,20 +69,14 @@ delete from vertical_tag_article where id_article = #{id} - - delete from vertical_tag_article where id = #{idArticleTag} - - \ No newline at end of file diff --git a/src/main/java/mapper/CommentMapper.xml b/src/main/java/mapper/CommentMapper.xml deleted file mode 100644 index cbc5cbc..0000000 --- a/src/main/java/mapper/CommentMapper.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - update vertical_comment set comment_sharp_url = #{commentSharpUrl} where id = #{idComment} - - - - - \ No newline at end of file diff --git a/src/main/java/mapper/RoleMapper.xml b/src/main/java/mapper/RoleMapper.xml index 95b5c0f..7967a39 100644 --- a/src/main/java/mapper/RoleMapper.xml +++ b/src/main/java/mapper/RoleMapper.xml @@ -17,7 +17,7 @@ update vertical_role set status = #{status},updated_time = sysdate() where id = #{idRole} - update vertical_role set name = #{name}, input_code = #{inputCode}, weights = #{weights}, updated_time = sysdate() where id = #{idRole} + update vertical_role set name = #{name}, input_code = ${inputCode}, weights = #{weights}, updated_time = sysdate() where id = #{idRole} - select art.*,su.nickname,su.avatar_url from vertical_article art left join vertical_user su on art.article_author_id = su.id order by updated_time desc + select art.*,su.nickname,su.avatar_url from vertical_article art left join vertical_user su on art.article_author_id = su.id where article_status = '0' order by updated_time desc + \ No newline at end of file diff --git a/src/main/java/mapper/CommentMapper.xml b/src/main/java/mapper/CommentMapper.xml new file mode 100644 index 0000000..cbc5cbc --- /dev/null +++ b/src/main/java/mapper/CommentMapper.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + update vertical_comment set comment_sharp_url = #{commentSharpUrl} where id = #{idComment} + + + + + \ No newline at end of file diff --git a/src/main/java/mapper/RoleMapper.xml b/src/main/java/mapper/RoleMapper.xml index 7967a39..95b5c0f 100644 --- a/src/main/java/mapper/RoleMapper.xml +++ b/src/main/java/mapper/RoleMapper.xml @@ -17,7 +17,7 @@ update vertical_role set status = #{status},updated_time = sysdate() where id = #{idRole} - update vertical_role set name = #{name}, input_code = ${inputCode}, weights = #{weights}, updated_time = sysdate() where id = #{idRole} + update vertical_role set name = #{name}, input_code = #{inputCode}, weights = #{weights}, updated_time = sysdate() where id = #{idRole} select count(*) from vertical_user_tag where id_tag = #{idTag} and id_user = #{idUser} + \ No newline at end of file diff --git a/src/main/java/mapper/UserMapper.xml b/src/main/java/mapper/UserMapper.xml index ea2ab1a..398908e 100644 --- a/src/main/java/mapper/UserMapper.xml +++ b/src/main/java/mapper/UserMapper.xml @@ -39,6 +39,7 @@ + insert into vertical_user_role (id_user,id_role,created_time) values (#{idUser},#{idRole},sysdate()) @@ -67,7 +68,7 @@ select id, nickname, sex, avatar_type, avatar_url, email, phone, account, status, signature, last_login_time from vertical_user where account = #{account} - select art.*,su.nickname,su.avatar_url from vertical_article art left join vertical_user su on art.article_author_id = su.id where article_status = '0' order by updated_time desc - - + + + \ No newline at end of file diff --git a/src/main/java/mapper/PortfolioMapper.xml b/src/main/java/mapper/PortfolioMapper.xml new file mode 100644 index 0000000..c7f93a4 --- /dev/null +++ b/src/main/java/mapper/PortfolioMapper.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + insert into vertical_portfolio_article (id_vertical_portfolio, id_vertical_article, sort_no) values (#{idPortfolio}, #{idArticle}, #{maxSortNo}) + + + update vertical_portfolio_article set sort_no = #{sortNo} where id_vertical_portfolio = #{idPortfolio} and id_vertical_article = #{idArticle} + + + delete from vertical_portfolio_article where id_vertical_portfolio = #{idPortfolio} and id_vertical_article = #{idArticle} + + + + + + + \ No newline at end of file diff --git a/src/main/java/mapper/SpecialDayMapper.xml b/src/main/java/mapper/SpecialDayMapper.xml new file mode 100644 index 0000000..d4977b7 --- /dev/null +++ b/src/main/java/mapper/SpecialDayMapper.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/mapper/UserMapper.xml b/src/main/java/mapper/UserMapper.xml index 398908e..f134db4 100644 --- a/src/main/java/mapper/UserMapper.xml +++ b/src/main/java/mapper/UserMapper.xml @@ -41,6 +41,11 @@ + + + + + insert into vertical_user_role (id_user,id_role,created_time) values (#{idUser},#{idRole},sysdate()) @@ -82,5 +87,8 @@ + \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index a6281ae..d4a3203 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,6 +1,6 @@ spring: # profiles: -# active: pord +# active: dev thymeleaf: prefix: classpath:/templates/ suffix: .html @@ -12,7 +12,7 @@ spring: redis: host: 127.0.0.1 port: 6379 - password: # redis 密码 + password: d9d2j9w2 database: 1 timeout: 3000 jedis: @@ -22,31 +22,86 @@ spring: max-idle: 500 min-idle: 0 datasource: - url: jdbc:mysql://localhost:3306/vertical?characterEncoding=UTF-8&autoReconnect=true&useSSL=false + url: jdbc:mysql://101.132.182.12:3306/vertical?characterEncoding=UTF-8&autoReconnect=true&useSSL=false username: root - password: # 数据库密码 + password: d9d2j9w2.RYMCU driver-class-name: com.mysql.cj.jdbc.Driver + max-wait: 60000 + min-idle: 20 + initial-size: 10 + max-active: 50 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + time-between-eviction-runs-millis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + min-evictable-idle-time-millis: 30000 + validation-query: SELECT 1 FROM DUAL + test-while-idle: true + test-on-borrow: false + test-on-return: false + log-slow-sql: true + filters: config,stat,wall,log4j + max-pool-prepared-statement-per-connection-size: 100 + stat-view-servlet: + enabled: true + pool-prepared-statements: true resources: add-mappings: true mail: - host: smtp.163.com + host: smtp.ym.163.com port: 465 - username: # 邮箱 - password: # 密码 -env: dev + username: service@rymcu.com + password: Aa12345678 + servlet: + multipart: + max-file-size: 10MB + max-request-size: 20MB +wx: + open: + componentAppId: wx9c4a7dfb3238d5f6 + componentSecret: e32a6f75ab6b746ec3ae38a39a79ba22 + componentToken: rymcu + componentAesKey: NWIwMDQyZjU0YWI2NGFlZThkOWZhZTg3NTg4NzQwN2E + mp: + configs: + - appId: wxf085386aa07c0857 + secret: aabd075d2851764714fd14a0d0b1b8b4 + token: rymcu + aesKey: NWIwMDQyZjU0YWI2NGFlZThkOWZhZTg3NTg4NzQwN2E + - appId: wxa49093339a5a822b + secret: 29e9390e6d58d57a2b2a2350dbee8754 + token: qwert + aesKey: + miniapp: + configs: + - appid: wxf57df4f171606a26 + secret: 574ff86cb48a42f3980b221e942c53b1 + token: #微信小程序消息服务器配置的token + aesKey: #微信小程序消息服务器配置的EncodingAESKey + msgDataFormat: JSON +env: pord logging: file: path: /logs/vertical + level: + com: + rymcu: + vertical: + wx: debug + web: debug server: port: 8099 servlet: context-path: /vertical + compression: + enabled: true + mime-types: application/json,application/xml,text/html,text/xml,text/plain + min-response-size: 1024 + max-http-header-size: 1024 version: 1.0 resource: - file-path: https://abc.com/vertical + domain: https://rymcu.com + file-path: https://rymcu.com/vertical baidu: data: - site: https://abc.com # 百度搜索资源配置网址 - token: xxxx # 百度搜索资源token -reserved-words: \u7cfb\u7edf\u516c\u544a\u002c\u516c\u544a - + site: https://www.rymcu.com + token: 9cdKR6bVCJzxDEJS \ No newline at end of file diff --git a/src/main/resources/static/vertical.pdman.json b/src/main/resources/static/vertical.pdman.json index d88e481..fb36b1b 100644 --- a/src/main/resources/static/vertical.pdman.json +++ b/src/main/resources/static/vertical.pdman.json @@ -1592,6 +1592,504 @@ } ], "chnname": "浏览表" + }, + { + "title": "vertical_special_day-副本", + "chnname": "特殊日", + "fields": [ + { + "name": "id", + "type": "INT_10", + "chnname": "", + "remark": "", + "pk": true, + "notNull": true, + "autoIncrement": true, + "defaultValue": "" + }, + { + "name": "special_day_name", + "type": "VARCHAR_200", + "chnname": "名称", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "weights", + "type": "INT_10", + "chnname": "权重/优先级,小数优秀", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "start_time", + "type": "DATETIME", + "chnname": "开始时间", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "expiration_time", + "type": "DATETIME", + "chnname": "过期时间", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "repeat", + "type": "INT_10", + "chnname": "是否重复", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "repeat_cycle", + "type": "INT_10", + "chnname": "重复周期", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "repeat_cycle_unit", + "type": "INT_10", + "chnname": "0:天1:周2:月3:年", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "created_time", + "type": "DATETIME", + "chnname": "创建时间", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "img_url", + "type": "VARCHAR_500", + "chnname": "图片路径", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "css_style", + "type": "VARCHAR_2000", + "chnname": "执行全局样式", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + } + ], + "indexs": [], + "headers": [ + { + "fieldName": "chnname", + "relationNoShow": false + }, + { + "fieldName": "name", + "relationNoShow": false + }, + { + "fieldName": "type", + "relationNoShow": false + }, + { + "fieldName": "dataType", + "relationNoShow": true + }, + { + "fieldName": "remark", + "relationNoShow": true + }, + { + "fieldName": "pk", + "relationNoShow": false + }, + { + "fieldName": "notNull", + "relationNoShow": true + }, + { + "fieldName": "autoIncrement", + "relationNoShow": true + }, + { + "fieldName": "defaultValue", + "relationNoShow": true + }, + { + "fieldName": "relationNoShow", + "relationNoShow": true + }, + { + "fieldName": "uiHint", + "relationNoShow": true + } + ] + }, + { + "title": "vertical_wx_user-副本", + "chnname": "微信用户表", + "fields": [ + { + "name": "id", + "type": "INT_10", + "chnname": "微信用户表主键", + "remark": "", + "pk": true, + "notNull": true, + "autoIncrement": true, + "defaultValue": "" + }, + { + "name": "nickname", + "type": "VARCHAR_50", + "chnname": "", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "union_id", + "type": "VARCHAR_32", + "chnname": "微信全局 unionId", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "open_id", + "type": "VARCHAR_32", + "chnname": "openId", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "app_id", + "type": "VARCHAR_32", + "chnname": "AppId", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "sex", + "type": "INT_10", + "chnname": "性别字段", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "sex_desc", + "type": "VARCHAR_32", + "chnname": "性别文本", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "head_img_url", + "type": "VARCHAR_200", + "chnname": "头像图片路径", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "country", + "type": "VARCHAR_32", + "chnname": "所属国家", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "province", + "type": "VARCHAR_32", + "chnname": "所属省/州", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "city", + "type": "VARCHAR_32", + "chnname": "所属市/区", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "act_token", + "type": "VARCHAR_64", + "chnname": "活动 Token", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "subscribe", + "type": "BIT_1", + "chnname": "是否关注", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "subscribe_time", + "type": "MEDIUMTEXT", + "chnname": "关注时间戳", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "language", + "type": "VARCHAR_10", + "chnname": "语言", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + } + ] + }, + { + "title": "vertical_collection", + "fields": [ + { + "name": "id", + "type": "BigInt", + "remark": "", + "chnname": "主键", + "pk": true, + "notNull": true, + "autoIncrement": true + }, + { + "name": "head_img_url", + "type": "VARCHAR_500", + "remark": "", + "chnname": "作品集头像" + }, + { + "name": "name", + "type": "DefaultString", + "remark": "", + "chnname": "作品集名称" + }, + { + "name": "portfolio_author_id", + "type": "BigInt", + "remark": "", + "chnname": "作品集作者" + }, + { + "name": "description", + "type": "MiddleString", + "remark": "", + "chnname": "作品集介绍" + }, + { + "name": "created_time", + "type": "DateTime", + "remark": "", + "chnname": "创建时间" + }, + { + "name": "updated_time", + "type": "DateTime", + "remark": "", + "chnname": "更新时间" + } + ], + "indexs": [], + "headers": [ + { + "fieldName": "chnname", + "relationNoShow": false + }, + { + "fieldName": "name", + "relationNoShow": false + }, + { + "fieldName": "type", + "relationNoShow": false + }, + { + "fieldName": "dataType", + "relationNoShow": true + }, + { + "fieldName": "remark", + "relationNoShow": true + }, + { + "fieldName": "pk", + "relationNoShow": false + }, + { + "fieldName": "notNull", + "relationNoShow": true + }, + { + "fieldName": "autoIncrement", + "relationNoShow": true + }, + { + "fieldName": "defaultValue", + "relationNoShow": true + }, + { + "fieldName": "relationNoShow", + "relationNoShow": true + }, + { + "fieldName": "uiHint", + "relationNoShow": true + } + ], + "chnname": "作品集", + "remark": "作品集" + }, + { + "title": "vertical_collection_article", + "fields": [ + { + "name": "id", + "type": "BigInt", + "remark": "", + "chnname": "主键", + "pk": true, + "notNull": true, + "autoIncrement": true + }, + { + "name": "id_vertical_portfolio", + "type": "BigInt", + "remark": "", + "chnname": "作品集表主键" + }, + { + "name": "id_vertical_article", + "type": "BigInt", + "remark": "", + "chnname": "文章表主键" + }, + { + "name": "sort_no", + "type": "Integer", + "remark": "", + "chnname": "排序号" + } + ], + "indexs": [], + "headers": [ + { + "fieldName": "chnname", + "relationNoShow": false + }, + { + "fieldName": "name", + "relationNoShow": false + }, + { + "fieldName": "type", + "relationNoShow": false + }, + { + "fieldName": "dataType", + "relationNoShow": true + }, + { + "fieldName": "remark", + "relationNoShow": true + }, + { + "fieldName": "pk", + "relationNoShow": false + }, + { + "fieldName": "notNull", + "relationNoShow": true + }, + { + "fieldName": "autoIncrement", + "relationNoShow": true + }, + { + "fieldName": "defaultValue", + "relationNoShow": true + }, + { + "fieldName": "relationNoShow", + "relationNoShow": true + }, + { + "fieldName": "uiHint", + "relationNoShow": true + } + ], + "chnname": "作品集与文章关系表" } ], "graphCanvas": { @@ -1982,6 +2480,336 @@ } } ] + }, + { + "name": "DB_REVERSE_MYSQL", + "chnname": "逆向解析_MYSQL", + "entities": [ + { + "title": "vertical_special_day", + "chnname": "特殊日", + "fields": [ + { + "name": "id", + "type": "BigInt", + "chnname": "", + "remark": "", + "pk": true, + "notNull": true, + "autoIncrement": true, + "defaultValue": "" + }, + { + "name": "special_day_name", + "type": "VARCHAR_200", + "chnname": "名称", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "weights", + "type": "Integer", + "chnname": "权重/优先级,小数优秀", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "start_time", + "type": "DATETIME", + "chnname": "开始时间", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "expiration_time", + "type": "DATETIME", + "chnname": "过期时间", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "repeat", + "type": "Integer", + "chnname": "是否重复", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "repeat_cycle", + "type": "Integer", + "chnname": "重复周期", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "repeat_cycle_unit", + "type": "Integer", + "chnname": "0:天1:周2:月3:年", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "created_time", + "type": "DATETIME", + "chnname": "创建时间", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "img_url", + "type": "VARCHAR_500", + "chnname": "图片路径", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "css_style", + "type": "VARCHAR_2000", + "chnname": "执行全局样式", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + } + ], + "indexs": [], + "headers": [ + { + "fieldName": "chnname", + "relationNoShow": false + }, + { + "fieldName": "name", + "relationNoShow": false + }, + { + "fieldName": "type", + "relationNoShow": false + }, + { + "fieldName": "dataType", + "relationNoShow": true + }, + { + "fieldName": "remark", + "relationNoShow": true + }, + { + "fieldName": "pk", + "relationNoShow": false + }, + { + "fieldName": "notNull", + "relationNoShow": true + }, + { + "fieldName": "autoIncrement", + "relationNoShow": true + }, + { + "fieldName": "defaultValue", + "relationNoShow": true + }, + { + "fieldName": "relationNoShow", + "relationNoShow": true + }, + { + "fieldName": "uiHint", + "relationNoShow": true + } + ] + }, + { + "title": "vertical_wx_user", + "chnname": "微信用户表", + "fields": [ + { + "name": "id", + "type": "INT_10", + "chnname": "微信用户表主键", + "remark": "", + "pk": true, + "notNull": true, + "autoIncrement": true, + "defaultValue": "" + }, + { + "name": "nickname", + "type": "VARCHAR_50", + "chnname": "", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "union_id", + "type": "VARCHAR_32", + "chnname": "微信全局 unionId", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "open_id", + "type": "VARCHAR_32", + "chnname": "openId", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "app_id", + "type": "VARCHAR_32", + "chnname": "AppId", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "sex", + "type": "INT_10", + "chnname": "性别字段", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "sex_desc", + "type": "VARCHAR_32", + "chnname": "性别文本", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "head_img_url", + "type": "VARCHAR_200", + "chnname": "头像图片路径", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "country", + "type": "VARCHAR_32", + "chnname": "所属国家", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "province", + "type": "VARCHAR_32", + "chnname": "所属省/州", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "city", + "type": "VARCHAR_32", + "chnname": "所属市/区", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "act_token", + "type": "VARCHAR_64", + "chnname": "活动 Token", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "subscribe", + "type": "BIT_1", + "chnname": "是否关注", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "subscribe_time", + "type": "MEDIUMTEXT", + "chnname": "关注时间戳", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + }, + { + "name": "language", + "type": "VARCHAR_10", + "chnname": "语言", + "remark": "", + "pk": false, + "notNull": false, + "autoIncrement": false, + "defaultValue": "" + } + ] + } + ], + "graphCanvas": { + "nodes": [], + "edges": [] + }, + "associations": [] } ], "dataTypeDomains": { @@ -2501,6 +3329,78 @@ "type": "VARCHAR(64)" } } + }, + { + "name": "BIT_1", + "code": "BIT_1", + "apply": { + "MYSQL": { + "type": "BIT(1)" + } + } + }, + { + "name": "DATE", + "code": "DATE", + "apply": { + "MYSQL": { + "type": "DATE" + } + } + }, + { + "name": "MEDIUMTEXT", + "code": "MEDIUMTEXT", + "apply": { + "MYSQL": { + "type": "MEDIUMTEXT" + } + } + }, + { + "name": "VARCHAR_10", + "code": "VARCHAR_10", + "apply": { + "MYSQL": { + "type": "VARCHAR(10)" + } + } + }, + { + "name": "VARCHAR_200", + "code": "VARCHAR_200", + "apply": { + "MYSQL": { + "type": "VARCHAR(200)" + } + } + }, + { + "name": "VARCHAR_2000", + "code": "VARCHAR_2000", + "apply": { + "MYSQL": { + "type": "VARCHAR(2000)" + } + } + }, + { + "name": "VARCHAR_50", + "code": "VARCHAR_50", + "apply": { + "MYSQL": { + "type": "VARCHAR(50)" + } + } + }, + { + "name": "VARCHAR_500", + "code": "VARCHAR_500", + "apply": { + "MYSQL": { + "type": "VARCHAR(500)" + } + } } ], "database": [ @@ -2609,18 +3509,30 @@ } ], "defaultFieldsType": "1", - "javaConfig": {}, + "javaConfig": { + "JAVA_HOME": "C:\\Program Files\\Java\\jdk1.8.0_111" + }, "sqlConfig": "", "dbs": [ { "name": "rymcu", - "defaultDB": true, + "defaultDB": false, "properties": { "driver_class_name": "com.mysql.jdbc.Driver", "url": "jdbc:mysql://101.132.182.12:3306/vertical?characterEncoding=UTF-8&useSSL=false&useUnicode=true&serverTimezone=UTC", "password": "d9d2j9w2.RYMCU", "username": "root" } + }, + { + "name": "test_rymcu", + "defaultDB": true, + "properties": { + "driver_class_name": "com.mysql.jdbc.Driver", + "url": "jdbc:mysql://120.26.175.127:3306/vertical?characterEncoding=UTF-8&useSSL=false&useUnicode=true&serverTimezone=UTC", + "password": "rymcu.Test4", + "username": "root" + } } ], "wordTemplateConfig": "" From 3d06abaacaba187bab25e252efcf0845419016b3 Mon Sep 17 00:00:00 2001 From: ronger Date: Mon, 8 Jun 2020 14:11:20 +0800 Subject: [PATCH 14/36] =?UTF-8?q?:fire:=20=E5=88=A0=E9=99=A4=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E7=9B=B8=E5=85=B3=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vertical/config/RedisProperties.java | 124 ++++++++++++++++++ .../service/redis/impl/RedisServiceImpl.java | 2 + .../rymcu/vertical/mapper/WxUserMapper.java | 10 -- .../rymcu/vertical/service/WxUserService.java | 14 -- .../service/impl/WxUserServiceImpl.java | 62 --------- src/main/java/mapper/WxUserMapper.xml | 21 --- 6 files changed, 126 insertions(+), 107 deletions(-) create mode 100644 src/main/java/com/rymcu/vertical/config/RedisProperties.java delete mode 100644 src/main/java/com/rymcu/vertical/mapper/WxUserMapper.java delete mode 100644 src/main/java/com/rymcu/vertical/service/WxUserService.java delete mode 100644 src/main/java/com/rymcu/vertical/service/impl/WxUserServiceImpl.java delete mode 100644 src/main/java/mapper/WxUserMapper.xml diff --git a/src/main/java/com/rymcu/vertical/config/RedisProperties.java b/src/main/java/com/rymcu/vertical/config/RedisProperties.java new file mode 100644 index 0000000..02ae5d2 --- /dev/null +++ b/src/main/java/com/rymcu/vertical/config/RedisProperties.java @@ -0,0 +1,124 @@ +package com.rymcu.vertical.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import redis.clients.jedis.JedisPoolConfig; +import redis.clients.jedis.Protocol; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLSocketFactory; + +/** + * @author 007 + */ +@ConfigurationProperties(prefix = "spring.redis") +public class RedisProperties extends JedisPoolConfig { + private String host = Protocol.DEFAULT_HOST; + private int port = Protocol.DEFAULT_PORT; + private String password; + private int database = 1; + private int connectionTimeout = Protocol.DEFAULT_TIMEOUT; + private int soTimeout = Protocol.DEFAULT_TIMEOUT; + private String clientName; + private boolean ssl; + private SSLSocketFactory sslSocketFactory; + private SSLParameters sslParameters; + private HostnameVerifier hostnameVerifier; + + public boolean isSsl() { + return ssl; + } + + public void setSsl(boolean ssl) { + this.ssl = ssl; + } + + public SSLSocketFactory getSslSocketFactory() { + return sslSocketFactory; + } + + public void setSslSocketFactory(SSLSocketFactory sslSocketFactory) { + this.sslSocketFactory = sslSocketFactory; + } + + public SSLParameters getSslParameters() { + return sslParameters; + } + + public void setSslParameters(SSLParameters sslParameters) { + this.sslParameters = sslParameters; + } + + public HostnameVerifier getHostnameVerifier() { + return hostnameVerifier; + } + + public void setHostnameVerifier(HostnameVerifier hostnameVerifier) { + this.hostnameVerifier = hostnameVerifier; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + if (host == null || "".equals(host)) { + host = Protocol.DEFAULT_HOST; + } + this.host = host; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + if ("".equals(password)) { + password = null; + } + this.password = password; + } + + public int getDatabase() { + return database; + } + + public void setDatabase(int database) { + this.database = database; + } + + public String getClientName() { + return clientName; + } + + public void setClientName(String clientName) { + if ("".equals(clientName)) { + clientName = null; + } + this.clientName = clientName; + } + + public int getConnectionTimeout() { + return connectionTimeout; + } + + public void setConnectionTimeout(int connectionTimeout) { + this.connectionTimeout = connectionTimeout; + } + + public int getSoTimeout() { + return soTimeout; + } + + public void setSoTimeout(int soTimeout) { + this.soTimeout = soTimeout; + } +} diff --git a/src/main/java/com/rymcu/vertical/core/service/redis/impl/RedisServiceImpl.java b/src/main/java/com/rymcu/vertical/core/service/redis/impl/RedisServiceImpl.java index 90ef3af..85dc35a 100644 --- a/src/main/java/com/rymcu/vertical/core/service/redis/impl/RedisServiceImpl.java +++ b/src/main/java/com/rymcu/vertical/core/service/redis/impl/RedisServiceImpl.java @@ -9,6 +9,7 @@ import com.rymcu.vertical.core.service.redis.RedisService; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import redis.clients.jedis.Jedis; @@ -27,6 +28,7 @@ import java.util.*; * 16/10/30 下午5:28 */ @Component("redisService") +@EnableConfigurationProperties({RedisProperties.class}) public class RedisServiceImpl implements RedisService { private static final Logger logger = LoggerFactory.getLogger(RedisServiceImpl.class); diff --git a/src/main/java/com/rymcu/vertical/mapper/WxUserMapper.java b/src/main/java/com/rymcu/vertical/mapper/WxUserMapper.java deleted file mode 100644 index 9e941d3..0000000 --- a/src/main/java/com/rymcu/vertical/mapper/WxUserMapper.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.rymcu.vertical.mapper; - -import com.rymcu.vertical.core.mapper.Mapper; -import com.rymcu.vertical.entity.WxUser; - -/** - * @author ronger - */ -public interface WxUserMapper extends Mapper { -} diff --git a/src/main/java/com/rymcu/vertical/service/WxUserService.java b/src/main/java/com/rymcu/vertical/service/WxUserService.java deleted file mode 100644 index 59e8527..0000000 --- a/src/main/java/com/rymcu/vertical/service/WxUserService.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.rymcu.vertical.service; - -import com.rymcu.vertical.core.service.Service; -import com.rymcu.vertical.entity.WxUser; -import me.chanjar.weixin.mp.bean.result.WxMpUser; - -/** - * @author ronger - */ -public interface WxUserService extends Service { - - WxUser saveUser(WxMpUser wxMpUser, String appId); - -} diff --git a/src/main/java/com/rymcu/vertical/service/impl/WxUserServiceImpl.java b/src/main/java/com/rymcu/vertical/service/impl/WxUserServiceImpl.java deleted file mode 100644 index 3309f0d..0000000 --- a/src/main/java/com/rymcu/vertical/service/impl/WxUserServiceImpl.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.rymcu.vertical.service.impl; - -import com.rymcu.vertical.core.service.AbstractService; -import com.rymcu.vertical.entity.WxUser; -import com.rymcu.vertical.mapper.WxUserMapper; -import com.rymcu.vertical.service.WxUserService; -import me.chanjar.weixin.mp.bean.result.WxMpUser; -import org.apache.commons.lang.StringUtils; -import org.springframework.stereotype.Service; - -import javax.annotation.Resource; -import java.util.List; - -/** - * @author ronger - */ -@Service -public class WxUserServiceImpl extends AbstractService implements WxUserService { - - @Resource - private WxUserMapper wxUserMapper; - - @Override - public WxUser saveUser(WxMpUser wxMpUser, String appId) { - WxUser searchWxUser = new WxUser(); - if (StringUtils.isBlank(wxMpUser.getUnionId())) { - searchWxUser.setUnionId(wxMpUser.getUnionId()); - } else { - searchWxUser.setAppId(appId); - searchWxUser.setOpenId(searchWxUser.getOpenId()); - } - List wxUsers = wxUserMapper.select(searchWxUser); - WxUser wxUser; - if (wxUsers.isEmpty()) { - wxUser = new WxUser(); - wxUser.setAppId(appId); - wxUser = copyWxUser(wxMpUser,wxUser); - wxUserMapper.insertSelective(wxUser); - } else { - wxUser = wxUsers.get(0); - wxUser = copyWxUser(wxMpUser,wxUser); - wxUserMapper.updateByPrimaryKeySelective(wxUser); - } - return wxUser; - } - - private WxUser copyWxUser(WxMpUser wxMpUser, WxUser wxUser) { - wxUser.setNickname(wxMpUser.getNickname()); - wxUser.setHeadImgUrl(wxMpUser.getHeadImgUrl()); - wxUser.setCountry(wxMpUser.getCountry()); - wxUser.setProvince(wxMpUser.getProvince()); - wxUser.setCity(wxMpUser.getCity()); - wxUser.setSex(wxMpUser.getSex()); - wxUser.setSubscribe(wxMpUser.getSubscribe()); - wxUser.setSubscribeTime(wxMpUser.getSubscribeTime()); - wxUser.setUnionId(wxMpUser.getUnionId()); - wxUser.setOpenId(wxMpUser.getOpenId()); - wxUser.setLanguage(wxMpUser.getLanguage()); - wxUser.setSexDesc(wxMpUser.getSexDesc()); - return wxUser; - } -} diff --git a/src/main/java/mapper/WxUserMapper.xml b/src/main/java/mapper/WxUserMapper.xml deleted file mode 100644 index 228a592..0000000 --- a/src/main/java/mapper/WxUserMapper.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From 9b713a9200731ce701cb17b04c7084de4bc3fb35 Mon Sep 17 00:00:00 2001 From: ronger Date: Wed, 24 Jun 2020 10:42:15 +0800 Subject: [PATCH 15/36] delete --- src/main/resources/application.yml | 107 ----------------------------- 1 file changed, 107 deletions(-) delete mode 100644 src/main/resources/application.yml diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml deleted file mode 100644 index d4a3203..0000000 --- a/src/main/resources/application.yml +++ /dev/null @@ -1,107 +0,0 @@ -spring: -# profiles: -# active: dev - thymeleaf: - prefix: classpath:/templates/ - suffix: .html - mode: LEGACYHTML5 - encoding: UTF-8 - servlet: - content-type: text/html - cache: false - redis: - host: 127.0.0.1 - port: 6379 - password: d9d2j9w2 - database: 1 - timeout: 3000 - jedis: - pool: - max-active: 8 - max-wait: 1 - max-idle: 500 - min-idle: 0 - datasource: - url: jdbc:mysql://101.132.182.12:3306/vertical?characterEncoding=UTF-8&autoReconnect=true&useSSL=false - username: root - password: d9d2j9w2.RYMCU - driver-class-name: com.mysql.cj.jdbc.Driver - max-wait: 60000 - min-idle: 20 - initial-size: 10 - max-active: 50 - # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 - time-between-eviction-runs-millis: 60000 - # 配置一个连接在池中最小生存的时间,单位是毫秒 - min-evictable-idle-time-millis: 30000 - validation-query: SELECT 1 FROM DUAL - test-while-idle: true - test-on-borrow: false - test-on-return: false - log-slow-sql: true - filters: config,stat,wall,log4j - max-pool-prepared-statement-per-connection-size: 100 - stat-view-servlet: - enabled: true - pool-prepared-statements: true - resources: - add-mappings: true - mail: - host: smtp.ym.163.com - port: 465 - username: service@rymcu.com - password: Aa12345678 - servlet: - multipart: - max-file-size: 10MB - max-request-size: 20MB -wx: - open: - componentAppId: wx9c4a7dfb3238d5f6 - componentSecret: e32a6f75ab6b746ec3ae38a39a79ba22 - componentToken: rymcu - componentAesKey: NWIwMDQyZjU0YWI2NGFlZThkOWZhZTg3NTg4NzQwN2E - mp: - configs: - - appId: wxf085386aa07c0857 - secret: aabd075d2851764714fd14a0d0b1b8b4 - token: rymcu - aesKey: NWIwMDQyZjU0YWI2NGFlZThkOWZhZTg3NTg4NzQwN2E - - appId: wxa49093339a5a822b - secret: 29e9390e6d58d57a2b2a2350dbee8754 - token: qwert - aesKey: - miniapp: - configs: - - appid: wxf57df4f171606a26 - secret: 574ff86cb48a42f3980b221e942c53b1 - token: #微信小程序消息服务器配置的token - aesKey: #微信小程序消息服务器配置的EncodingAESKey - msgDataFormat: JSON -env: pord -logging: - file: - path: /logs/vertical - level: - com: - rymcu: - vertical: - wx: debug - web: debug -server: - port: 8099 - servlet: - context-path: /vertical - compression: - enabled: true - mime-types: application/json,application/xml,text/html,text/xml,text/plain - min-response-size: 1024 - max-http-header-size: 1024 -version: 1.0 -resource: - domain: https://rymcu.com - file-path: https://rymcu.com/vertical -baidu: - data: - site: https://www.rymcu.com - token: 9cdKR6bVCJzxDEJS \ No newline at end of file From b7e0468007d834d9980058f6654c3b7774e7e5ff Mon Sep 17 00:00:00 2001 From: ronger Date: Wed, 24 Jun 2020 10:45:23 +0800 Subject: [PATCH 16/36] first commit --- src/main/resources/application.yml | 83 +++++------------------------- 1 file changed, 14 insertions(+), 69 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index d4a3203..4dd536e 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,6 +1,6 @@ spring: -# profiles: -# active: dev + # profiles: + # active: pord thymeleaf: prefix: classpath:/templates/ suffix: .html @@ -12,7 +12,7 @@ spring: redis: host: 127.0.0.1 port: 6379 - password: d9d2j9w2 + password: # redis 密码 database: 1 timeout: 3000 jedis: @@ -22,86 +22,31 @@ spring: max-idle: 500 min-idle: 0 datasource: - url: jdbc:mysql://101.132.182.12:3306/vertical?characterEncoding=UTF-8&autoReconnect=true&useSSL=false + url: jdbc:mysql://localhost:3306/vertical?characterEncoding=UTF-8&autoReconnect=true&useSSL=false username: root - password: d9d2j9w2.RYMCU + password: # 数据库密码 driver-class-name: com.mysql.cj.jdbc.Driver - max-wait: 60000 - min-idle: 20 - initial-size: 10 - max-active: 50 - # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 - time-between-eviction-runs-millis: 60000 - # 配置一个连接在池中最小生存的时间,单位是毫秒 - min-evictable-idle-time-millis: 30000 - validation-query: SELECT 1 FROM DUAL - test-while-idle: true - test-on-borrow: false - test-on-return: false - log-slow-sql: true - filters: config,stat,wall,log4j - max-pool-prepared-statement-per-connection-size: 100 - stat-view-servlet: - enabled: true - pool-prepared-statements: true resources: add-mappings: true mail: - host: smtp.ym.163.com + host: smtp.163.com port: 465 - username: service@rymcu.com - password: Aa12345678 - servlet: - multipart: - max-file-size: 10MB - max-request-size: 20MB -wx: - open: - componentAppId: wx9c4a7dfb3238d5f6 - componentSecret: e32a6f75ab6b746ec3ae38a39a79ba22 - componentToken: rymcu - componentAesKey: NWIwMDQyZjU0YWI2NGFlZThkOWZhZTg3NTg4NzQwN2E - mp: - configs: - - appId: wxf085386aa07c0857 - secret: aabd075d2851764714fd14a0d0b1b8b4 - token: rymcu - aesKey: NWIwMDQyZjU0YWI2NGFlZThkOWZhZTg3NTg4NzQwN2E - - appId: wxa49093339a5a822b - secret: 29e9390e6d58d57a2b2a2350dbee8754 - token: qwert - aesKey: - miniapp: - configs: - - appid: wxf57df4f171606a26 - secret: 574ff86cb48a42f3980b221e942c53b1 - token: #微信小程序消息服务器配置的token - aesKey: #微信小程序消息服务器配置的EncodingAESKey - msgDataFormat: JSON -env: pord + username: # 邮箱 + password: # 密码 +env: dev logging: file: path: /logs/vertical - level: - com: - rymcu: - vertical: - wx: debug - web: debug server: port: 8099 servlet: context-path: /vertical - compression: - enabled: true - mime-types: application/json,application/xml,text/html,text/xml,text/plain - min-response-size: 1024 - max-http-header-size: 1024 version: 1.0 resource: - domain: https://rymcu.com - file-path: https://rymcu.com/vertical + file-path: https://abc.com/vertical baidu: data: - site: https://www.rymcu.com - token: 9cdKR6bVCJzxDEJS \ No newline at end of file + site: https://abc.com # 百度搜索资源配置网址 + token: xxxx # 百度搜索资源token +reserved-words: \u7cfb\u7edf\u516c\u544a\u002c\u516c\u544a + From f127686c9ad4e536b41631cbd8bc830f05910b31 Mon Sep 17 00:00:00 2001 From: ronger Date: Wed, 24 Jun 2020 10:58:49 +0800 Subject: [PATCH 17/36] add application.yml --- src/main/resources/application.yml | 52 ++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/main/resources/application.yml diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..0026346 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,52 @@ +spring: + # profiles: + # active: pord + thymeleaf: + prefix: classpath:/templates/ + suffix: .html + mode: LEGACYHTML5 + encoding: UTF-8 + servlet: + content-type: text/html + cache: false + redis: + host: 127.0.0.1 + port: 6379 + password: # redis 密码 + database: 1 + timeout: 3000 + jedis: + pool: + max-active: 8 + max-wait: 1 + max-idle: 500 + min-idle: 0 + datasource: + url: jdbc:mysql://localhost:3306/vertical?characterEncoding=UTF-8&autoReconnect=true&useSSL=false + username: root + password: # 数据库密码 + driver-class-name: com.mysql.cj.jdbc.Driver + resources: + add-mappings: true + mail: + host: smtp.163.com + port: 465 + username: # 邮箱 + password: # 密码 +env: dev +logging: + file: + path: /logs/vertical +server: + port: 8099 + servlet: + context-path: /vertical +version: 1.0 +resource: + file-path: https://abc.com/vertical +baidu: + data: + site: https://abc.com # 百度搜索资源配置网址 + token: xxxx # 百度搜索资源token +reserved-words: \u7cfb\u7edf\u516c\u544a\u002c\u516c\u544a + From 26d8674f340fff1a071e1fc2ae789b63ab140455 Mon Sep 17 00:00:00 2001 From: x ronger Date: Sat, 1 Aug 2020 00:43:58 +0800 Subject: [PATCH 18/36] =?UTF-8?q?:sparkles:=20=20=E4=B8=93=E9=A2=98?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E5=8A=9F=E8=83=BD=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/rymcu/vertical/dto/ArticleDTO.java | 2 -- .../rymcu/vertical/dto/ArticleSearchDTO.java | 17 +++++++++++++++++ .../rymcu/vertical/mapper/ArticleMapper.java | 3 ++- .../rymcu/vertical/service/ArticleService.java | 6 +++--- .../service/impl/ArticleServiceImpl.java | 13 ++++++++----- .../web/api/common/CommonApiController.java | 12 ++++++------ 6 files changed, 36 insertions(+), 17 deletions(-) create mode 100644 src/main/java/com/rymcu/vertical/dto/ArticleSearchDTO.java diff --git a/src/main/java/com/rymcu/vertical/dto/ArticleDTO.java b/src/main/java/com/rymcu/vertical/dto/ArticleDTO.java index aaa0759..ac89644 100644 --- a/src/main/java/com/rymcu/vertical/dto/ArticleDTO.java +++ b/src/main/java/com/rymcu/vertical/dto/ArticleDTO.java @@ -50,8 +50,6 @@ public class ArticleDTO { private List tags; - private List articleComments; - private List portfolios; private Integer sortNo; diff --git a/src/main/java/com/rymcu/vertical/dto/ArticleSearchDTO.java b/src/main/java/com/rymcu/vertical/dto/ArticleSearchDTO.java new file mode 100644 index 0000000..1e3bb6f --- /dev/null +++ b/src/main/java/com/rymcu/vertical/dto/ArticleSearchDTO.java @@ -0,0 +1,17 @@ +package com.rymcu.vertical.dto; + +import lombok.Data; + +/** + * @author ronger + */ +@Data +public class ArticleSearchDTO { + + private String searchText; + + private String topicUri; + + private String tag; + +} diff --git a/src/main/java/com/rymcu/vertical/mapper/ArticleMapper.java b/src/main/java/com/rymcu/vertical/mapper/ArticleMapper.java index 6194cee..8c74ece 100644 --- a/src/main/java/com/rymcu/vertical/mapper/ArticleMapper.java +++ b/src/main/java/com/rymcu/vertical/mapper/ArticleMapper.java @@ -19,9 +19,10 @@ public interface ArticleMapper extends Mapper
{ * 获取文章列表 * @param searchText * @param tag + * @param topicUri * @return */ - List selectArticles(@Param("searchText") String searchText, @Param("tag") String tag); + List selectArticles(@Param("searchText") String searchText, @Param("tag") String tag, @Param("topicUri") String topicUri); /** * 根据文章 ID 查询文章 diff --git a/src/main/java/com/rymcu/vertical/service/ArticleService.java b/src/main/java/com/rymcu/vertical/service/ArticleService.java index 497cdf8..65f6718 100644 --- a/src/main/java/com/rymcu/vertical/service/ArticleService.java +++ b/src/main/java/com/rymcu/vertical/service/ArticleService.java @@ -2,6 +2,7 @@ package com.rymcu.vertical.service; import com.rymcu.vertical.core.service.Service; import com.rymcu.vertical.dto.ArticleDTO; +import com.rymcu.vertical.dto.ArticleSearchDTO; import com.rymcu.vertical.entity.Article; import com.rymcu.vertical.web.api.exception.BaseApiException; @@ -17,11 +18,10 @@ public interface ArticleService extends Service
{ /** * 根据检索内容/标签查询文章列表 - * @param searchText - * @param tag + * @param searchDTO * @return * */ - List findArticles(String searchText, String tag); + List findArticles(ArticleSearchDTO searchDTO); /** * 查询文章详情信息 diff --git a/src/main/java/com/rymcu/vertical/service/impl/ArticleServiceImpl.java b/src/main/java/com/rymcu/vertical/service/impl/ArticleServiceImpl.java index 271c40d..a041b7f 100644 --- a/src/main/java/com/rymcu/vertical/service/impl/ArticleServiceImpl.java +++ b/src/main/java/com/rymcu/vertical/service/impl/ArticleServiceImpl.java @@ -52,10 +52,16 @@ public class ArticleServiceImpl extends AbstractService
implements Arti private static final int MAX_PREVIEW = 200; private static final String defaultStatus = "0"; + private static final String defaultTopicUri = "news"; @Override - public List findArticles(String searchText, String tag) { - List list = articleMapper.selectArticles(searchText, tag); + public List findArticles(ArticleSearchDTO searchDTO) { + List list; + if (StringUtils.isNotBlank(searchDTO.getTopicUri()) && !defaultTopicUri.equals(searchDTO.getTopicUri())) { + list = articleMapper.selectArticlesByTopicUri(searchDTO.getTopicUri()); + } else { + list = articleMapper.selectArticles(searchDTO.getSearchText(), searchDTO.getTag(), searchDTO.getTopicUri()); + } list.forEach(article->{ genArticle(article,0); }); @@ -292,9 +298,6 @@ public class ArticleServiceImpl extends AbstractService
implements Arti ArticleContent articleContent = articleMapper.selectArticleContent(article.getIdArticle()); if (type.equals(ARTICLE_VIEW)){ article.setArticleContent(articleContent.getArticleContentHtml()); - // 获取评论列表数据 - List commentDTOList = commentService.getArticleComments(article.getIdArticle()); - article.setArticleComments(commentDTOList); // 获取所属作品集列表数据 List portfolioArticleDTOList = articleMapper.selectPortfolioArticles(article.getIdArticle()); article.setPortfolios(portfolioArticleDTOList); diff --git a/src/main/java/com/rymcu/vertical/web/api/common/CommonApiController.java b/src/main/java/com/rymcu/vertical/web/api/common/CommonApiController.java index 722b5bc..34f4971 100644 --- a/src/main/java/com/rymcu/vertical/web/api/common/CommonApiController.java +++ b/src/main/java/com/rymcu/vertical/web/api/common/CommonApiController.java @@ -43,14 +43,14 @@ public class CommonApiController { @GetMapping("/get-email-code") public GlobalResult> getEmailCode(@RequestParam("email") String email) throws MessagingException { Map map = new HashMap<>(1); - map.put("message",GlobalResultMessage.SEND_SUCCESS.getMessage()); + map.put("message", GlobalResultMessage.SEND_SUCCESS.getMessage()); User user = userService.findByAccount(email); if (user != null) { map.put("message","该邮箱已被注册!"); } else { Integer result = javaMailService.sendEmailCode(email); if(result == 0){ - map.put("message",GlobalResultMessage.SEND_FAIL.getMessage()); + map.put("message", GlobalResultMessage.SEND_FAIL.getMessage()); } } return GlobalResultGenerator.genSuccessResult(map); @@ -60,12 +60,12 @@ public class CommonApiController { @GetMapping("/get-forget-password-email") public GlobalResult> getForgetPasswordEmail(@RequestParam("email") String email) throws MessagingException { Map map = new HashMap<>(1); - map.put("message",GlobalResultMessage.SEND_SUCCESS.getMessage()); + map.put("message", GlobalResultMessage.SEND_SUCCESS.getMessage()); User user = userService.findByAccount(email); if (user != null) { Integer result = javaMailService.sendForgetPasswordEmail(email); if(result == 0){ - map.put("message",GlobalResultMessage.SEND_FAIL.getMessage()); + map.put("message", GlobalResultMessage.SEND_FAIL.getMessage()); } } else { map.put("message","该邮箱未注册!"); @@ -92,9 +92,9 @@ public class CommonApiController { @GetMapping("/articles") @VisitLogger - public GlobalResult articles(@RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "10") Integer rows, @RequestParam(defaultValue = "") String searchText, @RequestParam(defaultValue = "") String tag){ + public GlobalResult articles(@RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "10") Integer rows, ArticleSearchDTO searchDTO){ PageHelper.startPage(page, rows); - List list = articleService.findArticles(searchText,tag); + List list = articleService.findArticles(searchDTO); PageInfo pageInfo = new PageInfo(list); Map map = Utils.getArticlesGlobalResult(pageInfo); return GlobalResultGenerator.genSuccessResult(map); From 0d50debe6ad4dc2bca99383c7598a9f062bc7d65 Mon Sep 17 00:00:00 2001 From: x ronger Date: Mon, 3 Aug 2020 00:01:52 +0800 Subject: [PATCH 19/36] =?UTF-8?q?:bug:=20=E8=8D=89=E7=A8=BF=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/rymcu/vertical/config/WebMvcConfigurer.java | 12 +++++++----- .../vertical/service/impl/ArticleServiceImpl.java | 2 ++ .../vertical/web/api/common/UploadController.java | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/rymcu/vertical/config/WebMvcConfigurer.java b/src/main/java/com/rymcu/vertical/config/WebMvcConfigurer.java index c45c0b0..8c053f0 100644 --- a/src/main/java/com/rymcu/vertical/config/WebMvcConfigurer.java +++ b/src/main/java/com/rymcu/vertical/config/WebMvcConfigurer.java @@ -23,6 +23,7 @@ import java.util.List; /** * Spring MVC 配置 + * * @author ronger */ @Configuration @@ -49,7 +50,7 @@ public class WebMvcConfigurer extends WebMvcConfigurationSupport { /** * 解决跨域问题 - * */ + */ @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") @@ -65,17 +66,18 @@ public class WebMvcConfigurer extends WebMvcConfigurationSupport { /** * 添加拦截器 - * */ + */ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(restAuthTokenInterceptor()).addPathPatterns("/api/**") - .excludePathPatterns("/api/v1/console/**","/api/v1/article/articles/**","/api/v1/article/detail/**","/api/v1/topic/**","/api/v1/user/**"); + .excludePathPatterns("/api/v1/console/**", "/api/v1/article/articles/**", "/api/v1/article/detail/**" + , "/api/v1/topic/**", "/api/v1/user/**", "/api/v1/article/*/comments"); } /** * 访问静态资源 - * */ + */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { /** @@ -89,7 +91,7 @@ public class WebMvcConfigurer extends WebMvcConfigurationSupport { registry.addResourceHandler("/webjars/**") .addResourceLocations("classpath:/META-INF/resources/webjars/"); //将所有/static/** 访问都映射到classpath:/static/ 目录下 - registry.addResourceHandler("/static/**").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX +"/static/"); + registry.addResourceHandler("/static/**").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX + "/static/"); super.addResourceHandlers(registry); } } diff --git a/src/main/java/com/rymcu/vertical/service/impl/ArticleServiceImpl.java b/src/main/java/com/rymcu/vertical/service/impl/ArticleServiceImpl.java index a041b7f..ef3808d 100644 --- a/src/main/java/com/rymcu/vertical/service/impl/ArticleServiceImpl.java +++ b/src/main/java/com/rymcu/vertical/service/impl/ArticleServiceImpl.java @@ -303,6 +303,8 @@ public class ArticleServiceImpl extends AbstractService
implements Arti article.setPortfolios(portfolioArticleDTOList); } else if (type.equals(ARTICLE_EDIT)) { article.setArticleContent(articleContent.getArticleContent()); + } else { + article.setArticleContent(articleContent.getArticleContentHtml()); } } return article; diff --git a/src/main/java/com/rymcu/vertical/web/api/common/UploadController.java b/src/main/java/com/rymcu/vertical/web/api/common/UploadController.java index e2ae5c9..f8f9ddf 100644 --- a/src/main/java/com/rymcu/vertical/web/api/common/UploadController.java +++ b/src/main/java/com/rymcu/vertical/web/api/common/UploadController.java @@ -33,7 +33,7 @@ public class UploadController { private final static String UPLOAD_SIMPLE_URL = "/api/upload/file"; private final static String UPLOAD_URL = "/api/upload/file/batch"; - public static final String ctxHeadPicPath = "/usr/local/src/tomcat-hp/webapps/vertical"; + public static final String ctxHeadPicPath = "/usr/local/src/nebula/static"; @PostMapping("/file") public GlobalResult uploadPicture(@RequestParam(value = "file", required = false) MultipartFile multipartFile,@RequestParam(defaultValue = "1")Integer type, HttpServletRequest request){ From 7f1f92c82dbe4d9733128b459ab37bb1f7670f1d Mon Sep 17 00:00:00 2001 From: ronger Date: Mon, 3 Aug 2020 08:49:21 +0800 Subject: [PATCH 20/36] first commit --- src/main/resources/application.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 4dd536e..afa7b24 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,6 +1,6 @@ spring: - # profiles: - # active: pord +# profiles: +# active: dev thymeleaf: prefix: classpath:/templates/ suffix: .html From 22979810e50236a6763ff57514e88457ce5048e8 Mon Sep 17 00:00:00 2001 From: x ronger Date: Mon, 3 Aug 2020 21:28:47 +0800 Subject: [PATCH 21/36] =?UTF-8?q?:bug:=20=E6=B6=88=E6=81=AF=E6=A0=87?= =?UTF-8?q?=E8=AE=B0=E4=B8=BA=E5=B7=B2=E8=AF=BB=E9=97=AE=E9=A2=98=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/rymcu/vertical/service/NotificationService.java | 2 +- .../vertical/service/impl/NotificationServiceImpl.java | 7 +++++-- .../web/api/notification/NotificationController.java | 8 ++++++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/rymcu/vertical/service/NotificationService.java b/src/main/java/com/rymcu/vertical/service/NotificationService.java index df1c26f..4342adf 100644 --- a/src/main/java/com/rymcu/vertical/service/NotificationService.java +++ b/src/main/java/com/rymcu/vertical/service/NotificationService.java @@ -48,5 +48,5 @@ public interface NotificationService extends Service { * 标记消息已读 * @param id */ - void readNotification(Integer id); + Integer readNotification(Integer id); } diff --git a/src/main/java/com/rymcu/vertical/service/impl/NotificationServiceImpl.java b/src/main/java/com/rymcu/vertical/service/impl/NotificationServiceImpl.java index 564b17b..38d2593 100644 --- a/src/main/java/com/rymcu/vertical/service/impl/NotificationServiceImpl.java +++ b/src/main/java/com/rymcu/vertical/service/impl/NotificationServiceImpl.java @@ -5,6 +5,7 @@ import com.rymcu.vertical.entity.Notification; import com.rymcu.vertical.mapper.NotificationMapper; import com.rymcu.vertical.service.NotificationService; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.List; @@ -36,12 +37,14 @@ public class NotificationServiceImpl extends AbstractService imple } @Override + @Transactional(rollbackFor = Exception.class) public Integer save(Integer idUser, Integer dataId, String dataType, String dataSummary) { return notificationMapper.insertNotification(idUser,dataId,dataType,dataSummary); } @Override - public void readNotification(Integer id) { - notificationMapper.readNotification(id); + @Transactional(rollbackFor = Exception.class) + public Integer readNotification(Integer id) { + return notificationMapper.readNotification(id); } } diff --git a/src/main/java/com/rymcu/vertical/web/api/notification/NotificationController.java b/src/main/java/com/rymcu/vertical/web/api/notification/NotificationController.java index 3186585..b613e98 100644 --- a/src/main/java/com/rymcu/vertical/web/api/notification/NotificationController.java +++ b/src/main/java/com/rymcu/vertical/web/api/notification/NotificationController.java @@ -48,8 +48,12 @@ public class NotificationController { } @PutMapping("/read/{id}") - public void read(@PathVariable Integer id) { - notificationService.readNotification(id); + public GlobalResult read(@PathVariable Integer id) { + Integer result = notificationService.readNotification(id); + if (result == 0) { + return GlobalResultGenerator.genErrorResult("标记已读失败"); + } + return GlobalResultGenerator.genSuccessResult("标记已读成功"); } } From af17c90ef4feaffa3103503adc1c022fc682defa Mon Sep 17 00:00:00 2001 From: x ronger Date: Tue, 4 Aug 2020 21:00:54 +0800 Subject: [PATCH 22/36] =?UTF-8?q?:art:=20=E8=AF=84=E8=AE=BA=E5=88=86?= =?UTF-8?q?=E4=BA=AB=E9=93=BE=E6=8E=A5=E6=A0=BC=E5=BC=8F=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/rymcu/vertical/service/CommentService.java | 3 +++ .../com/rymcu/vertical/service/impl/CommentServiceImpl.java | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/rymcu/vertical/service/CommentService.java b/src/main/java/com/rymcu/vertical/service/CommentService.java index 5324a42..f859f25 100644 --- a/src/main/java/com/rymcu/vertical/service/CommentService.java +++ b/src/main/java/com/rymcu/vertical/service/CommentService.java @@ -8,6 +8,9 @@ import javax.servlet.http.HttpServletRequest; import java.util.List; import java.util.Map; +/** + * @author ronger + */ public interface CommentService extends Service { List getArticleComments(Integer idArticle); diff --git a/src/main/java/com/rymcu/vertical/service/impl/CommentServiceImpl.java b/src/main/java/com/rymcu/vertical/service/impl/CommentServiceImpl.java index f7268e1..b6aab70 100644 --- a/src/main/java/com/rymcu/vertical/service/impl/CommentServiceImpl.java +++ b/src/main/java/com/rymcu/vertical/service/impl/CommentServiceImpl.java @@ -83,7 +83,7 @@ public class CommentServiceImpl extends AbstractService implements Comm comment.setCreatedTime(new Date()); commentMapper.insertSelective(comment); StringBuilder commentSharpUrl = new StringBuilder(article.getArticlePermalink()); - commentSharpUrl.append("/comment/").append(comment.getIdComment()); + commentSharpUrl.append("#comment-").append(comment.getIdComment()); commentMapper.updateCommentSharpUrl(comment.getIdComment(), commentSharpUrl.toString()); String commentContent = comment.getCommentContent(); From 9a2bc1cadebf1b7b04bd53cc5080a12f25f4cd15 Mon Sep 17 00:00:00 2001 From: x ronger Date: Tue, 4 Aug 2020 21:03:10 +0800 Subject: [PATCH 23/36] =?UTF-8?q?:art:=20=E6=B6=88=E6=81=AF=E4=B8=AD?= =?UTF-8?q?=E5=BF=83=E5=B1=95=E7=A4=BA=E6=96=B9=E5=BC=8F=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rymcu/vertical/dto/NotificationDTO.java | 20 +++++ .../rymcu/vertical/entity/Notification.java | 2 +- .../vertical/service/NotificationService.java | 4 +- .../service/impl/NotificationServiceImpl.java | 76 +++++++++++++++++-- .../java/com/rymcu/vertical/util/Utils.java | 12 +++ .../notification/NotificationController.java | 7 +- 6 files changed, 110 insertions(+), 11 deletions(-) create mode 100644 src/main/java/com/rymcu/vertical/dto/NotificationDTO.java diff --git a/src/main/java/com/rymcu/vertical/dto/NotificationDTO.java b/src/main/java/com/rymcu/vertical/dto/NotificationDTO.java new file mode 100644 index 0000000..c9d69f7 --- /dev/null +++ b/src/main/java/com/rymcu/vertical/dto/NotificationDTO.java @@ -0,0 +1,20 @@ +package com.rymcu.vertical.dto; + +import com.rymcu.vertical.entity.Notification; +import lombok.Data; + +/** + * @author ronger + */ +@Data +public class NotificationDTO extends Notification { + + private Integer idNotification; + + private String dataTitle; + + private String dataUrl; + + private Author author; + +} diff --git a/src/main/java/com/rymcu/vertical/entity/Notification.java b/src/main/java/com/rymcu/vertical/entity/Notification.java index a104f2a..83ade86 100644 --- a/src/main/java/com/rymcu/vertical/entity/Notification.java +++ b/src/main/java/com/rymcu/vertical/entity/Notification.java @@ -43,7 +43,7 @@ public class Notification implements Serializable,Cloneable { * 数据摘要 */ @Column(name = "data_summary") - private String dataSummary ; + private String dataSummary; /** * 是否已读 */ diff --git a/src/main/java/com/rymcu/vertical/service/NotificationService.java b/src/main/java/com/rymcu/vertical/service/NotificationService.java index 4342adf..14537b5 100644 --- a/src/main/java/com/rymcu/vertical/service/NotificationService.java +++ b/src/main/java/com/rymcu/vertical/service/NotificationService.java @@ -1,8 +1,8 @@ package com.rymcu.vertical.service; import com.rymcu.vertical.core.service.Service; +import com.rymcu.vertical.dto.NotificationDTO; import com.rymcu.vertical.entity.Notification; -import org.apache.ibatis.annotations.Param; import java.util.List; @@ -23,7 +23,7 @@ public interface NotificationService extends Service { * @param idUser * @return */ - List findNotifications(Integer idUser); + List findNotifications(Integer idUser); /** * 获取消息数据 diff --git a/src/main/java/com/rymcu/vertical/service/impl/NotificationServiceImpl.java b/src/main/java/com/rymcu/vertical/service/impl/NotificationServiceImpl.java index 38d2593..f4ae200 100644 --- a/src/main/java/com/rymcu/vertical/service/impl/NotificationServiceImpl.java +++ b/src/main/java/com/rymcu/vertical/service/impl/NotificationServiceImpl.java @@ -1,13 +1,23 @@ package com.rymcu.vertical.service.impl; import com.rymcu.vertical.core.service.AbstractService; +import com.rymcu.vertical.dto.ArticleDTO; +import com.rymcu.vertical.dto.Author; +import com.rymcu.vertical.dto.NotificationDTO; +import com.rymcu.vertical.entity.Comment; import com.rymcu.vertical.entity.Notification; +import com.rymcu.vertical.entity.User; import com.rymcu.vertical.mapper.NotificationMapper; +import com.rymcu.vertical.service.ArticleService; +import com.rymcu.vertical.service.CommentService; import com.rymcu.vertical.service.NotificationService; +import com.rymcu.vertical.service.UserService; +import com.rymcu.vertical.util.BeanCopierUtil; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; +import java.util.ArrayList; import java.util.List; /** @@ -18,28 +28,84 @@ public class NotificationServiceImpl extends AbstractService imple @Resource private NotificationMapper notificationMapper; + @Resource + private ArticleService articleService; + @Resource + private CommentService commentService; + @Resource + private UserService userService; @Override - public List findUnreadNotifications(Integer idUser){ + public List findUnreadNotifications(Integer idUser) { List list = notificationMapper.selectUnreadNotifications(idUser); return list; } @Override - public List findNotifications(Integer idUser) { + public List findNotifications(Integer idUser) { List list = notificationMapper.selectNotifications(idUser); - return list; + List notifications = new ArrayList<>(); + list.forEach(notification -> { + NotificationDTO notificationDTO = genNotification(notification); + notifications.add(notificationDTO); + }); + return notifications; + } + + private NotificationDTO genNotification(Notification notification) { + NotificationDTO notificationDTO = new NotificationDTO(); + BeanCopierUtil.copy(notification, notificationDTO); + ArticleDTO article; + Comment comment; + User user; + switch (notification.getDataType()) { + case "0": + // 系统公告/帖子 + article = articleService.findArticleDTOById(notification.getDataId(), 0); + notificationDTO.setDataTitle("系统公告"); + notificationDTO.setDataUrl(article.getArticlePermalink()); + user = userService.findById(article.getArticleAuthorId().toString()); + notificationDTO.setAuthor(genAuthor(user)); + break; + case "1": + // 评论 + comment = commentService.findById(notification.getDataId().toString()); + article = articleService.findArticleDTOById(comment.getCommentArticleId(), 0); + notificationDTO.setDataTitle(article.getArticleTitle()); + notificationDTO.setDataUrl(comment.getCommentSharpUrl()); + user = userService.findById(comment.getCommentAuthorId().toString()); + notificationDTO.setAuthor(genAuthor(user)); + break; + case "2": + // 回帖 + comment = commentService.findById(notification.getDataId().toString()); + Comment originalComment = commentService.findById(comment.getCommentOriginalCommentId().toString()); + notificationDTO.setDataTitle(originalComment.getCommentContent()); + notificationDTO.setDataUrl(comment.getCommentSharpUrl()); + user = userService.findById(comment.getCommentAuthorId().toString()); + notificationDTO.setAuthor(genAuthor(user)); + break; + } + return notificationDTO; + } + + private Author genAuthor(User user) { + Author author = new Author(); + author.setUserNickname(user.getNickname()); + author.setUserAvatarURL(user.getAvatarUrl()); + author.setIdUser(user.getIdUser()); + return author; } @Override public Notification findNotification(Integer idUser, Integer dataId, String dataType) { - return notificationMapper.selectNotification(idUser,dataId,dataType); + return notificationMapper.selectNotification(idUser, dataId, dataType); } @Override @Transactional(rollbackFor = Exception.class) public Integer save(Integer idUser, Integer dataId, String dataType, String dataSummary) { - return notificationMapper.insertNotification(idUser,dataId,dataType,dataSummary); + return notificationMapper.insertNotification(idUser, dataId, dataType, dataSummary); } @Override diff --git a/src/main/java/com/rymcu/vertical/util/Utils.java b/src/main/java/com/rymcu/vertical/util/Utils.java index c4b6983..7b55a2f 100644 --- a/src/main/java/com/rymcu/vertical/util/Utils.java +++ b/src/main/java/com/rymcu/vertical/util/Utils.java @@ -2,6 +2,7 @@ package com.rymcu.vertical.util; import com.github.pagehelper.PageInfo; import com.rymcu.vertical.dto.ArticleDTO; +import com.rymcu.vertical.dto.NotificationDTO; import com.rymcu.vertical.entity.Notification; import com.rymcu.vertical.entity.User; import org.apache.shiro.SecurityUtils; @@ -182,4 +183,15 @@ public class Utils { return ip; } + + public static Map getNotificationDTOsGlobalResult(PageInfo pageInfo) { + Map map = new HashMap(2); + map.put("notifications", pageInfo.getList()); + Map pagination = new HashMap(4); + pagination.put("pageSize",pageInfo.getPageSize()); + pagination.put("total",pageInfo.getTotal()); + pagination.put("currentPage",pageInfo.getPageNum()); + map.put("pagination", pagination); + return map; + } } diff --git a/src/main/java/com/rymcu/vertical/web/api/notification/NotificationController.java b/src/main/java/com/rymcu/vertical/web/api/notification/NotificationController.java index b613e98..2b184e1 100644 --- a/src/main/java/com/rymcu/vertical/web/api/notification/NotificationController.java +++ b/src/main/java/com/rymcu/vertical/web/api/notification/NotificationController.java @@ -4,6 +4,7 @@ import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.rymcu.vertical.core.result.GlobalResult; import com.rymcu.vertical.core.result.GlobalResultGenerator; +import com.rymcu.vertical.dto.NotificationDTO; import com.rymcu.vertical.entity.Notification; import com.rymcu.vertical.entity.User; import com.rymcu.vertical.service.NotificationService; @@ -31,9 +32,9 @@ public class NotificationController { public GlobalResult notifications(@RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "10") Integer rows) throws BaseApiException { User user = UserUtils.getWxCurrentUser(); PageHelper.startPage(page, rows); - List list = notificationService.findNotifications(user.getIdUser()); - PageInfo pageInfo = new PageInfo(list); - Map map = Utils.getNotificationsGlobalResult(pageInfo); + List list = notificationService.findNotifications(user.getIdUser()); + PageInfo pageInfo = new PageInfo(list); + Map map = Utils.getNotificationDTOsGlobalResult(pageInfo); return GlobalResultGenerator.genSuccessResult(map); } From 6e0ddd530144536cc1e085d50a6452da64e58bd3 Mon Sep 17 00:00:00 2001 From: x ronger Date: Tue, 4 Aug 2020 23:03:47 +0800 Subject: [PATCH 24/36] =?UTF-8?q?:art:=20=E6=B6=88=E6=81=AF=E4=B8=AD?= =?UTF-8?q?=E5=BF=83=E5=B1=95=E7=A4=BA=E6=96=B9=E5=BC=8F=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/NotificationServiceImpl.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/rymcu/vertical/service/impl/NotificationServiceImpl.java b/src/main/java/com/rymcu/vertical/service/impl/NotificationServiceImpl.java index f4ae200..45d68cd 100644 --- a/src/main/java/com/rymcu/vertical/service/impl/NotificationServiceImpl.java +++ b/src/main/java/com/rymcu/vertical/service/impl/NotificationServiceImpl.java @@ -68,19 +68,13 @@ public class NotificationServiceImpl extends AbstractService imple notificationDTO.setAuthor(genAuthor(user)); break; case "1": - // 评论 - comment = commentService.findById(notification.getDataId().toString()); - article = articleService.findArticleDTOById(comment.getCommentArticleId(), 0); - notificationDTO.setDataTitle(article.getArticleTitle()); - notificationDTO.setDataUrl(comment.getCommentSharpUrl()); - user = userService.findById(comment.getCommentAuthorId().toString()); - notificationDTO.setAuthor(genAuthor(user)); + // 关注 break; case "2": // 回帖 comment = commentService.findById(notification.getDataId().toString()); - Comment originalComment = commentService.findById(comment.getCommentOriginalCommentId().toString()); - notificationDTO.setDataTitle(originalComment.getCommentContent()); + article = articleService.findArticleDTOById(comment.getCommentArticleId(), 0); + notificationDTO.setDataTitle(article.getArticleTitle()); notificationDTO.setDataUrl(comment.getCommentSharpUrl()); user = userService.findById(comment.getCommentAuthorId().toString()); notificationDTO.setAuthor(genAuthor(user)); From 0b9906de18f3a6a190bfbc7bc432ef067549903c Mon Sep 17 00:00:00 2001 From: x ronger Date: Sat, 15 Aug 2020 09:14:39 +0800 Subject: [PATCH 25/36] add jetbrains.png --- src/main/resources/static/jetbrains.png | Bin 0 -> 167813 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/main/resources/static/jetbrains.png diff --git a/src/main/resources/static/jetbrains.png b/src/main/resources/static/jetbrains.png new file mode 100644 index 0000000000000000000000000000000000000000..ccceb958418b0893c4b2fa064985fc77f28dd366 GIT binary patch literal 167813 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

h_VCw4^CfgM=hOM{yFunLNNbio=p$BG+L2$A zjXQyFRk{RNWz=l!2@n{=AGQ;sT;yRn38jrXv8`6O0j##RQgUpezO-xv&kkB5YCASP zSh@wr_tIW#$E%r@0F4EBy(-qK5D3^!fkjrHmCd5pE}~!ldIEy*=3B?3md>4$O*8wt z=|Q2H7SPppLxw~U*qy?+z-+J7@AKUT*G{^YMqbEfWqpxEz~~Pi9@Mc@Y-v_K zRW<%ped+v_g>d^i!j=z~*^)DIM~;BMnR1B|)wG)0EzFi}4mU`Ih3+a!MYjiIFv-QI zHz=%e_8;-mSJZFA3B0|$JaxmJu+?Ca8M!_%# zGMMaZ&kWi(B{h=~jhHRr*0u-T#b?ON!q)leKXKw~)r*R?^NC@h)+{x~MiklYq@hD- z-5vYtWh;lzCCo9CYjGzsTTfpajSc=F`IbW7V!2an?l(NVDc*FvhaAojxMLmON@K_L zXg&O5#cvQsJ%-DAh87Efkrlb`h<(@K;}o~`LPhfPVDdkShkq}k% z7ZUVRW|}MJa~T)1yyBGMv=lUQ!()EN#UUz^k$-YgeB#5Cykx51;e!`iXEQR8oGH~w zKB(FrHX}dwmBKh|l-6tUTT-Pza89(XRVs_h4#Wy1@R|*clS2kkd_1$G`P{Y9G3P5+f_Pi^ z1DimC-<_pa)>tESGt7S?bH@aw5{&N7)$rrMgd+F9CjRIJz!Y1|ZMf^bhPh}SMG_S( zDxe$gzws*Sp3F1yyC@&|hlM-vX755JKNVU`5!nq15Y;7K&bRw@Y^9t-wPrtrOW*(o z?4LEdogXG_KYeq>DW5vh;WGN1cq?nKN(wcT@7uqXseSk;nmpq+oRFw_%1uhWiP{V? zM<#Z_9UXAXYSZ{E}4>tbCJ z>3M^nJuVe{@$O9EkDyZ|CKDC{h5CPkX<``JM5LTM*(hWBo$JA#O~c5W_E)ZvF8&%r zAI|4+w#f03SOOj9nVjQJZOb(MmZ3dN)U#&4L`uR91f{(;%2=w^V%MJ)Owa=EF1Kxi z`>{NnsQ8Oo7A-C~f(}$c-j(4WI-W*b_v|e$(S~x&$VqXP+O+nZhAx40*EcJ>;LlgE z3!b+*%tYX4kGb}~cHvVVfD*xDpoeKwE6^?R;t)0Uq>{%0L99h@�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 Ra{6S(9Y5-dsyc%C Date: Thu, 24 Sep 2020 13:46:32 +0800 Subject: [PATCH 26/36] Update application.yml --- src/main/resources/application.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index afa7b24..ad864af 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -22,6 +22,7 @@ spring: max-idle: 500 min-idle: 0 datasource: + drud: url: jdbc:mysql://localhost:3306/vertical?characterEncoding=UTF-8&autoReconnect=true&useSSL=false username: root password: # 数据库密码 From 36842316bf803e6fd7bf2927d72e85af91f0f237 Mon Sep 17 00:00:00 2001 From: ronger Date: Thu, 24 Sep 2020 14:55:37 +0800 Subject: [PATCH 27/36] Update application.yml --- src/main/resources/application.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index ad864af..8254f9f 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -22,11 +22,11 @@ spring: max-idle: 500 min-idle: 0 datasource: - drud: - url: jdbc:mysql://localhost:3306/vertical?characterEncoding=UTF-8&autoReconnect=true&useSSL=false - username: root - password: # 数据库密码 - driver-class-name: com.mysql.cj.jdbc.Driver + druid: + url: jdbc:mysql://localhost:3306/vertical?characterEncoding=UTF-8&autoReconnect=true&useSSL=false + username: root + password: # 数据库密码 + driver-class-name: com.mysql.cj.jdbc.Driver resources: add-mappings: true mail: From 0fb2ed1de0422bf8ad1cbc4fe3f12c6f2c0c9b58 Mon Sep 17 00:00:00 2001 From: ronger Date: Thu, 24 Sep 2020 15:57:55 +0800 Subject: [PATCH 28/36] delete --- src/main/resources/static/vertical.pdman.json | 3540 ----------------- 1 file changed, 3540 deletions(-) delete mode 100644 src/main/resources/static/vertical.pdman.json diff --git a/src/main/resources/static/vertical.pdman.json b/src/main/resources/static/vertical.pdman.json deleted file mode 100644 index fb36b1b..0000000 --- a/src/main/resources/static/vertical.pdman.json +++ /dev/null @@ -1,3540 +0,0 @@ -{ - "modules": [ - { - "name": "rymcu", - "chnname": "rymcu", - "entities": [ - { - "title": "vertical_article", - "chnname": "文章表", - "fields": [ - { - "name": "id", - "type": "BIGINT_19", - "chnname": "主键", - "remark": "", - "pk": true, - "notNull": true, - "autoIncrement": true, - "defaultValue": "" - }, - { - "name": "article_title", - "type": "VARCHAR_128", - "chnname": "文章标题", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "article_thumbnail_url", - "type": "VARCHAR_128", - "chnname": "文章缩略图", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "article_author_id", - "type": "BIGINT_19", - "chnname": "文章作者id", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "article_type", - "type": "CHAR_1", - "chnname": "文章类型", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "article_tags", - "type": "VARCHAR_128", - "chnname": "文章标签", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "article_view_count", - "type": "INT_10", - "chnname": "浏览总数", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "article_preview_content", - "type": "VARCHAR_256", - "chnname": "预览内容", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "article_comment_count", - "type": "INT_10", - "chnname": "评论总数", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "article_permalink", - "type": "VARCHAR_128", - "chnname": "文章永久链接", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "article_link", - "type": "VARCHAR_32", - "chnname": "站内链接", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "created_time", - "type": "DATETIME", - "chnname": "创建时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "updated_time", - "type": "DATETIME", - "chnname": "更新时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "article_perfect", - "type": "CHAR_1", - "chnname": "0:非优选1:优选", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "article_status", - "type": "CHAR_1", - "chnname": "文章状态", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - } - ], - "indexs": [], - "headers": [ - { - "fieldName": "chnname", - "relationNoShow": false - }, - { - "fieldName": "name", - "relationNoShow": false - }, - { - "fieldName": "type", - "relationNoShow": false - }, - { - "fieldName": "dataType", - "relationNoShow": true - }, - { - "fieldName": "remark", - "relationNoShow": true - }, - { - "fieldName": "pk", - "relationNoShow": false - }, - { - "fieldName": "notNull", - "relationNoShow": true - }, - { - "fieldName": "autoIncrement", - "relationNoShow": true - }, - { - "fieldName": "defaultValue", - "relationNoShow": true - }, - { - "fieldName": "relationNoShow", - "relationNoShow": true - }, - { - "fieldName": "uiHint", - "relationNoShow": true - } - ] - }, - { - "title": "vertical_article_content", - "chnname": "文章内容表", - "fields": [ - { - "name": "id_article", - "type": "BIGINT_19", - "chnname": "主键", - "remark": "", - "pk": false, - "notNull": true, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "article_content", - "type": "TEXT", - "chnname": "文章内容原文", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "article_content_html", - "type": "TEXT", - "chnname": "文章内容Html", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "created_time", - "type": "DATETIME", - "chnname": "创建时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "updated_time", - "type": "DATETIME", - "chnname": "更新时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - } - ], - "indexs": [], - "headers": [ - { - "fieldName": "chnname", - "relationNoShow": false - }, - { - "fieldName": "name", - "relationNoShow": false - }, - { - "fieldName": "type", - "relationNoShow": false - }, - { - "fieldName": "dataType", - "relationNoShow": true - }, - { - "fieldName": "remark", - "relationNoShow": true - }, - { - "fieldName": "pk", - "relationNoShow": false - }, - { - "fieldName": "notNull", - "relationNoShow": true - }, - { - "fieldName": "autoIncrement", - "relationNoShow": true - }, - { - "fieldName": "defaultValue", - "relationNoShow": true - }, - { - "fieldName": "relationNoShow", - "relationNoShow": true - }, - { - "fieldName": "uiHint", - "relationNoShow": true - } - ] - }, - { - "title": "vertical_role", - "chnname": "权限表", - "fields": [ - { - "name": "id", - "type": "BIGINT_19", - "chnname": "主键", - "remark": "", - "pk": true, - "notNull": true, - "autoIncrement": true, - "defaultValue": "" - }, - { - "name": "name", - "type": "VARCHAR_32", - "chnname": "名称", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "input_code", - "type": "VARCHAR_32", - "chnname": "拼音码", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "status", - "type": "CHAR_1", - "chnname": "状态", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "created_time", - "type": "DATETIME", - "chnname": "创建时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "updated_time", - "type": "DATETIME", - "chnname": "更新时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "weights", - "type": "TINYINT_3", - "chnname": "权重,数值越小权限越大;0:无权限", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - } - ], - "indexs": [], - "headers": [ - { - "fieldName": "chnname", - "relationNoShow": false - }, - { - "fieldName": "name", - "relationNoShow": false - }, - { - "fieldName": "type", - "relationNoShow": false - }, - { - "fieldName": "dataType", - "relationNoShow": true - }, - { - "fieldName": "remark", - "relationNoShow": true - }, - { - "fieldName": "pk", - "relationNoShow": false - }, - { - "fieldName": "notNull", - "relationNoShow": true - }, - { - "fieldName": "autoIncrement", - "relationNoShow": true - }, - { - "fieldName": "defaultValue", - "relationNoShow": true - }, - { - "fieldName": "relationNoShow", - "relationNoShow": true - }, - { - "fieldName": "uiHint", - "relationNoShow": true - } - ] - }, - { - "title": "vertical_tag", - "chnname": "标签表 ", - "fields": [ - { - "name": "id", - "type": "BIGINT_19", - "chnname": "主键", - "remark": "", - "pk": true, - "notNull": true, - "autoIncrement": true, - "defaultValue": "" - }, - { - "name": "tag_title", - "type": "VARCHAR_32", - "chnname": "标签名", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "tag_icon_path", - "type": "VARCHAR_512", - "chnname": "标签图标", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "tag_uri", - "type": "VARCHAR_128", - "chnname": "标签uri", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "tag_description", - "type": "VARCHAR_1024", - "chnname": "描述", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "tag_view_count", - "type": "INT_10", - "chnname": "浏览量", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "tag_article_count", - "type": "INT_10", - "chnname": "关联文章总数", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "tag_ad", - "type": "CHAR_1", - "chnname": "标签广告", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "tag_show_side_ad", - "type": "CHAR_1", - "chnname": "是否显示全站侧边栏广告", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "created_time", - "type": "DATETIME", - "chnname": "创建时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "updated_time", - "type": "DATETIME", - "chnname": "更新时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "tag_status", - "type": "CHAR_1", - "chnname": "标签状态", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - } - ] - }, - { - "title": "vertical_tag_article", - "chnname": "标签 - 帖子关联表 ", - "fields": [ - { - "name": "id", - "type": "BIGINT_19", - "chnname": "主键", - "remark": "", - "pk": true, - "notNull": true, - "autoIncrement": true, - "defaultValue": "" - }, - { - "name": "id_tag", - "type": "BIGINT_19", - "chnname": "标签 id", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "id_article", - "type": "VARCHAR_32", - "chnname": "帖子 id", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "article_comment_count", - "type": "INT_10", - "chnname": "帖子评论计数 0", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "article_perfect", - "type": "INT_10", - "chnname": "0:非优选1:优选 0", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "created_time", - "type": "DATETIME", - "chnname": "创建时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "updated_time", - "type": "DATETIME", - "chnname": "更新时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - } - ] - }, - { - "title": "vertical_topic", - "chnname": "主题表", - "fields": [ - { - "name": "id", - "type": "BIGINT_19", - "chnname": "主键", - "remark": "", - "pk": true, - "notNull": true, - "autoIncrement": true, - "defaultValue": "" - }, - { - "name": "topic_title", - "type": "VARCHAR_32", - "chnname": "专题标题", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "topic_uri", - "type": "VARCHAR_32", - "chnname": "专题路径", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "topic_description", - "type": "TEXT", - "chnname": "专题描述", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "topic_type", - "type": "VARCHAR_32", - "chnname": "专题类型", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "topic_sort", - "type": "INT_10", - "chnname": "专题序号 10", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "topic_icon_path", - "type": "VARCHAR_128", - "chnname": "专题图片路径", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "topic_nva", - "type": "CHAR_1", - "chnname": "0:作为导航1:不作为导航 0", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "topic_tag_count", - "type": "INT_10", - "chnname": "专题下标签总数 0", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "topic_status", - "type": "CHAR_1", - "chnname": "0:正常1:禁用 0", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "created_time", - "type": "DATETIME", - "chnname": "创建时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "updated_time", - "type": "DATETIME", - "chnname": "更新时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - } - ] - }, - { - "title": "vertical_topic_tag", - "chnname": "专题- 标签关联表 ", - "fields": [ - { - "name": "id", - "type": "BIGINT_19", - "chnname": "主键", - "remark": "", - "pk": true, - "notNull": true, - "autoIncrement": true, - "defaultValue": "" - }, - { - "name": "id_topic", - "type": "BIGINT_19", - "chnname": "专题id", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "id_tag", - "type": "BIGINT_19", - "chnname": "标签id", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "created_time", - "type": "DATETIME", - "chnname": "创建时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "updated_time", - "type": "DATETIME", - "chnname": "更新时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - } - ] - }, - { - "title": "vertical_user", - "chnname": "用户表", - "fields": [ - { - "name": "id", - "type": "BIGINT_19", - "chnname": "用户ID", - "remark": "", - "pk": true, - "notNull": true, - "autoIncrement": true, - "defaultValue": "" - }, - { - "name": "account", - "type": "VARCHAR_32", - "chnname": "账号", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "password", - "type": "VARCHAR_64", - "chnname": "密码", - "remark": "", - "pk": false, - "notNull": true, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "nickname", - "type": "VARCHAR_128", - "chnname": "昵称", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "real_name", - "type": "VARCHAR_32", - "chnname": "真实姓名", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "sex", - "type": "CHAR_1", - "chnname": "性别", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "avatar_type", - "type": "CHAR_1", - "chnname": "头像类型", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "avatar_url", - "type": "VARCHAR_512", - "chnname": "头像路径", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "email", - "type": "VARCHAR_64", - "chnname": "邮箱", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "phone", - "type": "VARCHAR_11", - "chnname": "电话", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "status", - "type": "CHAR_1", - "chnname": "状态", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "created_time", - "type": "DATETIME", - "chnname": "创建时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "updated_time", - "type": "DATETIME", - "chnname": "更新时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "last_login_time", - "type": "DATETIME", - "chnname": "最后登录时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "signature", - "type": "VARCHAR_128", - "chnname": "签名", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - } - ], - "indexs": [], - "headers": [ - { - "fieldName": "chnname", - "relationNoShow": false - }, - { - "fieldName": "name", - "relationNoShow": false - }, - { - "fieldName": "type", - "relationNoShow": false - }, - { - "fieldName": "dataType", - "relationNoShow": true - }, - { - "fieldName": "remark", - "relationNoShow": true - }, - { - "fieldName": "pk", - "relationNoShow": false - }, - { - "fieldName": "notNull", - "relationNoShow": true - }, - { - "fieldName": "autoIncrement", - "relationNoShow": true - }, - { - "fieldName": "defaultValue", - "relationNoShow": true - }, - { - "fieldName": "relationNoShow", - "relationNoShow": true - }, - { - "fieldName": "uiHint", - "relationNoShow": true - } - ] - }, - { - "title": "vertical_user_role", - "chnname": "用户-权限表", - "fields": [ - { - "name": "id_user", - "type": "BIGINT_19", - "chnname": "用户表主键", - "remark": "", - "pk": false, - "notNull": true, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "id_role", - "type": "BIGINT_19", - "chnname": "角色表主键", - "remark": "", - "pk": false, - "notNull": true, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "created_time", - "type": "DATETIME", - "chnname": "创建时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - } - ], - "indexs": [], - "headers": [ - { - "fieldName": "chnname", - "relationNoShow": false - }, - { - "fieldName": "name", - "relationNoShow": false - }, - { - "fieldName": "type", - "relationNoShow": false - }, - { - "fieldName": "dataType", - "relationNoShow": true - }, - { - "fieldName": "remark", - "relationNoShow": true - }, - { - "fieldName": "pk", - "relationNoShow": false - }, - { - "fieldName": "notNull", - "relationNoShow": true - }, - { - "fieldName": "autoIncrement", - "relationNoShow": true - }, - { - "fieldName": "defaultValue", - "relationNoShow": true - }, - { - "fieldName": "relationNoShow", - "relationNoShow": true - }, - { - "fieldName": "uiHint", - "relationNoShow": true - } - ] - }, - { - "title": "vertical_user_tag", - "chnname": "用户 - 标签关联表 ", - "fields": [ - { - "name": "id", - "type": "BIGINT_19", - "chnname": "主键", - "remark": "", - "pk": true, - "notNull": true, - "autoIncrement": true, - "defaultValue": "" - }, - { - "name": "id_user", - "type": "BIGINT_19", - "chnname": "用户 id", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "id_tag", - "type": "VARCHAR_32", - "chnname": "标签 id", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "type", - "type": "CHAR_1", - "chnname": "0:创建者,1:帖子使用,2:用户自评标签", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "created_time", - "type": "DATETIME", - "chnname": "创建时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "updated_time", - "type": "DATETIME", - "chnname": "更新时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - } - ] - }, - { - "title": "vertical_notification", - "fields": [ - { - "name": "id", - "type": "BigInt", - "remark": "", - "chnname": "主键", - "pk": true, - "notNull": true, - "autoIncrement": true - }, - { - "name": "id_user", - "type": "BigInt", - "remark": "", - "chnname": "用户id" - }, - { - "name": "data_type", - "type": "Char", - "remark": "", - "chnname": "数据类型" - }, - { - "name": "data_id", - "type": "BigInt", - "remark": "", - "chnname": "数据id" - }, - { - "name": "data_summary", - "type": "ShortString", - "remark": "", - "chnname": "数据摘要" - }, - { - "name": "has_read", - "type": "Char", - "remark": "", - "chnname": "是否已读", - "defaultValue": "0" - } - ], - "indexs": [], - "headers": [ - { - "fieldName": "chnname", - "relationNoShow": false - }, - { - "fieldName": "name", - "relationNoShow": false - }, - { - "fieldName": "type", - "relationNoShow": false - }, - { - "fieldName": "dataType", - "relationNoShow": true - }, - { - "fieldName": "remark", - "relationNoShow": true - }, - { - "fieldName": "pk", - "relationNoShow": false - }, - { - "fieldName": "notNull", - "relationNoShow": true - }, - { - "fieldName": "autoIncrement", - "relationNoShow": true - }, - { - "fieldName": "defaultValue", - "relationNoShow": true - }, - { - "fieldName": "relationNoShow", - "relationNoShow": true - }, - { - "fieldName": "uiHint", - "relationNoShow": true - } - ], - "chnname": "通知表" - }, - { - "title": "vertical_comment", - "fields": [ - { - "name": "id", - "type": "BigInt", - "remark": "", - "chnname": "主键", - "pk": true, - "notNull": true, - "autoIncrement": true - }, - { - "name": "comment_content", - "type": "LongText", - "remark": "", - "chnname": "评论内容" - }, - { - "name": "comment_author_id", - "type": "BigInt", - "remark": "", - "chnname": "作者 id" - }, - { - "name": "comment_article_id", - "type": "BigInt", - "remark": "", - "chnname": "文章 id" - }, - { - "name": "comment_sharp_url", - "type": "VARCHAR_256", - "remark": "", - "chnname": "锚点 url" - }, - { - "name": "comment_original_comment_id", - "type": "BigInt", - "remark": "", - "chnname": "父评论 id" - }, - { - "name": "comment_status", - "type": "Char", - "remark": "", - "chnname": "状态", - "defaultValue": "0" - }, - { - "name": "comment_ip", - "type": "VARCHAR_128", - "remark": "", - "chnname": "评论 IP" - }, - { - "name": "comment_ua", - "type": "VARCHAR_128", - "remark": "", - "chnname": "User-Agent" - }, - { - "name": "comment_anonymous", - "type": "Char", - "remark": "", - "chnname": "0:公开回帖,1:匿名回帖" - }, - { - "name": "comment_reply_count", - "type": "Integer", - "remark": "", - "chnname": "回帖计数" - }, - { - "name": "comment_visible", - "type": "Char", - "remark": "", - "chnname": "0:所有人可见,1:仅楼主和自己可见" - }, - { - "name": "created_time", - "type": "DateTime", - "remark": "", - "chnname": "创建时间" - } - ], - "indexs": [], - "headers": [ - { - "fieldName": "chnname", - "relationNoShow": false - }, - { - "fieldName": "name", - "relationNoShow": false - }, - { - "fieldName": "type", - "relationNoShow": false - }, - { - "fieldName": "dataType", - "relationNoShow": true - }, - { - "fieldName": "remark", - "relationNoShow": true - }, - { - "fieldName": "pk", - "relationNoShow": false - }, - { - "fieldName": "notNull", - "relationNoShow": true - }, - { - "fieldName": "autoIncrement", - "relationNoShow": true - }, - { - "fieldName": "defaultValue", - "relationNoShow": true - }, - { - "fieldName": "relationNoShow", - "relationNoShow": true - }, - { - "fieldName": "uiHint", - "relationNoShow": true - } - ], - "chnname": "评论表" - }, - { - "title": "vertical_follow", - "fields": [ - { - "name": "id", - "type": "BigInt", - "remark": "", - "chnname": "主键", - "pk": true, - "notNull": true, - "autoIncrement": true - }, - { - "name": "follower_id", - "type": "BigInt", - "remark": "", - "chnname": "关注者 id" - }, - { - "name": "following_id", - "type": "BigInt", - "remark": "", - "chnname": "关注数据 id" - }, - { - "name": "following_type", - "type": "Char", - "remark": "", - "chnname": "0:用户,1:标签,2:帖子收藏,3:帖子关注" - } - ], - "indexs": [], - "headers": [ - { - "fieldName": "chnname", - "relationNoShow": false - }, - { - "fieldName": "name", - "relationNoShow": false - }, - { - "fieldName": "type", - "relationNoShow": false - }, - { - "fieldName": "dataType", - "relationNoShow": true - }, - { - "fieldName": "remark", - "relationNoShow": true - }, - { - "fieldName": "pk", - "relationNoShow": false - }, - { - "fieldName": "notNull", - "relationNoShow": true - }, - { - "fieldName": "autoIncrement", - "relationNoShow": true - }, - { - "fieldName": "defaultValue", - "relationNoShow": true - }, - { - "fieldName": "relationNoShow", - "relationNoShow": true - }, - { - "fieldName": "uiHint", - "relationNoShow": true - } - ], - "chnname": "关注表" - }, - { - "title": "vertical_visit", - "fields": [ - { - "name": "id", - "type": "BigInt", - "remark": "", - "chnname": "主键", - "pk": true, - "notNull": true, - "autoIncrement": true - }, - { - "name": "visit_url", - "type": "VARCHAR_256", - "remark": "", - "chnname": "浏览链接" - }, - { - "name": "visit_ip", - "type": "ShortString", - "remark": "", - "chnname": "IP" - }, - { - "name": "visit_ua", - "type": "VARCHAR_256", - "remark": "", - "chnname": "User-Agent" - }, - { - "name": "visit_city", - "type": "IdOrKey", - "remark": "", - "chnname": "城市" - }, - { - "name": "visit_device_id", - "type": "VARCHAR_256", - "remark": "", - "chnname": "设备唯一标识" - }, - { - "name": "visit_user_id", - "type": "BigInt", - "remark": "", - "chnname": "浏览者 id" - }, - { - "name": "visit_referer_url", - "type": "VARCHAR_256", - "remark": "", - "chnname": "上游链接" - }, - { - "name": "created_time", - "type": "DateTime", - "remark": "", - "chnname": "创建时间" - }, - { - "name": "expired_time", - "type": "DateTime", - "remark": "", - "chnname": "过期时间" - } - ], - "indexs": [], - "headers": [ - { - "fieldName": "chnname", - "relationNoShow": false - }, - { - "fieldName": "name", - "relationNoShow": false - }, - { - "fieldName": "type", - "relationNoShow": false - }, - { - "fieldName": "dataType", - "relationNoShow": true - }, - { - "fieldName": "remark", - "relationNoShow": true - }, - { - "fieldName": "pk", - "relationNoShow": false - }, - { - "fieldName": "notNull", - "relationNoShow": true - }, - { - "fieldName": "autoIncrement", - "relationNoShow": true - }, - { - "fieldName": "defaultValue", - "relationNoShow": true - }, - { - "fieldName": "relationNoShow", - "relationNoShow": true - }, - { - "fieldName": "uiHint", - "relationNoShow": true - } - ], - "chnname": "浏览表" - }, - { - "title": "vertical_special_day-副本", - "chnname": "特殊日", - "fields": [ - { - "name": "id", - "type": "INT_10", - "chnname": "", - "remark": "", - "pk": true, - "notNull": true, - "autoIncrement": true, - "defaultValue": "" - }, - { - "name": "special_day_name", - "type": "VARCHAR_200", - "chnname": "名称", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "weights", - "type": "INT_10", - "chnname": "权重/优先级,小数优秀", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "start_time", - "type": "DATETIME", - "chnname": "开始时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "expiration_time", - "type": "DATETIME", - "chnname": "过期时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "repeat", - "type": "INT_10", - "chnname": "是否重复", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "repeat_cycle", - "type": "INT_10", - "chnname": "重复周期", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "repeat_cycle_unit", - "type": "INT_10", - "chnname": "0:天1:周2:月3:年", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "created_time", - "type": "DATETIME", - "chnname": "创建时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "img_url", - "type": "VARCHAR_500", - "chnname": "图片路径", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "css_style", - "type": "VARCHAR_2000", - "chnname": "执行全局样式", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - } - ], - "indexs": [], - "headers": [ - { - "fieldName": "chnname", - "relationNoShow": false - }, - { - "fieldName": "name", - "relationNoShow": false - }, - { - "fieldName": "type", - "relationNoShow": false - }, - { - "fieldName": "dataType", - "relationNoShow": true - }, - { - "fieldName": "remark", - "relationNoShow": true - }, - { - "fieldName": "pk", - "relationNoShow": false - }, - { - "fieldName": "notNull", - "relationNoShow": true - }, - { - "fieldName": "autoIncrement", - "relationNoShow": true - }, - { - "fieldName": "defaultValue", - "relationNoShow": true - }, - { - "fieldName": "relationNoShow", - "relationNoShow": true - }, - { - "fieldName": "uiHint", - "relationNoShow": true - } - ] - }, - { - "title": "vertical_wx_user-副本", - "chnname": "微信用户表", - "fields": [ - { - "name": "id", - "type": "INT_10", - "chnname": "微信用户表主键", - "remark": "", - "pk": true, - "notNull": true, - "autoIncrement": true, - "defaultValue": "" - }, - { - "name": "nickname", - "type": "VARCHAR_50", - "chnname": "", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "union_id", - "type": "VARCHAR_32", - "chnname": "微信全局 unionId", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "open_id", - "type": "VARCHAR_32", - "chnname": "openId", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "app_id", - "type": "VARCHAR_32", - "chnname": "AppId", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "sex", - "type": "INT_10", - "chnname": "性别字段", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "sex_desc", - "type": "VARCHAR_32", - "chnname": "性别文本", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "head_img_url", - "type": "VARCHAR_200", - "chnname": "头像图片路径", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "country", - "type": "VARCHAR_32", - "chnname": "所属国家", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "province", - "type": "VARCHAR_32", - "chnname": "所属省/州", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "city", - "type": "VARCHAR_32", - "chnname": "所属市/区", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "act_token", - "type": "VARCHAR_64", - "chnname": "活动 Token", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "subscribe", - "type": "BIT_1", - "chnname": "是否关注", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "subscribe_time", - "type": "MEDIUMTEXT", - "chnname": "关注时间戳", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "language", - "type": "VARCHAR_10", - "chnname": "语言", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - } - ] - }, - { - "title": "vertical_collection", - "fields": [ - { - "name": "id", - "type": "BigInt", - "remark": "", - "chnname": "主键", - "pk": true, - "notNull": true, - "autoIncrement": true - }, - { - "name": "head_img_url", - "type": "VARCHAR_500", - "remark": "", - "chnname": "作品集头像" - }, - { - "name": "name", - "type": "DefaultString", - "remark": "", - "chnname": "作品集名称" - }, - { - "name": "portfolio_author_id", - "type": "BigInt", - "remark": "", - "chnname": "作品集作者" - }, - { - "name": "description", - "type": "MiddleString", - "remark": "", - "chnname": "作品集介绍" - }, - { - "name": "created_time", - "type": "DateTime", - "remark": "", - "chnname": "创建时间" - }, - { - "name": "updated_time", - "type": "DateTime", - "remark": "", - "chnname": "更新时间" - } - ], - "indexs": [], - "headers": [ - { - "fieldName": "chnname", - "relationNoShow": false - }, - { - "fieldName": "name", - "relationNoShow": false - }, - { - "fieldName": "type", - "relationNoShow": false - }, - { - "fieldName": "dataType", - "relationNoShow": true - }, - { - "fieldName": "remark", - "relationNoShow": true - }, - { - "fieldName": "pk", - "relationNoShow": false - }, - { - "fieldName": "notNull", - "relationNoShow": true - }, - { - "fieldName": "autoIncrement", - "relationNoShow": true - }, - { - "fieldName": "defaultValue", - "relationNoShow": true - }, - { - "fieldName": "relationNoShow", - "relationNoShow": true - }, - { - "fieldName": "uiHint", - "relationNoShow": true - } - ], - "chnname": "作品集", - "remark": "作品集" - }, - { - "title": "vertical_collection_article", - "fields": [ - { - "name": "id", - "type": "BigInt", - "remark": "", - "chnname": "主键", - "pk": true, - "notNull": true, - "autoIncrement": true - }, - { - "name": "id_vertical_portfolio", - "type": "BigInt", - "remark": "", - "chnname": "作品集表主键" - }, - { - "name": "id_vertical_article", - "type": "BigInt", - "remark": "", - "chnname": "文章表主键" - }, - { - "name": "sort_no", - "type": "Integer", - "remark": "", - "chnname": "排序号" - } - ], - "indexs": [], - "headers": [ - { - "fieldName": "chnname", - "relationNoShow": false - }, - { - "fieldName": "name", - "relationNoShow": false - }, - { - "fieldName": "type", - "relationNoShow": false - }, - { - "fieldName": "dataType", - "relationNoShow": true - }, - { - "fieldName": "remark", - "relationNoShow": true - }, - { - "fieldName": "pk", - "relationNoShow": false - }, - { - "fieldName": "notNull", - "relationNoShow": true - }, - { - "fieldName": "autoIncrement", - "relationNoShow": true - }, - { - "fieldName": "defaultValue", - "relationNoShow": true - }, - { - "fieldName": "relationNoShow", - "relationNoShow": true - }, - { - "fieldName": "uiHint", - "relationNoShow": true - } - ], - "chnname": "作品集与文章关系表" - } - ], - "graphCanvas": { - "nodes": [ - { - "shape": "table", - "title": "vertical_article", - "moduleName": false, - "x": 300, - "y": 210, - "id": "78d290b9" - }, - { - "shape": "table", - "title": "vertical_article_content", - "moduleName": false, - "x": 1017.125, - "y": 125, - "id": "36d1f0d8" - }, - { - "shape": "table", - "title": "vertical_tag", - "moduleName": false, - "x": 310, - "y": 560, - "id": "45e84f94" - }, - { - "shape": "table", - "title": "vertical_tag_article", - "moduleName": false, - "x": 1050, - "y": 380, - "id": "36f47f24" - }, - { - "shape": "table", - "title": "vertical_topic", - "moduleName": false, - "x": 320, - "y": 870, - "id": "07068933" - }, - { - "shape": "table", - "title": "vertical_topic_tag", - "moduleName": false, - "x": 1101.2953881820206, - "y": 670.7319562499999, - "id": "64620a69" - }, - { - "shape": "table", - "title": "vertical_role", - "moduleName": false, - "x": -890, - "y": 658.8888888888889, - "id": "953e8f99" - }, - { - "shape": "table", - "title": "vertical_user", - "moduleName": false, - "x": -860, - "y": 261.1111111111111, - "id": "145b5e72" - }, - { - "shape": "table", - "title": "vertical_user_tag", - "moduleName": false, - "x": -250, - "y": 290, - "id": "77fa9953" - }, - { - "shape": "table", - "title": "vertical_user_role", - "moduleName": false, - "x": -330, - "y": 600, - "id": "d71e9bc5" - } - ], - "edges": [ - { - "shape": "erdRelation", - "relation": "0,n:1", - "source": "36d1f0d8", - "target": "78d290b9", - "id": "8d47df12", - "controlPoints": [ - { - "x": 853.912109375, - "y": 97.28846153846153 - }, - { - "x": 494.3779296875, - "y": 72.10714285714286 - } - ], - "sourceAnchor": 0, - "targetAnchor": 1 - }, - { - "shape": "erdRelation", - "relation": "0,n:1", - "source": "36f47f24", - "target": "45e84f94", - "id": "910ac573", - "controlPoints": [ - { - "x": 854.9599609375, - "y": 352.3382352941177 - }, - { - "x": 516.3779296875, - "y": 462.1388888888889 - } - ], - "sourceAnchor": 2, - "targetAnchor": 1 - }, - { - "shape": "erdRelation", - "relation": "0,n:1", - "source": "36f47f24", - "target": "78d290b9", - "id": "506d4c83", - "controlPoints": [ - { - "x": 854.9599609375, - "y": 372.45588235294116 - }, - { - "x": 494.3779296875, - "y": 72.10714285714286 - } - ], - "sourceAnchor": 4, - "targetAnchor": 1 - }, - { - "shape": "erdRelation", - "relation": "0,n:1", - "source": "64620a69", - "target": "07068933", - "id": "1e7896c8", - "controlPoints": [ - { - "x": 965.9115991195206, - "y": 663.1742639423077 - }, - { - "x": 529.7060546875, - "y": 772.1388888888889 - } - ], - "sourceAnchor": 2, - "targetAnchor": 1 - }, - { - "shape": "erdRelation", - "relation": "0,n:1", - "source": "64620a69", - "target": "45e84f94", - "id": "083acf5e", - "controlPoints": [ - { - "x": 965.9115991195206, - "y": 683.3281100961538 - }, - { - "x": 516.3779296875, - "y": 462.1388888888889 - } - ], - "sourceAnchor": 4, - "targetAnchor": 1 - }, - { - "shape": "erdRelation", - "relation": "0,n:1", - "source": "78d290b9", - "target": "145b5e72", - "id": "2b15a6d7", - "controlPoints": [ - { - "x": 105.6220703125, - "y": 132.2785714285714 - }, - { - "x": -696.9755859375, - "y": 133.22474747474746 - } - ], - "sourceAnchor": 6, - "targetAnchor": 1 - }, - { - "shape": "erdRelation", - "relation": "0,n:1", - "source": "77fa9953", - "target": "45e84f94", - "id": "248f313d", - "controlPoints": [ - { - "x": -11.9638671875, - "y": 292.51666666666665 - }, - { - "x": 103.6220703125, - "y": 462.1388888888889 - } - ], - "sourceAnchor": 5, - "targetAnchor": 0 - }, - { - "shape": "erdRelation", - "relation": "0,n:1", - "source": "77fa9953", - "target": "145b5e72", - "id": "fcd2ee2c", - "controlPoints": [ - { - "x": -488.0361328125, - "y": 272.3833333333333 - }, - { - "x": -696.9755859375, - "y": 133.22474747474746 - } - ], - "sourceAnchor": 2, - "targetAnchor": 1 - }, - { - "shape": "erdRelation", - "relation": "0,n:1", - "source": "d71e9bc5", - "target": "145b5e72", - "id": "8fa954c4", - "controlPoints": [ - { - "x": -467.87109375, - "y": 592.4166666666666 - }, - { - "x": -696.9755859375, - "y": 133.22474747474746 - } - ], - "sourceAnchor": 0, - "targetAnchor": 1 - }, - { - "shape": "erdRelation", - "relation": "0,n:1", - "source": "d71e9bc5", - "target": "953e8f99", - "id": "0c61ae50", - "controlPoints": [ - { - "x": -467.87109375, - "y": 612.6388888888889 - }, - { - "x": -683.63671875, - "y": 611.1094771241831 - } - ], - "sourceAnchor": 2, - "targetAnchor": 1 - } - ] - }, - "associations": [ - { - "relation": "0,n:1", - "from": { - "entity": "vertical_article_content", - "field": "id_article" - }, - "to": { - "entity": "vertical_article", - "field": "id" - } - }, - { - "relation": "0,n:1", - "from": { - "entity": "vertical_tag_article", - "field": "id_tag" - }, - "to": { - "entity": "vertical_tag", - "field": "id" - } - }, - { - "relation": "0,n:1", - "from": { - "entity": "vertical_tag_article", - "field": "id_article" - }, - "to": { - "entity": "vertical_article", - "field": "id" - } - }, - { - "relation": "0,n:1", - "from": { - "entity": "vertical_topic_tag", - "field": "id_topic" - }, - "to": { - "entity": "vertical_topic", - "field": "id" - } - }, - { - "relation": "0,n:1", - "from": { - "entity": "vertical_topic_tag", - "field": "id_tag" - }, - "to": { - "entity": "vertical_tag", - "field": "id" - } - }, - { - "relation": "0,n:1", - "from": { - "entity": "vertical_article", - "field": "article_author_id" - }, - "to": { - "entity": "vertical_user", - "field": "id" - } - }, - { - "relation": "0,n:1", - "from": { - "entity": "vertical_user_tag", - "field": "id_tag" - }, - "to": { - "entity": "vertical_tag", - "field": "id" - } - }, - { - "relation": "0,n:1", - "from": { - "entity": "vertical_user_tag", - "field": "id_user" - }, - "to": { - "entity": "vertical_user", - "field": "id" - } - }, - { - "relation": "0,n:1", - "from": { - "entity": "vertical_user_role", - "field": "id_user" - }, - "to": { - "entity": "vertical_user", - "field": "id" - } - }, - { - "relation": "0,n:1", - "from": { - "entity": "vertical_user_role", - "field": "id_role" - }, - "to": { - "entity": "vertical_role", - "field": "id" - } - } - ] - }, - { - "name": "DB_REVERSE_MYSQL", - "chnname": "逆向解析_MYSQL", - "entities": [ - { - "title": "vertical_special_day", - "chnname": "特殊日", - "fields": [ - { - "name": "id", - "type": "BigInt", - "chnname": "", - "remark": "", - "pk": true, - "notNull": true, - "autoIncrement": true, - "defaultValue": "" - }, - { - "name": "special_day_name", - "type": "VARCHAR_200", - "chnname": "名称", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "weights", - "type": "Integer", - "chnname": "权重/优先级,小数优秀", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "start_time", - "type": "DATETIME", - "chnname": "开始时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "expiration_time", - "type": "DATETIME", - "chnname": "过期时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "repeat", - "type": "Integer", - "chnname": "是否重复", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "repeat_cycle", - "type": "Integer", - "chnname": "重复周期", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "repeat_cycle_unit", - "type": "Integer", - "chnname": "0:天1:周2:月3:年", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "created_time", - "type": "DATETIME", - "chnname": "创建时间", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "img_url", - "type": "VARCHAR_500", - "chnname": "图片路径", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "css_style", - "type": "VARCHAR_2000", - "chnname": "执行全局样式", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - } - ], - "indexs": [], - "headers": [ - { - "fieldName": "chnname", - "relationNoShow": false - }, - { - "fieldName": "name", - "relationNoShow": false - }, - { - "fieldName": "type", - "relationNoShow": false - }, - { - "fieldName": "dataType", - "relationNoShow": true - }, - { - "fieldName": "remark", - "relationNoShow": true - }, - { - "fieldName": "pk", - "relationNoShow": false - }, - { - "fieldName": "notNull", - "relationNoShow": true - }, - { - "fieldName": "autoIncrement", - "relationNoShow": true - }, - { - "fieldName": "defaultValue", - "relationNoShow": true - }, - { - "fieldName": "relationNoShow", - "relationNoShow": true - }, - { - "fieldName": "uiHint", - "relationNoShow": true - } - ] - }, - { - "title": "vertical_wx_user", - "chnname": "微信用户表", - "fields": [ - { - "name": "id", - "type": "INT_10", - "chnname": "微信用户表主键", - "remark": "", - "pk": true, - "notNull": true, - "autoIncrement": true, - "defaultValue": "" - }, - { - "name": "nickname", - "type": "VARCHAR_50", - "chnname": "", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "union_id", - "type": "VARCHAR_32", - "chnname": "微信全局 unionId", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "open_id", - "type": "VARCHAR_32", - "chnname": "openId", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "app_id", - "type": "VARCHAR_32", - "chnname": "AppId", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "sex", - "type": "INT_10", - "chnname": "性别字段", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "sex_desc", - "type": "VARCHAR_32", - "chnname": "性别文本", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "head_img_url", - "type": "VARCHAR_200", - "chnname": "头像图片路径", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "country", - "type": "VARCHAR_32", - "chnname": "所属国家", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "province", - "type": "VARCHAR_32", - "chnname": "所属省/州", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "city", - "type": "VARCHAR_32", - "chnname": "所属市/区", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "act_token", - "type": "VARCHAR_64", - "chnname": "活动 Token", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "subscribe", - "type": "BIT_1", - "chnname": "是否关注", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "subscribe_time", - "type": "MEDIUMTEXT", - "chnname": "关注时间戳", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - }, - { - "name": "language", - "type": "VARCHAR_10", - "chnname": "语言", - "remark": "", - "pk": false, - "notNull": false, - "autoIncrement": false, - "defaultValue": "" - } - ] - } - ], - "graphCanvas": { - "nodes": [], - "edges": [] - }, - "associations": [] - } - ], - "dataTypeDomains": { - "datatype": [ - { - "name": "默认字串", - "code": "DefaultString", - "apply": { - "JAVA": { - "type": "String" - }, - "MYSQL": { - "type": "VARCHAR(32)" - }, - "ORACLE": { - "type": "NVARCHAR2(32)" - }, - "SQLServer": { - "type": "NVARCHAR(32)" - }, - "PostgreSQL": { - "type": "VARCHAR(32)" - } - } - }, - { - "name": "标识号", - "code": "IdOrKey", - "apply": { - "JAVA": { - "type": "String" - }, - "ORACLE": { - "type": "VARCHAR2(32)" - }, - "MYSQL": { - "type": "VARCHAR(32)" - }, - "SQLServer": { - "type": "VARCHAR(32)" - }, - "PostgreSQL": { - "type": "VARCHAR(32)" - } - } - }, - { - "name": "标识号-长", - "code": "LongKey", - "apply": { - "MYSQL": { - "type": "VARCHAR(64)" - }, - "ORACLE": { - "type": "VARCHAR2(64)" - }, - "JAVA": { - "type": "String" - }, - "SQLServer": { - "type": "VARCHAR(64)" - }, - "PostgreSQL": { - "type": "VARCHAR(64)" - } - } - }, - { - "name": "名称", - "code": "Name", - "apply": { - "JAVA": { - "type": "String" - }, - "MYSQL": { - "type": "VARCHAR(128)" - }, - "ORACLE": { - "type": "NVARCHAR2(128)" - }, - "SQLServer": { - "type": "NVARCHAR(128)" - }, - "PostgreSQL": { - "type": "VARCHAR(128)" - } - } - }, - { - "name": "备注说明", - "code": "Intro", - "apply": { - "JAVA": { - "type": "String" - }, - "MYSQL": { - "type": "VARCHAR(512)" - }, - "ORACLE": { - "type": "NVARCHAR2(512)" - }, - "SQLServer": { - "type": "NVARCHAR(512)" - }, - "PostgreSQL": { - "type": "VARCHAR(512)" - } - } - }, - { - "name": "字串-短", - "code": "ShortString", - "apply": { - "JAVA": { - "type": "String" - }, - "MYSQL": { - "type": "VARCHAR(128)" - }, - "ORACLE": { - "type": "NVARCHAR2(128)" - }, - "SQLServer": { - "type": "NVARCHAR(128)" - }, - "PostgreSQL": { - "type": "VARCHAR(128)" - } - } - }, - { - "name": "字串-中", - "code": "MiddleString", - "apply": { - "JAVA": { - "type": "String" - }, - "MYSQL": { - "type": "VARCHAR(1024)" - }, - "ORACLE": { - "type": "NVARCHAR2(1024)" - }, - "SQLServer": { - "type": "NVARCHAR(1024)" - }, - "PostgreSQL": { - "type": "VARCHAR(1024)" - } - } - }, - { - "name": "字串-长", - "code": "LongString", - "apply": { - "JAVA": { - "type": "String" - }, - "ORACLE": { - "type": "NVARCHAR2(3072)" - }, - "MYSQL": { - "type": "VARCHAR(3072)" - }, - "SQLServer": { - "type": "NVARCHAR(3072)" - }, - "PostgreSQL": { - "type": "VARCHAR(3072)" - } - } - }, - { - "name": "大文本", - "code": "LongText", - "apply": { - "JAVA": { - "type": "String" - }, - "MYSQL": { - "type": "TEXT" - }, - "ORACLE": { - "type": "CLOB" - }, - "SQLServer": { - "type": "NTEXT" - }, - "PostgreSQL": { - "type": "TEXT" - } - } - }, - { - "name": "小数", - "code": "Double", - "apply": { - "JAVA": { - "type": "Double" - }, - "MYSQL": { - "type": "DECIMAL(32,10)" - }, - "ORACLE": { - "type": "NUMBER(32,10)" - }, - "SQLServer": { - "type": "DECIMAL(32,10)" - }, - "PostgreSQL": { - "type": "DECIMAL(32,10)" - } - } - }, - { - "name": "比例", - "code": "Ratio", - "apply": { - "MYSQL": { - "type": "DECIMAL(4,2)" - }, - "JAVA": { - "type": "Double" - }, - "ORACLE": { - "type": "NUMBER(4,2)" - }, - "SQLServer": { - "type": "DECIMAL(4,2)" - }, - "PostgreSQL": { - "type": "DECIMAL(4,2)" - } - } - }, - { - "name": "整数", - "code": "Integer", - "apply": { - "JAVA": { - "type": "Integer" - }, - "MYSQL": { - "type": "INT" - }, - "ORACLE": { - "type": "INT" - }, - "SQLServer": { - "type": "INT" - }, - "PostgreSQL": { - "type": "INT" - } - } - }, - { - "name": "大整数", - "code": "BigInt", - "apply": { - "MYSQL": { - "type": "BIGINT" - }, - "JAVA": { - "type": "Long" - }, - "ORACLE": { - "type": "NUMBER" - }, - "SQLServer": { - "type": "BIGINT" - }, - "PostgreSQL": { - "type": "BIGINT" - } - } - }, - { - "name": "金额", - "code": "Money", - "apply": { - "JAVA": { - "type": "Double" - }, - "MYSQL": { - "type": "DECIMAL(32,8)" - }, - "ORACLE": { - "type": "NUMBER(32,8)" - }, - "SQLServer": { - "type": "DECIMAL(32,8)" - }, - "PostgreSQL": { - "type": "DECIMAL(32,8)" - } - } - }, - { - "name": "是否", - "code": "YesNo", - "apply": { - "JAVA": { - "type": "String" - }, - "MYSQL": { - "type": "VARCHAR(1)" - }, - "ORACLE": { - "type": "VARCHAR2(1)" - }, - "SQLServer": { - "type": "VARCHAR(1)" - }, - "PostgreSQL": { - "type": "VARCHAR(1)" - } - } - }, - { - "name": "数据字典", - "code": "Dict", - "apply": { - "JAVA": { - "type": "String" - }, - "MYSQL": { - "type": "VARCHAR(32)" - }, - "ORACLE": { - "type": "VARCHAR2(32)" - }, - "SQLServer": { - "type": "VARCHAR(32)" - }, - "PostgreSQL": { - "type": "VARCHAR(32)" - } - } - }, - { - "name": "日期", - "code": "Date", - "apply": { - "JAVA": { - "type": "Date" - }, - "MYSQL": { - "type": "DATE" - }, - "ORACLE": { - "type": "DATE" - }, - "SQLServer": { - "type": "DATE" - }, - "PostgreSQL": { - "type": "DATE" - } - } - }, - { - "name": "日期时间", - "code": "DateTime", - "apply": { - "JAVA": { - "type": "Date" - }, - "MYSQL": { - "type": "DATETIME" - }, - "ORACLE": { - "type": "DATE" - }, - "SQLServer": { - "type": "DATE" - }, - "PostgreSQL": { - "type": "DATE" - } - } - }, - { - "name": "单字符", - "code": "Char", - "apply": { - "MYSQL": { - "type": "CHAR(1)" - }, - "ORACLE": { - "type": "CHAR(1)" - }, - "JAVA": { - "type": "String" - }, - "SQLServer": { - "type": "CHAR(1)" - }, - "PostgreSQL": { - "type": "CHAR(1)" - } - } - }, - { - "name": "BIGINT_19", - "code": "BIGINT_19", - "apply": { - "MYSQL": { - "type": "BIGINT(19)" - } - } - }, - { - "name": "CHAR_1", - "code": "CHAR_1", - "apply": { - "MYSQL": { - "type": "CHAR(1)" - } - } - }, - { - "name": "DATETIME", - "code": "DATETIME", - "apply": { - "MYSQL": { - "type": "DATETIME" - } - } - }, - { - "name": "INT_10", - "code": "INT_10", - "apply": { - "MYSQL": { - "type": "INT(10)" - } - } - }, - { - "name": "TEXT", - "code": "TEXT", - "apply": { - "MYSQL": { - "type": "TEXT" - } - } - }, - { - "name": "TINYINT_3", - "code": "TINYINT_3", - "apply": { - "MYSQL": { - "type": "TINYINT(3)" - } - } - }, - { - "name": "VARCHAR_1024", - "code": "VARCHAR_1024", - "apply": { - "MYSQL": { - "type": "VARCHAR(1024)" - } - } - }, - { - "name": "VARCHAR_11", - "code": "VARCHAR_11", - "apply": { - "MYSQL": { - "type": "VARCHAR(11)" - } - } - }, - { - "name": "VARCHAR_128", - "code": "VARCHAR_128", - "apply": { - "MYSQL": { - "type": "VARCHAR(128)" - } - } - }, - { - "name": "VARCHAR_256", - "code": "VARCHAR_256", - "apply": { - "MYSQL": { - "type": "VARCHAR(256)" - } - } - }, - { - "name": "VARCHAR_32", - "code": "VARCHAR_32", - "apply": { - "MYSQL": { - "type": "VARCHAR(32)" - } - } - }, - { - "name": "VARCHAR_512", - "code": "VARCHAR_512", - "apply": { - "MYSQL": { - "type": "VARCHAR(512)" - } - } - }, - { - "name": "VARCHAR_64", - "code": "VARCHAR_64", - "apply": { - "MYSQL": { - "type": "VARCHAR(64)" - } - } - }, - { - "name": "BIT_1", - "code": "BIT_1", - "apply": { - "MYSQL": { - "type": "BIT(1)" - } - } - }, - { - "name": "DATE", - "code": "DATE", - "apply": { - "MYSQL": { - "type": "DATE" - } - } - }, - { - "name": "MEDIUMTEXT", - "code": "MEDIUMTEXT", - "apply": { - "MYSQL": { - "type": "MEDIUMTEXT" - } - } - }, - { - "name": "VARCHAR_10", - "code": "VARCHAR_10", - "apply": { - "MYSQL": { - "type": "VARCHAR(10)" - } - } - }, - { - "name": "VARCHAR_200", - "code": "VARCHAR_200", - "apply": { - "MYSQL": { - "type": "VARCHAR(200)" - } - } - }, - { - "name": "VARCHAR_2000", - "code": "VARCHAR_2000", - "apply": { - "MYSQL": { - "type": "VARCHAR(2000)" - } - } - }, - { - "name": "VARCHAR_50", - "code": "VARCHAR_50", - "apply": { - "MYSQL": { - "type": "VARCHAR(50)" - } - } - }, - { - "name": "VARCHAR_500", - "code": "VARCHAR_500", - "apply": { - "MYSQL": { - "type": "VARCHAR(500)" - } - } - } - ], - "database": [ - { - "code": "MYSQL", - "template": "DROP TABLE {{=it.entity.title}};\n$blankline\nCREATE TABLE {{=it.entity.title}}(\n{{ pkList = [] ; }}\n{{~it.entity.fields:field:index}}\n {{? field.pk }}{{ pkList.push(field.name) }}{{?}}\n {{=field.name}} {{=field.type}} {{= field.pk ? 'NOT NULL' : '' }} COMMENT '{{=it.func.join(field.chnname,field.remark,';')}}' {{= index < it.entity.fields.length-1 ? ',' : ( pkList.length>0 ? ',' :'' ) }}\n{{~}}\n{{? pkList.length >0 }}\n PRIMARY KEY ({{~pkList:pkName:i}}{{= pkName }}{{= i0 ? ',' :'' ) }}\n{{~}}\n{{? pkList.length >0 }}\n PRIMARY KEY ({{~pkList:pkName:i}}{{= pkName }}{{= i0 ? ',' :'' ) }}\n{{~}}\n{{? pkList.length >0 }}\n PRIMARY KEY ({{~pkList:pkName:i}}{{= pkName }}{{= i0 ? ',' :'' ) }}\n{{~}}\n{{? pkList.length >0 }}\n PRIMARY KEY ({{~pkList:pkName:i}}{{= pkName }}{{= i0 ? ',' :'' ) }}\n{{~}}\n{{? pkList.length >0 }}\n PRIMARY KEY ({{~pkList:pkName:i}}{{= pkName }}{{= i0 ? ',' :'' ) }}\n{{~}}{{? pkList.length >0 }} PRIMARY KEY ({{~pkList:pkName:i}}{{= pkName }}{{= i0 ? ',' :'' ) }}\n{{~}}\n{{? pkList.length >0 }}\n CONSTRAINT PK_{{=it.entity.title}} PRIMARY KEY CLUSTERED ({{~pkList:pkName:i}}{{= pkName }} ASC {{= i0 ? ',' :'' ) }}\n{{~}}\n{{? pkList.length >0 }}\n PRIMARY KEY ({{~pkList:pkName:i}}{{= pkName }}{{= i0 ? ',' :'' ) }}\n{{~}}\n{{? pkList.length >0 }}\n PRIMARY KEY ({{~pkList:pkName:i}}{{= pkName }}{{= i0 ? ',' :'' ) }}\n{{~}}\n{{? pkList.length >0 }}\n PRIMARY KEY ({{~pkList:pkName:i}}{{= pkName }}{{= i Date: Thu, 24 Sep 2020 22:53:21 +0800 Subject: [PATCH 29/36] =?UTF-8?q?:sparkles:=201.=20=E5=85=B3=E6=B3=A8?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=202.=20=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= =?UTF-8?q?=203.=20=E6=B6=88=E6=81=AF=E9=80=9A=E7=9F=A5=E4=BC=98=E5=8C=96?= =?UTF-8?q?=204.=20=E5=90=8E=E5=8F=B0=E7=AE=A1=E7=90=86=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vertical/config/BaseExceptionHandler.java | 8 +- .../rymcu/vertical/config/BaseShiroRealm.java | 4 +- .../rymcu/vertical/config/ShiroConfig.java | 1 + .../rymcu/vertical/dto/NotificationDTO.java | 2 + .../java/com/rymcu/vertical/entity/Tag.java | 2 + .../java/com/rymcu/vertical/entity/Topic.java | 2 + .../rymcu/vertical/mapper/ArticleMapper.java | 22 +++ .../rymcu/vertical/mapper/TopicMapper.java | 4 +- .../com/rymcu/vertical/mapper/UserMapper.java | 7 + .../vertical/service/ArticleService.java | 8 ++ .../vertical/service/PermissionService.java | 7 +- .../rymcu/vertical/service/TopicService.java | 13 +- .../service/impl/ArticleServiceImpl.java | 131 +++++++++++------- .../service/impl/NotificationServiceImpl.java | 33 ++++- .../service/impl/PermissionServiceImpl.java | 7 +- .../service/impl/PortfolioServiceImpl.java | 4 +- .../vertical/service/impl/TagServiceImpl.java | 39 +++--- .../service/impl/TopicServiceImpl.java | 43 +++--- .../service/impl/UserServiceImpl.java | 4 +- .../com/rymcu/vertical/util/BaiDuUtils.java | 3 +- .../com/rymcu/vertical/util/UserUtils.java | 2 +- .../web/api/admin/AdminController.java | 13 +- .../web/api/article/ArticleController.java | 7 + .../web/api/common/UploadController.java | 41 +++--- .../notification/NotificationController.java | 4 +- .../vertical/web/api/user/UserController.java | 2 + src/main/java/mapper/ArticleMapper.xml | 17 ++- src/main/java/mapper/DashboardMapper.xml | 13 +- src/main/java/mapper/TopicMapper.xml | 6 +- src/main/java/mapper/UserMapper.xml | 3 + 30 files changed, 307 insertions(+), 145 deletions(-) diff --git a/src/main/java/com/rymcu/vertical/config/BaseExceptionHandler.java b/src/main/java/com/rymcu/vertical/config/BaseExceptionHandler.java index fc47680..9ebe05e 100644 --- a/src/main/java/com/rymcu/vertical/config/BaseExceptionHandler.java +++ b/src/main/java/com/rymcu/vertical/config/BaseExceptionHandler.java @@ -23,6 +23,8 @@ import java.util.Map; /** * 全局异常处理器 + * + * @author ronger * */ @RestControllerAdvice public class BaseExceptionHandler { @@ -46,7 +48,8 @@ public class BaseExceptionHandler { result.setCode(1000002); result.setMessage("用户无权限"); logger.info("用户无权限"); - }else if (ex instanceof ServiceException) {//业务失败的异常,如“账号或密码错误” + }else if (ex instanceof ServiceException) { + //业务失败的异常,如“账号或密码错误” result.setCode(((ServiceException) ex).getCode()); result.setMessage(ex.getMessage()); logger.info(ex.getMessage()); @@ -88,7 +91,8 @@ public class BaseExceptionHandler { } else if (ex instanceof UnauthorizedException) { attributes.put("code", "1000002"); attributes.put("message", "用户无权限"); - } else if (ex instanceof ServiceException) {//业务失败的异常,如“账号或密码错误” + } else if (ex instanceof ServiceException) { + //业务失败的异常,如“账号或密码错误” attributes.put("code",((ServiceException) ex).getCode()); attributes.put("message",ex.getMessage()); logger.info(ex.getMessage()); diff --git a/src/main/java/com/rymcu/vertical/config/BaseShiroRealm.java b/src/main/java/com/rymcu/vertical/config/BaseShiroRealm.java index 7c88b93..1a0126b 100644 --- a/src/main/java/com/rymcu/vertical/config/BaseShiroRealm.java +++ b/src/main/java/com/rymcu/vertical/config/BaseShiroRealm.java @@ -42,8 +42,6 @@ public class BaseShiroRealm extends AuthorizingRealm { @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { - //Principal principal = (Principal) getAvailablePrincipal(principals); -// System.out.println("权限配置-->MyShiroRealm.doGetAuthorizationInfo()"); SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); Principal principal = (Principal)principals.getPrimaryPrincipal(); User user = new User(); @@ -55,7 +53,7 @@ public class BaseShiroRealm extends AuthorizingRealm { authorizationInfo.addRole(role.getInputCode()); } } - List permissions = permissionService.selectMenuByUser(user); + List permissions = permissionService.selectPermissionByUser(user); for (Permission perm : permissions) { if (perm.getPermissionCategory() != null) { authorizationInfo.addStringPermission(perm.getPermissionCategory()); diff --git a/src/main/java/com/rymcu/vertical/config/ShiroConfig.java b/src/main/java/com/rymcu/vertical/config/ShiroConfig.java index 9fda51a..25b48ce 100644 --- a/src/main/java/com/rymcu/vertical/config/ShiroConfig.java +++ b/src/main/java/com/rymcu/vertical/config/ShiroConfig.java @@ -55,6 +55,7 @@ public class ShiroConfig implements EnvironmentAware { filterChainDefinitionMap.put("/api/**", "anon"); filterChainDefinitionMap.put("/ws/**", "anon"); + filterChainDefinitionMap.put("/wx/**", "anon"); filterChainDefinitionMap.put("/**", "auth"); //配置shiro默认登录界面地址,前后端分离中登录界面跳转应由前端路由控制,后台仅返回json数据 shiroFilterFactoryBean.setLoginUrl("/login"); diff --git a/src/main/java/com/rymcu/vertical/dto/NotificationDTO.java b/src/main/java/com/rymcu/vertical/dto/NotificationDTO.java index c9d69f7..4384763 100644 --- a/src/main/java/com/rymcu/vertical/dto/NotificationDTO.java +++ b/src/main/java/com/rymcu/vertical/dto/NotificationDTO.java @@ -2,11 +2,13 @@ package com.rymcu.vertical.dto; import com.rymcu.vertical.entity.Notification; import lombok.Data; +import lombok.EqualsAndHashCode; /** * @author ronger */ @Data +@EqualsAndHashCode(callSuper = false) public class NotificationDTO extends Notification { private Integer idNotification; diff --git a/src/main/java/com/rymcu/vertical/entity/Tag.java b/src/main/java/com/rymcu/vertical/entity/Tag.java index b53e68a..9184f90 100644 --- a/src/main/java/com/rymcu/vertical/entity/Tag.java +++ b/src/main/java/com/rymcu/vertical/entity/Tag.java @@ -44,4 +44,6 @@ public class Tag implements Serializable,Cloneable { private Date updatedTime; /** 保留标签 */ private String tagReservation; + /** 描述 */ + private String tagDescriptionHtml; } diff --git a/src/main/java/com/rymcu/vertical/entity/Topic.java b/src/main/java/com/rymcu/vertical/entity/Topic.java index 4cb6c72..0011dda 100644 --- a/src/main/java/com/rymcu/vertical/entity/Topic.java +++ b/src/main/java/com/rymcu/vertical/entity/Topic.java @@ -42,5 +42,7 @@ public class Topic { private Date createdTime; /** 更新时间 */ private Date updatedTime; + /** 专题描述 Html */ + private String topicDescriptionHtml; } diff --git a/src/main/java/com/rymcu/vertical/mapper/ArticleMapper.java b/src/main/java/com/rymcu/vertical/mapper/ArticleMapper.java index 8c74ece..81264f5 100644 --- a/src/main/java/com/rymcu/vertical/mapper/ArticleMapper.java +++ b/src/main/java/com/rymcu/vertical/mapper/ArticleMapper.java @@ -136,4 +136,26 @@ public interface ArticleMapper extends Mapper

{ * @return */ List selectPortfolioArticles(@Param("idArticle") Integer idArticle); + + /** + * 更新文章标签 + * @param idArticle + * @param tags + * @return + */ + Integer updateArticleTags(@Param("idArticle") Integer idArticle, @Param("tags") String tags); + + /** + * 判断是否有评论 + * @param id + * @return + */ + boolean existsCommentWithPrimaryKey(@Param("id") Integer id); + + /** + * 删除关联作品集数据 + * @param id + * @return + */ + Integer deleteLinkedPortfolioData(@Param("id") Integer id); } diff --git a/src/main/java/com/rymcu/vertical/mapper/TopicMapper.java b/src/main/java/com/rymcu/vertical/mapper/TopicMapper.java index 266d867..d1dbd99 100644 --- a/src/main/java/com/rymcu/vertical/mapper/TopicMapper.java +++ b/src/main/java/com/rymcu/vertical/mapper/TopicMapper.java @@ -32,6 +32,7 @@ public interface TopicMapper extends Mapper { List selectTopicTag(@Param("idTopic") Integer idTopic); /** + * 更新 * @param idTopic * @param topicTitle * @param topicUri @@ -40,9 +41,10 @@ public interface TopicMapper extends Mapper { * @param topicStatus * @param topicSort * @param topicDescription + * @param topicDescriptionHtml * @return */ - Integer update(@Param("idTopic") Integer idTopic, @Param("topicTitle") String topicTitle, @Param("topicUri") String topicUri, @Param("topicIconPath") String topicIconPath, @Param("topicNva") String topicNva, @Param("topicStatus") String topicStatus, @Param("topicSort") Integer topicSort, @Param("topicDescription") String topicDescription); + Integer update(@Param("idTopic") Integer idTopic, @Param("topicTitle") String topicTitle, @Param("topicUri") String topicUri, @Param("topicIconPath") String topicIconPath, @Param("topicNva") String topicNva, @Param("topicStatus") String topicStatus, @Param("topicSort") Integer topicSort, @Param("topicDescription") String topicDescription, @Param("topicDescriptionHtml") String topicDescriptionHtml); /** * @param idTopic diff --git a/src/main/java/com/rymcu/vertical/mapper/UserMapper.java b/src/main/java/com/rymcu/vertical/mapper/UserMapper.java index ce95279..de1eae8 100644 --- a/src/main/java/com/rymcu/vertical/mapper/UserMapper.java +++ b/src/main/java/com/rymcu/vertical/mapper/UserMapper.java @@ -113,4 +113,11 @@ public interface UserMapper extends Mapper { * @return */ Author selectAuthor(@Param("id") Integer id); + + /** + * 更新用户最后登录时间 + * @param idUser + * @return + */ + Integer updateLastLoginTime(@Param("idUser") Integer idUser); } \ No newline at end of file diff --git a/src/main/java/com/rymcu/vertical/service/ArticleService.java b/src/main/java/com/rymcu/vertical/service/ArticleService.java index 65f6718..74ead8d 100644 --- a/src/main/java/com/rymcu/vertical/service/ArticleService.java +++ b/src/main/java/com/rymcu/vertical/service/ArticleService.java @@ -105,4 +105,12 @@ public interface ArticleService extends Service
{ * @return */ List selectUnbindArticles(Integer idPortfolio, String searchText, Integer idUser); + + /** + * 更新文章标签 + * @param idArticle + * @param tags + * @return + */ + Map updateTags(Integer idArticle, String tags) throws UnsupportedEncodingException, BaseApiException; } diff --git a/src/main/java/com/rymcu/vertical/service/PermissionService.java b/src/main/java/com/rymcu/vertical/service/PermissionService.java index 74eea8c..bf577d1 100644 --- a/src/main/java/com/rymcu/vertical/service/PermissionService.java +++ b/src/main/java/com/rymcu/vertical/service/PermissionService.java @@ -14,5 +14,10 @@ import java.util.List; */ public interface PermissionService extends Service { - List selectMenuByUser(User sysUser); + /** + * 获取用户权限 + * @param sysUser + * @return + */ + List selectPermissionByUser(User sysUser); } diff --git a/src/main/java/com/rymcu/vertical/service/TopicService.java b/src/main/java/com/rymcu/vertical/service/TopicService.java index cffce69..60bbd27 100644 --- a/src/main/java/com/rymcu/vertical/service/TopicService.java +++ b/src/main/java/com/rymcu/vertical/service/TopicService.java @@ -22,11 +22,9 @@ public interface TopicService extends Service { /** * 根据 topicUri 获取主题信息及旗下标签数据 * @param topicUri 主题 URI - * @param page - * @param rows * @return * */ - Map findTopicByTopicUri(String topicUri, Integer page, Integer rows); + Topic findTopicByTopicUri(String topicUri); /** * 新增/更新主题信息 @@ -56,4 +54,13 @@ public interface TopicService extends Service { * @return */ Map unbindTopicTag(TopicTagDTO topicTag); + + /** + * 获取主题下标签列表 + * @param topicUri + * @param page + * @param rows + * @return + */ + Map findTagsByTopicUri(String topicUri, Integer page, Integer rows); } diff --git a/src/main/java/com/rymcu/vertical/service/impl/ArticleServiceImpl.java b/src/main/java/com/rymcu/vertical/service/impl/ArticleServiceImpl.java index ef3808d..dd620cc 100644 --- a/src/main/java/com/rymcu/vertical/service/impl/ArticleServiceImpl.java +++ b/src/main/java/com/rymcu/vertical/service/impl/ArticleServiceImpl.java @@ -25,10 +25,7 @@ import tk.mybatis.mapper.entity.Condition; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.io.UnsupportedEncodingException; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; /** * @author ronger @@ -62,19 +59,19 @@ public class ArticleServiceImpl extends AbstractService
implements Arti } else { list = articleMapper.selectArticles(searchDTO.getSearchText(), searchDTO.getTag(), searchDTO.getTopicUri()); } - list.forEach(article->{ - genArticle(article,0); + list.forEach(article -> { + genArticle(article, 0); }); return list; } @Override public ArticleDTO findArticleDTOById(Integer id, Integer type) { - ArticleDTO articleDTO = articleMapper.selectArticleDTOById(id,type); + ArticleDTO articleDTO = articleMapper.selectArticleDTOById(id, type); if (articleDTO == null) { return null; } - articleDTO = genArticle(articleDTO,type); + articleDTO = genArticle(articleDTO, type); return articleDTO; } @@ -82,7 +79,7 @@ public class ArticleServiceImpl extends AbstractService
implements Arti public List findArticlesByTopicUri(String name) { List articleDTOS = articleMapper.selectArticlesByTopicUri(name); articleDTOS.forEach(articleDTO -> { - genArticle(articleDTO,0); + genArticle(articleDTO, 0); }); return articleDTOS; } @@ -96,29 +93,30 @@ public class ArticleServiceImpl extends AbstractService
implements Arti @Override public List findUserArticlesByIdUser(Integer idUser) { List list = articleMapper.selectUserArticles(idUser); - list.forEach(article->{ - genArticle(article,0); + list.forEach(article -> { + genArticle(article, 0); }); return list; } @Override - @Transactional(rollbackFor = { UnsupportedEncodingException.class, BaseApiException.class }) + @Transactional(rollbackFor = {UnsupportedEncodingException.class, BaseApiException.class}) public Map postArticle(ArticleDTO article, HttpServletRequest request) throws UnsupportedEncodingException, BaseApiException { Map map = new HashMap(1); - if(StringUtils.isBlank(article.getArticleTitle())){ - map.put("message","标题不能为空!"); + if (StringUtils.isBlank(article.getArticleTitle())) { + map.put("message", "标题不能为空!"); return map; } - if(StringUtils.isBlank(article.getArticleContent())){ - map.put("message","正文不能为空!"); + if (StringUtils.isBlank(article.getArticleContent())) { + map.put("message", "正文不能为空!"); return map; } + boolean isUpdate = false; String articleTitle = article.getArticleTitle(); String articleTags = article.getArticleTags(); String articleContent = article.getArticleContent(); String articleContentHtml = article.getArticleContentHtml(); - User user = UserUtils.getWxCurrentUser(); + User user = UserUtils.getCurrentUserByToken(); String reservedTag = checkTags(articleTags); boolean notification = false; if (StringUtils.isNotBlank(reservedTag)) { @@ -131,7 +129,7 @@ public class ArticleServiceImpl extends AbstractService
implements Arti } } Article newArticle; - if(article.getIdArticle() == null || article.getIdArticle() == 0){ + if (article.getIdArticle() == null || article.getIdArticle() == 0) { newArticle = new Article(); newArticle.setArticleTitle(articleTitle); newArticle.setArticleAuthorId(user.getIdUser()); @@ -140,24 +138,19 @@ public class ArticleServiceImpl extends AbstractService
implements Arti newArticle.setUpdatedTime(newArticle.getCreatedTime()); newArticle.setArticleStatus(article.getArticleStatus()); articleMapper.insertSelective(newArticle); - articleMapper.insertArticleContent(newArticle.getIdArticle(),articleContent,articleContentHtml); - if (!ProjectConstant.ENV.equals(env) && defaultStatus.equals(newArticle.getArticleStatus())) { - BaiDuUtils.sendSEOData(newArticle.getArticlePermalink()); - } + articleMapper.insertArticleContent(newArticle.getIdArticle(), articleContent, articleContentHtml); } else { + isUpdate = true; newArticle = articleMapper.selectByPrimaryKey(article.getIdArticle()); - if(!user.getIdUser().equals(newArticle.getArticleAuthorId())){ - map.put("message","非法访问!"); + if (!user.getIdUser().equals(newArticle.getArticleAuthorId())) { + map.put("message", "非法访问!"); return map; } newArticle.setArticleTitle(articleTitle); newArticle.setArticleTags(articleTags); newArticle.setArticleStatus(article.getArticleStatus()); newArticle.setUpdatedTime(new Date()); - articleMapper.updateArticleContent(newArticle.getIdArticle(),articleContent,articleContentHtml); - if (!ProjectConstant.ENV.equals(env) && defaultStatus.equals(newArticle.getArticleStatus())) { - BaiDuUtils.sendUpdateSEOData(newArticle.getArticlePermalink()); - } + articleMapper.updateArticleContent(newArticle.getIdArticle(), articleContent, articleContentHtml); } if (notification && defaultStatus.equals(newArticle.getArticleStatus())) { @@ -174,23 +167,34 @@ public class ArticleServiceImpl extends AbstractService
implements Arti newArticle.setArticleLink("/draft/" + newArticle.getIdArticle()); } - if(StringUtils.isNotBlank(articleContentHtml)){ + if (StringUtils.isNotBlank(articleContentHtml)) { Integer length = articleContentHtml.length(); - if(length > MAX_PREVIEW){ + if (length > MAX_PREVIEW) { length = MAX_PREVIEW; } - String articlePreviewContent = articleContentHtml.substring(0,length); + String articlePreviewContent = articleContentHtml.substring(0, length); newArticle.setArticlePreviewContent(Html2TextUtil.getContent(articlePreviewContent)); } articleMapper.updateByPrimaryKeySelective(newArticle); + // 推送百度 SEO + if (!ProjectConstant.ENV.equals(env) + && defaultStatus.equals(newArticle.getArticleStatus()) + && articleContent.length() >= MAX_PREVIEW) { + if (isUpdate) { + BaiDuUtils.sendUpdateSEOData(newArticle.getArticlePermalink()); + } else { + BaiDuUtils.sendSEOData(newArticle.getArticlePermalink()); + } + } + map.put("id", newArticle.getIdArticle()); return map; } private String checkTags(String articleTags) { // 判断文章是否有标签 - if(StringUtils.isBlank(articleTags)){ + if (StringUtils.isBlank(articleTags)) { return ""; } // 判断是否存在系统配置的保留标签词 @@ -206,7 +210,7 @@ public class ArticleServiceImpl extends AbstractService
implements Arti continue; } - for (String articleTag: articleTagArr) { + for (String articleTag : articleTagArr) { if (StringUtils.isBlank(articleTag)) { continue; } @@ -223,21 +227,31 @@ public class ArticleServiceImpl extends AbstractService
implements Arti @Override @Transactional(rollbackFor = Exception.class) public Map delete(Integer id) { - Map map = new HashMap(1); + Map map = new HashMap(1); Integer result; - // 删除引用标签记录 - result = articleMapper.deleteTagArticle(id); - if (result > 0){ + // 判断是否有评论 + boolean isHavComment = articleMapper.existsCommentWithPrimaryKey(id); + if (isHavComment) { + map.put("message", "已有评论的文章不允许删除!"); + } else { + // 删除关联数据(作品集关联关系,标签关联关系) + deleteLinkedData(id); + // 删除文章 result = articleMapper.deleteByPrimaryKey(id); - if (result < 1){ + if (result < 1) { map.put("message", "删除失败!"); } - } else { - map.put("message", "删除失败!"); } return map; } + private void deleteLinkedData(Integer id) { + // 删除关联作品集 + articleMapper.deleteLinkedPortfolioData(id); + // 删除引用标签记录 + articleMapper.deleteTagArticle(id); + } + @Override @Transactional(rollbackFor = Exception.class) public void incrementArticleViewCount(Integer id) { @@ -249,7 +263,7 @@ public class ArticleServiceImpl extends AbstractService
implements Arti @Override public Map share(Integer id) throws BaseApiException { Article article = articleMapper.selectByPrimaryKey(id); - User user = UserUtils.getWxCurrentUser(); + User user = UserUtils.getCurrentUserByToken(); StringBuilder shareUrl = new StringBuilder(article.getArticlePermalink()); shareUrl.append("?s=").append(user.getNickname()); Map map = new HashMap(1); @@ -259,10 +273,10 @@ public class ArticleServiceImpl extends AbstractService
implements Arti @Override public List findDrafts() throws BaseApiException { - User user = UserUtils.getWxCurrentUser(); + User user = UserUtils.getCurrentUserByToken(); List list = articleMapper.selectDrafts(user.getIdUser()); - list.forEach(article->{ - genArticle(article,0); + list.forEach(article -> { + genArticle(article, 0); }); return list; } @@ -270,21 +284,38 @@ public class ArticleServiceImpl extends AbstractService
implements Arti @Override public List findArticlesByIdPortfolio(Integer idPortfolio) { List list = articleMapper.selectArticlesByIdPortfolio(idPortfolio); - list.forEach(article->{ - genArticle(article,0); + list.forEach(article -> { + genArticle(article, 0); }); return list; } @Override public List selectUnbindArticles(Integer idPortfolio, String searchText, Integer idUser) { - List list = articleMapper.selectUnbindArticlesByIdPortfolio(idPortfolio,searchText,idUser); - list.forEach(article->{ - genArticle(article,0); + List list = articleMapper.selectUnbindArticlesByIdPortfolio(idPortfolio, searchText, idUser); + list.forEach(article -> { + genArticle(article, 0); }); return list; } + @Override + @Transactional(rollbackFor = Exception.class) + public Map updateTags(Integer idArticle, String tags) throws UnsupportedEncodingException, BaseApiException { + Map map = new HashMap(2); + Article article = articleMapper.selectByPrimaryKey(idArticle); + if (Objects.nonNull(article)) { + article.setArticleTags(tags); + articleMapper.updateArticleTags(idArticle, tags); + tagService.saveTagArticle(article); + map.put("success", true); + } else { + map.put("success", false); + map.put("message", "更新失败,文章不存在!"); + } + return map; + } + private ArticleDTO genArticle(ArticleDTO article, Integer type) { Integer ARTICLE_LIST = 0; Integer ARTICLE_VIEW = 1; @@ -296,7 +327,7 @@ public class ArticleServiceImpl extends AbstractService
implements Arti article.setTags(tags); if (!type.equals(ARTICLE_LIST)) { ArticleContent articleContent = articleMapper.selectArticleContent(article.getIdArticle()); - if (type.equals(ARTICLE_VIEW)){ + if (type.equals(ARTICLE_VIEW)) { article.setArticleContent(articleContent.getArticleContentHtml()); // 获取所属作品集列表数据 List portfolioArticleDTOList = articleMapper.selectPortfolioArticles(article.getIdArticle()); diff --git a/src/main/java/com/rymcu/vertical/service/impl/NotificationServiceImpl.java b/src/main/java/com/rymcu/vertical/service/impl/NotificationServiceImpl.java index 45d68cd..5fc016e 100644 --- a/src/main/java/com/rymcu/vertical/service/impl/NotificationServiceImpl.java +++ b/src/main/java/com/rymcu/vertical/service/impl/NotificationServiceImpl.java @@ -5,20 +5,20 @@ import com.rymcu.vertical.dto.ArticleDTO; import com.rymcu.vertical.dto.Author; import com.rymcu.vertical.dto.NotificationDTO; import com.rymcu.vertical.entity.Comment; +import com.rymcu.vertical.entity.Follow; import com.rymcu.vertical.entity.Notification; import com.rymcu.vertical.entity.User; import com.rymcu.vertical.mapper.NotificationMapper; -import com.rymcu.vertical.service.ArticleService; -import com.rymcu.vertical.service.CommentService; -import com.rymcu.vertical.service.NotificationService; -import com.rymcu.vertical.service.UserService; +import com.rymcu.vertical.service.*; import com.rymcu.vertical.util.BeanCopierUtil; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; +import java.util.Objects; /** * @author ronger @@ -34,6 +34,10 @@ public class NotificationServiceImpl extends AbstractService imple private CommentService commentService; @Resource private UserService userService; + @Resource + private FollowService followService; + @Value("${resource.domain}") + private String domain; @Override public List findUnreadNotifications(Integer idUser) { @@ -58,6 +62,7 @@ public class NotificationServiceImpl extends AbstractService imple ArticleDTO article; Comment comment; User user; + Follow follow; switch (notification.getDataType()) { case "0": // 系统公告/帖子 @@ -69,6 +74,11 @@ public class NotificationServiceImpl extends AbstractService imple break; case "1": // 关注 + follow = followService.findById(notification.getDataId().toString()); + notificationDTO.setDataTitle("关注提醒"); + user = userService.findById(follow.getFollowerId().toString()); + notificationDTO.setDataUrl(getFollowLink(follow.getFollowingType(), user.getNickname())); + notificationDTO.setAuthor(genAuthor(user)); break; case "2": // 回帖 @@ -79,10 +89,25 @@ public class NotificationServiceImpl extends AbstractService imple user = userService.findById(comment.getCommentAuthorId().toString()); notificationDTO.setAuthor(genAuthor(user)); break; + default: + break; } return notificationDTO; } + private String getFollowLink(String followingType, String id) { + StringBuilder url = new StringBuilder(); + url.append(domain); + switch (followingType) { + case "0": + url = url.append("/user/").append(id); + break; + default: + url.append("/notification"); + } + return url.toString(); + } + private Author genAuthor(User user) { Author author = new Author(); author.setUserNickname(user.getNickname()); diff --git a/src/main/java/com/rymcu/vertical/service/impl/PermissionServiceImpl.java b/src/main/java/com/rymcu/vertical/service/impl/PermissionServiceImpl.java index 0631561..4e42d2b 100644 --- a/src/main/java/com/rymcu/vertical/service/impl/PermissionServiceImpl.java +++ b/src/main/java/com/rymcu/vertical/service/impl/PermissionServiceImpl.java @@ -17,10 +17,11 @@ import java.util.List; /** - * Created by CodeGenerator on 2018/05/29. + * + * @author CodeGenerator + * @date 2018/05/29 */ @Service -@Transactional public class PermissionServiceImpl extends AbstractService implements PermissionService { @Resource private PermissionMapper permissionMapper; @@ -29,7 +30,7 @@ public class PermissionServiceImpl extends AbstractService implement private RoleService roleService; @Override - public List selectMenuByUser(User sysUser) { + public List selectPermissionByUser(User sysUser) { List list = new ArrayList(); List roles = roleService.selectRoleByUser(sysUser); roles.forEach(role -> list.addAll(permissionMapper.selectMenuByIdRole(role.getIdRole()))); diff --git a/src/main/java/com/rymcu/vertical/service/impl/PortfolioServiceImpl.java b/src/main/java/com/rymcu/vertical/service/impl/PortfolioServiceImpl.java index d5814bc..fdf75db 100644 --- a/src/main/java/com/rymcu/vertical/service/impl/PortfolioServiceImpl.java +++ b/src/main/java/com/rymcu/vertical/service/impl/PortfolioServiceImpl.java @@ -62,7 +62,7 @@ public class PortfolioServiceImpl extends AbstractService implements @Override public Portfolio postPortfolio(Portfolio portfolio) throws BaseApiException { - User user = UserUtils.getWxCurrentUser(); + User user = UserUtils.getCurrentUserByToken(); if (portfolio.getIdPortfolio() == null || portfolio.getIdPortfolio() == 0) { portfolio.setPortfolioAuthorId(user.getIdUser()); portfolio.setCreatedTime(new Date()); @@ -78,7 +78,7 @@ public class PortfolioServiceImpl extends AbstractService implements @Override public Map findUnbindArticles(Integer page, Integer rows, String searchText, Integer idPortfolio) throws BaseApiException { Map map = new HashMap(1); - User user = UserUtils.getWxCurrentUser(); + User user = UserUtils.getCurrentUserByToken(); Portfolio portfolio = portfolioMapper.selectByPrimaryKey(idPortfolio); if (portfolio == null) { map.put("message", "该作品集不存在或已被删除!"); diff --git a/src/main/java/com/rymcu/vertical/service/impl/TagServiceImpl.java b/src/main/java/com/rymcu/vertical/service/impl/TagServiceImpl.java index 72be192..6c1b3e3 100644 --- a/src/main/java/com/rymcu/vertical/service/impl/TagServiceImpl.java +++ b/src/main/java/com/rymcu/vertical/service/impl/TagServiceImpl.java @@ -37,11 +37,11 @@ public class TagServiceImpl extends AbstractService implements TagService { private ArticleMapper articleMapper; @Override - @Transactional(rollbackFor = { UnsupportedEncodingException.class,BaseApiException.class }) + @Transactional(rollbackFor = {UnsupportedEncodingException.class, BaseApiException.class}) public Integer saveTagArticle(Article article) throws UnsupportedEncodingException, BaseApiException { - User user = UserUtils.getWxCurrentUser(); + User user = UserUtils.getCurrentUserByToken(); String articleTags = article.getArticleTags(); - if(StringUtils.isNotBlank(articleTags)){ + if (StringUtils.isNotBlank(articleTags)) { String[] tags = articleTags.split(","); List articleTagDTOList = articleMapper.selectTags(article.getIdArticle()); for (int i = 0; i < tags.length; i++) { @@ -50,10 +50,10 @@ public class TagServiceImpl extends AbstractService implements TagService { Tag tag = new Tag(); tag.setTagTitle(tags[i]); tag = tagMapper.selectOne(tag); - if(tag == null){ + if (tag == null) { tag = new Tag(); tag.setTagTitle(tags[i]); - tag.setTagUri(URLEncoder.encode(tag.getTagTitle(),"UTF-8")); + tag.setTagUri(URLEncoder.encode(tag.getTagTitle(), "UTF-8")); tag.setCreatedTime(new Date()); tag.setUpdatedTime(tag.getCreatedTime()); tag.setTagArticleCount(1); @@ -61,31 +61,34 @@ public class TagServiceImpl extends AbstractService implements TagService { addTagArticle = true; addUserTag = true; } else { - for(int m=0,n=articleTagDTOList.size()-1;m { articleMapper.deleteUnusedArticleTag(articleTagDTO.getIdArticleTag()); }); - if(addTagArticle){ - tagMapper.insertTagArticle(tag.getIdTag(),article.getIdArticle()); + if (addTagArticle) { + tagMapper.insertTagArticle(tag.getIdTag(), article.getIdArticle()); } - if(addUserTag){ - tagMapper.insertUserTag(tag.getIdTag(),user.getIdUser(),1); + if (addUserTag) { + tagMapper.insertUserTag(tag.getIdTag(), user.getIdUser(), 1); } } return 1; @@ -109,14 +112,14 @@ public class TagServiceImpl extends AbstractService implements TagService { Map map = new HashMap(1); if (tag.getIdTag() == null) { if (StringUtils.isBlank(tag.getTagTitle())) { - map.put("message","标签名不能为空!"); + map.put("message", "标签名不能为空!"); return map; } else { Condition tagCondition = new Condition(Tag.class); tagCondition.createCriteria().andCondition("tag_title =", tag.getTagTitle()); List tags = tagMapper.selectByCondition(tagCondition); if (!tags.isEmpty()) { - map.put("message","标签 '" + tag.getTagTitle() + "' 已存在!"); + map.put("message", "标签 '" + tag.getTagTitle() + "' 已存在!"); return map; } } @@ -132,10 +135,10 @@ public class TagServiceImpl extends AbstractService implements TagService { result = tagMapper.insertSelective(newTag); } else { tag.setUpdatedTime(new Date()); - result = tagMapper.update(tag.getIdTag(),tag.getTagUri(),tag.getTagIconPath(),tag.getTagStatus(),tag.getTagDescription(),tag.getTagReservation()); + result = tagMapper.update(tag.getIdTag(), tag.getTagUri(), tag.getTagIconPath(), tag.getTagStatus(), tag.getTagDescription(), tag.getTagReservation()); } if (result == 0) { - map.put("message","操作失败!"); + map.put("message", "操作失败!"); } else { map.put("tag", tag); } diff --git a/src/main/java/com/rymcu/vertical/service/impl/TopicServiceImpl.java b/src/main/java/com/rymcu/vertical/service/impl/TopicServiceImpl.java index e875202..64af131 100644 --- a/src/main/java/com/rymcu/vertical/service/impl/TopicServiceImpl.java +++ b/src/main/java/com/rymcu/vertical/service/impl/TopicServiceImpl.java @@ -37,23 +37,10 @@ public class TopicServiceImpl extends AbstractService implements TopicSer } @Override - public Map findTopicByTopicUri(String topicUri, Integer page, Integer rows) { - Map map = new HashMap(2); - TopicDTO topic = topicMapper.selectTopicByTopicUri(topicUri); - if (topic == null) { - return map; - } - PageHelper.startPage(page, rows); - List list = topicMapper.selectTopicTag(topic.getIdTopic()); - PageInfo pageInfo = new PageInfo(list); - topic.setTags(pageInfo.getList()); - map.put("topic", topic); - Map pagination = new HashMap(3); - pagination.put("pageSize",pageInfo.getPageSize()); - pagination.put("total",pageInfo.getTotal()); - pagination.put("currentPage",pageInfo.getPageNum()); - map.put("pagination", pagination); - return map; + public Topic findTopicByTopicUri(String topicUri) { + Topic searchTopic = new Topic(); + searchTopic.setTopicUri(topicUri); + return topicMapper.selectOne(searchTopic); } @Override @@ -82,6 +69,7 @@ public class TopicServiceImpl extends AbstractService implements TopicSer newTopic.setTopicStatus(topic.getTopicStatus()); newTopic.setTopicSort(topic.getTopicSort()); newTopic.setTopicDescription(topic.getTopicDescription()); + newTopic.setTopicDescriptionHtml(topic.getTopicDescriptionHtml()); newTopic.setCreatedTime(new Date()); newTopic.setUpdatedTime(topic.getCreatedTime()); result = topicMapper.insertSelective(newTopic); @@ -89,7 +77,7 @@ public class TopicServiceImpl extends AbstractService implements TopicSer topic.setCreatedTime(new Date()); result = topicMapper.update(topic.getIdTopic(),topic.getTopicTitle(),topic.getTopicUri() ,topic.getTopicIconPath(),topic.getTopicNva(),topic.getTopicStatus() - ,topic.getTopicSort(),topic.getTopicDescription()); + ,topic.getTopicSort(),topic.getTopicDescription(),topic.getTopicDescriptionHtml()); } if (result == 0) { map.put("message","操作失败!"); @@ -132,4 +120,23 @@ public class TopicServiceImpl extends AbstractService implements TopicSer } return map; } + + @Override + public Map findTagsByTopicUri(String topicUri, Integer page, Integer rows) { + Map map = new HashMap(2); + TopicDTO topic = topicMapper.selectTopicByTopicUri(topicUri); + if (topic == null) { + return map; + } + PageHelper.startPage(page, rows); + List list = topicMapper.selectTopicTag(topic.getIdTopic()); + PageInfo pageInfo = new PageInfo(list); + map.put("tags", pageInfo.getList()); + Map pagination = new HashMap(3); + pagination.put("pageSize",pageInfo.getPageSize()); + pagination.put("total",pageInfo.getTotal()); + pagination.put("currentPage",pageInfo.getPageNum()); + map.put("pagination", pagination); + return map; + } } diff --git a/src/main/java/com/rymcu/vertical/service/impl/UserServiceImpl.java b/src/main/java/com/rymcu/vertical/service/impl/UserServiceImpl.java index dc8ef02..136c58a 100644 --- a/src/main/java/com/rymcu/vertical/service/impl/UserServiceImpl.java +++ b/src/main/java/com/rymcu/vertical/service/impl/UserServiceImpl.java @@ -100,8 +100,7 @@ public class UserServiceImpl extends AbstractService implements UserServic user = userMapper.selectOne(user); if(user != null){ if(Utils.comparePwd(password, user.getPassword())){ - user.setLastLoginTime(new Date()); - userMapper.updateByPrimaryKeySelective(user); + userMapper.updateLastLoginTime(user.getIdUser()); TokenUser tokenUser = new TokenUser(); BeanCopierUtil.copy(user, tokenUser); tokenUser.setToken(tokenManager.createToken(account)); @@ -183,6 +182,7 @@ public class UserServiceImpl extends AbstractService implements UserServic if (StringUtils.isNotBlank(user.getAvatarType()) && avatarSvgType.equals(user.getAvatarType())) { String avatarUrl = UploadController.uploadBase64File(user.getAvatarUrl(), 0); user.setAvatarUrl(avatarUrl); + user.setAvatarType("0"); } Integer result = userMapper.updateUserInfo(user.getIdUser(), user.getNickname(), user.getAvatarType(),user.getAvatarUrl(), user.getEmail(),user.getPhone(),user.getSignature(), user.getSex()); diff --git a/src/main/java/com/rymcu/vertical/util/BaiDuUtils.java b/src/main/java/com/rymcu/vertical/util/BaiDuUtils.java index 262c558..3e72334 100644 --- a/src/main/java/com/rymcu/vertical/util/BaiDuUtils.java +++ b/src/main/java/com/rymcu/vertical/util/BaiDuUtils.java @@ -80,6 +80,7 @@ public class BaiDuUtils { } public static void main(String[] args){ - sendUpdateSEOData("https://rymcu.com"); +// sendUpdateSEOData("https://rymcu.com"); + sendSEOData("https://rymcu.com/article/98"); } } diff --git a/src/main/java/com/rymcu/vertical/util/UserUtils.java b/src/main/java/com/rymcu/vertical/util/UserUtils.java index 0edbd09..502b6b0 100644 --- a/src/main/java/com/rymcu/vertical/util/UserUtils.java +++ b/src/main/java/com/rymcu/vertical/util/UserUtils.java @@ -25,7 +25,7 @@ public class UserUtils { * 通过token获取当前用户的信息 * @return */ - public static User getWxCurrentUser() throws BaseApiException { + public static User getCurrentUserByToken() throws BaseApiException { String authHeader = ContextHolderUtils.getRequest().getHeader(JwtConstants.AUTHORIZATION); if (authHeader == null) { return null; diff --git a/src/main/java/com/rymcu/vertical/web/api/admin/AdminController.java b/src/main/java/com/rymcu/vertical/web/api/admin/AdminController.java index 643dc9b..d2ca280 100644 --- a/src/main/java/com/rymcu/vertical/web/api/admin/AdminController.java +++ b/src/main/java/com/rymcu/vertical/web/api/admin/AdminController.java @@ -109,11 +109,20 @@ public class AdminController { } @GetMapping("/topic/{topicUri}") - public GlobalResult topic(@RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "10") Integer rows,@PathVariable String topicUri){ + public GlobalResult topic(@PathVariable String topicUri){ if (StringUtils.isBlank(topicUri)) { return GlobalResultGenerator.genErrorResult("数据异常!"); } - Map map = topicService.findTopicByTopicUri(topicUri,page,rows); + Topic topic = topicService.findTopicByTopicUri(topicUri); + return GlobalResultGenerator.genSuccessResult(topic); + } + + @GetMapping("/topic/{topicUri}/tags") + public GlobalResult topicTags(@RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "10") Integer rows,@PathVariable String topicUri){ + if (StringUtils.isBlank(topicUri)) { + return GlobalResultGenerator.genErrorResult("数据异常!"); + } + Map map = topicService.findTagsByTopicUri(topicUri,page,rows); return GlobalResultGenerator.genSuccessResult(map); } diff --git a/src/main/java/com/rymcu/vertical/web/api/article/ArticleController.java b/src/main/java/com/rymcu/vertical/web/api/article/ArticleController.java index 13aab2c..1bf5b85 100644 --- a/src/main/java/com/rymcu/vertical/web/api/article/ArticleController.java +++ b/src/main/java/com/rymcu/vertical/web/api/article/ArticleController.java @@ -6,6 +6,7 @@ import com.rymcu.vertical.core.result.GlobalResult; import com.rymcu.vertical.core.result.GlobalResultGenerator; import com.rymcu.vertical.dto.ArticleDTO; import com.rymcu.vertical.dto.CommentDTO; +import com.rymcu.vertical.entity.Article; import com.rymcu.vertical.service.ArticleService; import com.rymcu.vertical.service.CommentService; import com.rymcu.vertical.util.Utils; @@ -80,4 +81,10 @@ public class ArticleController { return GlobalResultGenerator.genSuccessResult(map); } + @PostMapping("/{id}/update-tags") + public GlobalResult updateTags(@PathVariable Integer id, @RequestBody Article article) throws BaseApiException, UnsupportedEncodingException { + Map map = articleService.updateTags(id, article.getArticleTags()); + return GlobalResultGenerator.genSuccessResult(map); + } + } diff --git a/src/main/java/com/rymcu/vertical/web/api/common/UploadController.java b/src/main/java/com/rymcu/vertical/web/api/common/UploadController.java index f8f9ddf..7c8348e 100644 --- a/src/main/java/com/rymcu/vertical/web/api/common/UploadController.java +++ b/src/main/java/com/rymcu/vertical/web/api/common/UploadController.java @@ -25,6 +25,7 @@ import java.util.Set; /** * 文件上传控制器 + * * @author ronger */ @RestController @@ -36,22 +37,22 @@ public class UploadController { public static final String ctxHeadPicPath = "/usr/local/src/nebula/static"; @PostMapping("/file") - public GlobalResult uploadPicture(@RequestParam(value = "file", required = false) MultipartFile multipartFile,@RequestParam(defaultValue = "1")Integer type, HttpServletRequest request){ + public GlobalResult uploadPicture(@RequestParam(value = "file", required = false) MultipartFile multipartFile, @RequestParam(defaultValue = "1") Integer type, HttpServletRequest request) { if (multipartFile == null) { return GlobalResultGenerator.genErrorResult("请选择要上传的文件"); } String typePath = getTypePath(type); //图片存储路径 - String dir = ctxHeadPicPath+"/"+typePath; + String dir = ctxHeadPicPath + "/" + typePath; File file = new File(dir); if (!file.exists()) { file.mkdirs();// 创建文件根目录 } - String localPath = Utils.getProperty("resource.file-path")+"/"+typePath+"/"; + String localPath = Utils.getProperty("resource.file-path") + "/" + typePath + "/"; String orgName = multipartFile.getOriginalFilename(); - String fileName = System.currentTimeMillis()+"."+ FileUtils.getExtend(orgName).toLowerCase(); + String fileName = System.currentTimeMillis() + "." + FileUtils.getExtend(orgName).toLowerCase(); String savePath = file.getPath() + File.separator + fileName; @@ -59,7 +60,7 @@ public class UploadController { File saveFile = new File(savePath); try { FileCopyUtils.copy(multipartFile.getBytes(), saveFile); - data.put("url", localPath+fileName); + data.put("url", localPath + fileName); } catch (IOException e) { data.put("message", "上传失败!"); } @@ -68,43 +69,43 @@ public class UploadController { } @PostMapping("/file/batch") - public GlobalResult batchFileUpload(@RequestParam(value = "file[]", required = false)MultipartFile[] multipartFiles,@RequestParam(defaultValue = "1")Integer type,HttpServletRequest request){ + public GlobalResult batchFileUpload(@RequestParam(value = "file[]", required = false) MultipartFile[] multipartFiles, @RequestParam(defaultValue = "1") Integer type, HttpServletRequest request) { String typePath = getTypePath(type); //图片存储路径 - String dir = ctxHeadPicPath+"/"+typePath; + String dir = ctxHeadPicPath + "/" + typePath; File file = new File(dir); if (!file.exists()) { file.mkdirs();// 创建文件根目录 } - String localPath = Utils.getProperty("resource.file-path")+"/"+typePath+"/"; + String localPath = Utils.getProperty("resource.file-path") + "/" + typePath + "/"; Map succMap = new HashMap(10); Set errFiles = new HashSet(); - for(int i=0,len=multipartFiles.length;i list = notificationService.findNotifications(user.getIdUser()); PageInfo pageInfo = new PageInfo(list); @@ -40,7 +40,7 @@ public class NotificationController { @GetMapping("/unread") public GlobalResult unreadNotification(@RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "10") Integer rows) throws BaseApiException { - User user = UserUtils.getWxCurrentUser(); + User user = UserUtils.getCurrentUserByToken(); PageHelper.startPage(page, rows); List list = notificationService.findUnreadNotifications(user.getIdUser()); PageInfo pageInfo = new PageInfo(list); diff --git a/src/main/java/com/rymcu/vertical/web/api/user/UserController.java b/src/main/java/com/rymcu/vertical/web/api/user/UserController.java index 10f218c..ba2f040 100644 --- a/src/main/java/com/rymcu/vertical/web/api/user/UserController.java +++ b/src/main/java/com/rymcu/vertical/web/api/user/UserController.java @@ -4,6 +4,7 @@ import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.rymcu.vertical.core.result.GlobalResult; import com.rymcu.vertical.core.result.GlobalResultGenerator; +import com.rymcu.vertical.core.service.log.annotation.VisitLogger; import com.rymcu.vertical.dto.ArticleDTO; import com.rymcu.vertical.dto.PortfolioDTO; import com.rymcu.vertical.dto.UserDTO; @@ -33,6 +34,7 @@ public class UserController { private PortfolioService portfolioService; @GetMapping("/{nickname}") + @VisitLogger public GlobalResult detail(@PathVariable String nickname){ UserDTO userDTO = userService.findUserDTOByNickname(nickname); return GlobalResultGenerator.genSuccessResult(userDTO); diff --git a/src/main/java/mapper/ArticleMapper.xml b/src/main/java/mapper/ArticleMapper.xml index 3aac306..971037e 100644 --- a/src/main/java/mapper/ArticleMapper.xml +++ b/src/main/java/mapper/ArticleMapper.xml @@ -71,14 +71,26 @@ update vertical_article set article_view_count = #{articleViewCount} where id = #{id} + + update vertical_article set article_tags = #{tags} where id = #{idArticle} + delete from vertical_tag_article where id_article = #{id} delete from vertical_tag_article where id = #{idArticleTag} + + delete from vertical_portfolio_article where id_vertical_article = #{id} + select vp.portfolio_title,vp.portfolio_head_img_url,vpa.id_vertical_portfolio,vpa.id_vertical_article from vertical_portfolio vp join vertical_portfolio_article vpa on vp.id = vpa.id_vertical_portfolio where vpa.id_vertical_article = #{idArticle} + \ No newline at end of file diff --git a/src/main/java/mapper/DashboardMapper.xml b/src/main/java/mapper/DashboardMapper.xml index 50a8ef2..a777165 100644 --- a/src/main/java/mapper/DashboardMapper.xml +++ b/src/main/java/mapper/DashboardMapper.xml @@ -9,26 +9,23 @@ select count(*) from vertical_user select * from vertical_tag vt where not exists(select * from vertical_topic_tag vtt where vtt.id_topic = #{idTopic} and vtt.id_tag = vt.id) - and vt.tag_title = #{tagTitle} + and LOCATE(#{tagTitle}, vt.tag_title) > 0 order by vt.created_time desc diff --git a/src/main/java/mapper/UserMapper.xml b/src/main/java/mapper/UserMapper.xml index f134db4..2874d2c 100644 --- a/src/main/java/mapper/UserMapper.xml +++ b/src/main/java/mapper/UserMapper.xml @@ -65,6 +65,9 @@ where id = #{idUser} + + update vertical_user set last_login_time = sysdate() where id = #{idUser} + @@ -134,4 +133,4 @@ - \ No newline at end of file + From f572104ecfff13c7fc42717eb6083bff96f3efe6 Mon Sep 17 00:00:00 2001 From: caterpillar-_-42 Date: Fri, 25 Sep 2020 11:35:27 +0800 Subject: [PATCH 31/36] qwe --- src/main/java/mapper/ArticleMapper.xml | 2 +- src/main/resources/application-dev.yml | 93 ++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/application-dev.yml diff --git a/src/main/java/mapper/ArticleMapper.xml b/src/main/java/mapper/ArticleMapper.xml index 7f28d9d..18987cc 100644 --- a/src/main/java/mapper/ArticleMapper.xml +++ b/src/main/java/mapper/ArticleMapper.xml @@ -117,7 +117,7 @@ select vta.id, vta.id_tag, vta.id_article, vt.tag_title, vt.tag_icon_path, vt.tag_uri, vt.tag_description from vertical_tag vt join vertical_tag_article vta on vt.id = vta.id_tag where vta.id_article = #{idArticle}