├── .gitignore
├── .mvn
└── wrapper
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── LICENSE
├── README.assets
├── image-20230618141102891.png
├── image-20230618143345645.png
├── image-20230618145547696.png
├── image-20230618145555356.png
├── image-20230618145607492.png
├── image-20230618145620718.png
├── image-20230618145630355.png
├── image-20230618145636746.png
├── image-20230618153725342.png
└── image-20230618154257092.png
├── README.md
├── mvnw
├── mvnw.cmd
├── pom.xml
├── src
├── main
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── wendao
│ │ │ ├── WendaoApplication.java
│ │ │ ├── async
│ │ │ ├── EventConsumer.java
│ │ │ ├── EventHandler.java
│ │ │ ├── EventModel.java
│ │ │ ├── EventProducer.java
│ │ │ ├── EventType.java
│ │ │ └── handler
│ │ │ │ ├── CommentHandler.java
│ │ │ │ ├── FollowHandler.java
│ │ │ │ └── LikeHandler.java
│ │ │ ├── config
│ │ │ ├── CorsConfig.java
│ │ │ ├── CosClientConfig.java
│ │ │ ├── MybatisConfig.java
│ │ │ ├── QuartzConfig.java
│ │ │ └── RedisConfig.java
│ │ │ ├── controller
│ │ │ ├── ArticleController.java
│ │ │ ├── CommentController.java
│ │ │ ├── FansController.java
│ │ │ ├── FollowController.java
│ │ │ ├── IndexController.java
│ │ │ ├── LeaderBoardController.java
│ │ │ ├── LikeController.java
│ │ │ ├── LoginController.java
│ │ │ ├── NoticeController.java
│ │ │ ├── RegisterController.java
│ │ │ ├── UserController.java
│ │ │ └── VideoController.java
│ │ │ ├── dto
│ │ │ ├── CategoryFeedDto.java
│ │ │ ├── CommentDto.java
│ │ │ ├── RegisterDto.java
│ │ │ ├── UserDto.java
│ │ │ └── VideoActionDto.java
│ │ │ ├── entity
│ │ │ ├── Article.java
│ │ │ ├── Category.java
│ │ │ ├── Comment.java
│ │ │ ├── Fans.java
│ │ │ ├── Follow.java
│ │ │ ├── Like.java
│ │ │ ├── Message.java
│ │ │ ├── Notice.java
│ │ │ ├── User.java
│ │ │ └── VideoCategory.java
│ │ │ ├── mapper
│ │ │ ├── ArticleMapper.java
│ │ │ ├── CategoryMapper.java
│ │ │ ├── CommentMapper.java
│ │ │ ├── ElasticSearchMapper.java
│ │ │ ├── FansMapper.java
│ │ │ ├── FollowMapper.java
│ │ │ ├── LikeMapper.java
│ │ │ ├── NoticeMapper.java
│ │ │ ├── UserMapper.java
│ │ │ └── VideoMapper.java
│ │ │ ├── redis
│ │ │ ├── BasePrefix.java
│ │ │ ├── CommonKey.java
│ │ │ ├── FansKey.java
│ │ │ ├── FollowKey.java
│ │ │ ├── JedisService.java
│ │ │ ├── KeyPrefix.java
│ │ │ ├── LikeKey.java
│ │ │ ├── UserTokenKey.java
│ │ │ └── VerifyCodeKey.java
│ │ │ ├── service
│ │ │ ├── ArticleService.java
│ │ │ ├── CategoryService.java
│ │ │ ├── CommentService.java
│ │ │ ├── ElasticSearchService.java
│ │ │ ├── FansService.java
│ │ │ ├── FollowService.java
│ │ │ ├── LikeService.java
│ │ │ ├── NoticeService.java
│ │ │ ├── RegisterService.java
│ │ │ ├── UserService.java
│ │ │ ├── VideoService.java
│ │ │ └── impl
│ │ │ │ ├── ArticleServiceImpl.java
│ │ │ │ ├── CategoryServiceImpl.java
│ │ │ │ ├── CommentServiceImpl.java
│ │ │ │ ├── ElasticSearchServiceImpl.java
│ │ │ │ ├── FansServiceImpl.java
│ │ │ │ ├── FollowServiceImpl.java
│ │ │ │ ├── LikeServiceImpl.java
│ │ │ │ ├── NoticeServiceImpl.java
│ │ │ │ ├── UserServiceImpl.java
│ │ │ │ └── VideoServiceImpl.java
│ │ │ ├── task
│ │ │ ├── AchieveValueTask.java
│ │ │ └── LikeTask.java
│ │ │ ├── utils
│ │ │ ├── Base64URL.java
│ │ │ ├── BvToAvUtils.java
│ │ │ ├── CodeMsg.java
│ │ │ ├── CommonUtils.java
│ │ │ ├── GenerateRandomCode.java
│ │ │ ├── HttpClientUtils.java
│ │ │ ├── IpUtils.java
│ │ │ ├── RandomUtils.java
│ │ │ ├── Result.java
│ │ │ └── TLSSigAPIv2.java
│ │ │ ├── vo
│ │ │ ├── ArticleUserVo.java
│ │ │ ├── CommentUserVo.java
│ │ │ ├── FansVo.java
│ │ │ ├── FollowVo.java
│ │ │ ├── UserData.java
│ │ │ └── UserInfoVo.java
│ │ │ └── websocket
│ │ │ └── ChatEndPoint.java
│ └── resources
│ │ ├── application-dev.yml
│ │ ├── application.yml
│ │ └── mapper
│ │ ├── ArticleMapper.xml
│ │ ├── CategoryMapper.xml
│ │ ├── CommentMapper.xml
│ │ ├── FansMapper.xml
│ │ ├── FollowMapper.xml
│ │ ├── LikeMapper.xml
│ │ ├── NoticeMapper.xml
│ │ ├── UserMapper.xml
│ │ └── VideoMapper.xml
└── test
│ └── java
│ └── com
│ └── example
│ └── wendao
│ ├── WendaoApplicationTests.java
│ ├── mapper
│ ├── ArticleMapperTest.java
│ ├── CommentMapperTest.java
│ ├── LikeMapperTest.java
│ └── UserMapperTest.java
│ ├── service
│ ├── CommentServiceTest.java
│ ├── ElasticSearchServiceTest.java
│ ├── UserServiceTest.java
│ └── VideoServiceTest.java
│ └── utils
│ └── Utils.java
└── wendao.sql
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 | !**/src/main/**/target/
4 | !**/src/test/**/target/
5 |
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 | !**/src/main/**/build/
30 | !**/src/test/**/build/
31 |
32 | ### VS Code ###
33 | .vscode/
34 |
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuXiang123/wendao/ac26388330df8e10f41db0461d3ff9bbb27da7eb/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # https://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.7/apache-maven-3.8.7-bin.zip
18 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
19 |
--------------------------------------------------------------------------------
/README.assets/image-20230618141102891.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuXiang123/wendao/ac26388330df8e10f41db0461d3ff9bbb27da7eb/README.assets/image-20230618141102891.png
--------------------------------------------------------------------------------
/README.assets/image-20230618143345645.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuXiang123/wendao/ac26388330df8e10f41db0461d3ff9bbb27da7eb/README.assets/image-20230618143345645.png
--------------------------------------------------------------------------------
/README.assets/image-20230618145547696.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuXiang123/wendao/ac26388330df8e10f41db0461d3ff9bbb27da7eb/README.assets/image-20230618145547696.png
--------------------------------------------------------------------------------
/README.assets/image-20230618145555356.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuXiang123/wendao/ac26388330df8e10f41db0461d3ff9bbb27da7eb/README.assets/image-20230618145555356.png
--------------------------------------------------------------------------------
/README.assets/image-20230618145607492.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuXiang123/wendao/ac26388330df8e10f41db0461d3ff9bbb27da7eb/README.assets/image-20230618145607492.png
--------------------------------------------------------------------------------
/README.assets/image-20230618145620718.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuXiang123/wendao/ac26388330df8e10f41db0461d3ff9bbb27da7eb/README.assets/image-20230618145620718.png
--------------------------------------------------------------------------------
/README.assets/image-20230618145630355.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuXiang123/wendao/ac26388330df8e10f41db0461d3ff9bbb27da7eb/README.assets/image-20230618145630355.png
--------------------------------------------------------------------------------
/README.assets/image-20230618145636746.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuXiang123/wendao/ac26388330df8e10f41db0461d3ff9bbb27da7eb/README.assets/image-20230618145636746.png
--------------------------------------------------------------------------------
/README.assets/image-20230618153725342.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuXiang123/wendao/ac26388330df8e10f41db0461d3ff9bbb27da7eb/README.assets/image-20230618153725342.png
--------------------------------------------------------------------------------
/README.assets/image-20230618154257092.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MuXiang123/wendao/ac26388330df8e10f41db0461d3ff9bbb27da7eb/README.assets/image-20230618154257092.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 目录
2 |
3 | [TOC]
4 |
5 |
6 |
7 | # 项目简介
8 |
9 | 2023年毕设、校园论坛、网上社区、仿牛客论坛这一类的项目。
10 |
11 | **前端项目: **[MuXiang123/wendao-vue (github.com)](https://github.com/MuXiang123/wendao-vue)
12 |
13 | ### 技术栈
14 |
15 | - 后端: SpringBoot SpringMVC Mybatis Redis ElasticSearch Quartz
16 | - 前端: vue Element-UI Axios
17 |
18 | ### 主要功能
19 |
20 | 本系统主要包括用户模块、文章模块、通信模块、视频模块、搜索功能等模块。其中,用户模块主要负责用户的注册、登录、信息修改等操作;文章管理模块主要负责问题的发布、浏览、回答等操作;私信管理模块主要负责私信的发送、接收等操作;视频管理模块主要负责视频的浏览等操作;搜索管理模块主要负责问题的搜索和答案的搜索等操作。
21 |
22 | ### 系统功能架构图
23 |
24 | 
25 |
26 |
27 |
28 | # 如何部署
29 |
30 | ## 环境配置
31 |
32 | - JDK 1.8
33 | - Elasticsearch-7.0.0
34 | - Redis (本地开发下载的是windows版本)自己用的是5.0.x版本
35 | - MySQL 8.0及以上
36 | - Nginx (我使用的版本是1.22.1)
37 |
38 | ### 部署步骤
39 |
40 | 1. 导入数据库,数据库名为``wendao``
41 | 2. 修改application-dev.yml中的内容
42 | 3. 启动redis和ElasticSearch
43 | 4. 启动项目
44 |
45 | # 中间件安装
46 |
47 | ### redis
48 |
49 | 在windows系统下安装redis
50 |
51 | redis下载链接 :[Releases · tporadowski/redis (github.com)](https://github.com/tporadowski/redis/releases)
52 |
53 | 如果不会安装的,可以参考[Window下Redis的安装和部署详细图文教程(Redis的安装和可视化工具的使用)_redis安装_明金同学的博客-CSDN博客](https://blog.csdn.net/weixin_44893902/article/details/123087435)
54 |
55 | ### ElasticSearch
56 |
57 | 下载地址:[Releases · elastic/elasticsearch (github.com)](https://github.com/elastic/elasticsearch/releases) 找到自己合适的版本下载,本项目使用的是7.0.0
58 |
59 | 并且也要安装ik中文分词器,主要ik分词器的版本和es的版本要对应。readme文件中有讲:[medcl/elasticsearch-analysis-ik: The IK Analysis plugin integrates Lucene IK analyzer into elasticsearch, support customized dictionary. (github.com)](https://github.com/medcl/elasticsearch-analysis-ik)
60 |
61 | ik分词器下载地址:[Releases · medcl/elasticsearch-analysis-ik (github.com)](https://github.com/medcl/elasticsearch-analysis-ik/releases)
62 |
63 | 不会安装可以百度教程。
64 |
65 | ### Nginx配置
66 |
67 | Nginx安装教程 [Nginx系列:windows10系统下安装nginx的安装并配置!_windows10安装nginx_陈永佳的博客-CSDN博客](https://blog.csdn.net/Mrs_chens/article/details/92961608)
68 |
69 | 本项目使用的nginx是1.22.1版本。
70 |
71 | 安装完成后进行配置,在nginx -> conf -> nginx.conf 中添加server配置,安装实际的前端和后端项目进行设置。
72 |
73 | ```
74 | server{
75 | listen 7777; //这里是你想要映射出来的端口
76 | # server_name 127.0.0.1;
77 | location /{
78 | proxy_pass http://127.0.0.1:5173; //这是前端的host
79 | }
80 | location /api/{
81 | proxy_pass http://127.0.0.1:8081/; //这是后端的host
82 | }
83 | }
84 | ```
85 |
86 |
87 |
88 | # 配置文件中的问题
89 |
90 | ### b站的cookie
91 |
92 | 该项目中的视频模块,是通过实时获取b站的视频直链和feed链接得到视频的。可能有些链接需要省份验证,因此需要登录b站 -> f12 -> application
93 |
94 | 获取SESSDATA填入yml中。
95 |
96 | 
97 |
98 | ### 开通腾讯云对象存储
99 |
100 | [对象存储数据处理_COS数据处理_数据处理方案-腾讯云 (tencent.com)](https://cloud.tencent.com/product/cos)
101 |
102 | 对象存储用来存储项目中出现的图片。腾讯云对象存储有免费额度。
103 |
104 | 首先按照腾讯云官方文档开通对象存储服务
105 |
106 | [对象存储简介_对象存储购买指南_对象存储操作指南-腾讯云 (tencent.com)](https://cloud.tencent.com/document/product/436)
107 |
108 | 接着在控制台->访问密钥 中将SecretId 和 SecretKey 填到yml中。
109 |
110 | ### 开通腾讯云IM
111 |
112 | 使用腾讯云即时通讯作为本系统聊天模块的功能实现,可以使用IM体验版。
113 |
114 | [即时通信_免费即时通信_即时通信价格 - 腾讯云 (tencent.com)](https://cloud.tencent.com/product/im)
115 |
116 | 首先开通腾讯云IM 参考官方文档[即时通信 IM Web-含 UI 集成方案(荐)-文档中心-腾讯云 (tencent.com)](https://cloud.tencent.com/document/product/269/79737)
117 |
118 | 本项目直接在前端项目中使用腾讯云,参考文档[即时通信 IM Web-含 UI 集成方案(荐)-文档中心-腾讯云 (tencent.com)](https://cloud.tencent.com/document/product/269/79737)
119 |
120 | ### 数据库账户名密码
121 |
122 | 记得填自己本机的MySQL用户名密码。
123 |
124 |
125 |
126 | # 项目部分功能设计思路
127 |
128 | ### 1 查看热点文章实现思路
129 |
130 | 热点文章设计为:根据文章的浏览量降序排列,取TOP10进行展示
131 |
132 | ### 2 上传图片(使用七牛云服务器存储图片)实现思路
133 |
134 | 上传用户头像、修改用户头像操作将图片上传至腾讯云服务器上,自己上传了一张照片,返回的在线地址,这样就减少数据库存储图片带来的性能开销。
135 |
136 | ### 3 关注/取消关注别人,关注/粉丝列表实现思路
137 |
138 | 基于Redis的Set数据结构实现,原因是该结构类似于Java中的Hashset,可以实现去重功能,用sadd、scard来实现即可.
139 |
140 | ### 4 用户成就值排行榜实现思路
141 |
142 | 成就值加分规则:
143 |
144 | - 当用户发表一篇文章的时候,成就值+10分
145 | - 当用户的文章被别人点赞一次之后,成就值+5分
146 | - 当用户的文章被别人评论一次之后,成就值+5分
147 | - 当用户被一个人关注后,成就值+10分
148 | 实现思路:使用Quartz定时器框架,每一个月将用户的成就值清零,在这一个月之内根据用户的成就值降序排列,取成就值TOP10.
149 |
150 | # 项目重难点功能设计思路
151 |
152 | ### 1 异步通知功能设计
153 |
154 | 一般我们在购物或者博客的网站上都会收到系统推送的通知消息,而对应于校园论坛网站的开发中,我自己设计为当用户A对用户B发表的文章点赞、评论、以及用户A关注了用户B,都用到了异步通知的设计。 异步通知和同步通知(以点赞业务为例)的区别是:
155 |
156 | - 同步通知,点赞之后必须等到该操作执行完所有操作(更新点赞数等业务),才能执行后面的代码;
157 | - 异步通知,点赞之后启动一个新的线程去处理异步通知的业务逻辑,主线程执行后面的代码,互不影响,提升用户体验;
158 | 
159 | 如上图所示,异步通知的设计思路如下,分为业务代码、生产者、消费者、消息队列、统一的接口以及实现类,即:业务代码(如点赞业务)首先将点赞的事件封装成一个eventModel对象,然后将其传给生产者,生产者将该事件推到Redis的list的消息队列中,然后消费者监听有哪些实现类实现了统一的接口,并将其保存至Map中,然后开启一个新的线程不断的从消息队列中消费事件,如果有事件则根据事件的类型(点赞/评论/我的关注),去执行对应的实现类。在实现类中的实现是将事件的具体的内容(如用户A点赞了用户B的文章)保存至数据库中,并且设置有一个属性为has_read属性,默认为0(表示有未读消息),然后前端的实现是启用3秒的定时器轮询的调用接口(这个接口的作用是给前端返回有没有未读数据),如果有未读消息,就会给用户提示,当用户查看了提示的内容之后,将所有通知的has_read属性设置为1(表示没有未读消息),这样即实现了异步通知的功能。
160 |
161 | ### 2 ELK(ElasticSearch+Logstash+Kibana)同步MySQL以及ES搜索和MySQL模糊查询的搜索耗时对比
162 |
163 | 项目中考虑到文章的数据量只会越来越大,由于在大数据量的情况下,使用mysql的模糊查询的耗时十分巨大,如果给mysql中添加索引这又会带来新的开销,为此采用ES来搜索文章。首先则需要将MySQL的数据和ES的数据进行同步,采用Lostash工具就可以实现同步数据,kibana的作用是提供一个可视化的界面,方便开发人员搜索数据。同步完成之后,需要只需要集成Spring-data-elasticsearch,根据其api接口就可以实现按照文章标题和文章内容模糊查询,并实现了将关键字高亮展示(高亮展示是由前端来完成的,具体的思路为:前端通过搜索框拿到用户搜索的关键词,然后使用正则表达式匹配后端返回数据中的关键字,匹配之后将其样式改为红色标亮展示)。
164 |
165 | 
166 |
167 | 在指导老师的督促下,要拿数据说话为什么在大数量的情况下ES的搜索耗时要低于MySQL的搜索耗时?为此,自己写程序随机生成了100、1000、10000、100000、600000条数据来进行对比,对比结果如上图所示,得出结论:在数据量大于100000的时候,ES的搜索耗时已经优于MySQL了,数据量越大时,差距更加明显。
168 |
169 | ### 3 点赞在高并发环境下的设计思路
170 |
171 | - 业务场景:在高并发环境下用户频繁的给某一篇文章点赞,而点赞之后需要将点赞数更新至数据库中,这样就可能严重影响数据库的性能,甚至会导致数据的宕机。
172 | - 设计思路:将文章的点赞信息全部缓存在redis的set类型的数据结构中,读的时候直接从redis中返回点赞数据,然后使用Quartz每隔两个小时将Redis的数据同步至MySQL中,保证Redis和MySQL的数据一致性。
173 |
174 | ### 4 私信实现
175 |
176 | 使用腾讯云IM实现
177 |
178 | # 项目部分截图
179 |
180 | 
181 |
182 | 
183 |
184 | 
185 |
186 | 
187 |
188 | 
189 |
190 | 
191 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.3.0.RELEASE
9 |
10 |
11 | com.example
12 | wendao
13 | 0.0.1-SNAPSHOT
14 | wendao
15 | wendao
16 |
17 | 8
18 |
19 |
20 |
21 | org.springframework.boot
22 | spring-boot-starter-web
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-starter-test
44 | test
45 |
46 |
47 |
48 | org.springframework.boot
49 | spring-boot-starter-websocket
50 |
51 |
52 | com.github.pagehelper
53 | pagehelper-spring-boot-starter
54 | 1.2.10
55 |
56 |
57 | com.qiniu
58 | qiniu-java-sdk
59 | 7.5.0
60 |
61 |
62 |
63 | org.springframework.boot
64 | spring-boot-starter-data-jdbc
65 |
66 |
67 |
68 | org.mybatis.spring.boot
69 | mybatis-spring-boot-starter
70 | 2.1.3
71 |
72 |
73 |
74 |
75 | mysql
76 | mysql-connector-java
77 | 8.0.13
78 |
79 |
80 |
81 | com.alibaba
82 | druid
83 | 1.1.22
84 |
85 |
86 |
87 | org.apache.httpcomponents
88 | httpclient
89 | 4.5.2
90 |
91 |
92 |
93 | org.projectlombok
94 | lombok
95 | 1.18.12
96 | provided
97 |
98 |
99 |
100 | commons-codec
101 | commons-codec
102 |
103 |
104 |
105 |
106 | org.springframework.boot
107 | spring-boot-starter-quartz
108 |
109 |
110 |
111 | redis.clients
112 | jedis
113 | 3.0.0
114 |
115 |
116 | log4j
117 | log4j
118 | 1.2.17
119 |
120 |
121 | com.alibaba
122 | fastjson
123 | 1.2.71
124 |
125 |
126 |
127 |
128 | com.tencentcloudapi
129 | tencentcloud-sdk-java
130 |
131 |
132 | 3.1.217
133 |
134 |
135 |
136 |
137 | org.springframework.data
138 | spring-data-elasticsearch
139 |
140 |
141 |
142 | com.google.guava
143 | guava
144 | 29.0-jre
145 |
146 |
147 |
148 | com.qcloud
149 | cos_api
150 | 5.6.97
151 |
152 |
153 |
154 | cn.hutool
155 | hutool-all
156 | 5.8.12
157 |
158 |
159 |
160 |
161 |
162 |
163 | org.springframework.boot
164 | spring-boot-maven-plugin
165 | 2.3.4.RELEASE
166 |
167 |
168 |
169 | org.projectlombok
170 | lombok
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/WendaoApplication.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.boot.builder.SpringApplicationBuilder;
6 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
7 |
8 | @SpringBootApplication
9 | public class WendaoApplication extends SpringBootServletInitializer {
10 |
11 | public static void main(String[] args) {
12 | SpringApplication.run(WendaoApplication.class, args);
13 | }
14 |
15 | @Override
16 | protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
17 | return builder.sources(WendaoApplication.class);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/async/EventConsumer.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.async;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.example.wendao.redis.CommonKey;
5 | import com.example.wendao.redis.JedisService;
6 | import com.example.wendao.redis.LikeKey;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 | import org.springframework.beans.BeansException;
10 | import org.springframework.beans.factory.InitializingBean;
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.context.ApplicationContext;
13 | import org.springframework.context.ApplicationContextAware;
14 | import org.springframework.stereotype.Service;
15 |
16 | import java.util.ArrayList;
17 | import java.util.HashMap;
18 | import java.util.List;
19 | import java.util.Map;
20 |
21 | /**
22 | * @author: zhk
23 | * @description: 事件消费者 ,监听消息队列,如果消息队列中存在事件,则会立即消费
24 | * @date: 2023/3/3 16:11
25 | * @version: 1.0
26 | */
27 | @Service
28 | public class EventConsumer implements InitializingBean, ApplicationContextAware {
29 |
30 | private static Logger logger = LoggerFactory.getLogger(EventConsumer.class);
31 | @Autowired
32 | JedisService jedisService;
33 | private ApplicationContext applicationContext;
34 | /**
35 | * 通过map来实现简单的消息分发 事件类型 事件实现类
36 | */
37 | private Map> config = new HashMap<>();
38 |
39 |
40 | @Override
41 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
42 | this.applicationContext = applicationContext;
43 | }
44 |
45 | /**
46 | * 在包含BeanFactory的所有bean属性都已设置并满足BeanFactoryAware,
47 | * ApplicationContextAware等之后,调用此方法。
48 | *
49 | * @throws Exception
50 | */
51 | @Override
52 | public void afterPropertiesSet() throws Exception {
53 | // 首先从应用上下文中找出那些实现了EventHandler的接口
54 | Map beans = applicationContext.getBeansOfType(EventHandler.class);
55 | logger.info("实现了EventHandler接口的有:{} ", beans);
56 | if (beans != null) {
57 | for (Map.Entry entry : beans.entrySet()) {
58 | // 获取和该事件相关的所有类型
59 | List eventHandlers = entry.getValue().getSupportEventTypes();
60 | for (EventType type : eventHandlers) {
61 | // 从所有的类型中寻找符合条件的type,如果符合条件则将其加入到map中
62 | if (!config.containsKey(type)) {
63 | config.put(type, new ArrayList<>());
64 | }
65 | config.get(type).add(entry.getValue());
66 | }
67 | }
68 | }
69 | // 将需要处理的类型和那个类来处理都装进map了,另启动一个线程来监听该行为
70 | new Thread(() -> {
71 | while (true) {
72 | List strs = jedisService.brpop(LikeKey.LIKE_ASYNC_KEY, CommonKey.EVENT_LIKE_QUEUE);
73 | logger.info("即将处理的EventModel为{}", strs);
74 | for (String str : strs) {
75 | //遍历的时候 返回的是key,value;所以将所有的key过滤掉
76 | if (str.equals(LikeKey.LIKE_ASYNC_KEY.getPrefix() + CommonKey.EVENT_LIKE_QUEUE)) {
77 | continue;
78 | }
79 | // 从消息队列获取到EventModel对象
80 | EventModel eventModel = JSON.parseObject(str.replace("'\'", ""), EventModel.class);
81 | if (!config.containsKey(eventModel.getEventType())) {
82 | logger.info("{}是不能识别的事件类型", eventModel.getEventType());
83 | continue;
84 | }
85 | //能识别事件,然后就是一个个的处理事件
86 | for (EventHandler handler : config.get(eventModel.getEventType())) {
87 | logger.info("开始处理{}的事件", eventModel.getEventType());
88 | handler.doHandler(eventModel);
89 | logger.info("处理{}的事件完毕", eventModel.getEventType());
90 | }
91 |
92 | }
93 | }
94 |
95 | }).start();
96 | }
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/async/EventHandler.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.async;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * @author: zhk
7 | * @description:
8 | * @date: 2023/3/3 15:35
9 | * @version: 1.0
10 | */
11 | public interface EventHandler {
12 | /**
13 | * 处理EventModel给用户发送通知
14 | * @param eventModel
15 | */
16 | void doHandler(EventModel eventModel);
17 |
18 | /**
19 | * 获取支持事件类型
20 | * @return
21 | */
22 | List getSupportEventTypes();
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/async/EventModel.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.async;
2 |
3 | import lombok.NoArgsConstructor;
4 |
5 | import java.util.HashMap;
6 | import java.util.Map;
7 |
8 | /**
9 | * @author: zhk
10 | * @description: 异步事件模型
11 | * @date: 2023/3/3 15:36
12 | * @version: 1.0
13 | */
14 | @NoArgsConstructor
15 | public class EventModel {
16 | /**
17 | * 事件类型
18 | */
19 | private EventType eventType;
20 |
21 | /**
22 | * 触发事件人
23 | */
24 | private String actorId;
25 |
26 | /**
27 | * entityType和entityId标识了被触发的对象
28 | */
29 | private int entityType;
30 |
31 | private int entityId;
32 |
33 | /**
34 | * 触发事件后对谁产生影响
35 | */
36 | private String entityOwnerId;
37 |
38 | /**
39 | * 扩展
40 | */
41 | private Map exts = new HashMap<>();
42 |
43 | public EventModel(EventType eventType) {
44 | this.eventType = eventType;
45 | }
46 |
47 | public EventType getEventType() {
48 | return eventType;
49 | }
50 |
51 | public EventModel setEventType(EventType eventType) {
52 | this.eventType = eventType;
53 | return this;
54 | }
55 |
56 | public String getActorId() {
57 | return actorId;
58 | }
59 |
60 | public EventModel setActorId(String actorId) {
61 | this.actorId = actorId;
62 | return this;
63 | }
64 |
65 | public int getEntityType() {
66 | return entityType;
67 | }
68 |
69 | public EventModel setEntityType(int entityType) {
70 | this.entityType = entityType;
71 | return this;
72 | }
73 |
74 | public int getEntityId() {
75 | return entityId;
76 | }
77 |
78 | public EventModel setEntityId(int entityId) {
79 | this.entityId = entityId;
80 | return this;
81 | }
82 |
83 | public String getEntityOwnerId() {
84 | return entityOwnerId;
85 | }
86 |
87 | public EventModel setEntityOwnerId(String entityOwnerId) {
88 | this.entityOwnerId = entityOwnerId;
89 | return this;
90 | }
91 |
92 |
93 | public Map getExts() {
94 | return exts;
95 | }
96 |
97 | public EventModel setExts(Map exts) {
98 | this.exts = exts;
99 | return this;
100 | }
101 |
102 |
103 | /**
104 | * 重写扩展字段
105 | */
106 | public String getExts(String key) {
107 | return exts.get(key);
108 | }
109 |
110 | public EventModel setExts(String key, String value) {
111 | exts.put(key, value);
112 | return this;
113 | }
114 |
115 | @Override
116 | public String toString() {
117 | return "EventModel{" +
118 | "eventType=" + eventType +
119 | ", actorId='" + actorId + '\'' +
120 | ", entityType=" + entityType +
121 | ", entityId=" + entityId +
122 | ", entityOwnerId='" + entityOwnerId + '\'' +
123 | ", exts=" + exts +
124 | '}';
125 | }
126 |
127 | }
128 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/async/EventProducer.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.async;
2 |
3 | import com.example.wendao.async.EventModel;
4 | import com.example.wendao.redis.CommonKey;
5 | import com.example.wendao.redis.JedisService;
6 | import com.example.wendao.redis.LikeKey;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.stereotype.Service;
9 |
10 | /**
11 | * @author: zhk
12 | * @description: 事件生产者,将封装好的EventModel事件,
13 | * 塞进队列中,等待消费者的消费
14 | * @date: 2023/3/3 16:09
15 | * @version: 1.0
16 | */
17 | @Service
18 | public class EventProducer {
19 | @Autowired
20 | JedisService jedisService;
21 |
22 | /**
23 | * 将该事件推入到redis中的队列中
24 | *
25 | * @param eventModel
26 | */
27 | public boolean fireEvent(EventModel eventModel) {
28 | try {
29 | jedisService.lpush(LikeKey.LIKE_ASYNC_KEY, CommonKey.EVENT_LIKE_QUEUE, eventModel);
30 | return true;
31 | } catch (Exception e) {
32 | return false;
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/async/EventType.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.async;
2 |
3 | /**
4 | * @author: zhk
5 | * @description: 标识事件类型
6 | * @date: 2023/3/3 15:53
7 | * @version: 1.0
8 | */
9 | public enum EventType {
10 | LIKE(0),
11 | DISLIKE(1),
12 | COMMNET(2),
13 | FOLLOW(3),
14 | UNFOLLOW(4);
15 |
16 | private int value;
17 |
18 | EventType(int value) {
19 | this.value = value;
20 | }
21 |
22 | public int getValue() {
23 | return value;
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/async/handler/CommentHandler.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.async.handler;
2 |
3 | import com.example.wendao.async.EventHandler;
4 | import com.example.wendao.async.EventModel;
5 | import com.example.wendao.async.EventType;
6 | import com.example.wendao.entity.Article;
7 | import com.example.wendao.entity.Comment;
8 | import com.example.wendao.entity.Notice;
9 | import com.example.wendao.entity.User;
10 | import com.example.wendao.service.ArticleService;
11 | import com.example.wendao.service.CommentService;
12 | import com.example.wendao.service.NoticeService;
13 | import com.example.wendao.service.UserService;
14 | import org.slf4j.Logger;
15 | import org.slf4j.LoggerFactory;
16 | import org.springframework.beans.factory.annotation.Autowired;
17 | import org.springframework.stereotype.Component;
18 |
19 | import java.util.Arrays;
20 | import java.util.Date;
21 | import java.util.List;
22 |
23 |
24 | /**
25 | * @author: zhk
26 | * @description:
27 | * @date: 2023/3/3 15:42
28 | * @version: 1.0
29 | */
30 | @Component
31 | public class CommentHandler implements EventHandler {
32 |
33 | private static final Logger logger = LoggerFactory.getLogger(CommentHandler.class);
34 |
35 | @Autowired
36 | UserService userService;
37 |
38 | @Autowired
39 | ArticleService articleService;
40 |
41 | @Autowired
42 | NoticeService noticeService;
43 |
44 | @Autowired
45 | CommentService commentService;
46 |
47 | @Override
48 | public void doHandler(EventModel eventModel) {
49 | //对文章进行评论的用户
50 | String fromId = eventModel.getActorId();
51 | //用户信息
52 | User user = userService.selectByUserId(fromId);
53 | //发表该文章的作者
54 | String toId = eventModel.getEntityOwnerId();
55 | //通过用户id,关联文章id,通过文章id获取文章标题
56 | Integer articleId = Integer.valueOf(eventModel.getExts("articleId"));
57 | Article article = articleService.selectArticleByUserId(articleId);
58 | logger.info("文章信息为:{}", article);
59 |
60 | //获取评论id
61 | Integer commentId = Integer.valueOf(eventModel.getExts("commentId"));
62 | //查询评论内容
63 | Comment comment = commentService.selectCommentById(commentId);
64 | logger.info("评论信息为:{}", comment);
65 |
66 | //向作者发送通知
67 | Notice notice = new Notice();
68 | notice.setFromId(fromId);
69 | notice.setToId(toId);
70 | notice.setCreatedDate(new Date());
71 | notice.setContent(user.getNickname() + "评论您的文章:" + article.getArticleTitle() +
72 | ",评论的内容为:" + comment.getCommentContent());
73 | notice.setConversationId(fromId + "_" + toId);
74 | noticeService.insertNotice(notice);
75 | logger.info("notice:{}", notice);
76 |
77 | }
78 |
79 | @Override
80 | public List getSupportEventTypes() {
81 | return Arrays.asList(EventType.COMMNET);
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/async/handler/FollowHandler.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.async.handler;
2 |
3 | import com.example.wendao.async.EventHandler;
4 | import com.example.wendao.async.EventModel;
5 | import com.example.wendao.async.EventType;
6 | import com.example.wendao.entity.Notice;
7 | import com.example.wendao.entity.User;
8 | import com.example.wendao.redis.JedisService;
9 | import com.example.wendao.service.ArticleService;
10 | import com.example.wendao.service.NoticeService;
11 | import com.example.wendao.service.UserService;
12 | import org.slf4j.Logger;
13 | import org.slf4j.LoggerFactory;
14 | import org.springframework.beans.factory.annotation.Autowired;
15 | import org.springframework.stereotype.Component;
16 |
17 | import java.util.Arrays;
18 | import java.util.Date;
19 | import java.util.List;
20 |
21 | /**
22 | * @author: zhk
23 | * @description:
24 | * @date: 2023/3/3 16:02
25 | * @version: 1.0
26 | */
27 | @Component
28 | public class FollowHandler implements EventHandler {
29 | private static final Logger logger = LoggerFactory.getLogger(FollowHandler.class);
30 |
31 | @Autowired
32 | JedisService jedisService;
33 |
34 | @Autowired
35 | UserService userService;
36 |
37 | @Autowired
38 | ArticleService articleService;
39 |
40 | @Autowired
41 | NoticeService noticeService;
42 |
43 | @Override
44 | public void doHandler(EventModel eventModel) {
45 | //关注的用户
46 | String fromId = eventModel.getActorId();
47 | //被关注的用户
48 | String toId = eventModel.getEntityOwnerId();
49 | User userFrom = userService.selectByUserId(fromId);
50 | //通知 没必要在获取用户本身了,只需要写明谁关注了你
51 | Notice notice = new Notice();
52 | notice.setFromId(fromId);
53 | notice.setToId(toId);
54 | notice.setContent(userFrom.getNickname() + "关注了用户你");
55 | notice.setConversationId(fromId + "_" + toId);
56 | notice.setCreatedDate(new Date());
57 | notice.setHasRead(0);
58 | logger.info("notice:{}", notice);
59 | noticeService.insertNotice(notice);
60 | }
61 |
62 | @Override
63 | public List getSupportEventTypes() {
64 | return Arrays.asList(EventType.FOLLOW);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/async/handler/LikeHandler.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.async.handler;
2 |
3 | import com.example.wendao.async.EventHandler;
4 | import com.example.wendao.async.EventModel;
5 | import com.example.wendao.async.EventType;
6 | import com.example.wendao.entity.Article;
7 | import com.example.wendao.entity.Notice;
8 | import com.example.wendao.entity.User;
9 | import com.example.wendao.redis.JedisService;
10 | import com.example.wendao.service.ArticleService;
11 | import com.example.wendao.service.NoticeService;
12 | import com.example.wendao.service.UserService;
13 | import org.slf4j.Logger;
14 | import org.slf4j.LoggerFactory;
15 | import org.springframework.beans.factory.annotation.Autowired;
16 | import org.springframework.stereotype.Component;
17 |
18 | import java.util.Arrays;
19 | import java.util.Date;
20 | import java.util.List;
21 |
22 | /**
23 | * @author: zhk
24 | * @description:
25 | * @date: 2023/3/3 16:05
26 | * @version: 1.0
27 | */
28 | @Component
29 | public class LikeHandler implements EventHandler {
30 |
31 | private static final Logger logger = LoggerFactory.getLogger(LikeHandler.class);
32 |
33 | @Autowired
34 | JedisService jedisService;
35 |
36 | @Autowired
37 | UserService userService;
38 |
39 | @Autowired
40 | ArticleService articleService;
41 |
42 | @Autowired
43 | NoticeService noticeService;
44 |
45 | @Override
46 | public void doHandler(EventModel eventModel) {
47 | // 给文章点赞的用户
48 | String fromId = eventModel.getActorId();
49 | User user = userService.selectByUserId(fromId);
50 | // 发表该篇文章的作者
51 | String toId = eventModel.getEntityOwnerId();
52 | // 这里要通过用户的Id来关联文章,来获取到用户发表的文章,获取文章的标题信息
53 | int articleId = Integer.parseInt(eventModel.getExts("articleId"));
54 | logger.info(toId);
55 | logger.info(String.valueOf(articleId));
56 | //获取文章信息
57 | Article article = articleService.selectArticleByUserId(articleId);
58 | logger.info("文章信息为:{}", article);
59 | //进行通知
60 | Notice notice = new Notice();
61 | notice.setFromId(fromId);
62 | notice.setToId(toId);
63 | notice.setCreatedDate(new Date());
64 | notice.setContent(user.getNickname() + "点赞了您的文章:" + article.getArticleTitle());
65 | notice.setConversationId(fromId + "_" + toId);
66 | logger.info("notice:{}", notice);
67 | noticeService.insertNotice(notice);
68 | }
69 |
70 | @Override
71 | public List getSupportEventTypes() {
72 | return Arrays.asList(EventType.LIKE);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/config/CorsConfig.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.config;
2 |
3 | import org.springframework.context.annotation.Bean;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.web.servlet.config.annotation.CorsRegistry;
6 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
7 |
8 | /**
9 | * @author: zhk
10 | * @description:
11 | * @date: 2023/3/2 10:10
12 | * @version: 1.0
13 | */
14 | @Configuration
15 | public class CorsConfig {
16 | @Bean
17 | public WebMvcConfigurer corsConfigurer() {
18 | return new WebMvcConfigurer() {
19 | @Override
20 | public void addCorsMappings(CorsRegistry registry) {
21 | registry.addMapping("/**")
22 | .allowCredentials(true)
23 | .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
24 | .allowedOrigins("*")
25 | .allowedHeaders("*");
26 | }
27 | };
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/config/CosClientConfig.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.config;
2 |
3 |
4 | import com.qcloud.cos.COSClient;
5 | import com.qcloud.cos.ClientConfig;
6 | import com.qcloud.cos.auth.BasicCOSCredentials;
7 | import com.qcloud.cos.auth.COSCredentials;
8 | import com.qcloud.cos.http.HttpProtocol;
9 | import com.qcloud.cos.region.Region;
10 | import org.springframework.beans.factory.annotation.Value;
11 | import org.springframework.context.annotation.Bean;
12 | import org.springframework.context.annotation.Configuration;
13 |
14 | /**
15 | * @author: zhk
16 | * @description: 腾讯对象存储 COSClient,交给ioc容器管理
17 | * @date: 2023/3/2 15:42
18 | * @version: 1.0
19 | */
20 | @Configuration
21 | public class CosClientConfig {
22 | @Value("${tencent.cos.secretId}")
23 | private String secretId;
24 |
25 | @Value("${tencent.cos.secretKey}")
26 | private String secretKey;
27 |
28 | @Bean
29 | public COSClient getCosClient() {
30 | COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
31 | // 2 设置 bucket 的地域, COS 地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
32 | // clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或者常见问题 Java SDK 部分。
33 | Region region = new Region("ap-guangzhou");
34 | ClientConfig clientConfig = new ClientConfig(region);
35 | // 这里建议设置使用 https 协议
36 | clientConfig.setHttpProtocol(HttpProtocol.https);
37 | // 3 生成 cos 客户端。
38 | return new COSClient(cred, clientConfig);
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/config/MybatisConfig.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.config;
2 |
3 | import com.alibaba.druid.pool.DruidDataSource;
4 | import com.github.pagehelper.PageHelper;
5 | import org.mybatis.spring.annotation.MapperScan;
6 | import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
7 | import org.springframework.boot.context.properties.EnableConfigurationProperties;
8 | import org.springframework.context.annotation.Bean;
9 | import org.springframework.context.annotation.Configuration;
10 | import org.springframework.transaction.annotation.EnableTransactionManagement;
11 |
12 | import javax.annotation.Resource;
13 | import javax.sql.DataSource;
14 | import java.util.Properties;
15 |
16 | /**
17 | * @author: zhk
18 | * @description:
19 | * @date: 2023/3/1 17:54
20 | * @version: 1.0
21 | */
22 | @Configuration
23 | @MapperScan({"com.example.wendao.mapper"})
24 | @EnableTransactionManagement
25 | public class MybatisConfig {
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/config/QuartzConfig.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.config;
2 |
3 | import com.example.wendao.task.AchieveValueTask;
4 | import com.example.wendao.task.LikeTask;
5 | import org.quartz.*;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.context.annotation.Configuration;
8 |
9 | /**
10 | * @author: zhk
11 | * @description: 配置定时任务相关
12 | * @date: 2023/3/3 17:03
13 | * @version: 1.0
14 | */
15 | @Configuration
16 | public class QuartzConfig {
17 |
18 | private static final String LIKE_TASK_QUARTZ = "LIKE_TASK_QUARTZ";
19 | private static final String ACHIEVE_VALUE_SORT_QUARTZ = "ACHIEVE_VALUE_SORT_QUARTZ ";
20 |
21 | @Bean
22 | public JobDetail quartzDetail() {
23 | // Jobs added with no trigger must be durable.
24 | // 这里的意思就是如果没有添加触发器,那么必须就要是持续的,所以这里就要设置storeDurably
25 | return JobBuilder.newJob(LikeTask.class).storeDurably().build();
26 | }
27 |
28 | @Bean
29 | public JobDetail quartzDetail1() {
30 | // Jobs added with no trigger must be durable.
31 | // 这里的意思就是如果没有添加触发器,那么必须就要是持续的,所以这里就要设置storeDurably
32 | return JobBuilder.newJob(AchieveValueTask.class).storeDurably().build();
33 | }
34 |
35 |
36 | @Bean
37 | public Trigger quartzTrigger() {
38 | // 目前这里配置的是10s更新一次 现在更新为每2个小时更新下程序
39 | SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
40 | // .withIntervalInSeconds(10)
41 | .withIntervalInHours(2)
42 | .repeatForever();
43 | return TriggerBuilder.newTrigger().forJob(quartzDetail())
44 | .withIdentity(LIKE_TASK_QUARTZ)
45 | .withSchedule(scheduleBuilder)
46 | .build();
47 | }
48 |
49 | @Bean
50 | public Trigger quartzTrigger1() {
51 | // 这里设置的是用户表的成就值的属性,5040h即30天,会自动将用户表的成就值清零
52 | SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
53 | .withIntervalInHours(5040)
54 | .repeatForever();
55 | return TriggerBuilder.newTrigger().forJob(quartzDetail1())
56 | .withIdentity(ACHIEVE_VALUE_SORT_QUARTZ)
57 | .withSchedule(scheduleBuilder)
58 | .build();
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/config/RedisConfig.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.config;
2 |
3 | import org.springframework.beans.factory.annotation.Value;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.Configuration;
6 | import redis.clients.jedis.JedisPool;
7 | import redis.clients.jedis.JedisPoolConfig;
8 |
9 | /**
10 | * @author: zhk
11 | * @description: redis配置类
12 | * @date: 2023/3/2 10:09
13 | * @version: 1.0
14 | */
15 | @Configuration
16 | public class RedisConfig {
17 | @Value("${spring.redis.host}")
18 | private String host;
19 |
20 | @Value("${spring.redis.port}")
21 | private int port;
22 |
23 | @Value("${spring.redis.timeout}")
24 | private int timeout;
25 |
26 | @Value("${spring.redis.jedis.pool.max-active}")
27 | private int maxActive;
28 |
29 | @Value("${spring.redis.jedis.pool.max-idle}")
30 | private int maxIdle;
31 |
32 | @Value("${spring.redis.jedis.pool.min-idle}")
33 | private int minIdle;
34 |
35 |
36 | @Bean
37 | public JedisPool jedisPoolFactory() {
38 | JedisPoolConfig poolConfig = new JedisPoolConfig();
39 | poolConfig.setMinIdle(minIdle);
40 | poolConfig.setMaxIdle(maxIdle);
41 | poolConfig.setMaxTotal(maxActive);
42 |
43 | JedisPool jedisPool = new JedisPool(poolConfig, host, port, timeout);
44 | return jedisPool;
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/controller/CommentController.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.controller;
2 |
3 | import com.example.wendao.async.EventModel;
4 | import com.example.wendao.async.EventProducer;
5 | import com.example.wendao.async.EventType;
6 | import com.example.wendao.dto.CommentDto;
7 | import com.example.wendao.entity.Article;
8 | import com.example.wendao.entity.Comment;
9 | import com.example.wendao.entity.User;
10 | import com.example.wendao.redis.JedisService;
11 | import com.example.wendao.service.ArticleService;
12 | import com.example.wendao.service.CommentService;
13 | import com.example.wendao.service.UserService;
14 | import com.example.wendao.utils.CodeMsg;
15 | import com.example.wendao.utils.Result;
16 | import com.example.wendao.vo.CommentUserVo;
17 | import org.slf4j.Logger;
18 | import org.slf4j.LoggerFactory;
19 | import org.springframework.beans.factory.annotation.Autowired;
20 | import org.springframework.web.bind.annotation.*;
21 |
22 | import javax.servlet.http.HttpServletRequest;
23 | import java.util.Date;
24 | import java.util.List;
25 |
26 | /**
27 | * @author: zhk
28 | * @description:
29 | * @date: 2023/3/3 15:14
30 | * @version: 1.0
31 | */
32 | @RestController
33 | public class CommentController {
34 | private static final Logger logger = LoggerFactory.getLogger(CommentController.class);
35 | @Autowired
36 | LoginController loginController;
37 |
38 | @Autowired
39 | JedisService jedisService;
40 |
41 | @Autowired
42 | ArticleService articleService;
43 |
44 | @Autowired
45 | CommentService commentService;
46 |
47 | @Autowired
48 | UserService userService;
49 |
50 | @Autowired
51 | EventProducer eventProducer;
52 |
53 | /**
54 | * 在文章的详情页进行评论, 从前端界面传过来文章id以及评论的内容
55 | */
56 | @PostMapping("/insert/comment")
57 | @ResponseBody
58 | public Result commentArticle(HttpServletRequest request, @RequestBody CommentDto commentDto) {
59 | User user = loginController.getUserInfo(request);
60 | if (user == null) {
61 | return Result.error(CodeMsg.ERROR);
62 | }
63 |
64 | // 进入到下面来说明用户登录了,将这条评论插入comment表
65 | Comment comment = new Comment();
66 | comment.setCommentArticleId(commentDto.getArticleId());
67 | comment.setCommentUserId(user.getUserId());
68 | comment.setCommentContent(commentDto.getContent());
69 | comment.setCommentCreatedTime(new Date());
70 | if(commentDto.getParentId() != -1){
71 | comment.setParentCommentId(commentDto.getParentId());
72 | commentService.updateCommentCount(commentDto.getParentId());
73 | }else{
74 | //根评论的父id 为-1
75 | comment.setParentCommentId(-1);
76 | }
77 | commentService.insertComment(comment);
78 | // 评论添加成功之后,文章的评论数+1
79 | Article article = articleService.selectArticleByArticleId(commentDto.getArticleId());
80 | article.setArticleCommentCount(article.getArticleCommentCount() + 1);
81 | articleService.updateArticle(article);
82 |
83 | // 然后,需要将评论这个异步通知,发给被评论的用户
84 | EventModel eventModel = new EventModel();
85 |
86 | String articleAuthor = articleService.selectArticleByUserId(commentDto.getArticleId()).getArticleUserId();
87 | // 获取Comment表中最新的comment_id,即表示当前的comment对象
88 | int commentId = commentService.selectLastInsertCommentId();
89 | logger.info("评论的id:" + commentId);
90 |
91 |
92 | eventModel.setActorId(user.getUserId()).setEntityType(1).setEntityId(1).setEntityOwnerId(articleAuthor)
93 | .setEventType(EventType.COMMNET).setExts("articleId", commentDto.getArticleId() + "").
94 | setExts("commentId", commentId + "");
95 | // 将该评论异步通知给文章的作者
96 | eventProducer.fireEvent(eventModel);
97 |
98 | // 获取文章作者信息,然后更新文章的成就值
99 | User publishUser = userService.selectByUserId(articleAuthor);
100 | publishUser.setAchieveValue(publishUser.getAchieveValue() + 10);
101 | userService.updateByUserId(publishUser);
102 |
103 | return Result.success(true);
104 |
105 |
106 | }
107 |
108 | @GetMapping("/comment/list")
109 | @ResponseBody
110 | public Result> commentArticleLists(Integer articleId) {
111 | List commentUserVoList = commentService.selectCommentLists(articleId);
112 | return Result.success(commentUserVoList);
113 | }
114 |
115 | @PostMapping("/comment/like")
116 | public Result commentLike(int commentId){
117 | commentService.commentLike(commentId);
118 | return new Result(true);
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/controller/FansController.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.controller;
2 |
3 | import com.example.wendao.entity.Fans;
4 | import com.example.wendao.entity.User;
5 | import com.example.wendao.redis.FansKey;
6 | import com.example.wendao.redis.JedisService;
7 | import com.example.wendao.service.FansService;
8 | import com.example.wendao.service.UserService;
9 | import com.example.wendao.utils.CodeMsg;
10 | import com.example.wendao.utils.Result;
11 | import org.slf4j.Logger;
12 | import org.slf4j.LoggerFactory;
13 | import org.springframework.beans.factory.annotation.Autowired;
14 | import org.springframework.web.bind.annotation.GetMapping;
15 | import org.springframework.web.bind.annotation.RequestParam;
16 | import org.springframework.web.bind.annotation.ResponseBody;
17 | import org.springframework.web.bind.annotation.RestController;
18 |
19 | import javax.servlet.http.HttpServletRequest;
20 | import java.util.ArrayList;
21 | import java.util.List;
22 | import java.util.Set;
23 |
24 | /**
25 | * @author: zhk
26 | * @description:
27 | * @date: 2023/3/3 16:43
28 | * @version: 1.0
29 | */
30 | @RestController
31 | public class FansController {
32 | private static final Logger log = LoggerFactory.getLogger(FansController.class);
33 |
34 | @Autowired
35 | FansService fansService;
36 |
37 | @Autowired
38 | JedisService jedisService;
39 |
40 | @Autowired
41 | LoginController loginController;
42 |
43 | @Autowired
44 | UserService userService;
45 |
46 | @GetMapping("/fans/list")
47 | @ResponseBody
48 | public Result> fansList(@RequestParam String userId) {
49 | String realKey = FansKey.fansKey.getPrefix() + userId;
50 | Set set = jedisService.smembers(realKey);
51 | List usersList = new ArrayList<>();
52 | if (!set.isEmpty()) {
53 | // 这个set里面全部存储的userId,注意是String类型,然后根据这个来查询出User的信息
54 | for (String str : set) {
55 | User u = userService.selectByUserId(str);
56 | usersList.add(u);
57 | }
58 | log.info("从Redis中获取我的粉丝列表");
59 | } else {
60 | // 如果从Redis拿不到数据的话,就要从mysql中取数据
61 | List fansList = fansService.selectAllFansByUserId(userId);
62 | for (Fans fans : fansList) {
63 | User u = userService.selectByUserId(fans.getFansId());
64 | usersList.add(u);
65 | }
66 | log.info("从mysql中获取粉丝列表");
67 | }
68 | return Result.success(usersList);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/controller/FollowController.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.controller;
2 |
3 | import com.example.wendao.async.EventModel;
4 | import com.example.wendao.async.EventProducer;
5 | import com.example.wendao.async.EventType;
6 | import com.example.wendao.entity.Fans;
7 | import com.example.wendao.entity.Follow;
8 | import com.example.wendao.entity.User;
9 | import com.example.wendao.redis.FansKey;
10 | import com.example.wendao.redis.FollowKey;
11 | import com.example.wendao.redis.JedisService;
12 | import com.example.wendao.service.FansService;
13 | import com.example.wendao.service.FollowService;
14 | import com.example.wendao.service.UserService;
15 | import com.example.wendao.utils.CodeMsg;
16 | import com.example.wendao.utils.Result;
17 | import org.slf4j.Logger;
18 | import org.slf4j.LoggerFactory;
19 | import org.springframework.beans.factory.annotation.Autowired;
20 | import org.springframework.util.StringUtils;
21 | import org.springframework.web.bind.annotation.*;
22 |
23 | import javax.servlet.http.HttpServletRequest;
24 | import java.util.ArrayList;
25 | import java.util.Date;
26 | import java.util.List;
27 | import java.util.Set;
28 |
29 | /**
30 | * @author: zhk
31 | * @description:
32 | * @date: 2023/3/3 16:44
33 | * @version: 1.0
34 | */
35 | @RestController
36 | @RequestMapping("/follow")
37 | public class FollowController {
38 | private static final Logger log = LoggerFactory.getLogger(FollowController.class);
39 |
40 | @Autowired
41 | FollowService followService;
42 |
43 | @Autowired
44 | JedisService jedisService;
45 |
46 | @Autowired
47 | LoginController loginController;
48 |
49 | @Autowired
50 | UserService userService;
51 |
52 | @Autowired
53 | FansService fansService;
54 |
55 | @Autowired
56 | EventProducer eventProducer;
57 |
58 | /**
59 | *关注别人
60 | * @param followId :表示的是别人的userId,这里为了区分
61 | */
62 | @GetMapping("/add")
63 | @ResponseBody
64 | public Result addFollow(HttpServletRequest request, String followId) {
65 | User user = loginController.getUserInfo(request);
66 | if (user == null) {
67 | return Result.error(CodeMsg.ERROR);
68 | } else {
69 | // 说明用户已经登录,那么就可以拿到用户的userId,分别生成关注和粉丝的key
70 | // 我(userId)关注了你(followId)说明:在我followKey里面应该包含的是followId,表示我的关注者的列表
71 | // 在我fansKey里面应该包含的是userId,说明你(followId)的粉丝列表中有我(userId)
72 | // 首先生成set集合的key
73 |
74 | // User user = userService.selectByUserId("17643537768");
75 | String followRealKey = FollowKey.followKey.getPrefix() + user.getUserId();
76 | String fansRealKey = FansKey.fansKey.getPrefix() + followId;
77 | // 然后将当前用户自身的userId,保存到该set集合中去
78 | jedisService.sadd(followRealKey, followId);
79 | jedisService.sadd(fansRealKey, user.getUserId());
80 |
81 | // 关注成功后,要给用户发送通知,通知用户谁关注了你
82 | EventModel eventModel = new EventModel();
83 | eventModel.setActorId(user.getUserId()).setEntityId(1).setEntityType(2).setEventType(EventType.FOLLOW)
84 | .setEntityOwnerId(followId);
85 | eventProducer.fireEvent(eventModel);
86 | // 添加进redis之后,然后将其同步至mysql的follow表和fans表中
87 | Follow follow = new Follow();
88 | follow.setUserId(user.getUserId());
89 | follow.setFollowId(followId);
90 | follow.setCreatedTime(new Date());
91 | Fans fans = new Fans();
92 | fans.setUserId(followId);
93 | fans.setFansId(user.getUserId());
94 | fans.setCreatedTime(new Date());
95 | followService.insertFollow(follow);
96 | fansService.insertFans(fans);
97 |
98 | // 给被关注者增加成就值,首先应该先根据followId查找出user,然后更新其成就值
99 | User followedUser = userService.selectByUserId(followId);
100 | followedUser.setAchieveValue(followedUser.getAchieveValue() + 10);
101 | userService.updateByUserId(followedUser);
102 | return Result.success(true);
103 | }
104 | }
105 |
106 | @GetMapping("/cancel")
107 | @ResponseBody
108 | public Result cancelFollow(HttpServletRequest request, String followId) {
109 | User user = loginController.getUserInfo(request);
110 | if (user == null) {
111 | return Result.error(CodeMsg.NOT_LOGIN);
112 | } else {
113 |
114 | String followRealKey = FollowKey.followKey.getPrefix() + user.getUserId();
115 | String fansRealKey = FansKey.fansKey.getPrefix() + followId;
116 | if (StringUtils.isEmpty(followRealKey) || StringUtils.isEmpty(fansRealKey)) {
117 | return Result.error(CodeMsg.ERROR);
118 | } else {
119 | // 首先是从redis中去删除这个key,然后在数据库去删除这个key
120 | jedisService.srem(followRealKey, followId);
121 | jedisService.srem(fansRealKey, user.getUserId());
122 | followService.deleteFollow(user.getUserId(), followId);
123 | fansService.deleteFans(user.getUserId(), followId);
124 | return Result.success(true);
125 | }
126 | }
127 | }
128 |
129 | /**
130 | * 我的关注
131 | *
132 | * @return
133 | */
134 | @GetMapping("/list")
135 | @ResponseBody
136 | public Result> followList(@RequestParam String userId) {
137 | String realKey = FollowKey.followKey.getPrefix() + userId;
138 | Set set = jedisService.smembers(realKey);
139 | List usersList = new ArrayList<>();
140 | if (!set.isEmpty()) {
141 | // 这个set里面全部存储的userId,注意是String类型,然后根据这个来查询出User的信息
142 | for (String str : set) {
143 | User u = userService.selectByUserId(str);
144 | usersList.add(u);
145 | }
146 | log.info("从Redis的Set集合中获取到我的关注者");
147 | } else {
148 | // 如果从Redis拿不到数据的话,就要从mysql中取数据
149 | List followList = followService.selectAllFollowByUserId(userId);
150 | for (Follow f : followList) {
151 | User u = userService.selectByUserId(f.getFollowId());
152 | usersList.add(u);
153 | }
154 | log.info("从mysql中查询出来我的关注者");
155 | }
156 | return Result.success(usersList);
157 | }
158 |
159 | /**
160 | * 查询是否关注该用户
161 | * @param userId
162 | * @param followId
163 | * @return
164 | */
165 | @GetMapping("/isFollow")
166 | @ResponseBody
167 | public Result isFollow(@RequestParam String userId, @RequestParam String followId) {
168 | Follow follow = followService.isFollow(userId, followId);
169 | if(follow == null){
170 | return new Result(false);
171 | }else {
172 | return new Result(true);
173 | }
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/controller/IndexController.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.controller;
2 |
3 | import com.example.wendao.entity.Article;
4 | import com.example.wendao.redis.JedisService;
5 | import com.example.wendao.redis.LikeKey;
6 | import com.example.wendao.service.ArticleService;
7 | import com.example.wendao.utils.Result;
8 | import com.example.wendao.vo.ArticleUserVo;
9 | import org.apache.ibatis.annotations.Param;
10 | import org.slf4j.Logger;
11 | import org.slf4j.LoggerFactory;
12 | import org.springframework.beans.factory.annotation.Autowired;
13 | import org.springframework.web.bind.annotation.*;
14 |
15 | import java.util.List;
16 |
17 | /**
18 | * @author: zhk
19 | * @description:
20 | * @date: 2023/3/3 15:09
21 | * @version: 1.0
22 | */
23 | @RestController
24 | public class IndexController {
25 | private static Logger log = LoggerFactory.getLogger(IndexController.class);
26 |
27 | @Autowired
28 | ArticleService articleService;
29 |
30 | @Autowired
31 | JedisService jedisService;
32 |
33 | /**
34 | * 首页
35 | *
36 | * @param pageNum
37 | * @param pageSize
38 | * @return
39 | */
40 | @GetMapping("/")
41 | @ResponseBody
42 | public Result> index(@RequestParam("pageNum") Integer pageNum, @RequestParam("pageSize") Integer pageSize) {
43 | List articleList = articleService.selectAllArticleIndexViewData(pageNum, pageSize);
44 | return Result.success(articleList);
45 | }
46 |
47 | /**
48 | * 文章的详情页
49 | *
50 | * @param articleId
51 | * @return
52 | */
53 | @GetMapping("/detail/{articleId}")
54 | @ResponseBody
55 | public Result articleDetail(@PathVariable("articleId") int articleId) {
56 |
57 | //用户请求一次这个接口,相当于用户浏览量+1
58 | Article article = articleService.selectArticleByArticleId(articleId);
59 | article.setArticleViewCount(article.getArticleViewCount() + 1);
60 | articleService.updateArticle(article);
61 |
62 | // 这里查出来的数据,是从数据库查询出来的暂时没有like的数据,redis的数据才是实时最新的数据
63 | ArticleUserVo articleUserVo = articleService.selectAllArticleDetail(articleId);
64 | String likeKey = LikeKey.LIKE_KEY.getPrefix() + articleId;
65 | int likeCount = (int) jedisService.scard(likeKey);
66 |
67 | log.info("从Redis获取点赞数为:" + likeCount);
68 | articleUserVo.setArticleLikeCount(likeCount);
69 |
70 | return Result.success(articleUserVo);
71 | }
72 |
73 | /**
74 | * 根据目录id查询文章
75 | * @param categoryId
76 | * @param pageNum
77 | * @param pageSize
78 | * @return
79 | */
80 | @GetMapping("/category/{categoryId}")
81 | @ResponseBody
82 | public Result> articleCategory(@PathVariable("categoryId") Integer categoryId,
83 | @RequestParam("pageNum") Integer pageNum,
84 | @RequestParam("pageSize")Integer pageSize) {
85 | List articleList = articleService.selectAllArticleCategoryData(categoryId, pageNum, pageSize);
86 | return Result.success(articleList);
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/controller/LeaderBoardController.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.controller;
2 |
3 | import com.example.wendao.entity.User;
4 | import com.example.wendao.service.UserService;
5 | import com.example.wendao.utils.Result;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.web.bind.annotation.GetMapping;
8 | import org.springframework.web.bind.annotation.ResponseBody;
9 | import org.springframework.web.bind.annotation.RestController;
10 |
11 | import java.util.List;
12 |
13 | /**
14 | * @author: zhk
15 | * @description: 排行榜
16 | * @date: 2023/3/3 16:46
17 | * @version: 1.0
18 | */
19 |
20 | @RestController
21 | public class LeaderBoardController {
22 | @Autowired
23 | UserService userService;
24 |
25 |
26 | /**
27 | * 返回成就值排行
28 | *
29 | * @return
30 | */
31 | @GetMapping("/TopAchieve")
32 | @ResponseBody
33 | public Result> Top10LeaderBoard() {
34 | return Result.success(userService.top10LeaderBoard());
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/controller/LikeController.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.controller;
2 |
3 | import com.example.wendao.async.EventModel;
4 | import com.example.wendao.async.EventProducer;
5 | import com.example.wendao.async.EventType;
6 | import com.example.wendao.entity.Article;
7 | import com.example.wendao.entity.User;
8 | import com.example.wendao.redis.JedisService;
9 | import com.example.wendao.redis.LikeKey;
10 | import com.example.wendao.service.ArticleService;
11 | import com.example.wendao.service.LikeService;
12 | import com.example.wendao.service.UserService;
13 | import com.example.wendao.utils.CodeMsg;
14 | import com.example.wendao.utils.Result;
15 | import org.springframework.beans.factory.annotation.Autowired;
16 | import org.springframework.web.bind.annotation.GetMapping;
17 | import org.springframework.web.bind.annotation.ResponseBody;
18 | import org.springframework.web.bind.annotation.RestController;
19 |
20 | import javax.servlet.http.HttpServletRequest;
21 |
22 | /**
23 | * @author: zhk
24 | * @description:
25 | * @date: 2023/3/3 16:47
26 | * @version: 1.0
27 | */
28 | @RestController
29 | public class LikeController {
30 |
31 | @Autowired
32 | JedisService jedisService;
33 |
34 | @Autowired
35 | EventProducer eventProducer;
36 |
37 | @Autowired
38 | LoginController loginController;
39 |
40 | @Autowired
41 | LikeService likeService;
42 |
43 | @Autowired
44 | ArticleService articleService;
45 |
46 | @Autowired
47 | UserService userService;
48 |
49 | @GetMapping("/like")
50 | @ResponseBody
51 | public Result likeArticle(HttpServletRequest request, String articleId) {
52 | User user = loginController.getUserInfo(request);
53 | if (user == null) {
54 | return Result.error(CodeMsg.ERROR);
55 | }
56 | // User user = userService.selectByUserId("17643537768")
57 | // 这里的值,应该是userId,因为使用userId可以防止用户重复点赞
58 | long likeCount = likeService.like(articleId, user.getUserId());
59 | Integer articleInt = Integer.parseInt(articleId);
60 | Article article = articleService.selectArticleByUserId(articleInt);
61 | String articleAuthor = article.getArticleUserId();
62 | EventModel eventModel = new EventModel();
63 | // 点完赞之后,立即异步通知给用户
64 | eventProducer.fireEvent(eventModel.setEventType(EventType.LIKE).setActorId(user.getUserId())
65 | .setEntityType(1).setEntityId(2).setEntityOwnerId(articleAuthor).setExts("articleId", articleId + ""));
66 | // 点赞之后,articleCount的数据也会对应进行增加,这里使用Quartz设置每多长时间将redis中的数据
67 | // 更新到mysql中,在优化阶段每隔一小时将redis中存的点赞数量更新到数据库中去
68 | // 首先根据文章的id, 查找出这篇文章的发布者,然后通过文章发布者的id查找出user对象,然后更新其成就值
69 | User publishUser = userService.selectByUserId(articleAuthor);
70 | publishUser.setAchieveValue(publishUser.getAchieveValue() + 5);
71 | userService.updateByUserId(publishUser);
72 | return Result.success(likeCount);
73 | }
74 |
75 |
76 | @GetMapping("/dislike")
77 | @ResponseBody
78 | public Result dislikeArticle(HttpServletRequest request, int articleId) {
79 | User user = loginController.getUserInfo(request);
80 | if (user == null) {
81 | return Result.error(CodeMsg.ERROR);
82 | }
83 | // User user = userService.selectByUserId("17643537768");
84 |
85 | // 进入这里说明用户是登录过了,然后把用户的相关信息存储到Redis的Set中
86 |
87 | // 这里的值,应该是userId,因为使用userId可以防止用户重复点赞
88 | long likeCount = likeService.dislike(articleId, user.getUserId());
89 |
90 | /**
91 | Article article = articleService.selectArticleByTwoUserId(articleId);
92 | 这里就没必要进行异步通知了,并且也不需要即使更新进数据库,设置了定时任务每两个小时将redis的点赞数量
93 | 定时更新到数据库中
94 | article.setArticleLikeCount(article.getArticleLikeCount() - 1);
95 | */
96 | return Result.success(likeCount);
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/controller/LoginController.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.controller;
2 |
3 | import com.example.wendao.dto.UserDto;
4 | import com.example.wendao.entity.User;
5 | import com.example.wendao.redis.JedisService;
6 | import com.example.wendao.redis.UserTokenKey;
7 | import com.example.wendao.redis.VerifyCodeKey;
8 | import com.example.wendao.service.UserService;
9 | import com.example.wendao.utils.CodeMsg;
10 | import com.example.wendao.utils.CommonUtils;
11 | import com.example.wendao.utils.GenerateRandomCode;
12 | import com.example.wendao.utils.Result;
13 | import com.tencentcloudapi.common.Credential;
14 | import com.tencentcloudapi.common.exception.TencentCloudSDKException;
15 | import com.tencentcloudapi.common.profile.ClientProfile;
16 | import com.tencentcloudapi.common.profile.HttpProfile;
17 | import com.tencentcloudapi.sms.v20190711.SmsClient;
18 | import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest;
19 | import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse;
20 | import org.apache.commons.codec.digest.DigestUtils;
21 | import org.slf4j.Logger;
22 | import org.slf4j.LoggerFactory;
23 | import org.springframework.beans.factory.annotation.Autowired;
24 | import org.springframework.http.HttpHeaders;
25 | import org.springframework.http.ResponseCookie;
26 | import org.springframework.web.bind.annotation.*;
27 |
28 | import javax.servlet.http.Cookie;
29 | import javax.servlet.http.HttpServletRequest;
30 | import javax.servlet.http.HttpServletResponse;
31 | import java.time.Duration;
32 |
33 | /**
34 | * @author: zhk
35 | * @description:
36 | * @date: 2023/3/2 9:15
37 | * @version: 1.0
38 | */
39 | @RestController
40 | @RequestMapping("/login")
41 | public class LoginController {
42 | private Logger log = LoggerFactory.getLogger(RegisterController.class);
43 |
44 | @Autowired
45 | JedisService jedisService;
46 |
47 | @Autowired
48 | UserService userService;
49 | /**
50 | * 发送短信验证码
51 | *
52 | * @return
53 | */
54 | public static final String USER_TOKEN = "token";
55 |
56 | @GetMapping("/verifyLoginInfo")
57 | public Result loginVerify(String userId, String code, HttpServletResponse response, HttpServletRequest request) {
58 | String verifyCode = jedisService.getKey(VerifyCodeKey.verifyCodeKeyLogin, code, String.class);
59 | User user = userService.selectByUserId(userId);
60 | if (user == null) {
61 | return Result.error(CodeMsg.UNREGISTER_PHONE);
62 | }
63 | if (verifyCode == null || (!verifyCode.equals(code))) {
64 | return Result.error(CodeMsg.VERIFY_CODE_ERROR);
65 | }
66 | // 这里证明登录成功了,拿到用户信息了,这里我应该把用户的信息放在cookie和redis中
67 | addCookie(response, request, user);
68 | return Result.success(CodeMsg.SUCCESS);
69 | }
70 |
71 | /**
72 | * 提供一个可以提供手机号+密码的方式进行登录
73 | */
74 | @PostMapping("/loginPassword")
75 | public Result loginPassword(@RequestBody UserDto userDto, HttpServletResponse response, HttpServletRequest request) {
76 | User user = userService.selectByUserIdAll(userDto.getUserId());
77 | if (user == null) {
78 | return Result.error(CodeMsg.UNREGISTER_PHONE);
79 | }
80 |
81 | log.info(userDto.getPassword());
82 | log.info(user.getSalt());
83 |
84 | if (!(user.getPassword().equals(DigestUtils.md5Hex(userDto.getPassword() + user.getSalt())))) {
85 | return Result.error(CodeMsg.PASSWORD_ERROR);
86 | } else {
87 | addCookie(response, request, user);
88 | return new Result<>(CodeMsg.SUCCESS);
89 | }
90 | }
91 |
92 | public void addCookie(HttpServletResponse response, HttpServletRequest request, User user) {
93 | String token = CommonUtils.uuid();
94 | log.info("token=" + token);
95 | // 将token值以及user保存进redis
96 | jedisService.setKey(UserTokenKey.userTokenKey, token, user);
97 | // Cookie cookie = new Cookie(USER_TOKEN, token);
98 | // // 设置60天的有效期
99 | // cookie.setMaxAge(UserTokenKey.userTokenKey.expireSeconds());
100 | // cookie.setPath("/");
101 |
102 | ResponseCookie cookie = ResponseCookie.from(USER_TOKEN, token)
103 | // 在http下也传输
104 | .secure(true)
105 | .path("/")
106 | // 60天
107 | .maxAge(Duration.ofDays(60))
108 | .httpOnly(false)
109 | // 大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外
110 | .sameSite("None")
111 | .build();
112 | response.setHeader(HttpHeaders.SET_COOKIE, cookie.toString());
113 | response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
114 | }
115 |
116 | public String getUserToken(HttpServletRequest request, String cookieName) {
117 | Cookie[] cookies = request.getCookies();
118 | if (cookies == null || cookies.length <= 0) {
119 | return null;
120 | }
121 | for (Cookie cookie : cookies) {
122 | if (cookie.getName().equals(cookieName)) {
123 | return cookie.getValue();
124 | }
125 | }
126 | return null;
127 | }
128 |
129 |
130 | public User getUserInfo(HttpServletRequest request) {
131 | String token = getUserToken(request, LoginController.USER_TOKEN);
132 | return jedisService.getKey(UserTokenKey.userTokenKey, token, User.class);
133 | }
134 |
135 | /**
136 | * 当用户点击退出的时候,应该退出登录,并且应该清除Cookie
137 | */
138 | @GetMapping("/logout")
139 | @ResponseBody
140 | public Result logout(HttpServletRequest request) {
141 |
142 | Cookie[] cookies = request.getCookies();
143 | for (Cookie cookie : cookies) {
144 | if (cookie.getName().equals(LoginController.USER_TOKEN)) {
145 | // 马上设置该cookie过期
146 | String token = cookie.getValue();
147 | cookie.setMaxAge(0);
148 | cookie.setPath("/");
149 | // 设置完cookie过期之后,也应该清空Redis保存的Cookie值
150 | jedisService.del(UserTokenKey.userTokenKey, token);
151 |
152 | }
153 | }
154 | return Result.success(true);
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/controller/NoticeController.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.controller;
2 |
3 | import com.example.wendao.controller.LoginController;
4 | import com.example.wendao.entity.Notice;
5 | import com.example.wendao.entity.User;
6 | import com.example.wendao.service.NoticeService;
7 | import com.example.wendao.service.UserService;
8 | import com.example.wendao.utils.CodeMsg;
9 | import com.example.wendao.utils.Result;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.web.bind.annotation.GetMapping;
12 | import org.springframework.web.bind.annotation.ResponseBody;
13 | import org.springframework.web.bind.annotation.RestController;
14 |
15 | import javax.servlet.http.HttpServletRequest;
16 | import java.util.List;
17 |
18 | /**
19 | * @author: zhk
20 | * @description:
21 | * @date: 2023/3/3 16:51
22 | * @version: 1.0
23 | */
24 | @RestController
25 | public class NoticeController {
26 | @Autowired
27 | LoginController loginController;
28 |
29 | @Autowired
30 | NoticeService noticeService;
31 |
32 | @Autowired
33 | UserService userService;
34 |
35 | /**
36 | * 异步通知和前端联调设计思路:notice表中有一个has_read属性,has_read 0表示的是未读,
37 | * 1 表示的是已读,如果有未读的消息,则给前端返回true,没有未读的消息,则给前端返回false
38 | * 前端拿到true之后,应该出现红点,当用户点击红点的时候,后端逻辑给前端返回和该用户相关的
39 | * 数据,并将所有的数据has_read属性设置为1表示已读
40 | */
41 | @GetMapping("/hasReadNotice")
42 | @ResponseBody
43 | public Result hasReadIsZero(HttpServletRequest request) {
44 | User user = loginController.getUserInfo(request);
45 | if (user == null) {
46 | return Result.error(CodeMsg.NOT_LOGIN);
47 | }
48 | //User user = userService.selectByUserId("18392710807");
49 | //通过数据库查询notice表中是否有has_read属性是否为0,0表示的是未读
50 | int count = noticeService.countNoticeHasRead(user.getUserId());
51 | if (count > 0) {
52 | return Result.success(true);
53 | } else {
54 | return Result.success(false);
55 | }
56 | }
57 |
58 | @GetMapping("/notice/list")
59 | @ResponseBody
60 | public Result> noticeList(HttpServletRequest request) {
61 | User user = loginController.getUserInfo(request);
62 | if (user == null) {
63 | return Result.error(CodeMsg.NOT_LOGIN);
64 | }
65 | //User user = userService.selectByUserId("18392710807");
66 | noticeService.updateAllNoticeHasRead(user.getUserId());
67 | List notices = noticeService.noticeList(user.getUserId());
68 | return Result.success(notices);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/controller/RegisterController.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.controller;
2 |
3 |
4 | import cn.hutool.http.HttpRequest;
5 | import cn.hutool.http.HttpUtil;
6 | import com.alibaba.fastjson.JSONObject;
7 | import com.example.wendao.dto.RegisterDto;
8 | import com.example.wendao.dto.UserDto;
9 | import com.example.wendao.entity.User;
10 | import com.example.wendao.redis.JedisService;
11 |
12 | import com.example.wendao.service.UserService;
13 | import com.example.wendao.utils.*;
14 |
15 | import com.example.wendao.vo.UserInfoVo;
16 | import org.apache.commons.codec.digest.DigestUtils;
17 | import org.slf4j.Logger;
18 | import org.slf4j.LoggerFactory;
19 | import org.springframework.beans.factory.annotation.Autowired;
20 | import org.springframework.http.HttpMethod;
21 | import org.springframework.http.ResponseEntity;
22 | import org.springframework.web.bind.annotation.*;
23 | import org.springframework.web.client.RestTemplate;
24 | import org.springframework.web.util.UriComponentsBuilder;
25 |
26 | import javax.servlet.http.HttpServletRequest;
27 | import java.util.Date;
28 | import java.util.HashMap;
29 | import java.util.Map;
30 | import java.util.UUID;
31 |
32 | /**
33 | * @author: zhk
34 | * @description:
35 | * @date: 2023/3/2 9:15
36 | * @version: 1.0
37 | */
38 | @RestController
39 | @RequestMapping(value = "/register")
40 | public class RegisterController {
41 | private Logger log = LoggerFactory.getLogger(RegisterController.class);
42 |
43 | @Autowired
44 | JedisService jedisService;
45 |
46 | @Autowired
47 | UserService userService;
48 |
49 | /**
50 | * 注册
51 | *
52 | * @param registerDto
53 | * @return
54 | */
55 | @PostMapping("/verifyRegisterInfo")
56 | public Result registerVerify(@RequestBody RegisterDto registerDto, HttpServletRequest request) {
57 | // 判断该手机号是否注册过了
58 | UserInfoVo u = userService.selectByUserInfoId(registerDto.getUserId());
59 | if (u != null) {
60 | return Result.error(CodeMsg.DUPLICATE_REGISTRY);
61 | }
62 | // 随机生成一个6位数的小写字符串
63 | String salt = RandomUtils.randomSalt();
64 |
65 | User user = new User();
66 | user.setUserId(registerDto.getUserId());
67 | user.setSalt(salt);
68 | user.setPassword(DigestUtils.md5Hex((registerDto.getPassword() + salt)));
69 | user.setNickname(registerDto.getNickName());
70 | user.setLoginIp(IpUtils.getIpAddr(request));
71 | user.setCreateTime(new Date());
72 | userService.insert(user);
73 | //在腾讯im中注册账户
74 | RestTemplate restTemplate = new RestTemplate();
75 | String baseURL = "https://console.tim.qq.com/v4/im_open_login_svc/account_import";
76 | long appid = 1400807520;
77 | String identifier = "administrator";
78 | String key = "ba24710d781eec44402a5fbd1c98915393b8c3b080ed6f43bdc4b9f3f3ccd478";
79 | TLSSigAPIv2 tlsSigAPIv2 = new TLSSigAPIv2(appid, key);
80 | String userSig = tlsSigAPIv2.genUserSig(identifier, 1000 * 60 * 24 * 7);
81 | UUID uuid = UUID.randomUUID();
82 | long mostSigBits = uuid.getMostSignificantBits();
83 | long leastSigBits = uuid.getLeastSignificantBits();
84 | long unsignedInt = (mostSigBits & Long.MAX_VALUE) | (leastSigBits >>> 1);
85 | JSONObject jsonObject = new JSONObject();
86 | jsonObject.put("UserID", user.getUserId());
87 | jsonObject.put("Nick", user.getNickname());
88 |
89 | Map map = new HashMap<>();
90 | map.put("sdkappid", appid);
91 | map.put("identifier", identifier);
92 | map.put("usersig", userSig);
93 | map.put("random", unsignedInt);
94 | map.put("contenttype", "json");
95 | log.info(appid+" "+ identifier+" "+ userSig+" "+ unsignedInt+" "+ jsonObject);
96 | String responseEntity = HttpRequest.get(baseURL + "?sdkappid=" + appid + "&identifier=" +
97 | identifier + "&usersig=" + userSig + "&random=" + unsignedInt + "&contenttype=json")
98 | .body(jsonObject.toJSONString())
99 | .execute().body();
100 | log.info("TIM注册: " + responseEntity);
101 | return Result.success(CodeMsg.SUCCESS);
102 | }
103 |
104 | }
105 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/controller/UserController.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.controller;
2 |
3 | import com.example.wendao.entity.User;
4 | import com.example.wendao.service.UserService;
5 | import com.example.wendao.utils.IpUtils;
6 | import com.example.wendao.utils.RandomUtils;
7 | import com.example.wendao.utils.Result;
8 | import com.example.wendao.vo.UserData;
9 | import com.example.wendao.vo.UserInfoVo;
10 | import org.apache.commons.codec.digest.DigestUtils;
11 | import org.slf4j.Logger;
12 | import org.slf4j.LoggerFactory;
13 | import org.springframework.beans.factory.annotation.Autowired;;
14 | import org.springframework.web.bind.annotation.*;
15 | import org.springframework.web.multipart.MultipartFile;
16 |
17 | import javax.servlet.http.HttpServletRequest;
18 | import javax.servlet.http.HttpServletResponse;
19 | import java.util.HashMap;
20 |
21 |
22 | /**
23 | * @author: zhk
24 | * @description:
25 | * @date: 2023/3/1 21:10
26 | * @version: 1.0
27 | */
28 | @RestController
29 | public class UserController {
30 | private static Logger log = LoggerFactory.getLogger(UserController.class);
31 | @Autowired
32 | UserService userService;
33 |
34 | @Autowired
35 | LoginController loginController;
36 |
37 | /**
38 | * 默认展示用户的基本信息,
39 | *
40 | * @return
41 | */
42 | @GetMapping("/userInfo")
43 | @ResponseBody
44 | public Result userInfo(HttpServletRequest request) {
45 | User user = loginController.getUserInfo(request);
46 | String userId = user.getUserId();
47 | return Result.success(userService.selectByUserInfoId(userId));
48 | }
49 |
50 | @GetMapping("/userInfoId")
51 | @ResponseBody
52 | public Result userInfoById(@RequestParam String userId) {
53 | return Result.success(userService.selectByUserInfoId(userId));
54 | }
55 |
56 | @GetMapping("/userData")
57 | public Result userData(@RequestParam String userId){
58 | UserData userData = userService.getUserData(userId);
59 | return Result.success(userData);
60 | }
61 |
62 | @PostMapping("/update/userInfo")
63 | @ResponseBody
64 | public Result updateUserInfo(HttpServletResponse response, HttpServletRequest request,@RequestBody User user) {
65 | // 更新之前,需要将从前端传过来的图片信息,上传到腾讯云上去,然后存入数据库的话是一个链接
66 | // 需要更新的是用户昵称,用户头像,用户性别,用户学校,用户的个性签名
67 | // 重新设置Cookie,即更新Redis中User的信息
68 | String salt = RandomUtils.randomSalt();
69 | user.setSalt(salt);
70 | user.setPassword(DigestUtils.md5Hex((user.getPassword() + salt)));
71 | userService.updateByUserId(user);
72 | loginController.addCookie(response, request, user);
73 | return Result.success(true);
74 | }
75 |
76 | /**
77 | * 而且在postman测试工具的时候,必须要不仅选择文件,还要在key中写multipartFile, 不然会报错空指针异常
78 | *
79 | * @param file
80 | * @return
81 | */
82 | @PostMapping("/upload/images")
83 | @ResponseBody
84 | public Result uploadImages(MultipartFile file) {
85 | if (file != null) {
86 | if (file.getSize() > 1024 * 1024 * 4) {
87 | return new Result<>("文件大小不能大于4M");
88 | }
89 | String suffix = file.getOriginalFilename().
90 | substring(file.getOriginalFilename().lastIndexOf(".") + 1,
91 | file.getOriginalFilename().length());
92 | if (!"jpg,jpeg,gif,png".toUpperCase().contains(suffix.toUpperCase())) {
93 | return new Result<>("请选择jpg,jpeg,gif,png格式的图片");
94 | }
95 | String url = userService.uploadImages(file);
96 | HashMap stringStringHashMap = new HashMap<>();
97 | stringStringHashMap.put("url", url);
98 | if (url != null && !"".equals(url)) {
99 | return new Result(stringStringHashMap);
100 | } else {
101 | return new Result<>("上传失败");
102 | }
103 | } else {
104 | return new Result<>("图片不能为空");
105 | }
106 |
107 | }
108 |
109 |
110 |
111 | }
112 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/controller/VideoController.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.controller;
2 |
3 | import com.alibaba.fastjson.JSONArray;
4 | import com.alibaba.fastjson.JSONObject;
5 | import com.example.wendao.dto.CategoryFeedDto;
6 | import com.example.wendao.dto.VideoActionDto;
7 | import com.example.wendao.entity.VideoCategory;
8 | import com.example.wendao.service.CategoryService;
9 | import com.example.wendao.service.VideoService;
10 | import com.example.wendao.utils.Result;
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.web.bind.annotation.*;
13 |
14 | import java.util.List;
15 |
16 | /**
17 | * @author: zhk
18 | * @description:
19 | * @date: 2023/3/21 17:01
20 | * @version: 1.0
21 | */
22 | @RestController
23 | @RequestMapping("/video")
24 | public class VideoController {
25 |
26 | @Autowired
27 | VideoService videoService;
28 |
29 | /**
30 | * 分页获取目录
31 | * @param pageNum
32 | * @param pageSize
33 | * @return
34 | */
35 | @GetMapping("/category")
36 | public Result> categoryList(@RequestParam int pageNum, @RequestParam int pageSize){
37 | List videoCategories = videoService.categoryList(pageNum, pageSize);
38 | if(videoCategories.size() != 0){
39 | return new Result<>(videoCategories);
40 | }
41 | return new Result<>(null);
42 | }
43 |
44 | /**
45 | * 获取主分区
46 | * @return
47 | */
48 | @GetMapping("/category/parent")
49 | public Result> categoryList(){
50 | List videoCategories = videoService.categoryMainList();
51 | if(videoCategories.size() != 0){
52 | return new Result<>(videoCategories);
53 | }
54 | return new Result<>(null);
55 | }
56 |
57 | /**
58 | * 获取子分区
59 | * @param parentId
60 | * @return
61 | */
62 | @GetMapping("/category/child")
63 | public Result> categoryList(@RequestParam int parentId){
64 | List videoCategories = videoService.categoryChildList(parentId);
65 | if(videoCategories.size() != 0){
66 | return new Result<>(videoCategories);
67 | }
68 | return new Result<>(null);
69 | }
70 |
71 |
72 | /**
73 | * 获取分类下的视频推荐
74 | * @param categoryFeedDto
75 | * @return
76 | */
77 | @PostMapping("/category/feed")
78 | public Result categoryFeedList(@RequestBody CategoryFeedDto categoryFeedDto){
79 | JSONObject objects = videoService.categoryFeedList(categoryFeedDto.getPageNum(), categoryFeedDto.getPageSize(), categoryFeedDto.getTid());
80 | return new Result<>(objects);
81 | }
82 |
83 | /**
84 | * 视频播放地址
85 | * @param videoActionDto
86 | * @return
87 | */
88 | @PostMapping("/action")
89 | public Result action(@RequestBody VideoActionDto videoActionDto){
90 | JSONObject action = videoService.action(videoActionDto);
91 | return new Result<>(action);
92 | }
93 |
94 | /**
95 | * 获取某个视频下面的推荐视频
96 | * @param aid
97 | * @return
98 | */
99 | @GetMapping("/recommend")
100 | public Result recommend(@RequestParam int aid){
101 | JSONArray array = videoService.recommend(aid);
102 | return new Result(array);
103 | }
104 |
105 | /**
106 | * 视频信息
107 | * @param aid
108 | * @return
109 | */
110 | @GetMapping("/information")
111 | public Result videoDetail(@RequestParam Integer aid){
112 | JSONObject object = videoService.videoInformation(aid);
113 | return new Result(object);
114 | }
115 |
116 | /**
117 | * 热门推荐
118 | * @param pageNum
119 | * @param pageSize
120 | * @return
121 | */
122 | @GetMapping("/popular")
123 | public Result popular(@RequestParam Integer pageNum, @RequestParam Integer pageSize){
124 | JSONObject object = videoService.popular(pageNum, pageSize);
125 | return new Result(object);
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/dto/CategoryFeedDto.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.dto;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | /**
8 | * @author: zhk
9 | * @description:
10 | * @date: 2023/3/22 11:10
11 | * @version: 1.0
12 | */
13 | @Data
14 | @AllArgsConstructor
15 | @NoArgsConstructor
16 | public class CategoryFeedDto {
17 | private int pageNum;
18 | private int pageSize;
19 | private int tid;
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/dto/CommentDto.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.dto;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | /**
8 | * @author: zhk
9 | * @description:
10 | * @date: 2023/3/18 20:27
11 | * @version: 1.0
12 | */
13 | @Data
14 | @AllArgsConstructor
15 | @NoArgsConstructor
16 | public class CommentDto {
17 | private String content;
18 | private int articleId;
19 | private int parentId;
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/dto/RegisterDto.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.dto;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | /**
8 | * @author: zhk
9 | * @description:
10 | * @date: 2023/3/18 15:35
11 | * @version: 1.0
12 | */
13 | @Data
14 | @AllArgsConstructor
15 | @NoArgsConstructor
16 | public class RegisterDto {
17 | private String userId;
18 | private String password;
19 | private String nickName;
20 | }
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/dto/UserDto.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.dto;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | /**
8 | * @author: zhk
9 | * @description:
10 | * @date: 2023/3/3 17:44
11 | * @version: 1.0
12 | */
13 | @Data
14 | @AllArgsConstructor
15 | @NoArgsConstructor
16 | public class UserDto {
17 | private String userId;
18 | private String password;
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/dto/VideoActionDto.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.dto;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | /**
8 | * @author: zhk
9 | * @description:
10 | * @date: 2023/3/22 15:28
11 | * @version: 1.0
12 | */
13 | @Data
14 | @AllArgsConstructor
15 | @NoArgsConstructor
16 | public class VideoActionDto {
17 | /**
18 | * 视频avid
19 | */
20 | private int avid;
21 | /**
22 | * 视频cid
23 | */
24 | private int cid;
25 | /**
26 | * 视频清晰度
27 | */
28 | private int qn;
29 | /**
30 | * 视频流格式标识 默认为0
31 | */
32 | private int fnval;
33 | /**
34 | * 默认为0
35 | */
36 | private int fnver;
37 | /**
38 | * 4k开启 默认为0
39 | */
40 | private int fourk;
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/entity/Article.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.entity;
2 |
3 | import com.fasterxml.jackson.annotation.JsonFormat;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 | import org.springframework.data.annotation.Id;
8 | import org.springframework.data.elasticsearch.annotations.DateFormat;
9 | import org.springframework.data.elasticsearch.annotations.Document;
10 | import org.springframework.data.elasticsearch.annotations.Field;
11 | import org.springframework.data.elasticsearch.annotations.FieldType;
12 |
13 | import java.util.Date;
14 |
15 | /**
16 | * @author: zhk
17 | * @description: 文章实体
18 | * @date: 2023/3/1 15:57
19 | * @version: 1.0
20 | */
21 |
22 | @Data
23 | @AllArgsConstructor
24 | @NoArgsConstructor
25 | @Document(indexName = "wendao", type = "_doc", createIndex = true)
26 | public class Article {
27 |
28 | /**
29 | * 文章id
30 | */
31 | @Id
32 | @Field(type = FieldType.Integer, name = "article_id")
33 | private int articleId;
34 |
35 | /**
36 | * 文章标题
37 | */
38 | @Field(type = FieldType.Text, analyzer = "ik_max_word", name = "article_title", searchAnalyzer = "ik_max_word")
39 | private String articleTitle;
40 |
41 | /**
42 | * 文章摘要
43 | */
44 | @Field(type = FieldType.Text, name = "article_summary")
45 | private String articleSummary;
46 |
47 | /**
48 | * 文章内容
49 | */
50 | @Field(type = FieldType.Text, analyzer = "ik_max_word", name = "article_content", searchAnalyzer = "ik_max_word")
51 | private String articleContent;
52 |
53 | /**
54 | * 文章浏览量
55 | */
56 | @Field(type = FieldType.Integer, name = "article_view_count")
57 | private int articleViewCount;
58 |
59 | /**
60 | * 文章点赞数
61 | */
62 | @Field(type = FieldType.Integer, name = "article_like_count")
63 | private int articleLikeCount;
64 |
65 | /**
66 | * 文章评论数
67 | */
68 | @Field(type = FieldType.Integer, name = "article_comment_count")
69 | private int articleCommentCount;
70 |
71 | /**
72 | * 创建时间
73 | */
74 | @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
75 | @Field(type = FieldType.Date, name = "created_time", format = DateFormat.date_optional_time)
76 | private Date createdTime;
77 |
78 | /**
79 | * 更新时间
80 | */
81 | @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
82 | @Field(type = FieldType.Date, name = "update_time", format = DateFormat.date_optional_time)
83 | private Date updateTime;
84 |
85 | /**
86 | * isDelete表示两种状态,0表示未删除,1表示已删除
87 | */
88 | @Field(type = FieldType.Integer, name = "is_deleted")
89 | private int isDeleted;
90 |
91 | /**
92 | * 外键 对应category——id
93 | */
94 | @Field(type = FieldType.Integer, name = "article_category_id")
95 | private int articleCategoryId;
96 |
97 | /**
98 | * 外键,对应user——id
99 | */
100 | @Field(type = FieldType.Text, name = "article_category_name")
101 | private String articleCategoryName;
102 |
103 | /**
104 | * 分类表中的category——name
105 | */
106 | @Field(type = FieldType.Text, name = "article_user_id")
107 | private String articleUserId;
108 | }
109 |
110 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/entity/Category.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.entity;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | /**
8 | * @author: zhk
9 | * @description: 分类表
10 | * @date: 2023/3/1 16:00
11 | * @version: 1.0
12 | */
13 | @Data
14 | @AllArgsConstructor
15 | @NoArgsConstructor
16 | public class Category {
17 | /**
18 | * 分类表id
19 | */
20 | int categoryId;
21 |
22 | /**
23 | * 分类名
24 | */
25 | String categoryName;
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/entity/Comment.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.entity;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | import java.util.Date;
8 |
9 | /**
10 | * @author: zhk
11 | * @description: 评论
12 | * @date: 2023/3/1 16:01
13 | * @version: 1.0
14 | */
15 | @Data
16 | @AllArgsConstructor
17 | @NoArgsConstructor
18 | public class Comment {
19 | /**
20 | * 评论id
21 | */
22 | private int commentId;
23 |
24 | /**
25 | * 文章id
26 | */
27 | private int commentArticleId;
28 |
29 | /**
30 | * 用户id
31 | */
32 | private String commentUserId;
33 |
34 | /**
35 | * 评论内容
36 | */
37 | private String commentContent;
38 |
39 | /**
40 | * 评论点赞数
41 | */
42 | private int commentLikeCount;
43 |
44 | /**
45 | * 评论回复数
46 | */
47 | private int commentCount;
48 |
49 | /**
50 | * 评论创建时间
51 | */
52 | private Date commentCreatedTime;
53 | /**
54 | * 父评论id
55 | */
56 | private int parentCommentId;
57 | }
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/entity/Fans.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.entity;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | import java.util.Date;
8 |
9 | /**
10 | * @author: zhk
11 | * @description: 粉丝实体
12 | * @date: 2023/3/1 16:01
13 | * @version: 1.0
14 | */
15 | @Data
16 | @AllArgsConstructor
17 | @NoArgsConstructor
18 | public class Fans {
19 |
20 | /**
21 | * id
22 | */
23 | private int id;
24 |
25 | /**
26 | * 用户id
27 | */
28 | private String userId;
29 |
30 | /**
31 | * 粉丝id
32 | */
33 | private String fansId;
34 |
35 | /**
36 | * 创建时间
37 | */
38 | private Date createdTime;
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/entity/Follow.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.entity;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | import java.util.Date;
8 |
9 | /**
10 | * @author: zhk
11 | * @description: 关注实体
12 | * @date: 2023/3/1 16:01
13 | * @version: 1.0
14 | */
15 | @Data
16 | @AllArgsConstructor
17 | @NoArgsConstructor
18 | public class Follow {
19 |
20 | /**
21 | * id
22 | */
23 | private int id;
24 |
25 | /**
26 | * 用户id
27 | */
28 | private String userId;
29 |
30 | /**
31 | * 关注的id
32 | */
33 | private String followId;
34 |
35 | /**
36 | * 创建时间
37 | */
38 | private Date createdTime;
39 | }
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/entity/Like.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.entity;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | /**
8 | * @author: zhk
9 | * @description:
10 | * @date: 2023/4/5 11:12
11 | * @version: 1.0
12 | */
13 | @Data
14 | @AllArgsConstructor
15 | @NoArgsConstructor
16 | public class Like {
17 | private int likeId;
18 | private int articleId;
19 | private String userId;
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/entity/Message.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.entity;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | /**
8 | * @author: zhk
9 | * @description: 消息实体
10 | * @date: 2023/3/1 16:02
11 | * @version: 1.0
12 | */
13 | @Data
14 | @AllArgsConstructor
15 | @NoArgsConstructor
16 | public class Message {
17 |
18 | /**
19 | * id
20 | */
21 | int messageId;
22 |
23 | /**
24 | * 发送方id
25 | */
26 | String fromId;
27 |
28 | /**
29 | * 接收方
30 | */
31 | String toId;
32 |
33 | /**
34 | * 消息内容
35 | */
36 | String messageContent;
37 |
38 | /**
39 | * 0表示未读、1表示已读
40 | */
41 | int hasRead;
42 |
43 | /**
44 | * 点对点对话id
45 | */
46 | String conversationId;
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/entity/Notice.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.entity;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | import java.util.Date;
8 |
9 | /**
10 | * @author: zhk
11 | * @description: 通知实体
12 | * @date: 2023/3/1 16:02
13 | * @version: 1.0
14 | */
15 | @Data
16 | @AllArgsConstructor
17 | @NoArgsConstructor
18 | public class Notice {
19 |
20 | /**
21 | * 通知id
22 | */
23 | private int id;
24 |
25 | /**
26 | * 发送方ID
27 | */
28 | private String fromId;
29 |
30 | /**
31 | * 接收方ID
32 | */
33 | private String toId;
34 |
35 | /**
36 | * 内容
37 | */
38 | private String content;
39 |
40 | /**
41 | * 创建时间
42 | */
43 | private Date createdDate;
44 |
45 | /**
46 | * 1 已读 0 未读
47 | */
48 | private int hasRead;
49 |
50 | /**
51 | * 这次对话的ID
52 | */
53 | private String conversationId;
54 | }
55 |
56 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/entity/User.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.entity;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | import java.util.Date;
8 |
9 | /**
10 | * @author: zhk
11 | * @description: 用户实体
12 | * @date: 2023/3/1 16:02
13 | * @version: 1.0
14 | */
15 | @Data
16 | @AllArgsConstructor
17 | @NoArgsConstructor
18 | public class User {
19 |
20 | /**
21 | * 这里可以看做是手机号
22 | */
23 | private String userId;
24 |
25 | /**
26 | * 昵称
27 | */
28 | private String nickname;
29 |
30 | /**
31 | * 密码
32 | */
33 | private String password;
34 |
35 | /**
36 | * 加密密码
37 | */
38 | private String salt;
39 |
40 | /**
41 | * 头像
42 | */
43 | private String avatar;
44 |
45 | /**
46 | * 成就值
47 | */
48 | private int achieveValue;
49 |
50 | /**
51 | * 学校
52 | */
53 | private String school;
54 |
55 | /**
56 | * 登录ip地址
57 | */
58 | private String loginIp;
59 |
60 | /**
61 | * 登录时间
62 | */
63 | private Date createTime;
64 |
65 | /**
66 | * 登录类型
67 | */
68 | private String loginType;
69 |
70 | /**
71 | * 添加性别属性 1表示male,0表示female
72 | */
73 | private int sex;
74 |
75 | /**
76 | * 添加个性签名的属性
77 | */
78 | private String signature;
79 | }
80 |
81 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/entity/VideoCategory.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.entity;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | /**
8 | * @author: zhk
9 | * @description:
10 | * @date: 2023/3/21 17:08
11 | * @version: 1.0
12 | */
13 | @Data
14 | @AllArgsConstructor
15 | @NoArgsConstructor
16 | public class VideoCategory {
17 | private int tid;
18 | private String name;
19 | private String profile;
20 | private String parentId;
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/mapper/ArticleMapper.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.mapper;
2 |
3 | import com.example.wendao.entity.Article;
4 | import com.example.wendao.vo.ArticleUserVo;
5 | import org.apache.ibatis.annotations.Param;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * @author: zhk
11 | * @description:
12 | * @date: 2023/3/3 9:28
13 | * @version: 1.0
14 | */
15 | public interface ArticleMapper {
16 | /**
17 | * 新增文章
18 | *
19 | * @param article
20 | */
21 | void insertArticle(Article article);
22 |
23 | /**
24 | * 更新文章
25 | * 可以根据需要,只更新部分字段 注意这里的写法,
26 | * test里面的单引号双引号使用不当会报错
27 | *
28 | * @param article
29 | */
30 | void updateArticle(Article article);
31 |
32 | /**
33 | * 逻辑删除文章 0:未删除 1:删除
34 | *
35 | * @param articleId
36 | */
37 | void deleteArticle(int articleId);
38 |
39 | /**
40 | * 根据id查询文章
41 | *
42 | * @param articleId
43 | * @return
44 | */
45 | Article selectArticleByArticleId(int articleId);
46 |
47 | /**
48 | * 根据不同的分类id来查找对应的文章,默认按照发表文章的更新时间来进行排序
49 | * 并保证初始的时候,创建时间和更新时间必须相同
50 | *
51 | * @param categoryId
52 | * @return
53 | */
54 | List selectArticleByCategoryId(int categoryId);
55 |
56 | /**
57 | * 根据点赞数量进行排序,如果点赞数相同的话,然后在按照更新时间进行排序
58 | *
59 | * @return
60 | */
61 | List selectArticleByLikeCount();
62 |
63 | /**
64 | * 根据评论数量进行排序,如果点赞数相同的话,然后在按照更新时间进行排序
65 | *
66 | * @return
67 | */
68 | List selectArticleByCommentCount();
69 |
70 | /**
71 | * 根据浏览数量进行排序,如果点赞数相同的话,然后在按照更新时间进行排序
72 | *
73 | * @return
74 | */
75 | List selectArticleByViewCount();
76 |
77 | /**
78 | * 根据学校的不同,来展示不同的文章效果,这块效果未实现
79 | *
80 | * @param schoolName
81 | * @param categoryId
82 | * @return
83 | */
84 | List selectArticleBySchool(String schoolName, int categoryId);
85 |
86 | /**
87 | * 根据关键字查询文章
88 | *
89 | * @param keyword
90 | * @return
91 | */
92 | List selectArticleByKeyword(String keyword);
93 |
94 | /**
95 | * 根据文章id查询作者
96 | *
97 | * @param articleId
98 | * @return
99 | */
100 | Article selectArticleByUserId(int articleId);
101 |
102 | /**
103 | * 查询所有文章
104 | *
105 | * @return
106 | */
107 | List selectAllArticle();
108 |
109 | /**
110 | * 根据所有用户查询所有文章
111 | *
112 | * @param pageNum
113 | * @param pageSize
114 | * @return
115 | */
116 | List selectAllArticleIndexViewData(@Param("pageNum") int pageNum,
117 | @Param("pageSize") int pageSize);
118 |
119 | /**
120 | * 根据目录查询所有文章
121 | *
122 | * @param categoryId
123 | * @return
124 | */
125 | List selectAllArtilceCategoryData(int categoryId,
126 | @Param("pageNum") int pageNum,
127 | @Param("pageSize") int pageSize);
128 |
129 | /**
130 | * 查询文章详情
131 | *
132 | * @param articleId
133 | * @return
134 | */
135 | ArticleUserVo selectAllArticleDetail(int articleId);
136 |
137 | /**
138 | * 查询目录下的文章
139 | * @param pageNum
140 | * @param pageSize
141 | * @param categoryId
142 | * @return
143 | */
144 | List selectArticleListByCategoryId(@Param("pageNum") int pageNum, @Param("pageSize") int pageSize, int categoryId);
145 |
146 | /**
147 | * 查询用户发表的文章
148 | * @param pageNum
149 | * @param pageSize
150 | * @param userId
151 | * @return
152 | */
153 | List selectArticleListByUserId(@Param("pageNum") int pageNum, @Param("pageSize") int pageSize, String userId);
154 |
155 | /**
156 | * 查询所有文章
157 | * @param pageNum
158 | * @param pageSize
159 | * @param userId
160 | * @return
161 | */
162 | List selectArticleList( @Param("pageNum") int pageNum, @Param("pageSize") int pageSize, String userId);
163 |
164 | /**
165 | * 查询文章详情
166 | * @param articleId
167 | * @param userId
168 | * @return
169 | */
170 | ArticleUserVo getArticleDetail(int articleId, String userId);
171 |
172 | /**
173 | * 点赞数添加
174 | * @param articleId
175 | */
176 | void addLike(int articleId);
177 |
178 | /**
179 | * 点赞数减少
180 | * @param articleId
181 | */
182 | void delLike(int articleId);
183 |
184 | /**
185 | * 浏览数添加
186 | * @param articleId
187 | */
188 | void addView(int articleId);
189 |
190 | /**
191 | * 查询最后一个文章
192 | * @return
193 | */
194 | Article selectArticleLast();
195 | }
196 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/mapper/CategoryMapper.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.mapper;
2 |
3 | import com.example.wendao.entity.Category;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * @author: zhk
9 | * @description: 分类Mapper
10 | * @date: 2023/3/3 10:59
11 | * @version: 1.0
12 | */
13 | public interface CategoryMapper {
14 | /**
15 | * 新增目录
16 | * @param category
17 | */
18 | void insertCategory(Category category);
19 |
20 | /**
21 | * 更新目录
22 | * @param category
23 | */
24 | void updateCategory(Category category);
25 |
26 | /**
27 | * 根据id删除目录
28 | * @param categoryId
29 | */
30 | void deleteCategoryById(int categoryId);
31 |
32 | /**
33 | * 根据id查找目录
34 | * @param categoryId
35 | * @return
36 | */
37 | Category selectCategoryById(int categoryId);
38 |
39 | /**
40 | * 根据目录名查找目录
41 | * @param categoryName
42 | * @return
43 | */
44 | Category selectCategoryByName(String categoryName);
45 |
46 | /**
47 | * 查询所有目录
48 | * @return
49 | */
50 | List selectAllCategory();
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/mapper/CommentMapper.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.mapper;
2 |
3 | import com.example.wendao.entity.Comment;
4 | import com.example.wendao.vo.CommentUserVo;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * @author: zhk
10 | * @description:
11 | * @date: 2023/3/3 11:37
12 | * @version: 1.0
13 | */
14 | public interface CommentMapper {
15 |
16 | /**
17 | * 新增评论
18 | * @param comment
19 | */
20 | void insertComment(Comment comment);
21 |
22 | /**
23 | * 删除评论
24 | * @param commentId
25 | */
26 | void deleteComment(int commentId);
27 |
28 | /**
29 | * 根据id查询评论
30 | * @param commentId
31 | * @return
32 | */
33 | Comment selectCommentById(int commentId);
34 |
35 | /**
36 | * 查询所有评论
37 | * @param commentArticleId
38 | * @return
39 | */
40 | List selectAllComment(int commentArticleId);
41 |
42 | /**
43 | * 查询最后插入的评论
44 | * @return
45 | */
46 | int selectLastInsertCommentId();
47 |
48 |
49 | /**
50 | * 查询文章下的评论列表
51 | * @param commentArticleId
52 | * @return
53 | */
54 | List selectCommentLists(int commentArticleId);
55 |
56 | /**
57 | * 更新评论数
58 | * @param commentId
59 | * @param commentCount
60 | */
61 | void updateCommentCount(int commentId, int commentCount);
62 |
63 | /**
64 | * 查询根评论
65 | * @param commentArticleId
66 | * @param parentId
67 | * @return
68 | */
69 | List selectParentComment(int commentArticleId, int parentId);
70 |
71 | /**
72 | * 添加点赞数
73 | * @param comment
74 | */
75 | void updateCommentLike(int comment);
76 | }
77 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/mapper/ElasticSearchMapper.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.mapper;
2 |
3 | import com.example.wendao.entity.Article;
4 | import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
5 |
6 | /**
7 | * @author: zhk
8 | * @description:
9 | * @date: 2023/3/3 11:10
10 | * @version: 1.0
11 | */
12 | public interface ElasticSearchMapper extends ElasticsearchRepository {
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/mapper/FansMapper.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.mapper;
2 |
3 | import com.example.wendao.entity.Fans;
4 |
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * @author: zhk
10 | * @description:
11 | * @date: 2023/3/3 14:25
12 | * @version: 1.0
13 | */
14 | public interface FansMapper {
15 | /**
16 | * 新增粉丝
17 | * @param fans
18 | */
19 | void insertFans(Fans fans);
20 |
21 | /**
22 | * 删除粉丝
23 | * @param userId
24 | * @param fansId
25 | */
26 | void deleteFans(String userId, String fansId);
27 |
28 | /**
29 | * 展示用户的所有粉丝
30 | * @param userId
31 | * @return
32 | */
33 | List selectAllFansByUserId(String userId);
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/mapper/FollowMapper.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.mapper;
2 |
3 | import com.example.wendao.entity.Follow;
4 |
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * @author: zhk
10 | * @description:
11 | * @date: 2023/3/3 14:32
12 | * @version: 1.0
13 | */
14 | public interface FollowMapper {
15 |
16 | /**
17 | * 关注用户
18 | * @param follow
19 | */
20 | void insertFollow(Follow follow);
21 |
22 | /**
23 | * 取消关注
24 | * @param userId
25 | * @param followId
26 | */
27 | void deleteFollow(String userId, String followId);
28 |
29 | /**
30 | * 所有关注
31 | * @param userId
32 | * @return
33 | */
34 | List selectAllFollowByUserId(String userId);
35 |
36 | /**
37 | * 关注的粉丝
38 | * @param followId
39 | * @return
40 | */
41 | List selectAllFollowByFollowId(String followId);
42 |
43 | /**
44 | * 查询是否关注该用户
45 | * @param userId
46 | * @param followId
47 | * @return
48 | */
49 | Follow isFollow(String userId, String followId);
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/mapper/LikeMapper.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.mapper;
2 |
3 | import com.example.wendao.entity.Like;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * @author: zhk
9 | * @description:
10 | * @date: 2023/4/5 11:13
11 | * @version: 1.0
12 | */
13 | public interface LikeMapper {
14 |
15 | /**
16 | * 添加
17 | * @param like
18 | */
19 | void addLike(Like like);
20 |
21 | /**
22 | * 删除
23 | * @param userId
24 | * @param articleId
25 | */
26 | void deleteLikeById(int articleId, String userId);
27 |
28 | /**
29 | * 获取所有点赞列表
30 | * @return
31 | */
32 | List getAllLikes();
33 |
34 | /**
35 | * 更新
36 | * @param like
37 | */
38 | void updateLike(Like like);
39 |
40 | /**
41 | * 获取该用户的点赞列表
42 | * @param userId
43 | * @return
44 | */
45 | List getLikesByUserId(int userId);
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/mapper/NoticeMapper.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.mapper;
2 |
3 | import com.example.wendao.entity.Notice;
4 |
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * @author: zhk
10 | * @description:
11 | * @date: 2023/3/3 14:52
12 | * @version: 1.0
13 | */
14 | public interface NoticeMapper {
15 |
16 | /**
17 | * 新增通知
18 | * @param notice
19 | */
20 | void insertNotice(Notice notice);
21 |
22 | /**
23 | * 选择所有通知
24 | * @return
25 | */
26 | Notice selectAllNotice();
27 |
28 | /**
29 | * 更新所有已读通知
30 | * 是否已读,1表示已读,0表示未读
31 | * @param userId
32 | */
33 | void updateAllNoticeHasRead(String userId);
34 |
35 | /**
36 | * 已读通知数 是否已读,1表示已读,0表示未读
37 | * @param userId
38 | * @return
39 | */
40 | int countNoticeHasRead(String userId);
41 |
42 | /**
43 | * 查询通知列表
44 | * @param userId
45 | * @return
46 | */
47 | List noticeList(String userId);
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/mapper/UserMapper.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.mapper;
2 |
3 | import com.example.wendao.entity.User;
4 | import com.example.wendao.vo.UserData;
5 | import com.example.wendao.vo.UserInfoVo;
6 |
7 | import java.util.List;
8 |
9 | /**
10 | * @author: zhk
11 | * @description:
12 | * @date: 2023/3/1 16:35
13 | * @version: 1.0
14 | */
15 | public interface UserMapper {
16 |
17 | /**
18 | * 添加用户
19 | * @param user
20 | */
21 | void insertUser(User user);
22 |
23 | /**
24 | * 通过id查找用户
25 | * @param userId
26 | * @return
27 | */
28 | User selectByUserId(String userId);
29 |
30 | /**
31 | * 根据id查询userinfo
32 | * @param userId
33 | * @return
34 | */
35 | UserInfoVo selectByUserInfoId(String userId);
36 | /**
37 | * 更新用户信息
38 | *
39 | * @param user
40 | * @return
41 | */
42 | void updateByUserId(User user);
43 |
44 | /**
45 | * 重置成就值
46 | */
47 | void resetAchieveValue();
48 |
49 | /**
50 | * 查询成就值排行前十
51 | * @return
52 | */
53 | List top10LeaderBoard();
54 |
55 | /**
56 | * 查询用户所有信息
57 | * @param userId
58 | * @return
59 | */
60 | User selectByUserIdAll(String userId);
61 |
62 | /**
63 | * 查询用户粉丝、点赞、关注数
64 | * @param userId
65 | * @return
66 | */
67 | UserData getUserData(String userId);
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/mapper/VideoMapper.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.mapper;
2 |
3 | import com.example.wendao.entity.VideoCategory;
4 | import org.apache.ibatis.annotations.Param;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * @author: zhk
10 | * @description:
11 | * @date: 2023/3/21 17:13
12 | * @version: 1.0
13 | */
14 | public interface VideoMapper {
15 | /**
16 | * 分页获取视频目录
17 | * @param pageNum
18 | * @param pageSize
19 | * @return
20 | */
21 | List selectCategoryList(@Param("pageNum") int pageNum, @Param("pageSize") int pageSize);
22 |
23 | /**
24 | * 获取主分区
25 | * @return
26 | */
27 | List selectCategoryMainList();
28 |
29 | /**
30 | * 根据父id查询子id
31 | * @param parentId
32 | * @return
33 | */
34 | List selectCategoryChild(@Param("parentId") int parentId);
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/redis/BasePrefix.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.redis;
2 |
3 | /**
4 | * @author: zhk
5 | * @description: 过期秒数默认0,前缀为类名
6 | * @date: 2023/3/2 10:15
7 | * @version: 1.0
8 | */
9 | public abstract class BasePrefix implements KeyPrefix {
10 | private int expireSeconds;
11 |
12 | private String prefix;
13 |
14 | public BasePrefix(String prefix) {
15 | this(0, prefix);
16 | }
17 |
18 | public BasePrefix(int expireSeconds, String prefix) {
19 | this.expireSeconds = expireSeconds;
20 | this.prefix = prefix;
21 | }
22 |
23 | @Override
24 | public int expireSeconds() {
25 | return expireSeconds;
26 | }
27 |
28 | @Override
29 | public String getPrefix() {
30 | // 获取该类的名字
31 | String className = getClass().getSimpleName();
32 | return className + ":" + prefix;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/redis/CommonKey.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.redis;
2 |
3 | /**
4 | * @author: zhk
5 | * @description: 评论key
6 | * @date: 2023/3/2 10:17
7 | * @version: 1.0
8 | */
9 | public class CommonKey{
10 | public static final String EVENT_LIKE_QUEUE = "EVENT_LIKE_QUEUE";
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/redis/FansKey.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.redis;
2 |
3 | /**
4 | * @author: zhk
5 | * @description: 粉丝key 直接调用BasePrefix
6 | * @date: 2023/3/2 10:18
7 | * @version: 1.0
8 | */
9 | public class FansKey extends BasePrefix{
10 | public FansKey(String prefix) {
11 | super(prefix);
12 | }
13 |
14 | public FansKey(int expireSeconds, String prefix) {
15 | super(expireSeconds, prefix);
16 | }
17 |
18 | public static FansKey fansKey = new FansKey("myFans");
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/redis/FollowKey.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.redis;
2 |
3 | /**
4 | * @author: zhk
5 | * @description: 关注key
6 | * @date: 2023/3/2 10:20
7 | * @version: 1.0
8 | */
9 | public class FollowKey extends BasePrefix{
10 | public FollowKey(String prefix) {
11 | super(prefix);
12 | }
13 |
14 | public FollowKey(int expireSeconds, String prefix) {
15 | super(expireSeconds, prefix);
16 | }
17 |
18 | /**
19 | * 我的关注
20 | */
21 | public static FollowKey followKey = new FollowKey("myFollow");
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/redis/KeyPrefix.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.redis;
2 |
3 | /**
4 | * @author: zhk
5 | * @description: BasePrefix抽象类实现该接口,并且有多个子类继承BasePrefix
6 | * @date: 2023/3/2 10:12
7 | * @version: 1.0
8 | */
9 | public interface KeyPrefix {
10 | /**
11 | * 过期时间
12 | * @return
13 | */
14 | int expireSeconds();
15 |
16 | /**
17 | * 获取前缀
18 | * @return
19 | */
20 | String getPrefix();
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/redis/LikeKey.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.redis;
2 |
3 | /**
4 | * @author: zhk
5 | * @description:
6 | * @date: 2023/3/2 10:37
7 | * @version: 1.0
8 | */
9 | public class LikeKey extends BasePrefix{
10 | public LikeKey(String prefix) {
11 | super(prefix);
12 | }
13 |
14 | public LikeKey(int expireSeconds, String prefix) {
15 | super(expireSeconds, prefix);
16 | }
17 |
18 | /**
19 | * 在这里的话,其实应该可以理解为这个key,他是作为一个消息队列来发送消息
20 | */
21 | public static LikeKey LIKE_ASYNC_KEY = new LikeKey("likeAsync");
22 |
23 | public static LikeKey LIKE_KEY = new LikeKey("like");
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/redis/UserTokenKey.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.redis;
2 |
3 | /**
4 | * @author: zhk
5 | * @description:
6 | * @date: 2023/3/2 10:38
7 | * @version: 1.0
8 | */
9 | public class UserTokenKey extends BasePrefix{
10 | /**
11 | * 设置token的有效期为60天
12 | */
13 | public static final int TOKEN_EXPIRE = 3600 * 24 * 60;
14 |
15 | public UserTokenKey(String prefix) {
16 | super(prefix);
17 | }
18 |
19 | public UserTokenKey(int expireSeconds, String prefix) {
20 | super(expireSeconds, prefix);
21 | }
22 |
23 | public static UserTokenKey userTokenKey = new UserTokenKey(TOKEN_EXPIRE, "tk");
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/redis/VerifyCodeKey.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.redis;
2 |
3 | /**
4 | * @author: zhk
5 | * @description:
6 | * @date: 2023/3/2 10:38
7 | * @version: 1.0
8 | */
9 | public class VerifyCodeKey extends BasePrefix{
10 | public VerifyCodeKey(String prefix) {
11 | super(prefix);
12 | }
13 |
14 | public VerifyCodeKey(int expireSeconds, String prefix) {
15 | super(expireSeconds, prefix);
16 | }
17 |
18 | public static VerifyCodeKey verifyCodeKeyRegister = new VerifyCodeKey(180, "register");
19 | public static VerifyCodeKey verifyCodeKeyLogin = new VerifyCodeKey(180, "login");
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/service/ArticleService.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.service;
2 |
3 | import com.example.wendao.entity.Article;
4 | import com.example.wendao.vo.ArticleUserVo;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * @author: zhk
10 | * @description:
11 | * @date: 2023/3/3 11:05
12 | * @version: 1.0
13 | */
14 | public interface ArticleService {
15 | /**
16 | * 新增
17 | * @param article
18 | */
19 | void insertArticle(Article article);
20 |
21 | /**
22 | * 更新
23 | * @param article
24 | */
25 | void updateArticle(Article article);
26 |
27 | /**
28 | * 查询
29 | * @param articleId
30 | */
31 | void deleteArticle(int articleId);
32 |
33 | /**
34 | * 根据id查询
35 | * @param articleId
36 | * @return
37 | */
38 | Article selectArticleByArticleId(int articleId);
39 |
40 | /**
41 | * 查询目录下面的所有
42 | * @param categoryId
43 | * @return
44 | */
45 | List selectArticleByCategoryId(int categoryId);
46 |
47 | /**
48 | * 根据点赞数排序
49 | * @return
50 | */
51 | List selectArticleByLikeCount();
52 |
53 | /**
54 | * 根据评论数排序
55 | * @return
56 | */
57 | List selectArticleByCommentCount();
58 |
59 | /**
60 | * 根据浏览数排序
61 | * @return
62 | */
63 | List selectArticleByViewCount();
64 |
65 | /**
66 | * 根据学校不同进行推荐 未实现
67 | * @param schoolName
68 | * @param categoryId
69 | * @return
70 | */
71 | List selectArticleBySchool(String schoolName, int categoryId);
72 |
73 | /**
74 | * 根据关键字进行查询文章
75 | * @param keyword
76 | * @return
77 | */
78 | List selectArticleByKeyword(String keyword);
79 |
80 | /**
81 | * 查找文章作者
82 | * @param articleId
83 | * @return
84 | */
85 | Article selectArticleByUserId(int articleId);
86 |
87 | /**
88 | * 所有文章
89 | * @return
90 | */
91 | List selectAllArtilce();
92 |
93 | /**
94 | * 从es中获取所有文章
95 | * @return
96 | */
97 | List selectAllArticleByES();
98 |
99 | /**
100 | * 查询所有用户发布的文章
101 | * @param pageNum
102 | * @param pageSize
103 | * @return
104 | */
105 | List selectAllArticleIndexViewData(Integer pageNum, Integer pageSize);
106 |
107 | /**
108 | * 查询所有目录下的文章
109 | * @param categoryId
110 | * @return
111 | */
112 | List selectAllArticleCategoryData(Integer categoryId, Integer pageNum, Integer pageSize);
113 |
114 | /**
115 | * 查询文章详情
116 | * @param articleId
117 | * @return
118 | */
119 | ArticleUserVo selectAllArticleDetail(int articleId);
120 |
121 | /**
122 | * 根据关键字查询文章
123 | * @param keywords
124 | * @return
125 | */
126 | List selectArticleByKeywords(String keywords);
127 |
128 |
129 | /**
130 | * 获取首页推荐文章
131 | * @param userId
132 | * @param pageNum
133 | * @param pageSize
134 | * @return
135 | */
136 | List selectArticleList(String userId, int pageNum, int pageSize);
137 |
138 | /**
139 | * 获取用户发布的文章
140 | * @param pageNum
141 | * @param pageSize
142 | * @param userId
143 | * @return
144 | */
145 | List selectArticleListByUserId(int pageNum, int pageSize, String userId);
146 |
147 | /**
148 | * 获取目录下的id
149 | * @param pageNum
150 | * @param pageSize
151 | * @param category
152 | * @return
153 | */
154 | List selectArticleListByCategoryId(int pageNum, int pageSize, int category);
155 |
156 | /**
157 | * 获取文章详情
158 | * @param articleId
159 | * @param userId
160 | * @return
161 | */
162 | ArticleUserVo getArticleDetail(int articleId ,String userId);
163 |
164 | /**
165 | * 增加点赞数
166 | * @param articleId
167 | */
168 | void addLike(int articleId);
169 |
170 | /**
171 | * 删除点赞数
172 | * @param articleId
173 | */
174 | void delLike(int articleId);
175 |
176 | /**
177 | * 查询最后一个文章
178 | * @return
179 | */
180 | Article selectArticleLast();
181 | }
182 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/service/CategoryService.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.service;
2 |
3 | import com.example.wendao.entity.Category;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * @author: zhk
9 | * @description: 目录service
10 | * @date: 2023/3/3 11:12
11 | * @version: 1.0
12 | */
13 |
14 | public interface CategoryService {
15 | /**
16 | * 新增
17 | * @param category
18 | */
19 | void insertCategory(Category category);
20 |
21 | /**
22 | * 更新
23 | * @param category
24 | */
25 | void updateCategory(Category category);
26 |
27 | /**
28 | * 根据id删除
29 | * @param categoryId
30 | */
31 | void deleteCategoryById(int categoryId);
32 |
33 | /**
34 | * 根据id查询
35 | * @param categoryId
36 | * @return
37 | */
38 | Category selectCategoryById(int categoryId);
39 |
40 | /**
41 | * 根据名字查询
42 | * @param categoryName
43 | * @return
44 | */
45 | Category selectCategoryByName(String categoryName);
46 |
47 | /**
48 | * 查询所有
49 | * @return
50 | */
51 | List selectAllCategory();
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/service/CommentService.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.service;
2 |
3 | import com.example.wendao.entity.Comment;
4 | import com.example.wendao.vo.CommentUserVo;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * @author: zhk
10 | * @description:
11 | * @date: 2023/3/3 11:47
12 | * @version: 1.0
13 | */
14 | public interface CommentService {
15 |
16 | /**
17 | * 新增
18 | * @param comment
19 | */
20 | void insertComment(Comment comment);
21 |
22 | /**
23 | * 删除
24 | * @param commentId
25 | */
26 | void deleteComment(int commentId);
27 |
28 | /**
29 | * 根据id查询评论
30 | * @param commentId
31 | * @return
32 | */
33 | Comment selectCommentById(int commentId);
34 |
35 | /**
36 | * 查询所有评论
37 | * @param commentArticleId
38 | * @return
39 | */
40 | List selectAllComment(int commentArticleId);
41 |
42 | /**
43 | * 获取最后一条评论
44 | * @return
45 | */
46 | int selectLastInsertCommentId();
47 |
48 | /**
49 | * 查询评论的回复
50 | * @param articleCommentId
51 | * @return
52 | */
53 | List selectCommentLists(int articleCommentId);
54 |
55 | /**
56 | * 增加子评论数
57 | * @param commentId
58 | */
59 | void updateCommentCount(int commentId);
60 |
61 | /**
62 | * 点赞评论
63 | * @param commentId
64 | */
65 | void commentLike(int commentId);
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/service/ElasticSearchService.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.service;
2 |
3 | import com.example.wendao.entity.Article;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * @author: zhk
9 | * @description: es的crud
10 | * @date: 2023/3/7 9:58
11 | * @version: 1.0
12 | */
13 | public interface ElasticSearchService {
14 | /**
15 | * 搜索文章
16 | * @param keywords
17 | * @return
18 | */
19 | List searchArticle(String keywords);
20 |
21 | /**
22 | * 保存文章
23 | * @param article
24 | */
25 | void saveArticle(Article article);
26 |
27 | /**
28 | * 删除文章
29 | * @param articleId
30 | */
31 | void deleteArticle(String articleId);
32 |
33 | /**
34 | * 更新文章
35 | * @param article
36 | */
37 | void updateArticle(Article article);
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/service/FansService.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.service;
2 |
3 | import com.example.wendao.entity.Fans;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * @author: zhk
9 | * @description:
10 | * @date: 2023/3/3 14:29
11 | * @version: 1.0
12 | */
13 | public interface FansService {
14 |
15 | void insertFans(Fans fans);
16 |
17 | void deleteFans(String userId, String followId);
18 |
19 | List selectAllFansByUserId(String userId);
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/service/FollowService.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.service;
2 |
3 | import com.example.wendao.entity.Follow;
4 | import com.example.wendao.entity.User;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * @author: zhk
10 | * @description:
11 | * @date: 2023/3/3 14:39
12 | * @version: 1.0
13 | */
14 | public interface FollowService {
15 | /**
16 | * 新增关注
17 | * @param follow
18 | */
19 | void insertFollow(Follow follow);
20 |
21 | /**
22 | * 取消关注
23 | * @param userId
24 | * @param followId
25 | */
26 | void deleteFollow(String userId, String followId);
27 |
28 | /**
29 | * 查询当前用户的所有关注
30 | * @param userId
31 | * @return
32 | */
33 | List selectAllFollowByUserId(String userId);
34 |
35 | /**
36 | * 查询全部关注者关注 ID
37 | * @param followId
38 | * @return
39 | */
40 | List selectAllFollowByFollowId(String followId);
41 |
42 | /**
43 | * 查询是否关注该用户
44 | * @param userId
45 | * @param followId
46 | * @return
47 | */
48 | Follow isFollow(String userId, String followId);
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/service/LikeService.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.service;
2 |
3 | import java.util.Set;
4 |
5 | /**
6 | * @author: zhk
7 | * @description:
8 | * @date: 2023/3/3 14:40
9 | * @version: 1.0
10 | */
11 | public interface LikeService {
12 | /**
13 | * 将点赞的人添加进set集合,返回当前的点赞数
14 | *
15 | * @param articleId
16 | * @param value
17 | * @return
18 | */
19 | long like(String articleId, String value);
20 |
21 | /**
22 | * 将点赞的人从set集合中删除,返回当前的点赞数
23 | *
24 | * @param articleId
25 | * @param value
26 | * @return
27 | */
28 | long dislike(int articleId, String value);
29 |
30 | /**
31 | * 返回当前的点赞数
32 | *
33 | * @param key
34 | * @return
35 | */
36 | long likeCount(String key);
37 |
38 | Set likeCountUserId(String key);
39 |
40 | void transLikedCountFromRedis2DB();
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/service/NoticeService.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.service;
2 |
3 | import com.example.wendao.entity.Notice;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * @author: zhk
9 | * @description:
10 | * @date: 2023/3/3 14:59
11 | * @version: 1.0
12 | */
13 | public interface NoticeService {
14 | /**
15 | * 新增通知
16 | * @param notice
17 | */
18 | void insertNotice(Notice notice);
19 |
20 | /**
21 | * 查询通知
22 | * @return
23 | */
24 | Notice selectNotice();
25 |
26 | /**
27 | * 更新所有通知已读
28 | * @param userId
29 | */
30 | void updateAllNoticeHasRead(String userId);
31 |
32 | /**
33 | * 已读通知数
34 | * @param userId
35 | * @return
36 | */
37 | int countNoticeHasRead(String userId);
38 |
39 | /**
40 | * 通知列表
41 | * @param userId
42 | * @return
43 | */
44 | List noticeList(String userId);
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/service/RegisterService.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.service;
2 |
3 | /**
4 | * @author: zhk
5 | * @description:
6 | * @date: 2023/3/18 15:40
7 | * @version: 1.0
8 | */
9 | public interface RegisterService {
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/service/UserService.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.service;
2 |
3 | import com.example.wendao.entity.User;
4 | import com.example.wendao.vo.UserData;
5 | import com.example.wendao.vo.UserInfoVo;
6 | import org.springframework.web.multipart.MultipartFile;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * @author: zhk
12 | * @description:
13 | * @date: 2023/3/1 21:07
14 | * @version: 1.0
15 | */
16 | public interface UserService {
17 | /**
18 | * 添加用户
19 | * @param user
20 | */
21 | void insert(User user);
22 |
23 | /**
24 | * 通过id获取全部用户信息
25 | * @param userId
26 | * @return
27 | */
28 | User selectByUserId(String userId);
29 |
30 | /**
31 | * 查询用户部分信息
32 | * @param userId
33 | * @return
34 | */
35 | UserInfoVo selectByUserInfoId(String userId);
36 |
37 | /**
38 | * 更新用户信息
39 | * @param user
40 | */
41 | void updateByUserId(User user);
42 |
43 | /**
44 | * 重置成就值
45 | */
46 | void resetAchieveValue();
47 |
48 | /**
49 | * 查询成就值前十的用户
50 | * @return
51 | */
52 | List top10LeaderBoard();
53 |
54 | /**
55 | * 腾讯云对象存储上传图片
56 | * @param multipartFile
57 | * @return
58 | */
59 | String uploadImages(MultipartFile multipartFile);
60 |
61 | /**
62 | * 查询用户所有信息
63 | * @param userId
64 | * @return
65 | */
66 | User selectByUserIdAll(String userId);
67 |
68 | /**
69 | * 获取粉丝、点赞、关注数
70 | * @param userId
71 | * @return
72 | */
73 | UserData getUserData(String userId);
74 | }
75 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/service/VideoService.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.service;
2 |
3 | import com.alibaba.fastjson.JSONArray;
4 | import com.alibaba.fastjson.JSONObject;
5 | import com.example.wendao.dto.VideoActionDto;
6 | import com.example.wendao.entity.VideoCategory;
7 | import org.springframework.web.bind.annotation.RequestParam;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * @author: zhk
13 | * @description:
14 | * @date: 2023/3/21 17:11
15 | * @version: 1.0
16 | */
17 | public interface VideoService {
18 | /**
19 | * 目录列表
20 | *
21 | * @param pageNum
22 | * @param pageSize
23 | * @return
24 | */
25 | List categoryList(int pageNum, int pageSize);
26 |
27 | /**
28 | * 获取主分区
29 | * @return
30 | */
31 | List categoryMainList();
32 |
33 | /**
34 | * 获取子分区
35 | * @param parentId
36 | * @return
37 | */
38 | List categoryChildList(int parentId);
39 |
40 | /**
41 | * 获取分类下的视频推荐
42 | *
43 | * @param pageNum
44 | * @param pageSize
45 | * @param tid
46 | * @return
47 | */
48 | JSONObject categoryFeedList(int pageNum, int pageSize, int tid);
49 |
50 | /**
51 | * 获取热门推荐
52 | * @param pageNum
53 | * @param pageSize
54 | * @return
55 | */
56 | JSONObject popular(int pageNum, int pageSize);
57 |
58 | /**
59 | * 获取视频播放信息
60 | *
61 | * @param videoActionDto
62 | * @return
63 | */
64 | JSONObject action(VideoActionDto videoActionDto);
65 |
66 | /**
67 | * 获取某个视频下面的推荐视频
68 | *
69 | * @param aid
70 | * @return
71 | */
72 | JSONArray recommend(int aid);
73 |
74 | /**
75 | * 视频信息
76 | * @param aid
77 | * @return
78 | */
79 | JSONObject videoInformation(Integer aid);
80 | }
81 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/service/impl/CategoryServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.service.impl;
2 |
3 | import com.example.wendao.entity.Category;
4 | import com.example.wendao.mapper.CategoryMapper;
5 | import com.example.wendao.service.CategoryService;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.stereotype.Service;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * @author: zhk
13 | * @description:
14 | * @date: 2023/3/3 11:13
15 | * @version: 1.0
16 | */
17 | @Service
18 | public class CategoryServiceImpl implements CategoryService {
19 | @Autowired(required = false)
20 | CategoryMapper categoryMapper;
21 |
22 | @Override
23 | public void insertCategory(Category category) {
24 | categoryMapper.insertCategory(category);
25 | }
26 |
27 | @Override
28 | public void updateCategory(Category category) {
29 | categoryMapper.updateCategory(category);
30 | }
31 |
32 | @Override
33 | public void deleteCategoryById(int categoryId) {
34 | categoryMapper.deleteCategoryById(categoryId);
35 | }
36 |
37 | @Override
38 | public Category selectCategoryById(int categoryId) {
39 | return categoryMapper.selectCategoryById(categoryId);
40 | }
41 |
42 | @Override
43 | public Category selectCategoryByName(String categoryName) {
44 | return categoryMapper.selectCategoryByName(categoryName);
45 | }
46 |
47 | @Override
48 | public List selectAllCategory() {
49 | return categoryMapper.selectAllCategory();
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/service/impl/CommentServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.service.impl;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.example.wendao.entity.Comment;
5 | import com.example.wendao.mapper.CommentMapper;
6 | import com.example.wendao.service.CommentService;
7 | import com.example.wendao.vo.CommentUserVo;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.stereotype.Service;
10 |
11 | import java.util.Date;
12 | import java.util.LinkedList;
13 | import java.util.List;
14 |
15 | /**
16 | * @author: zhk
17 | * @description:
18 | * @date: 2023/3/3 11:48
19 | * @version: 1.0
20 | */
21 | @Service
22 | public class CommentServiceImpl implements CommentService {
23 | @Autowired(required = false)
24 | CommentMapper commentMapper;
25 |
26 | @Override
27 | public void insertComment(Comment comment) {
28 | commentMapper.insertComment(comment);
29 | }
30 |
31 | @Override
32 | public void deleteComment(int commentId) {
33 | commentMapper.deleteComment(commentId);
34 | }
35 |
36 | @Override
37 | public Comment selectCommentById(int commentId) {
38 | return commentMapper.selectCommentById(commentId);
39 | }
40 |
41 | @Override
42 | public List selectAllComment(int commentArticleId) {
43 | return commentMapper.selectAllComment(commentArticleId);
44 | }
45 |
46 | @Override
47 | public int selectLastInsertCommentId() {
48 | return commentMapper.selectLastInsertCommentId();
49 | }
50 |
51 | @Override
52 | public List selectCommentLists(int commentArticleId) {
53 | if (commentArticleId < 0) {
54 | return null;
55 | }
56 | List raw = commentMapper.selectParentComment(commentArticleId, -1);
57 | return getParent(raw);
58 | }
59 |
60 | /**
61 | * 处理每个根评论
62 | * @param rawComments
63 | * @return
64 | */
65 | private List getParent(List rawComments) {
66 | for (CommentUserVo topComment : rawComments) {
67 | // 将顶级评论的子孙评论归结到一个集合中
68 | LinkedList comments = new LinkedList<>();
69 | List replyCmtsByTopCmt = topComment.getReplyCommentList();
70 | for (CommentUserVo replyComment : replyCmtsByTopCmt) {
71 | handleChild(replyComment, comments, topComment.getNickname(), topComment.getCommentUserId(),
72 | topComment.getCommentContent(), topComment.getCommentLikeCount(), topComment.getCommentCreatedTime());
73 | }
74 | topComment.setReplyCommentList(comments);
75 | }
76 | return rawComments;
77 | }
78 |
79 | /**
80 | * 处理二级评论以及子评论
81 | * @param replyComment
82 | * @param parent
83 | */
84 | private void handleChild(CommentUserVo replyComment, List parent, String replyNickname,
85 | String replyId, String commentContent, int commentLikeCount, Date commentCreatedTime) {
86 | List grandchildren = replyComment.getReplyCommentList();
87 | replyComment.setReplyCommentList(null);
88 | replyComment.setReplyNickname(replyNickname);
89 | replyComment.setReplyId(replyId);
90 | replyComment.setCommentContent(replyComment.getCommentContent() != null ? replyComment.getCommentContent() : commentContent);
91 | replyComment.setCommentLikeCount(replyComment.getCommentLikeCount() > 0 ? replyComment.getCommentLikeCount() : commentLikeCount);
92 | replyComment.setCommentCreatedTime(replyComment.getCommentCreatedTime() != null ? replyComment.getCommentCreatedTime() : commentCreatedTime);
93 | parent.add(replyComment);
94 | if (grandchildren != null) {
95 | for (CommentUserVo grandChild : grandchildren) {
96 | handleChild(grandChild, parent, replyComment.getNickname(), replyComment.getCommentUserId(),
97 | replyComment.getCommentContent(), replyComment.getCommentLikeCount(), replyComment.getCommentCreatedTime());
98 | }
99 | }
100 | }
101 |
102 | @Override
103 | public void updateCommentCount(int commentId) {
104 | Comment comment = commentMapper.selectCommentById(commentId);
105 | commentMapper.updateCommentCount(commentId, comment.getCommentCount() + 1);
106 | }
107 |
108 | @Override
109 | public void commentLike(int commentId) {
110 | commentMapper.updateCommentLike(commentId);
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/service/impl/ElasticSearchServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.service.impl;
2 |
3 | import com.alibaba.druid.sql.builder.UpdateBuilder;
4 | import com.alibaba.fastjson.JSON;
5 | import com.example.wendao.entity.Article;
6 | import com.example.wendao.mapper.ElasticSearchMapper;
7 | import com.example.wendao.service.ElasticSearchService;
8 | import lombok.AllArgsConstructor;
9 | import org.elasticsearch.index.query.QueryBuilders;
10 | import org.elasticsearch.index.reindex.UpdateByQueryRequestBuilder;
11 | import org.slf4j.Logger;
12 | import org.slf4j.LoggerFactory;
13 | import org.springframework.beans.factory.annotation.Autowired;
14 | import org.springframework.data.domain.PageRequest;
15 | import org.springframework.data.domain.Pageable;
16 | import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
17 | import org.springframework.data.elasticsearch.core.SearchHit;
18 | import org.springframework.data.elasticsearch.core.SearchHits;
19 | import org.springframework.data.elasticsearch.core.document.Document;
20 | import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
21 | import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
22 | import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
23 | import org.springframework.data.elasticsearch.core.query.UpdateQuery;
24 | import org.springframework.data.elasticsearch.core.query.UpdateResponse;
25 | import org.springframework.stereotype.Service;
26 |
27 | import java.util.List;
28 | import java.util.Map;
29 | import java.util.stream.Collectors;
30 | import java.util.stream.Stream;
31 |
32 | /**
33 | * @author: zhk
34 | * @description:
35 | * @date: 2023/3/7 10:02
36 | * @version: 1.0
37 | */
38 | @Service
39 | public class ElasticSearchServiceImpl implements ElasticSearchService {
40 | private Logger logger = LoggerFactory.getLogger(ElasticSearchServiceImpl.class);
41 |
42 | @Autowired
43 | ElasticsearchRestTemplate restTemplate;
44 |
45 | @Autowired
46 | ElasticSearchMapper searchMapper;
47 |
48 | @Override
49 | public List searchArticle(String keywords) {
50 | NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
51 | .withQuery(QueryBuilders.boolQuery()
52 | .should(QueryBuilders.matchPhraseQuery("article_title", keywords))
53 | .should(QueryBuilders.matchPhraseQuery("article_summary", keywords))
54 | .should(QueryBuilders.matchPhraseQuery("article_content", keywords))
55 | )
56 | .withPageable(PageRequest.of(0, 9))
57 | .build();
58 | SearchHits search = restTemplate.search(nativeSearchQuery, Article.class);
59 | logger.info("total:{}", search.getTotalHits());
60 | Stream> searchHitStream = search.get();
61 | List articleList = searchHitStream.map(SearchHit::getContent).collect(Collectors.toList());
62 | logger.info("es搜索数量:{}",articleList.size());
63 | articleList.forEach(item->{
64 | logger.info(item.toString());
65 | });
66 | return articleList;
67 | }
68 |
69 | @Override
70 | public void saveArticle(Article article) {
71 | restTemplate.save(article);
72 | }
73 |
74 | @Override
75 | public void deleteArticle(String articleId) {
76 | restTemplate.delete(articleId, Article.class);
77 | }
78 |
79 | @Override
80 | public void updateArticle(Article article) {
81 | Document document = Document.create();
82 | Map map = JSON.parseObject(JSON.toJSONString(article), Map.class);
83 | for(Map.Entry entry : map.entrySet()){
84 | if(entry.getValue()!= null && !"".equals(entry.getValue())){
85 | document.put(entry.getKey(), entry.getValue());
86 | }
87 | }
88 | UpdateQuery updateQuery = UpdateQuery.builder(String.valueOf(article.getArticleId()))
89 | .withDocument(document)
90 | .build();
91 | UpdateResponse response = restTemplate.update(updateQuery, IndexCoordinates.of("wendao"));
92 |
93 | }
94 |
95 |
96 | }
97 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/service/impl/FansServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.service.impl;
2 |
3 | import com.example.wendao.entity.Fans;
4 | import com.example.wendao.mapper.FansMapper;
5 | import com.example.wendao.service.FansService;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.stereotype.Service;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * @author: zhk
13 | * @description:
14 | * @date: 2023/3/3 14:30
15 | * @version: 1.0
16 | */
17 | @Service
18 | public class FansServiceImpl implements FansService {
19 | @Autowired(required = false)
20 | FansMapper fansMapper;
21 |
22 | @Override
23 | public void insertFans(Fans fans) {
24 | fansMapper.insertFans(fans);
25 | }
26 |
27 | @Override
28 | public void deleteFans(String userId, String fansId) {
29 | fansMapper.deleteFans(userId, fansId);
30 | }
31 |
32 | @Override
33 | public List selectAllFansByUserId(String userId) {
34 | return fansMapper.selectAllFansByUserId(userId);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/service/impl/FollowServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.service.impl;
2 |
3 | import com.example.wendao.entity.Follow;
4 | import com.example.wendao.entity.User;
5 | import com.example.wendao.mapper.FollowMapper;
6 | import com.example.wendao.service.FollowService;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.stereotype.Service;
9 |
10 | import java.util.List;
11 |
12 | /**
13 | * @author: zhk
14 | * @description:
15 | * @date: 2023/3/3 14:39
16 | * @version: 1.0
17 | */
18 | @Service
19 | public class FollowServiceImpl implements FollowService {
20 | @Autowired(required = false)
21 | FollowMapper followMapper;
22 |
23 |
24 | @Override
25 | public void insertFollow(Follow follow) {
26 | followMapper.insertFollow(follow);
27 | }
28 |
29 | @Override
30 | public void deleteFollow(String userId, String followId) {
31 | followMapper.deleteFollow(userId, followId);
32 | }
33 |
34 | @Override
35 | public List selectAllFollowByUserId(String userId) {
36 | return followMapper.selectAllFollowByUserId(userId);
37 | }
38 |
39 | @Override
40 | public List selectAllFollowByFollowId(String followId) {
41 | return followMapper.selectAllFollowByFollowId(followId);
42 | }
43 |
44 | @Override
45 | public Follow isFollow(String userId, String followId) {
46 | return followMapper.isFollow(userId, followId);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/service/impl/LikeServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.service.impl;
2 |
3 | import com.example.wendao.entity.Article;
4 | import com.example.wendao.entity.Like;
5 | import com.example.wendao.mapper.LikeMapper;
6 | import com.example.wendao.redis.JedisService;
7 | import com.example.wendao.redis.LikeKey;
8 | import com.example.wendao.service.ArticleService;
9 | import com.example.wendao.service.LikeService;
10 | import org.slf4j.Logger;
11 | import org.slf4j.LoggerFactory;
12 | import org.springframework.beans.factory.annotation.Autowired;
13 | import org.springframework.stereotype.Service;
14 | import org.springframework.util.StopWatch;
15 |
16 | import javax.xml.bind.DataBindingException;
17 | import java.util.Date;
18 | import java.util.List;
19 | import java.util.Set;
20 |
21 | /**
22 | * @author: zhk
23 | * @description:
24 | * @date: 2023/3/3 14:41
25 | * @version: 1.0
26 | */
27 | @Service
28 | public class LikeServiceImpl implements LikeService {
29 | @Autowired
30 | JedisService jedisService;
31 |
32 | @Autowired
33 | ArticleService articleService;
34 |
35 | @Autowired
36 | LikeMapper likeMapper;
37 |
38 | private static final Logger log = LoggerFactory.getLogger(LikeServiceImpl.class);
39 |
40 | @Override
41 | public long like(String articleId, String userId) {// 进入这里说明用户是登录过了,然后把用户的相关信息存储到Redis的Set中
42 | String real = LikeKey.LIKE_KEY.getPrefix() + articleId;
43 | jedisService.sadd(real, userId);
44 | Like like = new Like();
45 | like.setUserId(userId);
46 | like.setArticleId(Integer.parseInt(articleId));
47 | likeMapper.addLike(like);
48 | articleService.addLike(Integer.parseInt(articleId));
49 | return jedisService.scard(real);
50 | }
51 |
52 | @Override
53 | public long dislike(int articleId, String value) {
54 | String key = LikeKey.LIKE_KEY.getPrefix() + articleId;
55 | jedisService.srem(key, value);
56 | likeMapper.deleteLikeById(articleId, value);
57 | articleService.delLike(articleId);
58 | return jedisService.scard(key);
59 | }
60 |
61 | @Override
62 | public long likeCount(String key) {
63 | return jedisService.scard(key);
64 | }
65 |
66 | @Override
67 | public Set likeCountUserId(String key) {
68 | return jedisService.smembers(key);
69 | }
70 |
71 | @Override
72 | public void transLikedCountFromRedis2DB() {
73 | /**
74 | * 从Redis中拿到以"LikeKey:like+articleId为key的key,根据这些key就可以拿到具体的文章Id,就
75 | * 可以有针对性的更新有点赞的文章,优化了以前遍历所有的文章来进行更新。
76 | * 经过分析,下面的代码耗时就比较小了"
77 | */
78 | StopWatch stopWatch = new StopWatch();
79 | stopWatch.start();
80 | List matchLikeKey = jedisService.scan(LikeKey.LIKE_KEY.getPrefix() + "[0-9]*");
81 | for (String s : matchLikeKey) {
82 | // 这里从LikeKey:like是12位数,所以12位开始遍历文章ID
83 | int articleId = Integer.parseInt(s.substring(12));
84 | Article article = articleService.selectArticleByArticleId(articleId);
85 | long likeCount = jedisService.scard(s);
86 | if (article != null) {
87 | article.setArticleLikeCount((int) likeCount);
88 | articleService.updateArticle(article);
89 | }
90 | }
91 | stopWatch.stop();
92 | log.info("{}: 将缓存中的点赞数量落库,耗时{}ms", new Date(), stopWatch.getTotalTimeMillis());
93 |
94 |
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/service/impl/NoticeServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.service.impl;
2 |
3 | import com.example.wendao.entity.Notice;
4 | import com.example.wendao.mapper.NoticeMapper;
5 | import com.example.wendao.service.NoticeService;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.stereotype.Service;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * @author: zhk
13 | * @description:
14 | * @date: 2023/3/3 14:59
15 | * @version: 1.0
16 | */
17 | @Service
18 | public class NoticeServiceImpl implements NoticeService {
19 | @Autowired(required = false)
20 | NoticeMapper noticeMapper;
21 |
22 | @Override
23 | public void insertNotice(Notice notice) {
24 | noticeMapper.insertNotice(notice);
25 | }
26 |
27 | @Override
28 | public Notice selectNotice() {
29 | return noticeMapper.selectAllNotice();
30 | }
31 |
32 | @Override
33 | public void updateAllNoticeHasRead(String userId) {
34 | noticeMapper.updateAllNoticeHasRead(userId);
35 | }
36 |
37 | @Override
38 | public int countNoticeHasRead(String userId) {
39 | return noticeMapper.countNoticeHasRead(userId);
40 | }
41 |
42 | @Override
43 | public List noticeList(String userId) {
44 | return noticeMapper.noticeList(userId);
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/service/impl/UserServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.service.impl;
2 |
3 | import com.example.wendao.controller.RegisterController;
4 | import com.example.wendao.entity.User;
5 | import com.example.wendao.mapper.UserMapper;
6 | import com.example.wendao.redis.JedisService;
7 | import com.example.wendao.redis.VerifyCodeKey;
8 | import com.example.wendao.service.UserService;
9 | import com.example.wendao.utils.GenerateRandomCode;
10 | import com.example.wendao.utils.Result;
11 | import com.example.wendao.vo.UserData;
12 | import com.example.wendao.vo.UserInfoVo;
13 | import com.mchange.io.FileUtils;
14 | import com.qcloud.cos.COSClient;
15 | import com.qcloud.cos.model.PutObjectRequest;
16 | import com.qcloud.cos.model.PutObjectResult;
17 | import com.tencentcloudapi.common.Credential;
18 | import com.tencentcloudapi.common.exception.TencentCloudSDKException;
19 | import com.tencentcloudapi.common.profile.ClientProfile;
20 | import com.tencentcloudapi.common.profile.HttpProfile;
21 | import com.tencentcloudapi.sms.v20190711.SmsClient;
22 | import com.tencentcloudapi.sms.v20190711.models.SendSmsRequest;
23 | import com.tencentcloudapi.sms.v20190711.models.SendSmsResponse;
24 | import org.slf4j.Logger;
25 | import org.slf4j.LoggerFactory;
26 | import org.springframework.beans.factory.annotation.Autowired;
27 | import org.springframework.stereotype.Service;
28 | import org.springframework.web.multipart.MultipartFile;
29 |
30 | import java.io.File;
31 | import java.io.IOException;
32 | import java.net.URL;
33 | import java.util.Date;
34 | import java.util.List;
35 | import java.util.UUID;
36 |
37 | /**
38 | * @author: zhk
39 | * @description:
40 | * @date: 2023/3/1 21:09
41 | * @version: 1.0
42 | */
43 | @Service
44 | public class UserServiceImpl implements UserService {
45 | private Logger log = LoggerFactory.getLogger(RegisterController.class);
46 | @Autowired
47 | COSClient cosClient;
48 | @Autowired(required = false)
49 | UserMapper userMapper;
50 |
51 | @Autowired
52 | JedisService jedisService;
53 |
54 | @Override
55 | public void insert(User user) {
56 | userMapper.insertUser(user);
57 | }
58 |
59 | @Override
60 | public User selectByUserId(String userId) {
61 | return userMapper.selectByUserId(userId);
62 | }
63 |
64 | @Override
65 | public UserInfoVo selectByUserInfoId(String userId) {
66 | return userMapper.selectByUserInfoId(userId);
67 | }
68 |
69 | @Override
70 | public void updateByUserId(User user) {
71 | userMapper.updateByUserId(user);
72 | }
73 |
74 | @Override
75 | public void resetAchieveValue() {
76 | userMapper.resetAchieveValue();
77 | }
78 |
79 | @Override
80 | public List top10LeaderBoard() {
81 | return userMapper.top10LeaderBoard();
82 | }
83 |
84 | @Override
85 | public String uploadImages(MultipartFile multipartFile) {
86 | //MultipartFile转file
87 | //获取最后一个点的索引值
88 | int doPos = multipartFile.getOriginalFilename().lastIndexOf(".");
89 | //获取扩展名
90 | String fileExt = multipartFile.getOriginalFilename().substring(doPos + 1).toLowerCase();
91 | String fileName = UUID.randomUUID().toString().replaceAll("-", "") + "." + fileExt;
92 | // 若须要防止生成的临时文件重复,能够在文件名后添加随机码
93 | try {
94 | File localFile = File.createTempFile(fileName, fileExt);
95 | multipartFile.transferTo(localFile);
96 | log.info(multipartFile.getOriginalFilename());
97 | log.info(String.valueOf(multipartFile.getSize()));
98 | // 指定文件将要存放的存储桶
99 | String bucketName = "wendao-1316683032";
100 | // 指定文件上传到 COS 上的路径,即对象键。例如对象键为 folder/picture.jpg,则表示将文件 picture.jpg 上传到 folder 路径下
101 |
102 | String key = "avatar/" + fileName;
103 | PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, localFile);
104 | PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
105 | log.info("putObjectResult" + putObjectResult.toString());
106 |
107 | //设置过期时间
108 | Date expiration = new Date(System.currentTimeMillis() + 5 * 60 * 10000);
109 | //获取图片地址
110 | URL oldUrl = cosClient.generatePresignedUrl(bucketName, key, expiration);
111 | String url = oldUrl.toString();
112 | // 直接查找到第一个?的位置
113 | url = url.substring(0, url.indexOf("?"));
114 | log.info("头像地址: " + url);
115 | return url;
116 | } catch (IOException e) {
117 | log.error("文件创建错误:{}",e);
118 | return "";
119 | }
120 | }
121 |
122 | @Override
123 | public User selectByUserIdAll(String userId) {
124 | return userMapper.selectByUserIdAll(userId);
125 | }
126 |
127 | @Override
128 | public UserData getUserData(String userId) {
129 | return userMapper.getUserData(userId);
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/task/AchieveValueTask.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.task;
2 |
3 | import com.example.wendao.service.UserService;
4 | import org.quartz.JobExecutionContext;
5 | import org.quartz.JobExecutionException;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.scheduling.quartz.QuartzJobBean;
10 | import org.springframework.stereotype.Component;
11 |
12 | import java.text.SimpleDateFormat;
13 | import java.util.Date;
14 |
15 | /**
16 | * @author: zhk
17 | * @description:
18 | * @date: 2023/3/3 16:53
19 | * @version: 1.0
20 | */
21 | @Component
22 | public class AchieveValueTask extends QuartzJobBean {
23 |
24 | private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
25 | private static final Logger logger = LoggerFactory.getLogger(AchieveValueTask.class);
26 |
27 | @Autowired
28 | UserService userService;
29 |
30 | @Override
31 | protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
32 | logger.info("AchieveValueTask--------------------------{}", sdf.format(new Date()));
33 | userService.resetAchieveValue();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/task/LikeTask.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.task;
2 |
3 | import com.example.wendao.service.LikeService;
4 | import org.quartz.JobExecutionContext;
5 | import org.quartz.JobExecutionException;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.scheduling.quartz.QuartzJobBean;
10 | import org.springframework.stereotype.Component;
11 |
12 | import java.text.SimpleDateFormat;
13 | import java.util.Date;
14 |
15 | /**
16 | * @author: zhk
17 | * @description:
18 | * @date: 2023/3/3 16:54
19 | * @version: 1.0
20 | */
21 | @Component
22 | public class LikeTask extends QuartzJobBean {
23 | @Autowired
24 | LikeService likeService;
25 |
26 | private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
27 | private static final Logger logger = LoggerFactory.getLogger(LikeTask.class);
28 |
29 | @Override
30 | protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
31 | logger.info("LikeTask--------------------------{}", sdf.format(new Date()));
32 | likeService.transLikedCountFromRedis2DB();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/utils/Base64URL.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.utils;
2 | import java.util.Base64;
3 | /**
4 | * @author: zhk
5 | * @description:
6 | * @date: 2023/4/30 14:45
7 | * @version: 1.0
8 | */
9 | public class Base64URL {
10 | public static byte[] base64EncodeUrl(byte[] input) {
11 | byte[] base64 = Base64.getEncoder().encode(input);
12 | for (int i = 0; i < base64.length; ++i)
13 | switch (base64[i]) {
14 | case '+':
15 | base64[i] = '*';
16 | break;
17 | case '/':
18 | base64[i] = '-';
19 | break;
20 | case '=':
21 | base64[i] = '_';
22 | break;
23 | default:
24 | break;
25 | }
26 | return base64;
27 | }
28 | }
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/utils/BvToAvUtils.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.utils;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | /**
7 | * @author: zhk
8 | * @description:
9 | * @date: 2023/3/21 20:11
10 | * @version: 1.0
11 | */
12 | public class BvToAvUtils {
13 | /**
14 | * 码表
15 | */
16 | private static final String TABLE = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF";
17 | /**
18 | * 字符顺序码表
19 | */
20 | private static final int[] S = new int[]{11, 10, 3, 8, 4, 6};
21 | private static final int XOR = 177451812;
22 | private static final long ADD = 8728348608L;
23 | private static final Map MAP = new HashMap<>();
24 |
25 | static {
26 | for (int i = 0; i < 58; i++) {
27 | MAP.put(TABLE.charAt(i), i);
28 | }
29 | }
30 |
31 | /**
32 | * avid 转 bvid 算法
33 | *
34 | * a = (avid 异或 177451812) + 8728348608
35 | * 以 i 为循环变量循环 6 次 b[i] = (a / 58 ^ i) % 58
36 | * 将 b[i] 中各个数字转换为以下码表中的字符
37 | * 初始化字符串 b[i]=BV1 4 1 7
38 | * 按照字符顺序编码表编码并填充至 b[i]
39 | *
40 | * @param aid
41 | * @return
42 | */
43 | public static String aidToBvid(int aid) {
44 | long x = (aid ^ XOR) + ADD;
45 | char[] chars = new char[]{'B', 'V', '1', ' ', ' ', '4', ' ', '1', ' ', '7', ' ', ' '};
46 | for (int i = 0; i < 6; i++) {
47 | int pow = (int) Math.pow(58, i);
48 | long i1 = x / pow;
49 | int index = (int) (i1 % 58);
50 | chars[S[i]] = TABLE.charAt(index);
51 | }
52 | return String.valueOf(chars);
53 | }
54 |
55 | /**
56 | * bvid转avid算法
57 | *
58 | * @param bvid
59 | * @return
60 | */
61 | public static int bvidToAid(String bvid) {
62 | long r = 0;
63 | for (int i = 0; i < 6; i++) {
64 | r += MAP.get(bvid.charAt(S[i])) * Math.pow(58, i);
65 | }
66 | return (int) ((r - ADD) ^ XOR);
67 | }
68 |
69 | public static void main(String[] args) {
70 | int aidOld = 653841742;
71 | String bidOld = "BV1WY4y1D7JA";
72 | int aidNew = bvidToAid(bidOld);
73 | String bidNew = aidToBvid(aidOld);
74 | System.out.println("比较aid: " + (aidOld == aidNew));
75 | System.out.println("比较bid: " + bidNew.equals(bidOld));
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/utils/CodeMsg.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.utils;
2 |
3 | import lombok.Data;
4 |
5 | /**
6 | * @author: zhk
7 | * @description:
8 | * @date: 2023/3/1 21:50
9 | * @version: 1.0
10 | */
11 | @Data
12 | public class CodeMsg {
13 | private int code;
14 | private String msg;
15 |
16 | public CodeMsg(int code, String msg) {
17 | this.code = code;
18 | this.msg = msg;
19 | }
20 |
21 | /**
22 | * 通用错误
23 | */
24 | public static CodeMsg SUCCESS = new CodeMsg(0, "SUCCESS");
25 | public static CodeMsg ERROR = new CodeMsg(000000, "ERROR");
26 | public static CodeMsg NOT_LOGIN = new CodeMsg(000001, "NOT_LOGIN");
27 |
28 | /**
29 | * 登录模块错误
30 | */
31 | public static CodeMsg VERIFY_CODE_ERROR = new CodeMsg(100000, "手机验证码错误");
32 | public static CodeMsg DUPLICATE_REGISTRY = new CodeMsg(100001, "手机号码重复注册");
33 | public static CodeMsg UNREGISTER_PHONE = new CodeMsg(100002, "手机号码未注册");
34 | public static CodeMsg PASSWORD_ERROR = new CodeMsg(100003, "登录密码错误");
35 | public static CodeMsg GITHUB_CODE_OR_STATE_EMPTY = new CodeMsg(100004, "Github获取code或者state为null");
36 | public static CodeMsg GITHUB_REQUEST_TOKEN_EMPTY = new CodeMsg(100005, "Github请求获取Token失败");
37 | public static CodeMsg GITHUB_REQUEST_USER_INFO_EMPTY = new CodeMsg(100006, "Github请求获取用户信息失败");
38 | public static CodeMsg FAILED_TO_SEND_THE_VERIFICATION_CODE = new CodeMsg(100007, "验证码发送失败");
39 |
40 | /**
41 | * 个人中心模块错误
42 | */
43 | public static CodeMsg UPLOAD_IMAGE_EMPTY = new CodeMsg(200000, "上传图片为空");
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/utils/CommonUtils.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.utils;
2 |
3 | import java.text.SimpleDateFormat;
4 | import java.util.Date;
5 | import java.util.UUID;
6 |
7 | /**
8 | * @author: zhk
9 | * @description: 通用工具类
10 | * @date: 2023/3/2 9:10
11 | * @version: 1.0
12 | */
13 | public class CommonUtils {
14 | /**
15 | * 将Github中的日期转为Date类型的日期
16 | *
17 | * @param createTime
18 | * @return
19 | */
20 | public static Date githubDateToDate(String createTime) {
21 | char[] ch = createTime.toCharArray();
22 | for (int i = 0; i < ch.length; i++) {
23 | if (ch[i] >= 'A' && ch[i] <= 'Z') {
24 | ch[i] = ' ';
25 | }
26 | }
27 | String value = String.valueOf(ch);
28 | Date createDate = null;
29 | try {
30 | SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
31 | createDate = sf.parse(value);
32 | } catch (Exception e) {
33 | e.printStackTrace();
34 | }
35 | return createDate;
36 | }
37 |
38 | /**
39 | * 生成随机的uuid值,用做token
40 | */
41 |
42 | public static String uuid() {
43 | return UUID.randomUUID().toString().replace("-", "");
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/utils/GenerateRandomCode.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.utils;
2 |
3 |
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 |
7 | import java.util.HashSet;
8 | import java.util.Random;
9 | import java.util.Set;
10 |
11 |
12 | /**
13 | * @author: zhk
14 | * @description: 6位随机验证码生成工具类
15 | * @date: 2023/3/1 22:01
16 | * @version: 1.0
17 | */
18 | public class GenerateRandomCode {
19 | private static Logger log = LoggerFactory.getLogger(GenerateRandomCode.class);
20 | private static Random random = new Random();
21 | private static Set usedCodes = new HashSet();
22 |
23 | public static String generateRandomVerificationCode() {
24 | while (true) {
25 | // 生成6位数
26 | Integer code = random.nextInt(900000) + 100000;
27 | // 检查是否已经生成过
28 | if (!usedCodes.contains(code)) {
29 | // 添加到哈希表
30 | usedCodes.add(code);
31 | // 返回6位数
32 | log.info("你的验证码为:" + code.toString());
33 | return code.toString();
34 | }
35 | }
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/utils/HttpClientUtils.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.utils;
2 |
3 | import com.alibaba.fastjson.JSONObject;
4 | import org.apache.http.HttpEntity;
5 | import org.apache.http.client.methods.CloseableHttpResponse;
6 | import org.apache.http.client.methods.HttpGet;
7 | import org.apache.http.impl.client.CloseableHttpClient;
8 | import org.apache.http.impl.client.HttpClients;
9 | import org.apache.http.util.EntityUtils;
10 |
11 | import java.util.HashMap;
12 | import java.util.Map;
13 |
14 | /**
15 | * @author: zhk
16 | * @description:
17 | * @date: 2023/3/2 9:13
18 | * @version: 1.0
19 | */
20 | public class HttpClientUtils {
21 | /**
22 | * 利用Java发请求
23 | *
24 | * @param url
25 | * @return
26 | */
27 | public static String doGet(String url) {
28 | // 创建HttpClient对象
29 | CloseableHttpClient httpClient = HttpClients.createDefault();
30 |
31 | // 创建一个Get请求对象实例, 注意这里的url必须是以http或者https开头
32 | HttpGet httpGet = new HttpGet(url);
33 | try {
34 | // 发送http请求
35 | CloseableHttpResponse response = httpClient.execute(httpGet);
36 | if (response.getStatusLine().getStatusCode() == 200) {
37 | // 状态码是200表示是请求成功, 获取响应体
38 | HttpEntity httpEntity = response.getEntity();
39 |
40 | return EntityUtils.toString(httpEntity);
41 | }
42 | } catch (Exception e) {
43 | e.printStackTrace();
44 | }
45 | return null;
46 |
47 | }
48 |
49 | /**
50 | * 利用Java发送请求,并且设置请求头
51 | *
52 | * @param url
53 | * @param token
54 | * @return
55 | */
56 | public static String doGetHeader(String url, String token) {
57 | // 创建HttpClient对象
58 | CloseableHttpClient httpClient = HttpClients.createDefault();
59 |
60 | // 创建一个Get请求对象实例, 注意这里的url必须是以http或者https开头
61 | HttpGet httpGet = new HttpGet(url);
62 | httpGet.setHeader("Authorization", "token " + token);
63 | try {
64 | // 发送http请求
65 | CloseableHttpResponse response = httpClient.execute(httpGet);
66 | System.out.println("response=" + response);
67 | System.out.println("responseCode=" + response.getStatusLine().getStatusCode());
68 | if (response.getStatusLine().getStatusCode() == 200) {
69 | // 状态码是200表示是请求成功, 获取响应体
70 | HttpEntity httpEntity = response.getEntity();
71 |
72 | return EntityUtils.toString(httpEntity);
73 | }
74 | } catch (Exception e) {
75 | e.printStackTrace();
76 | }
77 | return null;
78 |
79 | }
80 |
81 |
82 | public static Map getMap(String httpEntity) {
83 | Map map = new HashMap<>();
84 | // 以&来解析字符串
85 | String[] result = httpEntity.split("\\&");
86 | for (String s : result) {
87 | String[] split = s.split("=");
88 | // 将字符串存入map中
89 | if (split.length == 1) {
90 | map.put(split[0], null);
91 | } else {
92 | map.put(split[0], split[1]);
93 | }
94 | }
95 | return map;
96 | }
97 |
98 |
99 | public static Map getMapJSON(String response) {
100 | Map map = new HashMap<>();
101 | // 将字符串转为JSON对象
102 | JSONObject jsonObject = JSONObject.parseObject(response);
103 | for (Map.Entry entry : jsonObject.entrySet()) {
104 | String key = entry.getKey();
105 | String value = String.valueOf(entry.getValue());
106 | map.put(key, value);
107 |
108 | }
109 |
110 | return map;
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/utils/IpUtils.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.utils;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.alibaba.fastjson.JSONObject;
5 |
6 | import javax.servlet.http.HttpServletRequest;
7 | import java.io.BufferedReader;
8 | import java.io.IOException;
9 | import java.io.InputStream;
10 | import java.io.InputStreamReader;
11 | import java.net.HttpURLConnection;
12 | import java.net.MalformedURLException;
13 | import java.net.ProtocolException;
14 | import java.net.URL;
15 |
16 | /**
17 | * @author: zhk
18 | * @description:
19 | * @date: 2023/3/18 15:40
20 | * @version: 1.0
21 | */
22 | public class IpUtils {
23 | /**
24 | * 获取登录用户的IP地址
25 | *
26 | * @param request
27 | * @return
28 | */
29 | public static String getIpAddr(HttpServletRequest request) {
30 | String ip = request.getHeader("x-forwarded-for");
31 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
32 | ip = request.getHeader("Proxy-Client-IP");
33 | }
34 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
35 | ip = request.getHeader("WL-Proxy-Client-IP");
36 | }
37 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
38 | ip = request.getRemoteAddr();
39 | }
40 | if ("0:0:0:0:0:0:0:1".equals(ip)) {
41 | ip = "127.0.0.1";
42 | }
43 | if (ip.split(",").length > 1) {
44 | ip = ip.split(",")[0];
45 | }
46 | return ip;
47 | }
48 |
49 | /**
50 | * 通过IP获取地址(需要联网,调用淘宝的IP库)
51 | *
52 | * @param ip
53 | * @return
54 | */
55 | public static String getIpInfo(String ip) {
56 | if ("127.0.0.1".equals(ip)) {
57 | ip = "127.0.0.1";
58 | }
59 | String info = "";
60 | try {
61 | URL url = new URL("http://ip.taobao.com/service/getIpInfo.php?ip=" + ip);
62 | HttpURLConnection htpcon = (HttpURLConnection) url.openConnection();
63 | htpcon.setRequestMethod("GET");
64 | htpcon.setDoOutput(true);
65 | htpcon.setDoInput(true);
66 | htpcon.setUseCaches(false);
67 |
68 | InputStream in = htpcon.getInputStream();
69 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
70 | StringBuffer temp = new StringBuffer();
71 | String line = bufferedReader.readLine();
72 | while (line != null) {
73 | temp.append(line).append("\r\n");
74 | line = bufferedReader.readLine();
75 | }
76 | bufferedReader.close();
77 | JSONObject obj = (JSONObject) JSON.parse(temp.toString());
78 | if (obj.getIntValue("code") == 0) {
79 | JSONObject data = obj.getJSONObject("data");
80 | info += data.getString("country") + " ";
81 | info += data.getString("region") + " ";
82 | info += data.getString("city") + " ";
83 | info += data.getString("isp");
84 | }
85 | } catch (MalformedURLException e) {
86 | e.printStackTrace();
87 | } catch (ProtocolException e) {
88 | e.printStackTrace();
89 | } catch (IOException e) {
90 | e.printStackTrace();
91 | }
92 | return info;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/utils/RandomUtils.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.utils;
2 |
3 | import java.util.Random;
4 |
5 | /**
6 | * @author: zhk
7 | * @description: 生成随机的salt
8 | * @date: 2023/3/2 9:07
9 | * @version: 1.0
10 | */
11 | public class RandomUtils {
12 | /**
13 | * 随机生成一个6为的字符串,用来做salt。
14 | * 在密码学中,是指通过在密码任意固定位置插入特定的字符串,
15 | * 让散列后的结果和使用原始密码的散列结果不相符,这种过程称之为“加盐”。
16 | */
17 | public static String randomSalt() {
18 | String result = "";
19 | for (int i = 0; i < 6; i++) {
20 | // 生成的都是小写字母
21 | int val = (int) (Math.random() * 26 + 97);
22 | result = result + (char) val;
23 | }
24 | return result;
25 | }
26 |
27 | /**
28 | * 随机生成一个5位的字符串,用来作为用户的部分昵称: 然后拼接上:用户 + result + 号
29 | * 而且生成的随机数字保证在10000-99999之间
30 | */
31 |
32 | public static int randomNickName() {
33 | Random random = new Random();
34 | int value = random.nextInt(90000) + 10000;
35 | return value;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/utils/Result.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.utils;
2 |
3 | import lombok.Data;
4 |
5 | /**
6 | * @author: zhk
7 | * @description: 统一返回结果
8 | * @date: 2023/3/2 9:05
9 | * @version: 1.0
10 | */
11 | @Data
12 | public class Result {
13 | private int code;
14 | private String msg;
15 | private T data;
16 |
17 | public Result(T data) {
18 | this.code = 0;
19 | this.msg = "success";
20 | this.data = data;
21 | }
22 |
23 | public Result(CodeMsg cm) {
24 | if (null == cm) {
25 | return;
26 | }
27 | this.code = cm.getCode();
28 | this.msg = cm.getMsg();
29 | }
30 |
31 |
32 | public static Result success(T data) {
33 | return new Result(data);
34 | }
35 |
36 | public static Result error(CodeMsg cm) {
37 | return new Result(cm);
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/vo/ArticleUserVo.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.vo;
2 |
3 | import com.example.wendao.entity.Article;
4 | import lombok.Data;
5 |
6 | /**
7 | * @author: zhk
8 | * @description: 文章vo
9 | * @date: 2023/3/3 9:39
10 | * @version: 1.0
11 | */
12 | @Data
13 | public class ArticleUserVo extends Article {
14 | private String nickname;
15 |
16 | private String avatar;
17 |
18 | /**
19 | * 0 表示点赞了, 1 表示未点赞
20 | */
21 | private int isLiked;
22 |
23 | @Override
24 | public String toString() {
25 | return "ArticleUserVo{" + super.toString() +
26 | "nickname='" + nickname + '\'' +
27 | ", avatar='" + avatar + '\'' +
28 | ", isLiked=" + isLiked +
29 | '}';
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/vo/CommentUserVo.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.vo;
2 |
3 | import com.example.wendao.entity.Comment;
4 | import lombok.Data;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * @author: zhk
10 | * @description: 评论的用户vo
11 | * @date: 2023/3/3 9:40
12 | * @version: 1.0
13 | */
14 | @Data
15 | public class CommentUserVo extends Comment {
16 | /**
17 | * 用户头像
18 | */
19 | private String avatar;
20 |
21 | /**
22 | * 用户昵称
23 | */
24 | private String nickname;
25 |
26 | /**
27 | * 该评论下回复的评论,子评论
28 | */
29 | private List replyCommentList;
30 |
31 | /**
32 | * 子评论回复的人,当前评论是根评论时为空
33 | */
34 | private String replyNickname;
35 |
36 | /**
37 | * 子评论回复的人,当前评论是根评论时为空
38 | */
39 | private String replyId;
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/vo/FansVo.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.vo;
2 |
3 | import com.example.wendao.entity.Fans;
4 | import lombok.Data;
5 |
6 | /**
7 | * @author: zhk
8 | * @description:
9 | * @date: 2023/4/10 10:26
10 | * @version: 1.0
11 | */
12 | @Data
13 | public class FansVo extends Fans {
14 | private String nickname;
15 | private String avatar;
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/vo/FollowVo.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.vo;
2 |
3 | import com.example.wendao.entity.Follow;
4 |
5 | /**
6 | * @author: zhk
7 | * @description:
8 | * @date: 2023/4/10 10:27
9 | * @version: 1.0
10 | */
11 | public class FollowVo extends Follow {
12 | private String nickname;
13 | private String avatar;
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/vo/UserData.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.vo;
2 |
3 | import com.example.wendao.entity.Article;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * @author: zhk
12 | * @description:
13 | * @date: 2023/3/31 17:14
14 | * @version: 1.0
15 | */
16 | @Data
17 | @AllArgsConstructor
18 | @NoArgsConstructor
19 | public class UserData {
20 | private int fansCount;
21 | private int followCount;
22 | private int likeCount;
23 | private List articleList;
24 | private List fansVoList;
25 | private List followVoList;
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/vo/UserInfoVo.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.vo;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Data;
5 | import lombok.NoArgsConstructor;
6 |
7 | import java.util.Date;
8 |
9 | /**
10 | * @author: zhk
11 | * @description:
12 | * @date: 2023/3/18 16:13
13 | * @version: 1.0
14 | */
15 | @Data
16 | @AllArgsConstructor
17 | @NoArgsConstructor
18 | public class UserInfoVo {
19 |
20 | /**
21 | * 这里可以看做是手机号
22 | */
23 | private String userId;
24 |
25 | /**
26 | * 昵称
27 | */
28 | private String nickname;
29 |
30 | /**
31 | * 头像
32 | */
33 | private String avatar;
34 |
35 | /**
36 | * 成就值
37 | */
38 | private int achieveValue;
39 |
40 | /**
41 | * 学校
42 | */
43 | private String school;
44 |
45 | /**
46 | * 登录ip地址
47 | */
48 | private String loginIp;
49 |
50 | /**
51 | * 登录时间
52 | */
53 | private Date createTime;
54 |
55 | /**
56 | * 添加性别属性 1表示male,0表示female
57 | */
58 | private int sex;
59 |
60 | /**
61 | * 添加个性签名的属性
62 | */
63 | private String signature;
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/com/example/wendao/websocket/ChatEndPoint.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.websocket;
2 |
3 | import com.alibaba.fastjson.JSONObject;
4 | import com.example.wendao.entity.Message;
5 | import org.apache.logging.log4j.util.Strings;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.stereotype.Component;
9 |
10 | import javax.websocket.OnClose;
11 | import javax.websocket.OnMessage;
12 | import javax.websocket.OnOpen;
13 | import javax.websocket.Session;
14 | import javax.websocket.server.PathParam;
15 | import javax.websocket.server.ServerEndpoint;
16 | import java.util.Map;
17 | import java.util.concurrent.ConcurrentHashMap;
18 |
19 | /**
20 | * @author: zhk
21 | * @description:
22 | * @date: 2023/3/3 16:49
23 | * @version: 1.0
24 | */
25 | @Component
26 | @ServerEndpoint(value = "/chat/{userId}")
27 | public class ChatEndPoint {
28 | private Session session;
29 |
30 | private static Map onlineUsers = new ConcurrentHashMap<>();
31 |
32 | private static Logger logger = LoggerFactory.getLogger(ChatEndPoint.class);
33 |
34 | private static int onlineCount = 0;
35 |
36 | private String userId = "";
37 |
38 |
39 | @OnOpen
40 | public void onOpen(Session session, @PathParam("userId") String userId) {
41 | this.session = session;
42 | this.userId = userId;
43 | // 这里是将其加入到线程安全的Map中
44 | if (onlineUsers.containsKey(userId)) {
45 | onlineUsers.remove(userId);
46 | onlineUsers.put(userId, this);
47 | } else {
48 | onlineUsers.put(userId, this);
49 | onlineUsers.put("18392710807", this);
50 | logger.info(userId + "成功上线");
51 | addOnlineCount();
52 | }
53 | }
54 |
55 | @OnMessage
56 | /**
57 | * 用户之间一对一消息发送,这个message参数是从哪传递过来的?
58 | */
59 | public void onMessage(String message, Session session) {
60 | try {
61 | // 将message字符串进行反序列化
62 | System.out.println("message------------" + message);
63 | System.out.println(message);
64 | Message messA = JSONObject.parseObject(message, Message.class);
65 | // 这里相当于是上面请求路径上的userId
66 | String toId = messA.getToId();
67 | String messageContent = messA.getMessageContent();
68 | String fromId = messA.getFromId();
69 | logger.info(fromId + "向" + toId + "发送消息:" + messageContent);
70 |
71 | // 这里应该重新构建一个新的Message对象
72 | //Message messB = new Message();
73 | System.out.println(fromId);
74 | if (!Strings.isBlank(fromId)) {
75 | onlineUsers.get(fromId).session.getBasicRemote().sendText(message);
76 | }
77 |
78 | } catch (Exception e) {
79 | e.printStackTrace();
80 | }
81 | }
82 |
83 | @OnClose
84 | public void onClose() {
85 | if (onlineUsers.containsKey(userId)) {
86 | // 移除该客户端对象
87 | onlineUsers.remove(userId);
88 | // 在线用户数减1
89 | subOnlineCount();
90 | }
91 | }
92 |
93 | public static synchronized void addOnlineCount() {
94 | ChatEndPoint.onlineCount++;
95 | }
96 |
97 | public static synchronized void subOnlineCount() {
98 | ChatEndPoint.onlineCount--;
99 | }
100 |
101 | public static synchronized int onlineCount() {
102 | return onlineCount;
103 | }
104 |
105 | }
106 |
--------------------------------------------------------------------------------
/src/main/resources/application-dev.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 8081
3 |
4 | cookie: SESSDATA= #这里填写bilibili的cookie
5 |
6 | #druid
7 | spring:
8 | profiles: dev
9 | datasource:
10 | url: jdbc:mysql://localhost:3306/wendao?characterEncoding=utf-8&serverTimezone=Asia/Shanghai
11 | username: #数据库用户名
12 | password: #数据库密码
13 | driver-class-name: com.mysql.cj.jdbc.Driver
14 | type: com.alibaba.druid.pool.DruidDataSource
15 | initialSize: 5
16 | minIdle: 10
17 | maxActive: 20
18 | maxWait: 60000
19 | timeBetweenEvictionRunsMillis: 60000
20 | minEvictableIdleTimeMillis: 300000
21 | maxEvictableIdleTimeMillis: 900000
22 | validationQuery: SELECT 1 FROM DUAL
23 | testWhileIdle: true
24 | testOnBorrow: false
25 | testOnReturn: false
26 | poolPreparedStatements: true
27 | maxPoolPreparedStatementPerConnectionSize: 20
28 | filters: stat,wall,log4j
29 | useGlobalDataSourceStat: true
30 | connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500;
31 | #redis
32 | redis:
33 | host: localhost
34 | port: 6379 #redis端口号
35 | timeout: 1000
36 | jedis:
37 | pool:
38 | max-active: 1000
39 | max-idle: 800
40 | min-idle: 500
41 | max-wait: 500
42 | elasticsearch:
43 | rest:
44 | uris: localhost:9200 #es的host
45 | data:
46 | elasticsearch:
47 | repositories:
48 | enabled: true
49 |
50 |
51 | logging:
52 | level:
53 | root: info
54 | com.example.wendao.mapper: debug
55 |
56 | mybatis:
57 | mapper-locations: classpath*:mapper/*.xml
58 | type-aliases-package: com.example.wendao.entity
59 | configuration:
60 | map-underscore-to-camel-case: true #开启驼峰命名法转换
61 |
62 | pagehelper:
63 | helper-dialect: mysql
64 | reasonable: false
65 | support-methods-arguments: true
66 |
67 | #腾讯云对象存储,用于上传下载图片功能
68 | tencent:
69 | cos:
70 | secretId: #填写
71 | secretKey: #填写
--------------------------------------------------------------------------------
/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | profiles:
3 | active: dev
4 | jackson:
5 | time-zone: GMT+8
6 | date-format: yyyy-MM-dd HH:mm:ss
--------------------------------------------------------------------------------
/src/main/resources/mapper/CategoryMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | insert into category(category_id, category_name)
7 | values (#{categoryId}, #{categoryName})
8 |
9 |
10 | update category
11 |
12 | category_name = #{categoryName}
13 |
14 | where category_id = #{categoryId}
15 |
16 |
17 | delete
18 | from category
19 | where category_id = #{categoryId}
20 |
21 |
26 |
31 |
35 |
36 |
--------------------------------------------------------------------------------
/src/main/resources/mapper/CommentMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
21 |
22 |
27 |
34 |
35 |
40 |
41 |
53 |
66 |
70 |
78 |
87 |
99 |
104 |
--------------------------------------------------------------------------------
/src/main/resources/mapper/FansMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | insert into fans (user_id, fans_id, created_time)
6 | values (#{userId}, #{fansId}, #{createdTime})
7 |
8 |
9 | delete
10 | from fans
11 | where user_id = #{userId}
12 | and fans_id = #{fansId}
13 |
14 |
19 |
--------------------------------------------------------------------------------
/src/main/resources/mapper/FollowMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | insert into follow (user_id, follow_id, created_time)
6 | values (#{userId}, #{followId}, #{createdTime})
7 |
8 |
12 |
13 | delete
14 | from follow
15 | where user_id = #{userId}
16 | and follow_id = #{followId}
17 |
18 |
23 |
28 |
--------------------------------------------------------------------------------
/src/main/resources/mapper/LikeMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | insert into `like` (user_id, article_id)
7 | values (#{userId}, #{articleId})
8 |
9 |
10 | UPDATE `like`
11 | SET user_id = #{userId}
12 | WHERE like_id = #{likeId}
13 |
14 |
15 | DELETE
16 | FROM `like`
17 | WHERE user_id = #{userId}
18 | and article_id = #{articleId}
19 |
20 |
24 |
29 |
--------------------------------------------------------------------------------
/src/main/resources/mapper/NoticeMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | insert into notice(from_id, to_id, content, created_date, has_read, conversation_id)
6 | values (#{fromId}, #{toId}, #{content},
7 | #{createdDate}, #{hasRead}, #{conversationId})
8 |
9 |
10 | update notice
11 | set has_read = 1
12 | where to_id = #{userId}
13 |
14 |
23 |
24 |
30 |
36 |
--------------------------------------------------------------------------------
/src/main/resources/mapper/UserMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | INSERT INTO user
7 | (user_id, nickname, password, salt,
8 | avatar, achieve_value, school,
9 | login_ip, create_time, login_type,
10 | sex, signature)
11 | VALUES (#{userId}, #{nickname}, #{password},
12 | #{salt}, #{avatar}, #{achieveValue},
13 | #{school}, #{loginIp}, #{createTime},
14 | #{loginType}, #{sex}, #{signature})
15 |
16 |
17 |
31 |
32 |
49 |
62 |
67 |
77 |
78 |
79 | UPDATE user
80 |
81 | nickname = #{nickname},
82 | password = #{password},
83 | salt = #{salt},
84 | avatar = #{avatar},
85 | achieve_value = #{achieveValue},
86 | school = #{school},
87 | login_ip = #{loginIp},
88 | create_time = #{createTime},
89 | login_type = #{loginType},
90 | sex = #{sex},
91 | signature = #{signature}
92 |
93 | where user_id = #{userId}
94 |
95 |
96 |
97 | update user
98 | set achieve_value = 0
99 |
100 |
101 |
--------------------------------------------------------------------------------
/src/main/resources/mapper/VideoMapper.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
10 |
13 |
--------------------------------------------------------------------------------
/src/test/java/com/example/wendao/WendaoApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class WendaoApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/src/test/java/com/example/wendao/mapper/ArticleMapperTest.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.mapper;
2 |
3 | import com.example.wendao.vo.ArticleUserVo;
4 | import org.junit.jupiter.api.Test;
5 | import org.junit.runner.RunWith;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.boot.test.context.SpringBootTest;
8 | import org.springframework.test.context.junit4.SpringRunner;
9 |
10 | import static org.junit.jupiter.api.Assertions.*;
11 |
12 | @SpringBootTest
13 | @RunWith(SpringRunner.class)
14 | class ArticleMapperTest {
15 |
16 | @Autowired
17 | ArticleMapper articleMapper;
18 |
19 | @Test
20 | void addView() {
21 | ArticleUserVo articleDetail1 = articleMapper.getArticleDetail(36, "18420051370");
22 | articleMapper.addView(36);
23 | ArticleUserVo articleDetail = articleMapper.getArticleDetail(36, "18420051370");
24 | System.out.println(articleDetail1.getArticleViewCount()+"----"+articleDetail.getArticleViewCount());
25 | }
26 |
27 | @Test
28 | void addLike(){
29 | ArticleUserVo articleDetail1 = articleMapper.getArticleDetail(36, "18420051370");
30 | articleMapper.addLike(36);
31 | ArticleUserVo articleDetail = articleMapper.getArticleDetail(36, "18420051370");
32 | System.out.println(articleDetail1.getArticleLikeCount() +"-----"+ articleDetail.getArticleLikeCount());
33 | }
34 | @Test
35 | void delLike(){
36 | ArticleUserVo articleDetail1 = articleMapper.getArticleDetail(36, "18420051370");
37 | articleMapper.delLike(36);
38 | ArticleUserVo articleDetail = articleMapper.getArticleDetail(36, "18420051370");
39 | System.out.println(articleDetail1.getArticleLikeCount() == 1+articleDetail.getArticleLikeCount());
40 | }
41 | }
--------------------------------------------------------------------------------
/src/test/java/com/example/wendao/mapper/CommentMapperTest.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.mapper;
2 |
3 | import com.example.wendao.vo.CommentUserVo;
4 | import org.junit.jupiter.api.Test;
5 | import org.junit.runner.RunWith;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.boot.test.context.SpringBootTest;
8 | import org.springframework.test.context.junit4.SpringRunner;
9 |
10 | import java.util.List;
11 |
12 | /**
13 | * @author: zhk
14 | * @description:
15 | * @date: 2023/3/19 9:27
16 | * @version: 1.0
17 | */
18 | @RunWith(SpringRunner.class)
19 | @SpringBootTest
20 | public class CommentMapperTest {
21 | @Autowired
22 | CommentMapper commentMapper;
23 | @Test
24 | void test1(){
25 | List commentUserVos = commentMapper.selectParentComment(3, -1);
26 | for (CommentUserVo item:
27 | commentUserVos) {
28 | System.out.println(item.getCommentCreatedTime());
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/test/java/com/example/wendao/mapper/LikeMapperTest.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.mapper;
2 |
3 | import com.example.wendao.entity.Like;
4 | import org.junit.jupiter.api.Test;
5 | import org.junit.runner.RunWith;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.boot.test.context.SpringBootTest;
8 | import org.springframework.test.context.junit4.SpringRunner;
9 |
10 | import java.util.List;
11 |
12 | import static org.junit.jupiter.api.Assertions.*;
13 | @RunWith(SpringRunner.class)
14 | @SpringBootTest
15 | class LikeMapperTest {
16 |
17 |
18 | @Autowired
19 | private LikeMapper likeMapper;
20 |
21 | @Test
22 | public void testAddLike() {
23 | Like like = new Like();
24 | like.setUserId("1");
25 | like.setArticleId(100);
26 |
27 | likeMapper.addLike(like);
28 |
29 | assertNotNull(like.getLikeId());
30 | }
31 |
32 | @Test
33 | public void testUpdateLike() {
34 | Like like = new Like();
35 | like.setLikeId(1);
36 | like.setUserId("1");
37 |
38 | likeMapper.updateLike(like);
39 |
40 | // Like updatedLike = likeMapper.getLikeById(1);
41 | // assertEquals(2, updatedLike.getUserId());
42 | }
43 |
44 | @Test
45 | public void testDeleteLikeById() {
46 | String userId = "18420051370";
47 | int article_id = 1;
48 | likeMapper.deleteLikeById( article_id,userId);
49 |
50 | // Like deletedLike = likeMapper.getLikeById(likeId);
51 | // assertNull(deletedLike);
52 | }
53 |
54 | @Test
55 | public void testGetAllLikes() {
56 | List likes = likeMapper.getAllLikes();
57 | assertNotNull(likes);
58 | assertTrue(likes.size() > 0);
59 | }
60 |
61 | @Test
62 | public void testGetLikesByUserId() {
63 | int userId = 1;
64 | List likes = likeMapper.getLikesByUserId(userId);
65 | assertNotNull(likes);
66 | assertTrue(likes.size() > 0);
67 | }
68 | }
--------------------------------------------------------------------------------
/src/test/java/com/example/wendao/mapper/UserMapperTest.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.mapper;
2 |
3 | import com.example.wendao.entity.User;
4 | import org.junit.Assert;
5 |
6 | import org.junit.jupiter.api.Test;
7 | import org.junit.runner.RunWith;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.boot.test.context.SpringBootTest;
10 | import org.springframework.test.context.junit4.SpringRunner;
11 |
12 | import javax.annotation.Resource;
13 | import java.util.Date;
14 | import java.util.List;
15 |
16 | import static org.junit.jupiter.api.Assertions.*;
17 |
18 | @RunWith(SpringRunner.class)
19 | @SpringBootTest
20 | class UserMapperTest {
21 |
22 | @Resource
23 | private UserMapper userMapper;
24 |
25 | @Test
26 | void insert() {
27 | User user = new User();
28 | user.setUserId("12345678902");
29 | user.setNickname("John");
30 | user.setPassword("password");
31 | user.setSalt("salt");
32 | user.setAvatar("avatar");
33 | user.setAchieveValue(100);
34 | user.setSchool("school");
35 | user.setLoginIp("192.168.1.1");
36 | user.setCreateTime(new Date());
37 | user.setLoginType("web");
38 | user.setSex(1);
39 | user.setSignature("signature");
40 | userMapper.insertUser(user);
41 |
42 | User insertedUser = userMapper.selectByUserId(user.getUserId());
43 | Assert.assertEquals(user.getNickname(), insertedUser.getNickname());
44 | Assert.assertEquals(user.getPassword(), insertedUser.getPassword());
45 | Assert.assertEquals(user.getSalt(), insertedUser.getSalt());
46 | Assert.assertEquals(user.getAvatar(), insertedUser.getAvatar());
47 | Assert.assertEquals(user.getAchieveValue(), insertedUser.getAchieveValue());
48 | Assert.assertEquals(user.getSchool(), insertedUser.getSchool());
49 | Assert.assertEquals(user.getLoginIp(), insertedUser.getLoginIp());
50 | Assert.assertEquals(user.getCreateTime(), insertedUser.getCreateTime());
51 | Assert.assertEquals(user.getLoginType(), insertedUser.getLoginType());
52 | Assert.assertEquals(user.getSex(), insertedUser.getSex());
53 | Assert.assertEquals(user.getSignature(), insertedUser.getSignature());
54 |
55 | }
56 |
57 | @Test
58 | void selectByUserId() {
59 | User user = new User();
60 | user.setUserId("123456789");
61 | user.setNickname("张三");
62 | user.setPassword("123456");
63 | user.setSalt("abc");
64 | user.setAvatar("http://xxx.com/avatar.png");
65 | user.setAchieveValue(100);
66 | user.setSchool("清华大学");
67 | user.setLoginIp("127.0.0.1");
68 | user.setCreateTime(new Date());
69 | user.setLoginType("PC");
70 | user.setSex(1);
71 | user.setSignature("我是张三");
72 |
73 | // 插入测试数据
74 | userMapper.insertUser(user);
75 |
76 | // 查询测试数据
77 | User result = userMapper.selectByUserId("123456789");
78 | System.out.println(result);
79 |
80 | // 断言查询结果是否符合预期
81 | Assert.assertNotNull(result);
82 | Assert.assertEquals("123456789", result.getUserId());
83 | Assert.assertEquals("张三", result.getNickname());
84 | Assert.assertEquals("123456", result.getPassword());
85 | Assert.assertEquals("abc", result.getSalt());
86 | Assert.assertEquals("http://xxx.com/avatar.png", result.getAvatar());
87 | Assert.assertEquals(100, result.getAchieveValue());
88 | Assert.assertEquals("清华大学", result.getSchool());
89 | Assert.assertEquals("127.0.0.1", result.getLoginIp());
90 | Assert.assertEquals("PC", result.getLoginType());
91 | Assert.assertEquals(1, result.getSex());
92 | Assert.assertEquals("我是张三", result.getSignature());
93 | }
94 |
95 | @Test
96 | void updateByUserId() {
97 | User user = new User();
98 | user.setUserId("123456789");
99 | user.setNickname("张三");
100 | user.setPassword("123456");
101 | user.setSalt("abc");
102 | user.setAvatar("http://xxx.com/avatar.png");
103 | user.setAchieveValue(100);
104 | user.setSchool("清华大学");
105 | user.setLoginIp("127.0.0.1");
106 | user.setCreateTime(new Date());
107 | user.setLoginType("PC");
108 | user.setSex(1);
109 |
110 | userMapper.updateByUserId(user);
111 | User result = userMapper.selectByUserId(user.getUserId());
112 |
113 | // 断言查询结果是否符合预期
114 | Assert.assertNotNull(result);
115 | Assert.assertEquals("123456789", result.getUserId());
116 | Assert.assertEquals("张三", result.getNickname());
117 | Assert.assertEquals("123456", result.getPassword());
118 | Assert.assertEquals("abc", result.getSalt());
119 | Assert.assertEquals("http://xxx.com/avatar.png", result.getAvatar());
120 | Assert.assertEquals(100, result.getAchieveValue());
121 | Assert.assertEquals("清华大学", result.getSchool());
122 | Assert.assertEquals("127.0.0.1", result.getLoginIp());
123 | Assert.assertEquals("PC", result.getLoginType());
124 | Assert.assertEquals(1, result.getSex());
125 | Assert.assertEquals("我是张三", result.getSignature());
126 | }
127 |
128 | @Test
129 | void resetAchieveValue() {
130 | userMapper.resetAchieveValue();
131 | }
132 |
133 | @Test
134 | void top10LeaderBoard() {
135 | List users = userMapper.top10LeaderBoard();
136 | // 校验查询结果
137 | assertNotNull(users);
138 | assertEquals(10, users.size());
139 | // 校验每个用户的成就值都比后面的用户大或相等
140 | int previousAchieveValue = Integer.MAX_VALUE;
141 | for (User user : users) {
142 | assertTrue(user.getAchieveValue() <= previousAchieveValue);
143 | previousAchieveValue = user.getAchieveValue();
144 | }
145 | }
146 | }
--------------------------------------------------------------------------------
/src/test/java/com/example/wendao/service/CommentServiceTest.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.service;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.alibaba.fastjson.JSONArray;
5 | import com.alibaba.fastjson.JSONObject;
6 | import com.example.wendao.vo.CommentUserVo;
7 | import org.junit.jupiter.api.Test;
8 | import org.junit.runner.RunWith;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.boot.test.context.SpringBootTest;
11 | import org.springframework.test.context.junit4.SpringRunner;
12 |
13 | import java.sql.SQLOutput;
14 | import java.util.List;
15 |
16 | /**
17 | * @author: zhk
18 | * @description:
19 | * @date: 2023/3/19 10:06
20 | * @version: 1.0
21 | */
22 | @SpringBootTest
23 | @RunWith(SpringRunner.class)
24 | public class CommentServiceTest {
25 | @Autowired
26 | CommentService commentService;
27 | int i;
28 | @Test
29 | void test1(){
30 | List commentUserVos = commentService.selectCommentLists(3);
31 | // JSONObject jsonObject = JSON.parseObject(commentUserVos.toString());
32 | String s = JSONObject.toJSONString(commentUserVos);
33 | System.out.println(s);
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/test/java/com/example/wendao/service/UserServiceTest.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.service;
2 |
3 | import com.example.wendao.entity.User;
4 | import com.example.wendao.utils.RandomUtils;
5 | import org.apache.commons.codec.digest.DigestUtils;
6 | import org.junit.Assert;
7 | import org.junit.jupiter.api.Test;
8 | import org.junit.runner.RunWith;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.boot.test.context.SpringBootTest;
11 | import org.springframework.test.context.junit4.SpringRunner;
12 |
13 | import java.util.Date;
14 |
15 | import static org.junit.jupiter.api.Assertions.*;
16 | @RunWith(SpringRunner.class)
17 | @SpringBootTest
18 | class UserServiceTest {
19 |
20 | @Autowired
21 | UserService userService;
22 |
23 | @Test
24 | void insert() {
25 | User user = new User();
26 | user.setUserId("13800138000");
27 | user.setNickname("test");
28 | user.setPassword("123456");
29 | user.setSalt("abc");
30 | user.setAvatar("default.png");
31 | user.setAchieveValue(0);
32 | user.setSchool("Tsinghua University");
33 | user.setLoginIp("127.0.0.1");
34 | user.setCreateTime(new Date());
35 | user.setLoginType("mobile");
36 | user.setSex(1);
37 | user.setSignature("Hello, world!");
38 |
39 | userService.insert(user);
40 |
41 | User insertedUser = userService.selectByUserId(user.getUserId());
42 |
43 | Assert.assertEquals(user.getNickname(), insertedUser.getNickname());
44 | Assert.assertEquals(user.getPassword(), insertedUser.getPassword());
45 | Assert.assertEquals(user.getSalt(), insertedUser.getSalt());
46 | Assert.assertEquals(user.getAvatar(), insertedUser.getAvatar());
47 | Assert.assertEquals(user.getAchieveValue(), insertedUser.getAchieveValue());
48 | Assert.assertEquals(user.getSchool(), insertedUser.getSchool());
49 | Assert.assertEquals(user.getLoginIp(), insertedUser.getLoginIp());
50 | // Assert.assertEquals(user.getCreateTime(), insertedUser.getCreateTime());
51 | Assert.assertEquals(user.getLoginType(), insertedUser.getLoginType());
52 | Assert.assertEquals(user.getSex(), insertedUser.getSex());
53 | Assert.assertEquals(user.getSignature(), insertedUser.getSignature());
54 | }
55 |
56 | @Test
57 | void selectByUserId() {
58 | }
59 |
60 | @Test
61 | void updateByUserId() {
62 | User user = new User();
63 | user.setUserId("18420051370");
64 | user.setNickname("zhk");
65 | user.setPassword("123456");
66 | user.setAvatar("default.png");
67 | user.setAchieveValue(0);
68 | user.setSchool("Tsinghua University");
69 | user.setSex(1);
70 | user.setSignature("Hello, world!");
71 | String salt = RandomUtils.randomSalt();
72 | user.setSalt(salt);
73 | user.setPassword(DigestUtils.md5Hex((user.getPassword() + salt)));
74 | userService.updateByUserId(user);
75 | }
76 |
77 | @Test
78 | void resetAchieveValue() {
79 | }
80 |
81 | @Test
82 | void top10LeaderBoard() {
83 | }
84 |
85 | @Test
86 | void sendSMSCode() {
87 | }
88 |
89 | @Test
90 | void uploadImages() {
91 | }
92 | }
--------------------------------------------------------------------------------
/src/test/java/com/example/wendao/utils/Utils.java:
--------------------------------------------------------------------------------
1 | package com.example.wendao.utils;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | import javax.servlet.http.HttpServletRequest;
9 |
10 | /**
11 | * @author: zhk
12 | * @description:
13 | * @date: 2023/3/18 15:43
14 | * @version: 1.0
15 | */
16 | @RunWith(SpringRunner.class)
17 | @SpringBootTest
18 | public class Utils {
19 | @Test
20 | void test(){
21 | }
22 | }
23 |
--------------------------------------------------------------------------------