Compare commits
No commits in common. "master" and "1.0" have entirely different histories.
24
.drone.yml
24
.drone.yml
@ -1,24 +0,0 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: bookmarkPublish
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
||||
|
||||
clone:
|
||||
disable: true
|
||||
|
||||
steps:
|
||||
- name: deploy
|
||||
image: appleboy/drone-ssh
|
||||
settings:
|
||||
host:
|
||||
from_secret: devHost
|
||||
port: 22
|
||||
user: root
|
||||
key:
|
||||
from_secret: privateSsh
|
||||
command_timeout: 30m
|
||||
script:
|
||||
- cd /root/bookmark && git pull && bash build.sh && bash syncFile.sh
|
31
.env
31
.env
@ -1,31 +0,0 @@
|
||||
#Mysql地址
|
||||
MYSQL_ADDRESS=mysql:3306
|
||||
#Mysql密码
|
||||
MYSQL_PASSWORD=123456
|
||||
#redis地址
|
||||
REDIS_HOST=redis
|
||||
#redis端口
|
||||
REDIS_PORT=6379
|
||||
# smtp地址
|
||||
SMTP_HOST=
|
||||
# smtp用户名
|
||||
SMTP_USERNAME=
|
||||
# smtp密码
|
||||
SMTP_PASSWORD=
|
||||
# 外网访问域名
|
||||
BOOKMARK_HOST=localhost
|
||||
# 文件存储地址(比如用户上传的icon文件)
|
||||
BOOKMARK_FILE_SAVE_PATH=./data/files
|
||||
# jwt密钥
|
||||
JWT_SECRET=123456
|
||||
# http网络代理ip(github api调用可能需要)
|
||||
PROXY_IP=
|
||||
# http网络代理端口
|
||||
PROXY_PORT=
|
||||
# 如果要支持github登陆需要配置以下两个参数
|
||||
# github clientId
|
||||
GITHUB_CLIENT_ID=
|
||||
# github secret
|
||||
GITHUB_SECRET=
|
||||
# 管理员用户id
|
||||
MANAGE_USER_ID=-1
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +0,0 @@
|
||||
.idea
|
20
DEPLOY.md
20
DEPLOY.md
@ -1,20 +0,0 @@
|
||||
本程序基于 docker 来进行部署,使用 docker-compose 管理服务。
|
||||
|
||||
**注意,仅在 x86 环境下测试,arm 下不保证可用性(目前测试可用)**
|
||||
|
||||
## 首次部署
|
||||
|
||||
0. 克隆代码`git clone https://github.com/FleyX/bookmark.git`
|
||||
1. 进入文件夹`cd bookmark`
|
||||
2. 安装新版的 docker,docker-compose,zip `apt install docker docker-compose zip`
|
||||
3. 修改.env 文件中的参数,改为你的实际配置
|
||||
4. 修改`浏览器插件/bookmarkBrowserPlugin/static/js/config.js`中的 bookmarkHost,改为你的实际部署路径
|
||||
5. 修改`浏览器插件/bookmarkBrowserPlugin/tab/index.html`中的`<meta http-equiv="Refresh" content="0;url=https://bm.fleyx.com" />`,将 url 改为你的实际部署地址
|
||||
6. 执行`build.sh`编译前后端代码 `bash build.sh`
|
||||
7. root 权限运行 `docker-compose up -d` 启动服务。
|
||||
|
||||
## 更新系统
|
||||
|
||||
0. 代码库更新`cd bookmark;git pull`
|
||||
1. 执行`build.sh`编译前后端代码 `bash build.sh`
|
||||
2. root 权限运行 `docker-compose restart` 启动服务
|
115
HELP.md
115
HELP.md
@ -1,115 +0,0 @@
|
||||
## 使用教程
|
||||
|
||||
### 首页
|
||||
|
||||
![首页](https://qiniupic.fleyx.com/blog/20220329202726.png?imageView2/2/w/1920)
|
||||
|
||||
#### 多功能搜索框
|
||||
|
||||
1. 搜索
|
||||
|
||||
搜索框支持书签搜索和网页搜索,输入关键词会在下方展示搜索结果:
|
||||
|
||||
![](https://qiniupic.fleyx.com/blog/20220329203152.png?imageView2/2/w/1920)
|
||||
|
||||
书签搜索支持**拼音/拼音首字母/名称关键字/链接关键词**搜索.比如对于`博客园。https://cnblogs.com`,可通过以下方式搜索到:
|
||||
|
||||
- ky (拼音首字母)
|
||||
- boke (拼音)
|
||||
- 客园 (名称关键词)
|
||||
- blogs (链接关键词)
|
||||
|
||||
**注意不支持组合搜索,也就是不能同时用两种内容搜索**
|
||||
|
||||
2. 快捷键
|
||||
|
||||
tab/方向键上/下:用于选择书签(默认不选中书签)
|
||||
enter/回车: 未选中书签情况下,用于发起网页搜索。选中书签的情况下跳转到对应书签
|
||||
|
||||
3. 网页搜索引擎
|
||||
|
||||
默认网页搜索引擎为**百度**,可点击图标进行切换,会自动保存选择的搜索引擎
|
||||
|
||||
![](https://qiniupic.fleyx.com/blog/20220329204103.png?imageView2/2/w/1920)
|
||||
|
||||
4. 搜索结果快捷操作
|
||||
|
||||
搜索书签后,通过鼠标悬浮在搜索结果上展示快捷操作,可进行如下操作:
|
||||
|
||||
- 定位到书签树中(仅在书签管理页面展示)
|
||||
- 复制书签链接
|
||||
- 固定到首页下方
|
||||
|
||||
![](https://qiniupic.fleyx.com/blog/20220329212023.png?imageView2/2/w/1920)
|
||||
|
||||
#### 书签固定区
|
||||
|
||||
可将一些常用书签固定在下方,方便快速跳转,最多可添加 20 个书签,未手动固定的情况下默认会按访问量顺序展示书签
|
||||
|
||||
![](https://qiniupic.fleyx.com/blog/20220329212211.png?imageView2/2/w/1920)
|
||||
|
||||
### 书签管理
|
||||
|
||||
通过点击右上方的头像,选择书签管理进入。
|
||||
|
||||
![](https://qiniupic.fleyx.com/blog/20220329212513.png?imageView2/2/w/1920)
|
||||
|
||||
本页面以书签树的形式展示所有的书签。
|
||||
|
||||
![](https://qiniupic.fleyx.com/blog/20220329212745.png?imageView2/2/w/1920)
|
||||
|
||||
上方搜索框介绍见[上一节:多功能搜索框](#多功能搜索框)
|
||||
|
||||
#### 书签树
|
||||
|
||||
- 新增
|
||||
|
||||
新增书签/文件夹可通过点击第一行"+"(添加到根路径)或者右键文件夹选择新增(添加到当前文件夹下)
|
||||
|
||||
![](https://qiniupic.fleyx.com/blog/20220329213056.png?imageView2/2/w/1920)
|
||||
|
||||
- 修改
|
||||
|
||||
右键要修改的书签/文件夹,选择修改按钮
|
||||
|
||||
- 删除
|
||||
|
||||
- 右键要删除的书签/文件夹选择删除
|
||||
- 点击第一行的![](https://qiniupic.fleyx.com/blog/20220329213336.png?imageView2/2/w/1920),进入多选模式,然后再点击删除图标进行批量删除
|
||||
![](https://qiniupic.fleyx.com/blog/20220329213551.png?imageView2/2/w/1920)
|
||||
|
||||
- 排序
|
||||
|
||||
支持拖拽排序或移动文件夹
|
||||
|
||||
![](https://qiniupic.fleyx.com/blog/20220329213716.png?imageView2/2/w/1920)
|
||||
|
||||
- 导入/导出
|
||||
|
||||
通过文件导入功能,快速导入现有浏览器书签
|
||||
|
||||
![](https://qiniupic.fleyx.com/blog/20220329214827.png?imageView2/2/w/1920)
|
||||
|
||||
点击书签右侧导出按钮,可导出现有书签数据到 html 文件中,此文件可直接导入到浏览器中
|
||||
|
||||
![](https://qiniupic.fleyx.com/blog/20220329214936.png?imageView2/2/w/1920)
|
||||
|
||||
### 个人中心
|
||||
|
||||
通过右上角悬浮菜单进入个人中心页面,可进行头像更换,密码修改等操作
|
||||
|
||||
### 浏览器插件
|
||||
|
||||
浏览器插件功能终于有 0.1 版本,支持鼠标右键菜单添加书签。
|
||||
|
||||
#### 安装插件
|
||||
|
||||
1. 首先下载插件压缩包,下载地址:[点击下载](https://fleyx.com/static/bookmarkBrowserPlugin.7z)
|
||||
|
||||
2. 安装插件(以 chrome 浏览器为例,其他支持插件的浏览器差不多)进入插件管理页面->开启开发者模式->加载已解压的拓展程序
|
||||
|
||||
![](https://qiniupic.fleyx.com/blog/202204151605709.png)
|
||||
|
||||
3. 之后页面点击右键->添加到书签,即可
|
||||
|
||||
![](https://qiniupic.fleyx.com/blog/202204151607593.png)
|
21
LICENSE
21
LICENSE
@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 FleyX
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
86
README.md
86
README.md
@ -1,12 +1,8 @@
|
||||
![图片](https://s3.fleyx.com/picbed/2023/08/Snipaste_2023-08-13_15-33-16.png)
|
||||
本项目是一个云书签的项目,取名为:签签世界。
|
||||
|
||||
本项目是一个在线书签管理的项目,名为:签签世界.
|
||||
访问地址:[bm.tapme.top](http://bm.tapme.top)
|
||||
|
||||
在线使用地址(长期提供服务):[bm.fleyx.com](https://bm.fleyx.com),
|
||||
|
||||
**为获得更好的体验,建议将主页设置为 bm.fleyx.com,并安装浏览器拓展,[点击查看如何安装](https://blog.fleyx.com/blog/detail/20220329/#%e6%b5%8f%e8%a7%88%e5%99%a8%e6%8f%92%e4%bb%b6)**
|
||||
|
||||
也可自己部署搭建,教程见:[docker-compose 部署](https://github.com/FleyX/bookmark/blob/master/DEPLOY.md)
|
||||
web端已经完成。
|
||||
|
||||
# 缘由
|
||||
|
||||
@ -18,39 +14,71 @@
|
||||
|
||||
所以有了这样这样一个项目,建立一个和平台无关的书签管理器,可在任意平台使用。
|
||||
|
||||
计划开发顺序如下:web 端->chrome 插件->firfox 插件。
|
||||
|
||||
最终目的就是所有浏览器(不包含 ie10 及以下等远古浏览器)中都能便捷的使用书签。
|
||||
|
||||
# 主要功能
|
||||
|
||||
帮助文档:[点击跳转](https://blog.fleyx.com/blog/detail/20220329/)
|
||||
## 查
|
||||
|
||||
- 支持从 chrome,edge,firefox 等浏览器导入书签数据。
|
||||
- 支持从 OneEnv 导入书签数据
|
||||
- 树型多级目录支持
|
||||
- 支持导出标准 html 书签文件
|
||||
- 强大的检索功能,支持拼音检索
|
||||
- 支持浏览器插件,安装插件以后可右键添加书签
|
||||
1. 节点树展示书签
|
||||
![](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190801185846.png)
|
||||
采用懒加载方式加载每一层数据,即使大量数据也不会卡顿。
|
||||
|
||||
# 更新日志
|
||||
2. 全文检索<br>
|
||||
![](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190801190427.png)
|
||||
|
||||
## 1.4.1
|
||||
- 可对`书签名`和`链接`进行全文检索
|
||||
- 支持方向键-上/下切换,回车确认
|
||||
- 可直接搜索 google/baidu,tab 键切换。
|
||||
![](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190801190720.png)
|
||||
- 支持右键复制 url(移动端不支持右键,需点击编辑-->菜单键)
|
||||
![](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190801191010.png)
|
||||
|
||||
- 修复书签名过长无法导入问题
|
||||
## 增
|
||||
|
||||
## 1.4
|
||||
![](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190801191452.png)
|
||||
|
||||
- 优化首图加载逻辑
|
||||
- 支持 OneEnv 备份文件导入
|
||||
1. 手动编辑导入
|
||||
![](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190801191601.png)
|
||||
2. 谷歌、火狐浏览器书签备份文件直接导入.如果同一级别下名称相同导致冲突,将跳过,保留原有的。
|
||||
![](https://raw.githubusercontent.com/FleyX/files/master/blogImg/20190801191721.png)
|
||||
|
||||
## 1.3
|
||||
## 改
|
||||
|
||||
![pic](https://s3.fleyx.com/picbed/2023/08/Snipaste_2023-08-13_15-01-20.png)
|
||||
1. 修改节点内容,右键->编辑。(移动端长按相当于右键)
|
||||
2. 修改书签顺序,所属文件夹,直接拖拽书签到目标位置
|
||||
|
||||
搜索引擎支持自定义[#43](https://github.com/FleyX/bookmark/issues/43)
|
||||
|
||||
位置:右上角个人中心-管理搜索引擎
|
||||
# 开发进度
|
||||
|
||||
# TODO
|
||||
## 2019-06-27
|
||||
|
||||
- [x] 主页功能
|
||||
- [x] 拼音检索
|
||||
- [x] 书签导出
|
||||
- [x] 浏览器插件
|
||||
**tag: 第一篇:环境搭建**
|
||||
|
||||
前端 react 框架搭建完成。
|
||||
|
||||
## 2019-07-10
|
||||
|
||||
**tag: 第二篇:注册登录重置密码完成**
|
||||
|
||||
后台框架搭建,并完成以下功能:
|
||||
|
||||
- 登录,注册,重置密码,发送验证码接口完成
|
||||
- 书签 html 上传解析并存到数据库,仅测试了 chrome 导出的书签文件
|
||||
- 查询某个用户的书签树
|
||||
|
||||
前台完成以下功能:
|
||||
|
||||
- 注册,登录,重置密码界面完成
|
||||
|
||||
## 2019-07-22
|
||||
|
||||
增删改查功能完成。支持节点拖拽
|
||||
|
||||
## 2019-07-30
|
||||
|
||||
- docker 部署重新整理,部署更方便了。
|
||||
- 加入 elasticsearch 全文检索,可以方便的搜索书签啦。
|
||||
- 树节点增加右键菜单,更加便捷的增删改
|
||||
|
4
bookMarkDocker/.gitignore
vendored
Normal file
4
bookMarkDocker/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
mavenRep
|
||||
es/data
|
||||
mysql/data
|
||||
nginx/log
|
29
bookMarkDocker/README.md
Normal file
29
bookMarkDocker/README.md
Normal file
@ -0,0 +1,29 @@
|
||||
本程序基于 docker 来进行部署。
|
||||
|
||||
docker 镜像 构建文件为本目录下的`Dockerfile`,已经生产推送到阿里云的容器镜像库:registry.cn-hangzhou.aliyuncs.com/fleyx/node-java-env:v2.本镜像包含如下:
|
||||
|
||||
- node 运行环境,已安装 cnpm
|
||||
- java 运行编译环境,openjdk11
|
||||
- maven 运行环境,已设置为阿里源
|
||||
|
||||
部署过程如下:
|
||||
|
||||
1. 首先运行 init.sh 进行前后端打包。
|
||||
2. 将密码,smtp 等相关敏感信息设置 到环境变量中,内容如下:<br/>
|
||||
|
||||
```bash
|
||||
export MYSQL_PASSWORD=123456
|
||||
export JWT_SECRET=123456
|
||||
export SMTP_HOST=localhost
|
||||
export SMTP_USERNAME=test
|
||||
export SMTP_PASSWORD=test
|
||||
export SMTP_PORT=465
|
||||
```
|
||||
|
||||
两种设置办法:
|
||||
|
||||
- 在终端执行上述命令.这种办法在关闭终端后这些变量会失效,如果重新部署 docker-compose 会报警告--环境变量未定义
|
||||
|
||||
- 写到配置文件中,比如/etc/profile 等文件中,然后`source /etc/profile` 使其生效。
|
||||
|
||||
3. 执行`docker-compose up -d` 后台启动系统。
|
98
bookMarkDocker/docker-compose.yml
Normal file
98
bookMarkDocker/docker-compose.yml
Normal file
@ -0,0 +1,98 @@
|
||||
version: "2"
|
||||
services:
|
||||
bookmark-mysql:
|
||||
image: mysql:8.0.16
|
||||
container_name: bookmark-mysql
|
||||
ports:
|
||||
- 3307:3306
|
||||
networks:
|
||||
- bookmark
|
||||
volumes:
|
||||
- ./mysql/data:/var/lib/mysql
|
||||
- ./mysql/temp:/var/lib/mysql-files
|
||||
- ./mysql/my.cnf:/etc/mysql/my.cnf
|
||||
- /etc/localtime:/etc/localtime
|
||||
- ./timezone:/etc/timezone
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=${MYSQL_PASSWORD}
|
||||
- MYSQL_DATABASE=bookmark
|
||||
bookmark-redis:
|
||||
image: redis:3.2.10
|
||||
container_name: bookmark-redis
|
||||
volumes:
|
||||
- /etc/localtime:/etc/localtime
|
||||
- ./timezone:/etc/timezone
|
||||
networks:
|
||||
- bookmark
|
||||
# redis未设置密码,如端口暴露可能会被攻击
|
||||
ports:
|
||||
- 6380:6379
|
||||
bookmark-es:
|
||||
image: elasticsearch:7.2.0
|
||||
container_name: bookmark-es
|
||||
volumes:
|
||||
- /etc/localtime:/etc/localtime
|
||||
- ./timezone:/etc/timezone
|
||||
- ./es/data:/usr/share/elasticsearch/data
|
||||
- ./es/ik:/usr/share/elasticsearch/plugins/ik
|
||||
- ./es/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
|
||||
environment:
|
||||
- "ES_JAVA_OPTS=-Xms1500m -Xmx1500m"
|
||||
ports:
|
||||
- 9200:9200
|
||||
- 9300:9300
|
||||
networks:
|
||||
- bookmark
|
||||
bookmark-front:
|
||||
image: nginx
|
||||
container_name: bookmark-front
|
||||
depends_on:
|
||||
- bookmark-service
|
||||
networks:
|
||||
- bookmark
|
||||
volumes:
|
||||
- /etc/localtime:/etc/localtime
|
||||
- ./timezone:/etc/timezone
|
||||
- ../front/build:/opt/dist
|
||||
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./nginx/log:/var/log/nginx
|
||||
- ${BOOKMARK_FILE_SAVE_PATH}/files/public:/opt/files/public
|
||||
ports:
|
||||
- 8083:8080
|
||||
bookmark-service:
|
||||
image: registry.cn-hangzhou.aliyuncs.com/fleyx/node-java-env:v2
|
||||
container_name: bookmark-service
|
||||
depends_on:
|
||||
- bookmark-mysql
|
||||
- bookmark-redis
|
||||
- bookmark-es
|
||||
networks:
|
||||
- bookmark
|
||||
volumes:
|
||||
- /etc/localtime:/etc/localtime
|
||||
- ./timezone:/etc/timezone
|
||||
- ../bookMarkService/web/target/bookmark-web-1.0-SNAPSHOT.jar:/opt/app/service.jar
|
||||
- ${BOOKMARK_FILE_SAVE_PATH}:/opt/files
|
||||
working_dir: /opt/app
|
||||
command:
|
||||
- /bin/bash
|
||||
- -c
|
||||
- |
|
||||
sleep 20 && \
|
||||
ls -l && \
|
||||
java -jar -DisDev=false \
|
||||
-DjwtSecret=${JWT_SECRET} \
|
||||
-Dmybatis-plus.configuration.log-impl=org.apache.ibatis.logging.nologging.NoLoggingImpl \
|
||||
-Dspring.mail.host=${SMTP_HOST} \
|
||||
-Dspring.mail.username=${SMTP_USERNAME} \
|
||||
-Dspring.mail.password=${SMTP_PASSWORD} \
|
||||
-Dspring.datasource.druid.password=${MYSQL_PASSWORD} \
|
||||
-Dspring.datasource.druid.url=jdbc:mysql://bookmark-mysql:3306/bookmark?useUnicode=true\&characterEncoding=utf-8\&useSSL=false\&useJDBCCompliantTimezoneShift=true\&useLegacyDatetimeCode=false\&serverTimezone=UTC \
|
||||
-Dspring.redis.host=bookmark-redis \
|
||||
-Des.host=bookmark-es \
|
||||
-DserviceAddress=${BOOKMARK_HOST} \
|
||||
-DfileSavePath=/opt/files \
|
||||
-DserviceAddress=https://bm.tapme.top \
|
||||
service.jar
|
||||
networks:
|
||||
bookmark:
|
15
bookMarkDocker/init.sh
Executable file
15
bookMarkDocker/init.sh
Executable file
@ -0,0 +1,15 @@
|
||||
#/bin/bash
|
||||
base=$(cd "$(dirname "$0")";pwd)
|
||||
|
||||
# 创建es存放数据文件夹并设置读写权限
|
||||
mkdir $base/es/data>/dev/null 2>&1
|
||||
|
||||
chmod 777 $base/es/data
|
||||
|
||||
sysctl -w vm.max_map_count=262144>/dev/null 2>&1
|
||||
|
||||
# 用于前后端打包
|
||||
|
||||
docker run -it --rm --name buildBookmark -v $base/../front:/opt/front registry.cn-hangzhou.aliyuncs.com/fleyx/node-java-env:v2 sh -c "cd /opt/front && npm --registry https://registry.npm.taobao.org install && npm run build"
|
||||
|
||||
docker run -it --rm --name buildBookmark -v $base/mavenRep:/opt/mavenRep -v $base/../bookMarkService:/opt/backend registry.cn-hangzhou.aliyuncs.com/fleyx/node-java-env:v2 sh -c "cd /opt/backend && mvn clean install && echo over"
|
@ -10,8 +10,8 @@ http {
|
||||
# SSL Settings
|
||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||
# Logging Settings
|
||||
access_log /dev/stdout;
|
||||
error_log /dev/stderr;
|
||||
access_log /var/log/nginx/access.log;
|
||||
error_log /var/log/nginx/error.log;
|
||||
# Gzip Settings
|
||||
gzip on;
|
||||
tcp_nopush on;
|
||||
@ -31,7 +31,7 @@ http {
|
||||
root /opt/dist/;
|
||||
server_name _;
|
||||
location /bookmark/api/ {
|
||||
proxy_pass http://backend:8088;
|
||||
proxy_pass http://bookmark-service:8088;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
client_max_body_size 100m;
|
@ -51,7 +51,8 @@ under the License.
|
||||
|
|
||||
| Default: ${user.home}/.m2/repository
|
||||
-->
|
||||
<localRepository>/var/maven/.m2/repository</localRepository>
|
||||
<localRepository>/opt/mavenRep</localRepository>
|
||||
|
||||
|
||||
<!-- interactiveMode
|
||||
| This will determine whether maven prompts you when it needs input. If set to false,
|
1
bookMarkService/.gitignore
vendored
1
bookMarkService/.gitignore
vendored
@ -17,7 +17,6 @@ static
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
node_modules
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
|
@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>bookmark-business</artifactId>
|
||||
<groupId>com.fanxb</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>bookmark-business-api</artifactId>
|
||||
|
||||
|
||||
</project>
|
@ -1,28 +0,0 @@
|
||||
package com.fanxb.bookmark.business.api;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author fanxb
|
||||
* @date 2021/3/13
|
||||
**/
|
||||
public interface BookmarkApi {
|
||||
/**
|
||||
* 更新某个用户的icon数据
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @author fanxb
|
||||
* @date 2021/3/11
|
||||
**/
|
||||
void updateUserBookmarkIcon(int userId);
|
||||
|
||||
/***
|
||||
* 删除一次数据
|
||||
* @author fanxb
|
||||
* @param delete 是否删除问题数据
|
||||
* @param userId userId
|
||||
* @return 返回删除的数据
|
||||
* @date 2021/3/17
|
||||
**/
|
||||
Set<String> dealBadBookmark(boolean delete, int userId);
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package com.fanxb.bookmark.business.api;
|
||||
|
||||
/**
|
||||
* @author fanxb
|
||||
* @date 2021/8/20 下午2:12
|
||||
*/
|
||||
public interface UserApi {
|
||||
/**
|
||||
* 版本自增
|
||||
*
|
||||
* @param userId 用户id
|
||||
*/
|
||||
void versionPlus(int userId);
|
||||
|
||||
/**
|
||||
* 更新所有用户的version
|
||||
*
|
||||
* @author fanxb
|
||||
* @date 2021/3/13
|
||||
**/
|
||||
void allUserVersionPlus();
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
/**
|
||||
* 用于模块间的方法相互调用,具体使用如下:
|
||||
* 1. 首先在business模块下建立interface接口,然后在个具体模块中实现
|
||||
* 2. 最后诸如interface,就能实现同级模块间的直接调用
|
||||
*/
|
||||
package com.fanxb.bookmark.business.api;
|
@ -12,27 +12,12 @@
|
||||
<artifactId>bookmark-business-bookmark</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.fanxb</groupId>
|
||||
<artifactId>bookmark-business-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<!--html文件解析-->
|
||||
<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
|
||||
<dependency>
|
||||
<groupId>org.jsoup</groupId>
|
||||
<artifactId>jsoup</artifactId>
|
||||
<version>1.15.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.houbb</groupId>
|
||||
<artifactId>pinyin</artifactId>
|
||||
<version>0.3.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.44.1.0</version>
|
||||
<version>1.12.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
@ -1,16 +0,0 @@
|
||||
package com.fanxb.bookmark.business.bookmark.constant;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @author fanxb
|
||||
*/
|
||||
public class FileConstant {
|
||||
|
||||
/**
|
||||
* 网站icon存储路径
|
||||
*/
|
||||
public static final String FAVICON_PATH = Paths.get("files", "public", "favicon").toString();
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package com.fanxb.bookmark.business.bookmark.consumer;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.fanxb.bookmark.business.bookmark.dao.PinBookmarkDao;
|
||||
import com.fanxb.bookmark.business.bookmark.entity.redis.BookmarkDeleteMessage;
|
||||
import com.fanxb.bookmark.common.annotation.MqConsumer;
|
||||
import com.fanxb.bookmark.common.constant.EsConstant;
|
||||
import com.fanxb.bookmark.common.constant.RedisConstant;
|
||||
import com.fanxb.bookmark.common.entity.redis.RedisConsumer;
|
||||
import com.fanxb.bookmark.common.util.EsUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA
|
||||
*
|
||||
* @author fanxb
|
||||
* Date: 2020/3/29
|
||||
* Time: 13:08
|
||||
*/
|
||||
@MqConsumer(RedisConstant.BOOKMARK_DELETE_ES)
|
||||
public class BookmarkDeleteMessageConsumer implements RedisConsumer {
|
||||
private final PinBookmarkDao pinBookmarkDao;
|
||||
private final EsUtil esUtil;
|
||||
|
||||
@Autowired
|
||||
public BookmarkDeleteMessageConsumer(PinBookmarkDao pinBookmarkDao, EsUtil esUtil) {
|
||||
this.pinBookmarkDao = pinBookmarkDao;
|
||||
this.esUtil = esUtil;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deal(String message) {
|
||||
BookmarkDeleteMessage obj = JSON.parseObject(message, BookmarkDeleteMessage.class);
|
||||
//删除首页固定的数据
|
||||
pinBookmarkDao.deleteUnExistBookmark(obj.getUserId());
|
||||
//删除es数据
|
||||
if (CollectionUtil.isNotEmpty(obj.getBookmarkIds())) {
|
||||
esUtil.deleteBatch(EsConstant.BOOKMARK_INDEX, obj.getBookmarkIds());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package com.fanxb.bookmark.business.bookmark.consumer;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.fanxb.bookmark.business.bookmark.entity.BookmarkEs;
|
||||
import com.fanxb.bookmark.common.annotation.MqConsumer;
|
||||
import com.fanxb.bookmark.common.constant.EsConstant;
|
||||
import com.fanxb.bookmark.common.constant.RedisConstant;
|
||||
import com.fanxb.bookmark.common.entity.po.Bookmark;
|
||||
import com.fanxb.bookmark.common.entity.EsEntity;
|
||||
import com.fanxb.bookmark.common.entity.redis.RedisConsumer;
|
||||
import com.fanxb.bookmark.common.util.EsUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 插入/更新数据到es中
|
||||
* Created with IntelliJ IDEA
|
||||
* Created By Fxb
|
||||
* Date: 2020/3/29
|
||||
* Time: 11:34
|
||||
* @author fanxb
|
||||
*/
|
||||
@MqConsumer(RedisConstant.BOOKMARK_INSERT_ES)
|
||||
public class BookmarkInsertEsConsumer implements RedisConsumer {
|
||||
|
||||
|
||||
@Autowired
|
||||
private EsUtil esUtil;
|
||||
|
||||
@Override
|
||||
public void deal(String message) {
|
||||
List<Bookmark> bookmarks = JSONArray.parseArray(message, Bookmark.class);
|
||||
if (CollectionUtil.isEmpty(bookmarks)) {
|
||||
return;
|
||||
}
|
||||
List<EsEntity<BookmarkEs>> esList = bookmarks.stream()
|
||||
.map(item -> new EsEntity<>(item.getBookmarkId().toString(), new BookmarkEs(item))).collect(Collectors.toList());
|
||||
esUtil.insertBatch(EsConstant.BOOKMARK_INDEX, esList);
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package com.fanxb.bookmark.business.bookmark.consumer;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.fanxb.bookmark.business.bookmark.dao.BookmarkDao;
|
||||
import com.fanxb.bookmark.business.bookmark.entity.redis.VisitNumPlus;
|
||||
import com.fanxb.bookmark.common.annotation.MqConsumer;
|
||||
import com.fanxb.bookmark.common.constant.RedisConstant;
|
||||
import com.fanxb.bookmark.common.entity.redis.RedisConsumer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* 更新书签时间
|
||||
* Created with IntelliJ IDEA
|
||||
* Created By Fxb
|
||||
* Date: 2020/5/12
|
||||
* Time: 10:33
|
||||
*
|
||||
* @author fanxb
|
||||
*/
|
||||
@MqConsumer(RedisConstant.BOOKMARK_VISIT_NUM_PLUS)
|
||||
@Slf4j
|
||||
public class BookmarkVisitNumPlusConsumer implements RedisConsumer {
|
||||
|
||||
private final BookmarkDao bookmarkDao;
|
||||
|
||||
@Autowired
|
||||
public BookmarkVisitNumPlusConsumer(BookmarkDao bookmarkDao) {
|
||||
this.bookmarkDao = bookmarkDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deal(String message) {
|
||||
VisitNumPlus item = JSON.parseObject(message, VisitNumPlus.class);
|
||||
try {
|
||||
bookmarkDao.updateVisitNum(item);
|
||||
} catch (Exception e) {
|
||||
log.error("书签访问次数增加失败:{}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package com.fanxb.bookmark.business.bookmark.controller;
|
||||
|
||||
import com.fanxb.bookmark.business.bookmark.service.BookmarkBackupService;
|
||||
import com.fanxb.bookmark.business.bookmark.service.impl.BookmarkBackupServiceImpl;
|
||||
import com.fanxb.bookmark.common.entity.Result;
|
||||
import com.fanxb.bookmark.common.util.ThreadPoolUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -21,17 +20,17 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
@RequestMapping("/bookmarkBackup")
|
||||
public class BookmarkBackupController {
|
||||
|
||||
private final BookmarkBackupService backupService;
|
||||
private BookmarkBackupService backupService;
|
||||
|
||||
@Autowired
|
||||
public BookmarkBackupController(BookmarkBackupServiceImpl backupService) {
|
||||
public BookmarkBackupController(BookmarkBackupService backupService) {
|
||||
this.backupService = backupService;
|
||||
}
|
||||
|
||||
@PostMapping("/mysqlToEs")
|
||||
public Result backupToEs() {
|
||||
//异步执行同步任务
|
||||
ThreadPoolUtil.execute(backupService::backupToEs);
|
||||
ThreadPoolUtil.execute(() -> backupService.backupToEs());
|
||||
return Result.success(null);
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,12 @@
|
||||
package com.fanxb.bookmark.business.bookmark.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.fanxb.bookmark.business.bookmark.entity.BatchDeleteBody;
|
||||
import com.fanxb.bookmark.business.bookmark.entity.BookmarkEs;
|
||||
import com.fanxb.bookmark.business.bookmark.entity.MoveNodeBody;
|
||||
import com.fanxb.bookmark.business.bookmark.service.BookmarkBackupService;
|
||||
import com.fanxb.bookmark.business.bookmark.service.BookmarkService;
|
||||
import com.fanxb.bookmark.business.bookmark.service.PinYinService;
|
||||
import com.fanxb.bookmark.common.entity.po.Bookmark;
|
||||
import com.fanxb.bookmark.common.entity.Bookmark;
|
||||
import com.fanxb.bookmark.common.entity.Result;
|
||||
import com.fanxb.bookmark.common.entity.UserContext;
|
||||
import com.fanxb.bookmark.common.util.UserContextHolder;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@ -26,12 +24,9 @@ import java.util.List;
|
||||
@RestController
|
||||
@RequestMapping("/bookmark")
|
||||
public class BookmarkController {
|
||||
@Autowired
|
||||
private BookmarkBackupService bookmarkBackupService;
|
||||
|
||||
@Autowired
|
||||
private BookmarkService bookmarkService;
|
||||
@Autowired
|
||||
private PinYinService pinYinService;
|
||||
|
||||
/**
|
||||
* Description: 获取路径为path的书签数据
|
||||
@ -67,9 +62,9 @@ public class BookmarkController {
|
||||
* @author fanxb
|
||||
* @date 2019/7/8 15:17
|
||||
*/
|
||||
@RequestMapping("/uploadBookmarkFile")
|
||||
@PutMapping("/uploadBookmarkFile")
|
||||
public Result uploadFile(@RequestParam("file") MultipartFile file, @RequestParam("path") String path) throws Exception {
|
||||
bookmarkService.parseBookmarkFile(UserContextHolder.get().getUserId(), file, path);
|
||||
bookmarkService.parseBookmarkFile(UserContextHolder.get().getUserId(), file.getInputStream(), path);
|
||||
return Result.success(null);
|
||||
}
|
||||
|
||||
@ -98,7 +93,8 @@ public class BookmarkController {
|
||||
*/
|
||||
@PostMapping("/updateOne")
|
||||
public Result editCurrentUserBookmark(@RequestBody Bookmark bookmark) {
|
||||
return Result.success(bookmarkService.updateOne(UserContextHolder.get().getUserId(), bookmark));
|
||||
bookmarkService.updateOne(UserContextHolder.get().getUserId(), bookmark);
|
||||
return Result.success(null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -111,7 +107,7 @@ public class BookmarkController {
|
||||
*/
|
||||
@PostMapping("/batchDelete")
|
||||
public Result batchDelete(@RequestBody BatchDeleteBody body) {
|
||||
bookmarkService.batchDelete(UserContextHolder.get().getUserId(), body.getPathList(), body.getBookmarkIdList());
|
||||
bookmarkService.batchDelete(UserContextHolder.get().getUserId(), body.getFolderIdList(), body.getBookmarkIdList());
|
||||
return Result.success(null);
|
||||
}
|
||||
|
||||
@ -144,70 +140,8 @@ public class BookmarkController {
|
||||
*/
|
||||
@PostMapping("/syncBookmark")
|
||||
public Result syncBookmark() {
|
||||
bookmarkBackupService.syncUserBookmark(UserContextHolder.get().getUserId());
|
||||
bookmarkService.syncUserBookmark(UserContextHolder.get().getUserId());
|
||||
return Result.success(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能描述: 全量更新拼音数据
|
||||
*
|
||||
* @return com.fanxb.bookmark.common.entity.Result
|
||||
* @author fanxb
|
||||
* @date 2020/3/22 22:22
|
||||
*/
|
||||
@PostMapping("/allPinyinCreate")
|
||||
public Result changeAllPinyin() {
|
||||
pinYinService.changeAll();
|
||||
return Result.success(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能描述: 书签增加1
|
||||
*
|
||||
* @param id id
|
||||
* @return com.fanxb.bookmark.common.entity.Result
|
||||
* @author fanxb
|
||||
* @date 2020/5/12 10:44
|
||||
*/
|
||||
@PostMapping("/visitNum")
|
||||
public Result visitNum(int id) {
|
||||
bookmarkService.visitNumPlus(id);
|
||||
return Result.success(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能描述: 获取用户访问次数前10的书签
|
||||
*
|
||||
* @author fanxb
|
||||
*/
|
||||
@GetMapping("/user/popular")
|
||||
public Result currentUserPopular() {
|
||||
return Result.success(bookmarkService.userPopular(10));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新所有的icon
|
||||
*
|
||||
* @author fanxb
|
||||
* @date 2021/3/11
|
||||
**/
|
||||
@PostMapping("/updateCurrentUserIcon")
|
||||
public Result updateCurrentUserIcon() {
|
||||
bookmarkService.updateUserBookmarkIcon(UserContextHolder.get().getUserId());
|
||||
return Result.success(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查/删除无父节点的数据
|
||||
*
|
||||
* @return com.fanxb.bookmark.common.entity.Result
|
||||
* @author fanxb
|
||||
* @date 2021/3/17
|
||||
**/
|
||||
@PostMapping("/dealBadBookmark")
|
||||
public Result dealBadBookmark(@RequestBody JSONObject obj) {
|
||||
return Result.success(bookmarkService.dealBadBookmark(obj.getBoolean("delete"), UserContextHolder.get().getUserId()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,56 +0,0 @@
|
||||
package com.fanxb.bookmark.business.bookmark.controller;
|
||||
|
||||
import com.fanxb.bookmark.business.bookmark.entity.po.PInBookmarkPo;
|
||||
import com.fanxb.bookmark.business.bookmark.service.HomePinService;
|
||||
import com.fanxb.bookmark.common.entity.Result;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 首页相关接口
|
||||
*
|
||||
* @author fanxb
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/home")
|
||||
public class HomeController {
|
||||
|
||||
private final HomePinService homePinService;
|
||||
|
||||
@Autowired
|
||||
public HomeController(HomePinService homePinService) {
|
||||
this.homePinService = homePinService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取首页固定标签
|
||||
*
|
||||
* @author fanxb
|
||||
*/
|
||||
@GetMapping("/pin")
|
||||
public Result getPin() {
|
||||
return Result.success(homePinService.getHomePinList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增固定书签
|
||||
*
|
||||
* @author fanxb
|
||||
*/
|
||||
@PutMapping("/pin")
|
||||
public Result addPin(@RequestBody PInBookmarkPo po) {
|
||||
return Result.success(homePinService.addOne(po));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除书签
|
||||
*
|
||||
* @param id url参数id
|
||||
* @author fanxb
|
||||
*/
|
||||
@DeleteMapping("/pin")
|
||||
public Result deleteOne(int id) {
|
||||
homePinService.delete(id);
|
||||
return Result.success();
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.fanxb.bookmark.business.bookmark.dao;
|
||||
|
||||
import com.fanxb.bookmark.common.entity.Bookmark;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA
|
||||
* Created By Fxb
|
||||
* Date: 2019/11/12
|
||||
* Time: 0:24
|
||||
*/
|
||||
@Mapper
|
||||
public interface BookmarkBackupDao {
|
||||
|
||||
/**
|
||||
* 分页获取所有的书签
|
||||
* @param size 大小
|
||||
* @param startIndex 开始下标
|
||||
* @return
|
||||
*/
|
||||
@Select("select * from bookmark order by bookmarkId limit ${startIndex},${size}")
|
||||
List<Bookmark> getBookmarkListPage(@Param("size") int size,@Param("startIndex") int startIndex);
|
||||
}
|
@ -1,12 +1,8 @@
|
||||
package com.fanxb.bookmark.business.bookmark.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.fanxb.bookmark.business.bookmark.entity.BookmarkEs;
|
||||
import com.fanxb.bookmark.business.bookmark.entity.redis.VisitNumPlus;
|
||||
import com.fanxb.bookmark.common.entity.po.Bookmark;
|
||||
import com.fanxb.bookmark.common.entity.Bookmark;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
@ -19,12 +15,13 @@ import java.util.List;
|
||||
* @date 2019/7/8 16:39
|
||||
*/
|
||||
@Component
|
||||
public interface BookmarkDao extends BaseMapper<Bookmark> {
|
||||
public interface BookmarkDao {
|
||||
|
||||
/**
|
||||
* Description: 插入一条书签记录
|
||||
*
|
||||
* @param node node
|
||||
* @return void
|
||||
* @author fanxb
|
||||
* @date 2019/7/8 16:49
|
||||
*/
|
||||
@ -57,7 +54,7 @@ public interface BookmarkDao extends BaseMapper<Bookmark> {
|
||||
* Description: 根据用户id获取其所有数据
|
||||
*
|
||||
* @param userId userid
|
||||
* @return java.util.List<com.fanxb.bookmark.common.entity.po.Bookmark>
|
||||
* @return java.util.List<com.fanxb.bookmark.common.entity.Bookmark>
|
||||
* @author fanxb
|
||||
* @date 2019/7/9 18:55
|
||||
*/
|
||||
@ -68,21 +65,21 @@ public interface BookmarkDao extends BaseMapper<Bookmark> {
|
||||
*
|
||||
* @param userId userId
|
||||
* @param path path
|
||||
* @return java.util.List<com.fanxb.bookmark.common.entity.po.Bookmark>
|
||||
* @return java.util.List<com.fanxb.bookmark.common.entity.Bookmark>
|
||||
* @author fanxb
|
||||
* @date 2019/7/17 14:48
|
||||
*/
|
||||
List<Bookmark> getListByUserIdAndPath(@Param("userId") int userId, @Param("path") String path);
|
||||
|
||||
/**
|
||||
* Description: 删除某用户某个书签路径下所有数据,不包含文件夹自身
|
||||
* Description: 删除某用户某个书签文件下所有数据
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @param path 文件夹id
|
||||
* @param folderId 文件夹id
|
||||
* @author fanxb
|
||||
* @date 2019/7/12 14:13
|
||||
*/
|
||||
void deleteUserFolder(@Param("userId") int userId, @Param("path") String path);
|
||||
void deleteUserFolder(@Param("userId") int userId, @Param("folderId") int folderId);
|
||||
|
||||
/**
|
||||
* Description: 删除用户书签
|
||||
@ -138,127 +135,27 @@ public interface BookmarkDao extends BaseMapper<Bookmark> {
|
||||
void updatePathAndSort(@Param("userId") int userId, @Param("bookmarkId") int bookmarkId, @Param("path") String path, @Param("sort") int sort);
|
||||
|
||||
/**
|
||||
* Description: 获取某个路径下所有的节点id
|
||||
* Description: 获取某个文件夹下所有的节点id
|
||||
*
|
||||
* @param userId userId
|
||||
* @param path path
|
||||
* @param folderId folderId
|
||||
* @return java.util.List<java.lang.Integer>
|
||||
* @author fanxb
|
||||
* @date 2019/7/25 14:14
|
||||
*/
|
||||
List<Integer> getChildrenBookmarkId(@Param("userId") int userId, @Param("path") String path);
|
||||
List<Integer> getChildrenBookmarkId(@Param("userId") int userId, @Param("folderId") int folderId);
|
||||
|
||||
/**
|
||||
* Description: 根据用户id,类别,分页查找书签
|
||||
*
|
||||
* @author fanxb
|
||||
* @date 2019/7/26 15:23
|
||||
* @param userId userId
|
||||
* @param type type
|
||||
* @param start start
|
||||
* @param size size
|
||||
* @return java.util.List<com.fanxb.bookmark.business.bookmark.entity.BookmarkEs>
|
||||
* @author fanxb
|
||||
* @date 2019/7/26 15:23
|
||||
*/
|
||||
List<BookmarkEs> selectBookmarkEsByUserIdAndType(@Param("userId") int userId, @Param("type") int type, @Param("start") int start, @Param("size") int size);
|
||||
|
||||
/**
|
||||
* 功能描述: 查询所有的bookmark,用于全量更新拼音key
|
||||
*
|
||||
* @param bookmarkId bookmarkId
|
||||
* @param size size
|
||||
* @return List<Bookmark>
|
||||
* @author fanxb
|
||||
* @date 2020/3/22 22:06
|
||||
*/
|
||||
@Select("select bookmarkId,name,url from bookmark where bookmarkId>${bookmarkId} order by bookmarkId asc limit 0,${size}")
|
||||
List<Bookmark> selectPinyinEmpty(@Param("bookmarkId") int bookmarkId, @Param("size") int size);
|
||||
|
||||
/**
|
||||
* 功能描述: 更新一个bookmark的key
|
||||
*
|
||||
* @param bookmarkId id
|
||||
* @param searchKey searchKey
|
||||
* @author fanxb
|
||||
* @date 2020/3/22 22:08
|
||||
*/
|
||||
@Update("update bookmark set searchKey=#{searchKey} where bookmarkId=#{bookmarkId}")
|
||||
void updateSearchKey(@Param("bookmarkId") int bookmarkId, @Param("searchKey") String searchKey);
|
||||
|
||||
/**
|
||||
* 批量更新searchKey
|
||||
*
|
||||
* @param list list
|
||||
* @author fanxb
|
||||
* @date 2020/3/22 22:08
|
||||
*/
|
||||
void updateSearchKeyBatch(List<Bookmark> list);
|
||||
|
||||
/**
|
||||
* 分页获取所有的书签
|
||||
*
|
||||
* @param size 大小
|
||||
* @param startIndex 开始下标
|
||||
* @return bookmark List
|
||||
* @author fanxb
|
||||
*/
|
||||
@Select("select * from bookmark order by bookmarkId limit ${startIndex},${size}")
|
||||
List<Bookmark> getBookmarkListPage(@Param("size") int size, @Param("startIndex") int startIndex);
|
||||
|
||||
/**
|
||||
* 功能描述: 书签访问次数+1
|
||||
*
|
||||
* @param item 信息
|
||||
* @author fanxb
|
||||
* @date 2020/5/12 10:40
|
||||
*/
|
||||
@Update("update bookmark set visitNum=visitNum+1 where userId=#{userId} and bookmarkId=#{bookmarkId}")
|
||||
void updateVisitNum(VisitNumPlus item);
|
||||
|
||||
/**
|
||||
* 查询用户最常访问的几个书签
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @param num num
|
||||
* @return java.util.List<com.fanxb.bookmark.common.entity.po.Bookmark>
|
||||
* @author fanxb
|
||||
* @date 2021/8/20 上午11:52
|
||||
*/
|
||||
@Select("select bookmarkId,name,url,icon from bookmark where userId=#{userId} and type=0 order by visitNum desc limit 0,#{num}")
|
||||
List<Bookmark> selectPopular(@Param("userId") int userId, @Param("num") int num);
|
||||
|
||||
/**
|
||||
* 获取某用户无icon的条目
|
||||
*
|
||||
* @param userId userId
|
||||
* @param start 开始
|
||||
* @param size 数量
|
||||
* @return java.util.List<com.fanxb.bookmark.common.entity.po.Bookmark>
|
||||
* @author fanxb
|
||||
* @date 2021/8/20 下午12:02
|
||||
*/
|
||||
@Select("select userId,bookmarkId,url,icon from bookmark where userId=#{userId} and icon='' order by bookmarkId asc limit #{start},#{size}")
|
||||
List<Bookmark> selectUserNoIcon(@Param("userId") int userId, @Param("start") int start, @Param("size") int size);
|
||||
|
||||
/**
|
||||
* 更新icon
|
||||
*
|
||||
* @param bookmarkId bookmarkId
|
||||
* @param icon icon
|
||||
* @author fanxb
|
||||
* @date 2021/3/13
|
||||
**/
|
||||
@Update("update bookmark set icon=#{icon} where bookmarkId=#{bookmarkId}")
|
||||
void updateIcon(@Param("bookmarkId") int bookmarkId, @Param("icon") String icon);
|
||||
|
||||
/**
|
||||
* 查询一个用户全部的书签路径
|
||||
*
|
||||
* @param userId userId
|
||||
* @return java.util.List<com.fanxb.bookmark.common.entity.po.Bookmark>
|
||||
* @author fanxb
|
||||
* @date 2021/8/20 上午11:58
|
||||
*/
|
||||
@Select("select bookmarkId,path from bookmark where userId=#{userId}")
|
||||
List<Bookmark> selectBookmarkIdPathByUserId(int userId);
|
||||
|
||||
}
|
||||
|
@ -1,39 +0,0 @@
|
||||
package com.fanxb.bookmark.business.bookmark.dao;
|
||||
|
||||
import org.apache.ibatis.annotations.*;
|
||||
|
||||
/**
|
||||
* @author fanxb
|
||||
*/
|
||||
@Mapper
|
||||
public interface HostIconDao {
|
||||
|
||||
/**
|
||||
* 插入一条数据
|
||||
*
|
||||
* @param host host
|
||||
* @param iconPath path
|
||||
* @author fanxb
|
||||
*/
|
||||
@Insert("insert into host_icon(host,iconPath) value(#{host},#{iconPath})")
|
||||
void insert(@Param("host") String host, @Param("iconPath") String iconPath);
|
||||
|
||||
/**
|
||||
* 根据host获取iconPath
|
||||
*
|
||||
* @param host host
|
||||
* @return {@link String}
|
||||
* @author fanxb
|
||||
*/
|
||||
@Select("select iconPath from host_icon where host=#{host} limit 1")
|
||||
String selectByHost(String host);
|
||||
|
||||
/**
|
||||
* 删除一条
|
||||
*
|
||||
* @param host host
|
||||
* @author FleyX
|
||||
*/
|
||||
@Delete("delete from host_icon where host=#{host}")
|
||||
void deleteByHost(String host);
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
package com.fanxb.bookmark.business.bookmark.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.fanxb.bookmark.business.bookmark.entity.po.PInBookmarkPo;
|
||||
import com.fanxb.bookmark.business.bookmark.entity.vo.HomePinItemVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author fanxb
|
||||
*/
|
||||
@Mapper
|
||||
public interface PinBookmarkDao extends BaseMapper<PInBookmarkPo> {
|
||||
|
||||
/***
|
||||
* 获取用户固定的书签
|
||||
*
|
||||
* @param userId userId
|
||||
* @return {@link List<HomePinItemVo>}
|
||||
* @author fanxb
|
||||
*/
|
||||
@Select("select a.id,b.bookmarkId,b.name,b.url,b.icon from pin_bookmark a inner join bookmark b on a.bookmarkId=b.bookmarkId where a.userId=#{userId}")
|
||||
List<HomePinItemVo> selectUserPin(int userId);
|
||||
|
||||
/**
|
||||
* 获取当前最大的序列号
|
||||
*
|
||||
* @param userId userId
|
||||
* @return {@link int}
|
||||
* @author fanxb
|
||||
*/
|
||||
@Select("select ifnull(max(sort),0) from pin_bookmark where userId=#{userId}")
|
||||
int getUserMaxSort(int userId);
|
||||
|
||||
/**
|
||||
* 删除书签后,需要清理此表,将不存在的书签删除
|
||||
*
|
||||
* @param userId userId
|
||||
* @author fanxb
|
||||
*/
|
||||
void deleteUnExistBookmark(int userId);
|
||||
}
|
@ -13,12 +13,6 @@ import java.util.List;
|
||||
*/
|
||||
@Data
|
||||
public class BatchDeleteBody{
|
||||
/**
|
||||
* 要删除的书签路径
|
||||
*/
|
||||
private List<String> pathList;
|
||||
/**
|
||||
* 要删除的书签id
|
||||
*/
|
||||
private List<Integer> folderIdList;
|
||||
private List<Integer> bookmarkIdList;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package com.fanxb.bookmark.business.bookmark.entity;
|
||||
|
||||
import com.fanxb.bookmark.common.entity.po.Bookmark;
|
||||
import com.fanxb.bookmark.common.entity.Bookmark;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
|
@ -1,41 +0,0 @@
|
||||
package com.fanxb.bookmark.business.bookmark.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA
|
||||
*
|
||||
* @author fanxb
|
||||
* Date: 2020/3/19
|
||||
* Time: 0:05
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
public class PinYinBody {
|
||||
/**
|
||||
* 待转换拼音的文本列表
|
||||
*/
|
||||
private List<String> strs;
|
||||
private Config config;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public static class Config {
|
||||
/**
|
||||
* 是否启用分词模式
|
||||
*/
|
||||
private boolean segment;
|
||||
/**
|
||||
* 是否启用多音字
|
||||
*/
|
||||
private boolean heteronym;
|
||||
/**
|
||||
* 风格
|
||||
*/
|
||||
private int style;
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package com.fanxb.bookmark.business.bookmark.entity.po;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 首页固定标签
|
||||
*
|
||||
* @author fanxb
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
@TableName("pin_bookmark")
|
||||
public class PInBookmarkPo {
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private int id;
|
||||
private int userId;
|
||||
private int bookmarkId;
|
||||
private int sort;
|
||||
private long createDate;
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package com.fanxb.bookmark.business.bookmark.entity.redis;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author fanxb
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class BookmarkDeleteMessage {
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
private int userId;
|
||||
/**
|
||||
* 批量删除的书签id
|
||||
*/
|
||||
private Collection<String> bookmarkIds;
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
package com.fanxb.bookmark.business.bookmark.entity.redis;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA
|
||||
*
|
||||
* @author fanxb
|
||||
* Date: 2020/5/12 11:47
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class VisitNumPlus {
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
private int userId;
|
||||
/**
|
||||
* 书签id
|
||||
*/
|
||||
private int bookmarkId;
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package com.fanxb.bookmark.business.bookmark.entity.vo;
|
||||
|
||||
import com.fanxb.bookmark.business.bookmark.entity.po.PInBookmarkPo;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* @author fanxb
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
public class HomePinItemVo {
|
||||
/**
|
||||
* pinBookmark Id
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 书签id
|
||||
*/
|
||||
private int bookmarkId;
|
||||
/**
|
||||
* 书签名
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* url
|
||||
*/
|
||||
private String url;
|
||||
/**
|
||||
* icon
|
||||
*/
|
||||
private String icon;
|
||||
}
|
@ -1,12 +1,38 @@
|
||||
package com.fanxb.bookmark.business.bookmark.service;
|
||||
|
||||
/**
|
||||
* @author fanxb
|
||||
* Date: 2020/3/29
|
||||
* Time: 12:43
|
||||
*/
|
||||
public interface BookmarkBackupService {
|
||||
import com.fanxb.bookmark.business.bookmark.dao.BookmarkBackupDao;
|
||||
import com.fanxb.bookmark.business.bookmark.dao.BookmarkDao;
|
||||
import com.fanxb.bookmark.common.constant.EsConstant;
|
||||
import com.fanxb.bookmark.common.entity.Bookmark;
|
||||
import com.fanxb.bookmark.common.entity.EsEntity;
|
||||
import com.fanxb.bookmark.common.util.EsUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA
|
||||
* Created By Fxb
|
||||
* Date: 2019/11/12
|
||||
* Time: 0:22
|
||||
*
|
||||
* @author fanxb
|
||||
*/
|
||||
@Service
|
||||
public class BookmarkBackupService {
|
||||
|
||||
@Autowired
|
||||
private BookmarkBackupDao bookmarkBackupDao;
|
||||
|
||||
@Autowired
|
||||
private EsUtil esUtil;
|
||||
|
||||
/**
|
||||
* 一次同步BACKUP_SIZE条到es中
|
||||
*/
|
||||
private static final int BACKUP_SIZE = 500;
|
||||
|
||||
/**
|
||||
* 功能描述: 将mysql数据同步到es中
|
||||
@ -14,14 +40,14 @@ public interface BookmarkBackupService {
|
||||
* @author fanxb
|
||||
* @date 2019/11/12 0:22
|
||||
*/
|
||||
void backupToEs();
|
||||
|
||||
/**
|
||||
* Description: 将某个用户的书签数据mysql同步到es中
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @author fanxb
|
||||
* @date 2019/7/26 11:27
|
||||
*/
|
||||
void syncUserBookmark(int userId);
|
||||
public void backupToEs() {
|
||||
int start = 0;
|
||||
List<Bookmark> list;
|
||||
while ((list = bookmarkBackupDao.getBookmarkListPage(BACKUP_SIZE, start)).size() != 0) {
|
||||
List<EsEntity> batchList = new ArrayList<>(list.size());
|
||||
list.forEach(item -> batchList.add(new EsEntity<>(item.getBookmarkId().toString(), item)));
|
||||
esUtil.insertBatch(EsConstant.BOOKMARK_INDEX, batchList);
|
||||
start += BACKUP_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,150 +1,323 @@
|
||||
package com.fanxb.bookmark.business.bookmark.service;
|
||||
|
||||
import com.fanxb.bookmark.business.bookmark.dao.BookmarkDao;
|
||||
import com.fanxb.bookmark.business.bookmark.entity.BookmarkEs;
|
||||
import com.fanxb.bookmark.business.bookmark.entity.MoveNodeBody;
|
||||
import com.fanxb.bookmark.common.entity.po.Bookmark;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.fanxb.bookmark.common.constant.EsConstant;
|
||||
import com.fanxb.bookmark.common.constant.RedisConstant;
|
||||
import com.fanxb.bookmark.common.entity.Bookmark;
|
||||
import com.fanxb.bookmark.common.entity.EsEntity;
|
||||
import com.fanxb.bookmark.common.entity.redis.UserBookmarkUpdate;
|
||||
import com.fanxb.bookmark.common.exception.FormDataException;
|
||||
import com.fanxb.bookmark.common.util.EsUtil;
|
||||
import com.fanxb.bookmark.common.util.RedisUtil;
|
||||
import com.fanxb.bookmark.common.util.UserContextHolder;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.elasticsearch.index.query.BoolQueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.index.query.TermQueryBuilder;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA
|
||||
* 类功能简述:
|
||||
* 类功能详述:
|
||||
*
|
||||
* @author fanxb
|
||||
* Date: 2020/3/29
|
||||
* Time: 12:25
|
||||
* @date 2019/7/8 15:00
|
||||
*/
|
||||
public interface BookmarkService {
|
||||
@Service
|
||||
@Slf4j
|
||||
public class BookmarkService {
|
||||
/**
|
||||
* chrome导出书签tag
|
||||
*/
|
||||
String DT = "dt";
|
||||
String A = "a";
|
||||
private static final String DT = "dt";
|
||||
private static final String A = "a";
|
||||
|
||||
/**
|
||||
* Description: 根据userId和path获取书签列表
|
||||
*
|
||||
* @param userId userId
|
||||
* @param path path
|
||||
* @return java.util.List<com.fanxb.bookmark.common.entity.po.Bookmark>
|
||||
* @author fanxb
|
||||
* @date 2019/7/15 13:40
|
||||
*/
|
||||
List<Bookmark> getBookmarkListByPath(int userId, String path);
|
||||
@Autowired
|
||||
private BookmarkDao bookmarkDao;
|
||||
@Autowired
|
||||
private StringRedisTemplate redisTemplate;
|
||||
|
||||
/**
|
||||
* 功能描述: 获取某个用户的书签map
|
||||
*
|
||||
* @param userId userId
|
||||
* @return java.util.Map<java.lang.String, java.util.List < com.fanxb.bookmark.common.entity.po.Bookmark>>
|
||||
* @author fanxb
|
||||
* @date 2019/12/14 0:02
|
||||
*/
|
||||
Map<String, List<Bookmark>> getOneBookmarkTree(int userId);
|
||||
@Autowired
|
||||
private EsUtil esUtil;
|
||||
|
||||
/**
|
||||
* Description: 解析书签文件
|
||||
*
|
||||
* @param stream 输入流
|
||||
* @param path 存放路径
|
||||
* @param userId userId
|
||||
* @throws Exception 各种异常
|
||||
* @author fanxb
|
||||
* @date 2019/7/9 18:44
|
||||
*/
|
||||
void parseBookmarkFile(int userId, MultipartFile file, String path) throws Exception;
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void parseBookmarkFile(int userId, InputStream stream, String path) throws Exception {
|
||||
Document doc = Jsoup.parse(stream, "utf-8", "");
|
||||
Elements elements = doc.select("html>body>dl>dt");
|
||||
//获取当前层sort最大值
|
||||
Integer sortBase = bookmarkDao.selectMaxSort(userId, path);
|
||||
if (sortBase == null) {
|
||||
sortBase = 0;
|
||||
}
|
||||
int count = 0;
|
||||
// 將要插入es的书签数据放到list中,最后一次插入,尽量避免mysql回滚了,但是es插入了
|
||||
List<EsEntity> insertEsList = new ArrayList<>();
|
||||
for (int i = 0, length = elements.size(); i < length; i++) {
|
||||
if (i == 0) {
|
||||
Elements firstChildren = elements.get(0).child(1).children();
|
||||
count = firstChildren.size();
|
||||
for (int j = 0; j < count; j++) {
|
||||
dealBookmark(userId, firstChildren.get(j), path, sortBase + j, insertEsList);
|
||||
}
|
||||
} else {
|
||||
dealBookmark(userId, elements.get(i), path, sortBase + count + i - 1, insertEsList);
|
||||
}
|
||||
}
|
||||
redisTemplate.opsForList().leftPush(RedisConstant.BOOKMARK_UPDATE_TIME, new UserBookmarkUpdate(userId, System.currentTimeMillis()).toString());
|
||||
esUtil.insertBatch(EsConstant.BOOKMARK_INDEX, insertEsList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Description: 处理html节点,解析出文件夹和书签
|
||||
*
|
||||
* @param ele 待处理节点
|
||||
* @param path 节点路径,不包含自身
|
||||
* @param sort 当前层级中的排序序号
|
||||
* @author fanxb
|
||||
* @date 2019/7/8 14:49
|
||||
*/
|
||||
private void dealBookmark(int userId, Element ele, String path, int sort, List<EsEntity> insertList) {
|
||||
if (!DT.equalsIgnoreCase(ele.tagName())) {
|
||||
return;
|
||||
}
|
||||
Element first = ele.child(0);
|
||||
if (A.equalsIgnoreCase(first.tagName())) {
|
||||
//说明为链接
|
||||
Bookmark node = new Bookmark(userId, path, first.ownText(), first.attr("href"), first.attr("icon")
|
||||
, Long.parseLong(first.attr("add_date")) * 1000, sort);
|
||||
//存入数据库
|
||||
insertOne(node);
|
||||
insertList.add(new EsEntity<>(node.getBookmarkId().toString(), new BookmarkEs(node)));
|
||||
} else {
|
||||
//说明为文件夹
|
||||
Bookmark node = new Bookmark(userId, path, first.ownText(), Long.parseLong(first.attr("add_date")) * 1000, sort);
|
||||
Integer sortBase = 0;
|
||||
if (insertOne(node)) {
|
||||
sortBase = bookmarkDao.selectMaxSort(node.getUserId(), path);
|
||||
if (sortBase == null) {
|
||||
sortBase = 0;
|
||||
}
|
||||
}
|
||||
String childPath = path + "." + node.getBookmarkId();
|
||||
Elements children = ele.child(1).children();
|
||||
for (int i = 0, size = children.size(); i < size; i++) {
|
||||
dealBookmark(userId, children.get(i), childPath, sortBase + i + 1, insertList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Description: 插入一条书签,如果已经存在同名书签将跳过
|
||||
*
|
||||
* @param node node
|
||||
* @return boolean 如果已经存在返回true,否则false
|
||||
* @author fanxb
|
||||
* @date 2019/7/8 17:25
|
||||
*/
|
||||
private boolean insertOne(Bookmark node) {
|
||||
//先根据name,userId,parentId获取此节点id
|
||||
Integer id = bookmarkDao.selectIdByUserIdAndNameAndPath(node.getUserId(), node.getName(), node.getPath());
|
||||
if (id == null) {
|
||||
bookmarkDao.insertOne(node);
|
||||
return false;
|
||||
} else {
|
||||
node.setBookmarkId(id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 功能描述: 获取某个用户的书签map
|
||||
*
|
||||
* @param userId userId
|
||||
* @return java.util.Map<java.lang.String, java.util.List < com.fanxb.bookmark.common.entity.Bookmark>>
|
||||
* @author fanxb
|
||||
* @date 2019/12/14 0:02
|
||||
*/
|
||||
public Map<String, List<Bookmark>> getOneBookmarkTree(int userId) {
|
||||
List<Bookmark> list = bookmarkDao.getListByUserId(userId);
|
||||
Map<String, List<Bookmark>> map = new HashMap<>(50);
|
||||
list.forEach(item -> {
|
||||
map.computeIfAbsent(item.getPath(), k -> new ArrayList<>());
|
||||
map.get(item.getPath()).add(item);
|
||||
});
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Description: 根据userId和path获取书签列表
|
||||
*
|
||||
* @param userId userId
|
||||
* @param path path
|
||||
* @return java.util.List<com.fanxb.bookmark.common.entity.Bookmark>
|
||||
* @author fanxb
|
||||
* @date 2019/7/15 13:40
|
||||
*/
|
||||
public List<Bookmark> getBookmarkListByPath(int userId, String path) {
|
||||
return bookmarkDao.getListByUserIdAndPath(userId, path);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Description: 批量删除书签
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @param folderIdList 书签文件夹id list
|
||||
* @param bookmarkIdList 书签id list
|
||||
* @author fanxb
|
||||
* @date 2019/7/12 14:09
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchDelete(int userId, List<Integer> folderIdList, List<Integer> bookmarkIdList) {
|
||||
Set<Integer> set = new HashSet<>();
|
||||
for (Integer item : folderIdList) {
|
||||
set.addAll(bookmarkDao.getChildrenBookmarkId(userId, item));
|
||||
bookmarkDao.deleteUserFolder(userId, item);
|
||||
bookmarkIdList.add(item);
|
||||
}
|
||||
if (bookmarkIdList.size() > 0) {
|
||||
bookmarkDao.deleteUserBookmark(userId, bookmarkIdList);
|
||||
}
|
||||
set.addAll(bookmarkIdList);
|
||||
redisTemplate.opsForList().leftPush(RedisConstant.BOOKMARK_UPDATE_TIME, new UserBookmarkUpdate(userId, System.currentTimeMillis()).toString());
|
||||
//es 中批量删除
|
||||
esUtil.deleteBatch(EsConstant.BOOKMARK_INDEX, set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Description: 详情
|
||||
*
|
||||
* @param bookmark 插入一条记录
|
||||
* @return com.fanxb.bookmark.common.entity.po.Bookmark
|
||||
* @return com.fanxb.bookmark.common.entity.Bookmark
|
||||
* @author fanxb
|
||||
* @date 2019/7/12 17:18
|
||||
*/
|
||||
Bookmark addOne(Bookmark bookmark);
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Bookmark addOne(Bookmark bookmark) {
|
||||
int userId = UserContextHolder.get().getUserId();
|
||||
Integer sort = bookmarkDao.selectMaxSort(userId, bookmark.getPath());
|
||||
bookmark.setSort(sort == null ? 1 : sort + 1);
|
||||
bookmark.setUserId(userId);
|
||||
bookmark.setCreateTime(System.currentTimeMillis());
|
||||
bookmark.setAddTime(bookmark.getCreateTime());
|
||||
try {
|
||||
bookmarkDao.insertOne(bookmark);
|
||||
} catch (DuplicateKeyException e) {
|
||||
throw new FormDataException("同级目录下不能存在相同名称的数据");
|
||||
}
|
||||
//如果是书签,插入到es中
|
||||
if (bookmark.getType() == 0) {
|
||||
esUtil.insertOrUpdateOne(EsConstant.BOOKMARK_INDEX,
|
||||
new EsEntity<>(bookmark.getBookmarkId().toString(), new BookmarkEs(bookmark)));
|
||||
}
|
||||
redisTemplate.opsForList().leftPush(RedisConstant.BOOKMARK_UPDATE_TIME, new UserBookmarkUpdate(userId, System.currentTimeMillis()).toString());
|
||||
return bookmark;
|
||||
}
|
||||
|
||||
/**
|
||||
* Description: 编辑某个用户的某个书签
|
||||
*
|
||||
* @param userId userId
|
||||
* @param bookmark bookmark
|
||||
* @return 更新后的icon
|
||||
* @author fanxb
|
||||
* @date 2019/7/17 14:42
|
||||
*/
|
||||
String updateOne(int userId, Bookmark bookmark);
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateOne(int userId, Bookmark bookmark) {
|
||||
bookmark.setUserId(userId);
|
||||
bookmarkDao.editBookmark(bookmark);
|
||||
if (bookmark.getType() == 0) {
|
||||
esUtil.insertOrUpdateOne(EsConstant.BOOKMARK_INDEX,
|
||||
new EsEntity<>(bookmark.getBookmarkId().toString(), new BookmarkEs(bookmark)));
|
||||
}
|
||||
redisTemplate.opsForList().leftPush(RedisConstant.BOOKMARK_UPDATE_TIME, new UserBookmarkUpdate(userId, System.currentTimeMillis()).toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Description: 批量删除书签
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @param pathList 要删除的路径list
|
||||
* @param bookmarkIdList 书签id list
|
||||
* @author fanxb
|
||||
* @date 2019/7/12 14:09
|
||||
*/
|
||||
void batchDelete(int userId, List<String> pathList, List<Integer> bookmarkIdList);
|
||||
|
||||
/**
|
||||
* 功能描述: 移动一个节点
|
||||
*
|
||||
* @param userId userId
|
||||
* @param body body
|
||||
* @author 123
|
||||
* @date 2020/3/29 12:30
|
||||
*/
|
||||
void moveNode(int userId, MoveNodeBody body);
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void moveNode(int userId, MoveNodeBody body) {
|
||||
if (body.getSort() == -1) {
|
||||
Integer max = bookmarkDao.selectMaxSort(userId, body.getTargetPath());
|
||||
body.setSort(max == null ? 1 : max);
|
||||
} else {
|
||||
//更新目标节点的sort
|
||||
bookmarkDao.sortPlus(userId, body.getTargetPath(), body.getSort());
|
||||
}
|
||||
//如果目标位置和当前位置不在一个层级中需要更新子节点的path
|
||||
if (!body.getTargetPath().equals(body.getSourcePath())) {
|
||||
bookmarkDao.updateChildrenPath(userId, body.getSourcePath() + "." + body.getBookmarkId()
|
||||
, body.getTargetPath() + "." + body.getBookmarkId());
|
||||
}
|
||||
//更新被移动节点的path和sort
|
||||
bookmarkDao.updatePathAndSort(userId, body.getBookmarkId(), body.getTargetPath(), body.getSort());
|
||||
redisTemplate.opsForList().leftPush(RedisConstant.BOOKMARK_UPDATE_TIME, new UserBookmarkUpdate(userId, System.currentTimeMillis()).toString());
|
||||
log.info("{},从{}移动到{},sort:{}", userId, body.getSourcePath(), body.getTargetPath(), body.getSort());
|
||||
}
|
||||
|
||||
/**
|
||||
* Description: 根据context搜索
|
||||
*
|
||||
* @param userId userId
|
||||
* @param context context
|
||||
* @return es搜索结果
|
||||
* @author fanxb
|
||||
* @date 2019/7/25 10:45
|
||||
*/
|
||||
List<BookmarkEs> searchUserBookmark(int userId, String context);
|
||||
|
||||
/**
|
||||
* 功能描述: 当前用户书签访问次数+1
|
||||
*
|
||||
* @param id 书签id
|
||||
* @author fanxb
|
||||
* @date 2020/5/12 10:21
|
||||
*/
|
||||
void visitNumPlus(int id);
|
||||
|
||||
/**
|
||||
* 功能描述: 获取用户访问次数前num的书签数据
|
||||
*
|
||||
* @param num 获取条数
|
||||
* @return java.util.List<com.fanxb.bookmark.common.entity.po.Bookmark>
|
||||
* @author fanxb
|
||||
* @date 2020/8/26 15:54
|
||||
*/
|
||||
List<Bookmark> userPopular(int num);
|
||||
|
||||
/**
|
||||
* 更新某个用户的icon数据
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @author fanxb
|
||||
* @date 2021/3/11
|
||||
**/
|
||||
void updateUserBookmarkIcon(int userId);
|
||||
|
||||
/***
|
||||
* 检查无父节点的数据
|
||||
* @author fanxb
|
||||
* @param delete 是否删除数据
|
||||
* @param userId 用户id
|
||||
* @return java.util.List<java.lang.String>
|
||||
* @date 2021/3/17
|
||||
**/
|
||||
Set<String> dealBadBookmark(boolean delete, int userId);
|
||||
public List<BookmarkEs> searchUserBookmark(int userId, String context) {
|
||||
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
|
||||
boolQueryBuilder.must(QueryBuilders.termQuery("userId", userId));
|
||||
boolQueryBuilder.must(QueryBuilders.multiMatchQuery(context, "name", "url"));
|
||||
SearchSourceBuilder builder = new SearchSourceBuilder();
|
||||
builder.size(5);
|
||||
builder.query(boolQueryBuilder);
|
||||
return esUtil.search(EsConstant.BOOKMARK_INDEX, builder, BookmarkEs.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Description: 将某个用户的书签数据mysql同步到es中
|
||||
*
|
||||
* @author fanxb
|
||||
* @date 2019/7/26 11:27
|
||||
*/
|
||||
public void syncUserBookmark(int userId) {
|
||||
//删除旧的数据
|
||||
esUtil.deleteByQuery(EsConstant.BOOKMARK_INDEX, new TermQueryBuilder("userId", userId));
|
||||
int index = 0;
|
||||
int size = 500;
|
||||
List<EsEntity> res = new ArrayList<>();
|
||||
do {
|
||||
res.clear();
|
||||
bookmarkDao.selectBookmarkEsByUserIdAndType(userId, 0, index, size)
|
||||
.forEach(item -> res.add(new EsEntity<>(item.getBookmarkId().toString(), item)));
|
||||
if (res.size() > 0) {
|
||||
esUtil.insertBatch(EsConstant.BOOKMARK_INDEX, res);
|
||||
}
|
||||
index += size;
|
||||
} while (res.size() == 500);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,39 +0,0 @@
|
||||
package com.fanxb.bookmark.business.bookmark.service;
|
||||
|
||||
import com.fanxb.bookmark.business.bookmark.entity.po.PInBookmarkPo;
|
||||
import com.fanxb.bookmark.business.bookmark.entity.vo.HomePinItemVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 首页相关的书签接口
|
||||
*
|
||||
* @author fanxb
|
||||
*/
|
||||
public interface HomePinService {
|
||||
|
||||
/**
|
||||
* 获取固定的标签
|
||||
*
|
||||
* @return {@link List<HomePinItemVo>}
|
||||
* @author fanxb
|
||||
*/
|
||||
List<HomePinItemVo> getHomePinList();
|
||||
|
||||
/**
|
||||
* 新增一个
|
||||
*
|
||||
* @return {@link HomePinItemVo}
|
||||
* @author fanxb
|
||||
*/
|
||||
PInBookmarkPo addOne(PInBookmarkPo po);
|
||||
|
||||
/**
|
||||
* 删除一个
|
||||
*
|
||||
* @param id id
|
||||
* @author fanxb
|
||||
*/
|
||||
void delete(int id);
|
||||
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
package com.fanxb.bookmark.business.bookmark.service;
|
||||
|
||||
import com.fanxb.bookmark.common.entity.po.Bookmark;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA
|
||||
*
|
||||
* @author fanxb
|
||||
* Date: 2020/3/18
|
||||
* Time: 23:47
|
||||
*/
|
||||
public interface PinYinService {
|
||||
|
||||
/**
|
||||
* 分隔符
|
||||
*/
|
||||
String PARTITION = "||";
|
||||
/**
|
||||
* 拼音接口路径
|
||||
*/
|
||||
String PATH = "/pinyinChange";
|
||||
/**
|
||||
* 分页查询页大小
|
||||
*/
|
||||
int SIZE = 500;
|
||||
|
||||
/**
|
||||
* 功能描述: 首次上线用于全量初始化
|
||||
*
|
||||
* @author fanxb
|
||||
* @date 2020/3/22 21:40
|
||||
*/
|
||||
void changeAll();
|
||||
|
||||
/**
|
||||
* 处理bookmark searchKey
|
||||
*
|
||||
* @param bookmark 处理单个
|
||||
* @return java.util.List<com.fanxb.bookmark.common.entity.po.Bookmark>
|
||||
* @author fanxb
|
||||
* @date 2021/3/13
|
||||
**/
|
||||
Bookmark changeBookmark(Bookmark bookmark);
|
||||
|
||||
/**
|
||||
* 处理bookmarks searchKey
|
||||
*
|
||||
* @param bookmarks 待处理舒淇啊你列表
|
||||
* @return java.util.List<com.fanxb.bookmark.common.entity.po.Bookmark>
|
||||
* @author fanxb
|
||||
* @date 2021/3/13
|
||||
**/
|
||||
List<Bookmark> changeBookmarks(List<Bookmark> bookmarks);
|
||||
|
||||
/**
|
||||
* 功能描述:返回用于前端搜索的key
|
||||
*
|
||||
* @param stringList 待拼音化的字符串
|
||||
* @return java.util.List<java.lang.String>
|
||||
* @author fanxb
|
||||
* @date 2020/3/22 21:38
|
||||
*/
|
||||
List<String> changeStrings(List<String> stringList);
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package com.fanxb.bookmark.business.bookmark.service.impl;
|
||||
|
||||
import com.fanxb.bookmark.business.api.BookmarkApi;
|
||||
import com.fanxb.bookmark.business.bookmark.service.BookmarkService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* bookmark模块api暴露
|
||||
*
|
||||
* @author fanxb
|
||||
* @date 2021/3/13
|
||||
**/
|
||||
@Service
|
||||
public class BookmarkApiImpl implements BookmarkApi {
|
||||
private final BookmarkService bookmarkService;
|
||||
|
||||
@Autowired
|
||||
public BookmarkApiImpl(BookmarkService bookmarkService) {
|
||||
this.bookmarkService = bookmarkService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUserBookmarkIcon(int userId) {
|
||||
bookmarkService.updateUserBookmarkIcon(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> dealBadBookmark(boolean delete, int userId) {
|
||||
return bookmarkService.dealBadBookmark(delete, userId);
|
||||
}
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
package com.fanxb.bookmark.business.bookmark.service.impl;
|
||||
|
||||
import com.fanxb.bookmark.business.bookmark.dao.BookmarkDao;
|
||||
import com.fanxb.bookmark.business.bookmark.entity.BookmarkEs;
|
||||
import com.fanxb.bookmark.business.bookmark.service.BookmarkBackupService;
|
||||
import com.fanxb.bookmark.common.constant.EsConstant;
|
||||
import com.fanxb.bookmark.common.entity.po.Bookmark;
|
||||
import com.fanxb.bookmark.common.entity.EsEntity;
|
||||
import com.fanxb.bookmark.common.util.EsUtil;
|
||||
import org.elasticsearch.index.query.TermQueryBuilder;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA
|
||||
* Created By Fxb
|
||||
* Date: 2019/11/12
|
||||
* Time: 0:22
|
||||
*
|
||||
* @author fanxb
|
||||
*/
|
||||
@Service
|
||||
public class BookmarkBackupServiceImpl implements BookmarkBackupService {
|
||||
|
||||
@Autowired
|
||||
private BookmarkDao bookmarkDao;
|
||||
|
||||
@Autowired
|
||||
private EsUtil esUtil;
|
||||
|
||||
/**
|
||||
* 一次同步BACKUP_SIZE条到es中
|
||||
*/
|
||||
private static final int BACKUP_SIZE = 500;
|
||||
|
||||
@Override
|
||||
public void backupToEs() {
|
||||
int start = 0;
|
||||
List<Bookmark> list;
|
||||
while ((list = bookmarkDao.getBookmarkListPage(BACKUP_SIZE, start)).size() != 0) {
|
||||
List<EsEntity<BookmarkEs>> batchList = new ArrayList<>(list.size());
|
||||
list.forEach(item -> batchList.add(new EsEntity<>(item.getBookmarkId().toString(), new BookmarkEs(item))));
|
||||
esUtil.insertBatch(EsConstant.BOOKMARK_INDEX, batchList);
|
||||
start += BACKUP_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncUserBookmark(int userId) {
|
||||
//删除旧的数据
|
||||
esUtil.deleteByQuery(EsConstant.BOOKMARK_INDEX, new TermQueryBuilder("userId", userId));
|
||||
int index = 0;
|
||||
int size = 500;
|
||||
List<EsEntity<BookmarkEs>> res = new ArrayList<>();
|
||||
do {
|
||||
res.clear();
|
||||
bookmarkDao.selectBookmarkEsByUserIdAndType(userId, 0, index, size)
|
||||
.forEach(item -> res.add(new EsEntity<>(item.getBookmarkId().toString(), item)));
|
||||
if (res.size() > 0) {
|
||||
esUtil.insertBatch(EsConstant.BOOKMARK_INDEX, res);
|
||||
}
|
||||
index += size;
|
||||
} while (res.size() == 500);
|
||||
|
||||
}
|
||||
}
|
@ -1,503 +0,0 @@
|
||||
package com.fanxb.bookmark.business.bookmark.service.impl;
|
||||
|
||||
import cn.hutool.core.codec.Base64Decoder;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.*;
|
||||
import cn.hutool.core.util.HashUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.fanxb.bookmark.business.api.UserApi;
|
||||
import com.fanxb.bookmark.business.bookmark.constant.FileConstant;
|
||||
import com.fanxb.bookmark.business.bookmark.dao.BookmarkDao;
|
||||
import com.fanxb.bookmark.business.bookmark.dao.HostIconDao;
|
||||
import com.fanxb.bookmark.business.bookmark.entity.BookmarkEs;
|
||||
import com.fanxb.bookmark.business.bookmark.entity.MoveNodeBody;
|
||||
import com.fanxb.bookmark.business.bookmark.entity.redis.BookmarkDeleteMessage;
|
||||
import com.fanxb.bookmark.business.bookmark.entity.redis.VisitNumPlus;
|
||||
import com.fanxb.bookmark.business.bookmark.service.BookmarkService;
|
||||
import com.fanxb.bookmark.business.bookmark.service.PinYinService;
|
||||
import com.fanxb.bookmark.common.constant.CommonConstant;
|
||||
import com.fanxb.bookmark.common.constant.EsConstant;
|
||||
import com.fanxb.bookmark.common.constant.RedisConstant;
|
||||
import com.fanxb.bookmark.common.entity.po.Bookmark;
|
||||
import com.fanxb.bookmark.common.exception.CustomException;
|
||||
import com.fanxb.bookmark.common.util.*;
|
||||
import com.mysql.cj.conf.url.SingleConnectionUrl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.elasticsearch.index.query.BoolQueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.awt.print.Book;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 类功能简述:
|
||||
* 类功能详述:
|
||||
*
|
||||
* @author fanxb
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class BookmarkServiceImpl implements BookmarkService {
|
||||
@Value("${urlIconAddress}")
|
||||
private String urlIconAddress;
|
||||
|
||||
private final BookmarkDao bookmarkDao;
|
||||
private final PinYinService pinYinService;
|
||||
private final UserApi userApi;
|
||||
private final EsUtil esUtil;
|
||||
private final HostIconDao hostIconDao;
|
||||
|
||||
@Autowired
|
||||
public BookmarkServiceImpl(BookmarkDao bookmarkDao, PinYinService pinYinService, UserApi userApi, EsUtil esUtil, HostIconDao hostIconDao) {
|
||||
this.bookmarkDao = bookmarkDao;
|
||||
this.pinYinService = pinYinService;
|
||||
this.userApi = userApi;
|
||||
this.esUtil = esUtil;
|
||||
this.hostIconDao = hostIconDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void parseBookmarkFile(int userId, MultipartFile file, String path) throws Exception {
|
||||
List<Bookmark> bookmarks = new ArrayList<>();
|
||||
//获取当前层sort最大值
|
||||
Integer sortBase = bookmarkDao.selectMaxSort(userId, path);
|
||||
if (sortBase == null) {
|
||||
sortBase = 0;
|
||||
}
|
||||
if (file.getOriginalFilename().endsWith(".db3")) {
|
||||
//处理db文件
|
||||
readFromOneEnv(bookmarks, userId, file, path, sortBase);
|
||||
} else {
|
||||
InputStream stream = file.getInputStream();
|
||||
Document doc = Jsoup.parse(stream, "utf-8", "");
|
||||
Elements elements = doc.select("html>body>dl>dt");
|
||||
for (int i = 0, length = elements.size(); i < length; i++) {
|
||||
dealBookmark(userId, elements.get(i), path, sortBase + i, bookmarks);
|
||||
}
|
||||
}
|
||||
|
||||
//每一千条处理插入一次,批量更新搜索字段
|
||||
List<Bookmark> tempList = new ArrayList<>(1000);
|
||||
for (int i = 0; i < bookmarks.size(); i++) {
|
||||
tempList.add(bookmarks.get(i));
|
||||
if (tempList.size() == 1000 || i == bookmarks.size() - 1) {
|
||||
tempList = pinYinService.changeBookmarks(tempList);
|
||||
bookmarkDao.updateSearchKeyBatch(tempList);
|
||||
tempList.clear();
|
||||
}
|
||||
}
|
||||
userApi.versionPlus(userId);
|
||||
|
||||
//异步更新icon
|
||||
ThreadPoolUtil.execute(() -> {
|
||||
updateUserBookmarkIcon(userId);
|
||||
userApi.versionPlus(userId);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Description: 处理html节点,解析出文件夹和书签
|
||||
*
|
||||
* @param ele 待处理节点
|
||||
* @param path 节点路径,不包含自身
|
||||
* @param sort 当前层级中的排序序号
|
||||
* @author fanxb
|
||||
*/
|
||||
private void dealBookmark(int userId, Element ele, String path, int sort, List<Bookmark> bookmarks) {
|
||||
if (!DT.equalsIgnoreCase(ele.tagName())) {
|
||||
return;
|
||||
}
|
||||
Element first = ele.child(0);
|
||||
if (A.equalsIgnoreCase(first.tagName())) {
|
||||
//说明为链接
|
||||
Bookmark node = new Bookmark(userId, path, first.ownText(), first.attr("href"), ""
|
||||
, Long.parseLong(first.attr("add_date")) * 1000, sort);
|
||||
//存入数据库
|
||||
insertOne(node);
|
||||
bookmarks.add(node);
|
||||
} else {
|
||||
//说明为文件夹
|
||||
Bookmark node = new Bookmark(userId, path, first.ownText(), Long.parseLong(first.attr("add_date")) * 1000, sort);
|
||||
Integer sortBase = 0;
|
||||
//同名文件夹将会合并
|
||||
if (insertOne(node)) {
|
||||
sortBase = bookmarkDao.selectMaxSort(node.getUserId(), path);
|
||||
if (sortBase == null) {
|
||||
sortBase = 0;
|
||||
}
|
||||
}
|
||||
String childPath = path + "." + node.getBookmarkId();
|
||||
Elements children = ele.child(1).children();
|
||||
for (int i = 0, size = children.size(); i < size; i++) {
|
||||
dealBookmark(userId, children.get(i), childPath, sortBase + i + 1, bookmarks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理oneenv的导出
|
||||
*
|
||||
* @param bookmarks 书签列表
|
||||
* @param userId 用户id
|
||||
* @param file file
|
||||
* @param path path
|
||||
* @param sort sort
|
||||
*/
|
||||
private void readFromOneEnv(List<Bookmark> bookmarks, int userId, MultipartFile file, String path, int sort) {
|
||||
String filePath = CommonConstant.fileSavePath + "/files/" + IdUtil.simpleUUID() + ".db3";
|
||||
try {
|
||||
file.transferTo(FileUtil.newFile(filePath));
|
||||
try (Connection conn = DriverManager.getConnection("jdbc:sqlite:" + filePath)) {
|
||||
Statement stat = conn.createStatement();
|
||||
ResultSet rs = stat.executeQuery("select * from on_categorys");
|
||||
Map<Long, Bookmark> folderMap = new HashMap<>();
|
||||
Map<Long, Integer> childSortBaseMap = new HashMap<>();
|
||||
while (rs.next()) {
|
||||
long addTime = rs.getLong("add_time");
|
||||
Bookmark folder = new Bookmark(userId, path, StrUtil.nullToEmpty(rs.getString("name")), addTime == 0 ? System.currentTimeMillis() : addTime * 1000, sort++);
|
||||
int childSortBase = 0;
|
||||
if (insertOne(folder)) {
|
||||
childSortBase = ObjectUtil.defaultIfNull(bookmarkDao.selectMaxSort(userId, path), 0);
|
||||
}
|
||||
long id = rs.getLong("id");
|
||||
folderMap.put(id, folder);
|
||||
childSortBaseMap.put(id, childSortBase);
|
||||
}
|
||||
rs.close();
|
||||
rs = stat.executeQuery("select * from on_links");
|
||||
while (rs.next()) {
|
||||
long fId = rs.getLong("fid");
|
||||
long addTime = rs.getLong("add_time");
|
||||
int tempSort = childSortBaseMap.get(fId);
|
||||
childSortBaseMap.put(fId, tempSort + 1);
|
||||
Bookmark folder = folderMap.get(fId);
|
||||
String curPath = folder == null ? "" : folder.getPath() + "." + folder.getBookmarkId();
|
||||
Bookmark bookmark = new Bookmark(userId, curPath, StrUtil.nullToEmpty(rs.getString("title"))
|
||||
, StrUtil.nullToEmpty(rs.getString("url")), "", addTime == 0 ? System.currentTimeMillis() : addTime * 1000, tempSort);
|
||||
bookmarks.add(bookmark);
|
||||
insertOne(bookmark);
|
||||
}
|
||||
rs.close();
|
||||
stat.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Description: 插入一条书签,如果已经存在同名书签将跳过
|
||||
*
|
||||
* @param node node
|
||||
* @return boolean 如果已经存在返回true,否则false
|
||||
* @author fanxb
|
||||
*/
|
||||
private boolean insertOne(Bookmark node) {
|
||||
//先根据name,userId,parentId获取此节点id
|
||||
Integer id = bookmarkDao.selectIdByUserIdAndNameAndPath(node.getUserId(), node.getName(), node.getPath());
|
||||
if (id == null) {
|
||||
bookmarkDao.insertOne(node);
|
||||
return false;
|
||||
} else {
|
||||
node.setBookmarkId(id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Map<String, List<Bookmark>> getOneBookmarkTree(int userId) {
|
||||
List<Bookmark> list = bookmarkDao.getListByUserId(userId);
|
||||
Map<String, List<Bookmark>> map = new HashMap<>(50);
|
||||
list.forEach(item -> {
|
||||
map.computeIfAbsent(item.getPath(), k -> new ArrayList<>());
|
||||
map.get(item.getPath()).add(item);
|
||||
});
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<Bookmark> getBookmarkListByPath(int userId, String path) {
|
||||
return bookmarkDao.getListByUserIdAndPath(userId, path);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchDelete(int userId, List<String> pathList, List<Integer> bookmarkIdList) {
|
||||
//所有要删除的书签id
|
||||
Set<String> set = new HashSet<>();
|
||||
for (String path : pathList) {
|
||||
Integer id = Integer.parseInt(ArrayUtil.reverse(path.split("\\."))[0]);
|
||||
set.addAll(bookmarkDao.getChildrenBookmarkId(userId, path).stream().map(String::valueOf).collect(Collectors.toSet()));
|
||||
//删除此文件夹所有的子节点
|
||||
bookmarkDao.deleteUserFolder(userId, path);
|
||||
bookmarkIdList.add(id);
|
||||
}
|
||||
if (bookmarkIdList.size() > 0) {
|
||||
bookmarkDao.deleteUserBookmark(userId, bookmarkIdList);
|
||||
set.addAll(bookmarkIdList.stream().map(String::valueOf).collect(Collectors.toSet()));
|
||||
}
|
||||
RedisUtil.addToMq(RedisConstant.BOOKMARK_DELETE_ES, new BookmarkDeleteMessage(userId, set));
|
||||
userApi.versionPlus(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Bookmark addOne(Bookmark bookmark) {
|
||||
int userId = UserContextHolder.get().getUserId();
|
||||
Integer sort = bookmarkDao.selectMaxSort(userId, bookmark.getPath());
|
||||
bookmark.setSort(sort == null ? 1 : sort + 1);
|
||||
bookmark.setUserId(userId);
|
||||
bookmark.setCreateTime(System.currentTimeMillis());
|
||||
bookmark.setAddTime(bookmark.getCreateTime());
|
||||
bookmark.setIcon(bookmark.getType() == 1 ? "" : getIconPath(bookmark.getUrl(), bookmark.getIcon(), bookmark.getIconUrl(), true));
|
||||
//文件夹和书签都建立搜索key
|
||||
pinYinService.changeBookmark(bookmark);
|
||||
bookmarkDao.insertOne(bookmark);
|
||||
userApi.versionPlus(userId);
|
||||
if (StrUtil.isEmpty(bookmark.getIcon()) && bookmark.getType() == 0) {
|
||||
updateIconAsync(bookmark.getBookmarkId(), bookmark.getUrl(), userId);
|
||||
}
|
||||
return bookmark;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String updateOne(int userId, Bookmark bookmark) {
|
||||
bookmark.setUserId(userId);
|
||||
if (bookmark.getType() == 0) {
|
||||
pinYinService.changeBookmark(bookmark);
|
||||
bookmark.setIcon(getIconPath(bookmark.getUrl(), null, null, true));
|
||||
if (StrUtil.isEmpty(bookmark.getIcon())) {
|
||||
updateIconAsync(bookmark.getBookmarkId(), bookmark.getUrl(), userId);
|
||||
}
|
||||
}
|
||||
bookmarkDao.editBookmark(bookmark);
|
||||
userApi.versionPlus(userId);
|
||||
return bookmark.getIcon();
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步更新书签icon
|
||||
*
|
||||
* @param id 书签id
|
||||
* @param url 书签url
|
||||
* @param userId userId
|
||||
*/
|
||||
private void updateIconAsync(int id, String url, int userId) {
|
||||
ThreadPoolUtil.execute(() -> {
|
||||
String icon = getIconPath(url, null, null, false);
|
||||
if (StrUtil.isEmpty(icon)) {
|
||||
return;
|
||||
}
|
||||
bookmarkDao.updateIcon(id, icon);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void moveNode(int userId, MoveNodeBody body) {
|
||||
if (body.getSort() == -1) {
|
||||
Integer max = bookmarkDao.selectMaxSort(userId, body.getTargetPath());
|
||||
body.setSort(max == null ? 1 : max);
|
||||
} else {
|
||||
//更新目标节点的sort
|
||||
bookmarkDao.sortPlus(userId, body.getTargetPath(), body.getSort());
|
||||
}
|
||||
//如果目标位置和当前位置不在一个层级中需要更新子节点的path
|
||||
if (!body.getTargetPath().equals(body.getSourcePath())) {
|
||||
bookmarkDao.updateChildrenPath(userId, body.getSourcePath() + "." + body.getBookmarkId()
|
||||
, body.getTargetPath() + "." + body.getBookmarkId());
|
||||
}
|
||||
//更新被移动节点的path和sort
|
||||
bookmarkDao.updatePathAndSort(userId, body.getBookmarkId(), body.getTargetPath(), body.getSort());
|
||||
userApi.versionPlus(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BookmarkEs> searchUserBookmark(int userId, String context) {
|
||||
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
|
||||
boolQueryBuilder.must(QueryBuilders.termQuery("userId", userId));
|
||||
boolQueryBuilder.must(QueryBuilders.multiMatchQuery(context, "name", "url"));
|
||||
SearchSourceBuilder builder = new SearchSourceBuilder();
|
||||
builder.size(5);
|
||||
builder.query(boolQueryBuilder);
|
||||
return esUtil.search(EsConstant.BOOKMARK_INDEX, builder, BookmarkEs.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNumPlus(int id) {
|
||||
VisitNumPlus item = new VisitNumPlus(UserContextHolder.get().getUserId(), id);
|
||||
RedisUtil.addToMq(RedisConstant.BOOKMARK_VISIT_NUM_PLUS, JSON.toJSONString(item));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Bookmark> userPopular(int num) {
|
||||
return bookmarkDao.selectPopular(UserContextHolder.get().getUserId(), num);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUserBookmarkIcon(int userId) {
|
||||
log.info("开始更新:{}", userId);
|
||||
int size = 100;
|
||||
int start = 0;
|
||||
List<Bookmark> deal;
|
||||
while (!(deal = bookmarkDao.selectUserNoIcon(userId, start, size)).isEmpty()) {
|
||||
start += size;
|
||||
deal.forEach(item -> {
|
||||
String icon = getIconPath(item.getUrl(), null, null, false);
|
||||
if (StrUtil.isNotEmpty(icon)) {
|
||||
bookmarkDao.updateIcon(item.getBookmarkId(), icon);
|
||||
}
|
||||
});
|
||||
}
|
||||
userApi.versionPlus(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> dealBadBookmark(boolean delete, int userId) {
|
||||
List<Bookmark> bookmarks = bookmarkDao.selectBookmarkIdPathByUserId(userId);
|
||||
Set<Integer> idSet = new HashSet<>(bookmarks.size());
|
||||
bookmarks.forEach(item -> idSet.add(item.getBookmarkId()));
|
||||
Set<String> resPath = new HashSet<>();
|
||||
bookmarks.forEach(item -> {
|
||||
if (StrUtil.isEmpty(item.getPath())) {
|
||||
return;
|
||||
}
|
||||
String parentId = item.getPath().substring(item.getPath().lastIndexOf(".") + 1);
|
||||
if (!idSet.contains(Integer.valueOf(parentId))) {
|
||||
resPath.add(item.getPath());
|
||||
}
|
||||
});
|
||||
if (delete && resPath.size() > 0) {
|
||||
resPath.forEach(item -> bookmarkDao.deleteUserFolder(userId, item));
|
||||
userApi.versionPlus(userId);
|
||||
}
|
||||
return resPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取icon,通过网络获取,或者从base64还原
|
||||
*
|
||||
* @param url 书签url路径
|
||||
* @param icon base64编码的icon
|
||||
* @param iconUrl base64编码的文件,文件名,用于获取文件名后缀
|
||||
* @param quick 是否快速获取
|
||||
* @return {@link String}
|
||||
* @author fanxb
|
||||
*/
|
||||
private String getIconPath(String url, String icon, String iconUrl, boolean quick) {
|
||||
String host;
|
||||
try {
|
||||
URL urlObj = new URL(url);
|
||||
host = urlObj.getAuthority();
|
||||
} catch (Exception e) {
|
||||
log.warn("url无法解析出domain:{}", url);
|
||||
return "";
|
||||
}
|
||||
if (StrUtil.isNotBlank(icon)) {
|
||||
//优先从base64还原出图片
|
||||
try {
|
||||
byte[] b = Base64Decoder.decode(icon.substring(icon.indexOf(",") + 1));
|
||||
String iconPath = saveToFile(iconUrl, host, b);
|
||||
hostIconDao.deleteByHost(host);
|
||||
hostIconDao.insert(host, iconPath);
|
||||
return iconPath;
|
||||
} catch (Exception e) {
|
||||
log.error("解析base64获取icon故障:{}", iconUrl, e);
|
||||
}
|
||||
}
|
||||
|
||||
String iconPath = hostIconDao.selectByHost(host);
|
||||
if (iconPath != null) {
|
||||
return iconPath;
|
||||
}
|
||||
//再根据url解析
|
||||
iconPath = saveFile(host, urlIconAddress + "/icon?url=" + host + "&size=16..128..256", quick);
|
||||
if (StrUtil.isNotEmpty(iconPath)) {
|
||||
hostIconDao.insert(host, iconPath);
|
||||
}
|
||||
return iconPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存文件到icon路径
|
||||
*
|
||||
* @param host host
|
||||
* @param url url
|
||||
* @param quick 是否快速获取,快速获取超时时间1s
|
||||
* @return {@link String}
|
||||
* @author FleyX
|
||||
*/
|
||||
private String saveFile(String host, String url, boolean quick) {
|
||||
try (Response res = (quick ? HttpUtil.getSHORT_CLIENT() : HttpUtil.getClient(false)).newCall(new Request.Builder().url(url)
|
||||
.header("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36 Edg/100.0.1185.36")
|
||||
.get().build()).execute()) {
|
||||
assert res.body() != null;
|
||||
if (!HttpUtil.checkIsOk(res.code())) {
|
||||
throw new CustomException("请求错误:" + res.code());
|
||||
}
|
||||
byte[] data = res.body().byteStream().readAllBytes();
|
||||
if (data.length > 0) {
|
||||
String iconUrl = new URL(res.request().url().toString()).getPath();
|
||||
return saveToFile(iconUrl, host, data);
|
||||
} else {
|
||||
log.info("未获取到icon:{}", url);
|
||||
}
|
||||
} catch (SocketTimeoutException timeoutException) {
|
||||
log.info("获取icon超时:{}", host);
|
||||
} catch (Exception e) {
|
||||
log.error("url获取icon故障:{}", url, e);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 保存到文件中
|
||||
*
|
||||
* @param iconUrl icon文件名
|
||||
* @param host host
|
||||
* @param b 数据
|
||||
* @return {@link String}
|
||||
* @author FleyX
|
||||
*/
|
||||
private String saveToFile(String iconUrl, String host, byte[] b) {
|
||||
String fileName = host.replace(":", ".") + iconUrl.substring(iconUrl.lastIndexOf("."));
|
||||
String filePath = Paths.get(FileConstant.FAVICON_PATH, host.replace("www", "").replaceAll("\\.", "").substring(0, 2), fileName).toString();
|
||||
FileUtil.writeBytes(b, Paths.get(CommonConstant.fileSavePath, filePath).toString());
|
||||
return File.separator + filePath;
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
package com.fanxb.bookmark.business.bookmark.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
|
||||
import com.fanxb.bookmark.business.bookmark.dao.BookmarkDao;
|
||||
import com.fanxb.bookmark.business.bookmark.dao.PinBookmarkDao;
|
||||
import com.fanxb.bookmark.business.bookmark.entity.po.PInBookmarkPo;
|
||||
import com.fanxb.bookmark.business.bookmark.entity.vo.HomePinItemVo;
|
||||
import com.fanxb.bookmark.business.bookmark.service.BookmarkService;
|
||||
import com.fanxb.bookmark.business.bookmark.service.HomePinService;
|
||||
import com.fanxb.bookmark.common.entity.UserContext;
|
||||
import com.fanxb.bookmark.common.entity.po.Bookmark;
|
||||
import com.fanxb.bookmark.common.exception.CustomException;
|
||||
import com.fanxb.bookmark.common.util.UserContextHolder;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author fanxb
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class HomePinServiceImpl implements HomePinService {
|
||||
|
||||
private final PinBookmarkDao pinBookmarkDao;
|
||||
private final BookmarkDao bookmarkDao;
|
||||
|
||||
@Autowired
|
||||
public HomePinServiceImpl(PinBookmarkDao pinBookmarkDao, BookmarkDao bookmarkDao) {
|
||||
this.pinBookmarkDao = pinBookmarkDao;
|
||||
this.bookmarkDao = bookmarkDao;
|
||||
}
|
||||
|
||||
/**
|
||||
* 首页固定书签最大数量
|
||||
*/
|
||||
private static final int MAX_PIN = 20;
|
||||
|
||||
|
||||
@Override
|
||||
public List<HomePinItemVo> getHomePinList() {
|
||||
List<HomePinItemVo> res = new ArrayList<>(MAX_PIN);
|
||||
if (UserContextHolder.get() != null) {
|
||||
res.addAll(pinBookmarkDao.selectUserPin(UserContextHolder.get().getUserId()));
|
||||
if (res.size() < MAX_PIN - 1) {
|
||||
//需要从取到的书签数据中排除已经固定到首页的数据
|
||||
Set<Integer> existBookmark = res.stream().map(HomePinItemVo::getBookmarkId).collect(Collectors.toSet());
|
||||
List<Bookmark> bookmarks = bookmarkDao.selectPopular(UserContextHolder.get().getUserId(), MAX_PIN - 1);
|
||||
res.addAll(bookmarks.stream().filter(item -> !existBookmark.contains(item.getBookmarkId())).limit(MAX_PIN - res.size() - 1)
|
||||
.map(item -> new HomePinItemVo(null, item.getBookmarkId(), item.getName(), item.getUrl(), item.getIcon())).collect(Collectors.toList()));
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PInBookmarkPo addOne(PInBookmarkPo po) {
|
||||
int userId = UserContextHolder.get().getUserId();
|
||||
long count = pinBookmarkDao.selectCount(new QueryWrapper<PInBookmarkPo>().eq("userId", userId));
|
||||
if (count > MAX_PIN) {
|
||||
throw new CustomException("固定数量已超过最大限制:" + MAX_PIN);
|
||||
}
|
||||
po.setUserId(userId);
|
||||
po.setCreateDate(System.currentTimeMillis());
|
||||
po.setSort(pinBookmarkDao.getUserMaxSort(userId) + 1);
|
||||
pinBookmarkDao.insert(po);
|
||||
return po;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(int id) {
|
||||
pinBookmarkDao.deleteById(id);
|
||||
}
|
||||
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
package com.fanxb.bookmark.business.bookmark.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.fanxb.bookmark.business.api.UserApi;
|
||||
import com.fanxb.bookmark.business.bookmark.dao.BookmarkDao;
|
||||
import com.fanxb.bookmark.business.bookmark.service.PinYinService;
|
||||
import com.fanxb.bookmark.common.entity.po.Bookmark;
|
||||
import com.fanxb.bookmark.common.exception.CustomException;
|
||||
import com.fanxb.bookmark.common.util.UserContextHolder;
|
||||
import com.github.houbb.pinyin.constant.enums.PinyinStyleEnum;
|
||||
import com.github.houbb.pinyin.util.PinyinHelper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA
|
||||
*
|
||||
* @author fanxb
|
||||
* Date: 2020/3/18
|
||||
* Time: 23:48
|
||||
*/
|
||||
@Service
|
||||
public class PinYinServiceImpl implements PinYinService {
|
||||
|
||||
|
||||
private final BookmarkDao bookmarkDao;
|
||||
private final UserApi userApi;
|
||||
|
||||
@Autowired
|
||||
public PinYinServiceImpl(BookmarkDao bookmarkDao, UserApi userApi) {
|
||||
this.bookmarkDao = bookmarkDao;
|
||||
this.userApi = userApi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeAll() {
|
||||
if (!UserContextHolder.get().getManageUser()) {
|
||||
throw new CustomException("非管理员用户,无法执行本操作");
|
||||
}
|
||||
int i = 0;
|
||||
while (true) {
|
||||
List<Bookmark> bookmarks = changeBookmarks(bookmarkDao.selectPinyinEmpty(i, SIZE));
|
||||
if (bookmarks.size() > 0) {
|
||||
bookmarkDao.updateSearchKeyBatch(bookmarks);
|
||||
}
|
||||
if (bookmarks.size() < SIZE) {
|
||||
break;
|
||||
}
|
||||
i = bookmarks.get(SIZE - 1).getBookmarkId();
|
||||
}
|
||||
//更新所有用户版本数据
|
||||
userApi.allUserVersionPlus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bookmark changeBookmark(Bookmark bookmark) {
|
||||
return changeBookmarks(Collections.singletonList(bookmark)).get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Bookmark> changeBookmarks(List<Bookmark> bookmarks) {
|
||||
List<String> resList = changeStrings(bookmarks.stream().map(Bookmark::getName).collect(Collectors.toList()));
|
||||
for (int j = 0, size = bookmarks.size(); j < size; j++) {
|
||||
Bookmark bookmark = bookmarks.get(j);
|
||||
int length = bookmark.getUrl().length();
|
||||
bookmark.setSearchKey(resList.get(j) + (length == 0 ? "" : (PARTITION + bookmark.getUrl().substring(0, Math.min(length, 50)))));
|
||||
}
|
||||
return bookmarks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> changeStrings(List<String> stringList) {
|
||||
return stringList.stream().map(item -> {
|
||||
List<String> temp = Arrays.stream(PinyinHelper.toPinyin(item.replaceAll(" ", ""), PinyinStyleEnum.NORMAL).split(" "))
|
||||
.filter(one -> one.length() > 0).collect(Collectors.toList());
|
||||
return item.toLowerCase(Locale.getDefault()) + PARTITION + CollectionUtil.join(temp, "") + PARTITION
|
||||
+ temp.stream().map(one -> one.substring(0, 1)).collect(Collectors.joining());
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
}
|
@ -4,16 +4,22 @@
|
||||
|
||||
|
||||
<insert id="insertOne" useGeneratedKeys="true" keyColumn="bookmarkId" keyProperty="bookmarkId">
|
||||
insert into bookmark(userId,path,type,name,searchKey,url,icon,sort,addTime,createTime)
|
||||
insert into bookmark(userId,path,type,name,url,icon,sort,addTime,createTime)
|
||||
value
|
||||
( #{userId},#{path},#{type},#{name},#{searchKey},#{url},#{icon},
|
||||
( #{userId},#{path},#{type},#{name},
|
||||
<if test="url == null">
|
||||
"","",
|
||||
</if>
|
||||
<if test="url != null">
|
||||
#{url},#{icon},
|
||||
</if>
|
||||
#{sort},#{addTime},#{createTime})
|
||||
</insert>
|
||||
|
||||
<select id="selectIdByUserIdAndNameAndPath" resultType="java.lang.Integer">
|
||||
select bookmarkId
|
||||
from bookmark
|
||||
where userId = #{userId} and path = #{path} and name = #{name} limit 1;
|
||||
where userId = #{userId} and path = #{path} and name = #{name};
|
||||
</select>
|
||||
|
||||
<select id="selectMaxSort" resultType="java.lang.Integer">
|
||||
@ -22,13 +28,12 @@
|
||||
where userId = #{userId} and path = #{path}
|
||||
</select>
|
||||
|
||||
<select id="getListByUserId" resultType="com.fanxb.bookmark.common.entity.po.Bookmark">
|
||||
<select id="getListByUserId" resultType="com.fanxb.bookmark.common.entity.Bookmark">
|
||||
select
|
||||
bookmarkId,
|
||||
path,
|
||||
type,
|
||||
name,
|
||||
searchKey,
|
||||
url,
|
||||
icon,
|
||||
sort
|
||||
@ -37,7 +42,7 @@
|
||||
order by path, sort
|
||||
</select>
|
||||
|
||||
<select id="getListByUserIdAndPath" resultType="com.fanxb.bookmark.common.entity.po.Bookmark">
|
||||
<select id="getListByUserIdAndPath" resultType="com.fanxb.bookmark.common.entity.Bookmark">
|
||||
select
|
||||
bookmarkId,
|
||||
path,
|
||||
@ -57,7 +62,10 @@
|
||||
bookmark
|
||||
WHERE
|
||||
userId = #{userId}
|
||||
and (path = #{path} or path like concat(#{path},".%"))
|
||||
and path LIKE (SELECT a.path
|
||||
FROM (SELECT CONCAT(path, '.', '${folderId}', '%') AS path
|
||||
FROM bookmark
|
||||
WHERE bookmarkId = #{folderId}) a);
|
||||
</delete>
|
||||
|
||||
<select id="getChildrenBookmarkId" resultType="integer">
|
||||
@ -65,7 +73,10 @@
|
||||
from bookmark
|
||||
where
|
||||
userId = #{userId}
|
||||
and (path =#{path} or path like concat(#{path},".%") );
|
||||
and path LIKE (SELECT a.path
|
||||
FROM (SELECT CONCAT(path, '.', '${folderId}', '%') AS path
|
||||
FROM bookmark
|
||||
WHERE bookmarkId = #{folderId}) a);
|
||||
</select>
|
||||
|
||||
<delete id="deleteUserBookmark">
|
||||
@ -75,9 +86,9 @@
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<update id="editBookmark" parameterType="com.fanxb.bookmark.common.entity.po.Bookmark">
|
||||
<update id="editBookmark" parameterType="com.fanxb.bookmark.common.entity.Bookmark">
|
||||
update bookmark
|
||||
set name = #{name}, url = #{url},searchKey = #{searchKey},icon=#{icon}
|
||||
set name = #{name}, url = #{url}
|
||||
where bookmarkId = #{bookmarkId} and userId = #{userId}
|
||||
</update>
|
||||
|
||||
@ -111,15 +122,5 @@
|
||||
limit ${start}, ${size}
|
||||
</select>
|
||||
|
||||
<update id="updateSearchKeyBatch">
|
||||
UPDATE `bookmark` a JOIN
|
||||
(
|
||||
<foreach collection="list" item="item" separator="union">
|
||||
select #{item.bookmarkId} as bookmarkId,#{item.searchKey} as searchKey
|
||||
</foreach>
|
||||
) b USING(bookmarkId)
|
||||
SET a.searchKey=b.searchKey;
|
||||
</update>
|
||||
|
||||
|
||||
</mapper>
|
@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.fanxb.bookmark.business.bookmark.dao.PinBookmarkDao">
|
||||
|
||||
<delete id="deleteUnExistBookmark">
|
||||
delete
|
||||
a
|
||||
from pin_bookmark a
|
||||
left join bookmark b on
|
||||
a.bookmarkId = b.bookmarkId
|
||||
where a.userId = #{userId}
|
||||
and b.bookmarkId is null
|
||||
</delete>
|
||||
|
||||
</mapper>
|
@ -14,7 +14,6 @@
|
||||
<modules>
|
||||
<module>user</module>
|
||||
<module>bookmark</module>
|
||||
<module>api</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
@ -23,6 +22,12 @@
|
||||
<artifactId>bookmark-common</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
|
@ -11,12 +11,5 @@
|
||||
|
||||
<artifactId>bookmark-business-user</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.fanxb</groupId>
|
||||
<artifactId>bookmark-business-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -1,8 +1,10 @@
|
||||
package com.fanxb.bookmark.business.user.constant;
|
||||
|
||||
import com.fanxb.bookmark.common.constant.CommonConstant;
|
||||
import com.fanxb.bookmark.common.constant.Constant;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.io.File;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/**
|
||||
@ -18,6 +20,6 @@ public class FileConstant {
|
||||
/**
|
||||
* 用户头像目录
|
||||
*/
|
||||
public static String iconPath = Paths.get(CommonConstant.fileSavePath, "files", "public", "icon").toString();
|
||||
public static String iconPath = Paths.get("files", "public", "icon").toString();
|
||||
|
||||
}
|
||||
|
@ -1,30 +0,0 @@
|
||||
package com.fanxb.bookmark.business.user.consumer;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.fanxb.bookmark.business.user.dao.UserDao;
|
||||
import com.fanxb.bookmark.common.annotation.MqConsumer;
|
||||
import com.fanxb.bookmark.common.constant.RedisConstant;
|
||||
import com.fanxb.bookmark.common.entity.redis.RedisConsumer;
|
||||
import com.fanxb.bookmark.common.entity.redis.UserBookmarkUpdate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* @author fanxb
|
||||
* @date 2020/1/26 上午11:54
|
||||
*/
|
||||
@MqConsumer(RedisConstant.BOOKMARK_UPDATE_VERSION)
|
||||
public class UserInfoUpdateConsumer implements RedisConsumer {
|
||||
|
||||
@Autowired
|
||||
private UserDao userDao;
|
||||
|
||||
@Override
|
||||
public void deal(String message) {
|
||||
// int userId = Integer.parseInt(message);
|
||||
// if (userId == -1) {
|
||||
// userDao.updateAllBookmarkUpdateVersion();
|
||||
// } else {
|
||||
// userDao.updateLastBookmarkUpdateTime(userId);
|
||||
// }
|
||||
}
|
||||
}
|
@ -1,16 +1,16 @@
|
||||
package com.fanxb.bookmark.business.user.controller;
|
||||
|
||||
import com.fanxb.bookmark.business.user.entity.EmailUpdateBody;
|
||||
import com.fanxb.bookmark.business.user.entity.UpdatePasswordBody;
|
||||
import com.fanxb.bookmark.business.user.entity.UsernameBody;
|
||||
import com.fanxb.bookmark.business.user.service.BaseInfoService;
|
||||
import com.fanxb.bookmark.business.user.vo.EmailUpdateBody;
|
||||
import com.fanxb.bookmark.business.user.vo.UpdatePasswordBody;
|
||||
import com.fanxb.bookmark.business.user.vo.UsernameBody;
|
||||
import com.fanxb.bookmark.common.entity.Result;
|
||||
import com.fanxb.bookmark.common.entity.po.User;
|
||||
import com.fanxb.bookmark.common.util.UserContextHolder;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
|
||||
/**
|
||||
* 类功能简述:用户基本信息相关功能
|
||||
@ -23,12 +23,8 @@ import org.springframework.web.bind.annotation.*;
|
||||
@Validated
|
||||
public class BaseInfoController {
|
||||
|
||||
private final BaseInfoService baseInfoService;
|
||||
|
||||
@Autowired
|
||||
public BaseInfoController(BaseInfoService baseInfoService) {
|
||||
this.baseInfoService = baseInfoService;
|
||||
}
|
||||
private BaseInfoService baseInfoService;
|
||||
|
||||
/**
|
||||
* Description: 修改密码
|
||||
@ -86,17 +82,4 @@ public class BaseInfoController {
|
||||
baseInfoService.verifyEmail(secret);
|
||||
return Result.success(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户默认搜索引擎
|
||||
*
|
||||
* @author fanxb
|
||||
* @date 2021/3/14
|
||||
**/
|
||||
@PostMapping("/updateSearchEngine")
|
||||
public Result updateSearchEngine(@RequestBody User user) {
|
||||
user.setUserId(UserContextHolder.get().getUserId());
|
||||
baseInfoService.changeDefaultSearchEngine(user);
|
||||
return Result.success(null);
|
||||
}
|
||||
}
|
||||
|
@ -1,32 +0,0 @@
|
||||
package com.fanxb.bookmark.business.user.controller;
|
||||
|
||||
import com.fanxb.bookmark.business.user.entity.Feedback;
|
||||
import com.fanxb.bookmark.business.user.service.FeedbackService;
|
||||
import com.fanxb.bookmark.common.entity.Result;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA
|
||||
*
|
||||
* @author fanxb
|
||||
* Date: 2020/3/10
|
||||
* Time: 23:16
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/feedback")
|
||||
public class FeedbackController {
|
||||
|
||||
@Autowired
|
||||
private FeedbackService feedbackService;
|
||||
|
||||
@PutMapping("")
|
||||
public Result addone(@Validated @RequestBody Feedback feedback) {
|
||||
feedbackService.addOne(feedback);
|
||||
return Result.success(null);
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package com.fanxb.bookmark.business.user.controller;
|
||||
|
||||
import com.fanxb.bookmark.business.user.service.NotifyAnnounceService;
|
||||
import com.fanxb.bookmark.common.entity.Result;
|
||||
import com.fanxb.bookmark.common.util.UserContextHolder;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
|
||||
/**
|
||||
* @author fanxb
|
||||
* @date 2021-10-17 14:03
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/announce/user")
|
||||
public class NotifyAnnounceController {
|
||||
@Autowired
|
||||
private NotifyAnnounceService notifyAnnounceService;
|
||||
|
||||
/**
|
||||
* 获取站内信
|
||||
*/
|
||||
@GetMapping
|
||||
public Result getUserAnnounce(@RequestParam int status) {
|
||||
return Result.success(notifyAnnounceService.getUserAnnounce(UserContextHolder.get().getUserId(), status));
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记为已读
|
||||
*/
|
||||
@PostMapping("/read")
|
||||
public Result readNotifyAnnounce(@RequestParam int notifyAnnounceId) {
|
||||
notifyAnnounceService.markAsRead(UserContextHolder.get().getUserId(), notifyAnnounceId);
|
||||
return Result.success();
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
package com.fanxb.bookmark.business.user.controller;
|
||||
|
||||
import com.fanxb.bookmark.business.user.dao.SearchEngineDao;
|
||||
import com.fanxb.bookmark.business.user.entity.SearchEngine;
|
||||
import com.fanxb.bookmark.business.user.service.SearchEngineService;
|
||||
import com.fanxb.bookmark.common.entity.Result;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/searchEngine")
|
||||
public class SearchEngineController {
|
||||
@Autowired
|
||||
private SearchEngineService searchEngineService;
|
||||
|
||||
/**
|
||||
* 列表查询
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public Result list() {
|
||||
return Result.success(searchEngineService.list());
|
||||
}
|
||||
|
||||
@PostMapping("/insert")
|
||||
public Result insert(@RequestBody SearchEngine body){
|
||||
searchEngineService.insertOne(body);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@PostMapping("/edit")
|
||||
public Result edit(@RequestBody SearchEngine body){
|
||||
searchEngineService.editOne(body);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Result delete(@RequestBody SearchEngine body){
|
||||
searchEngineService.deleteOne(body.getId());
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@PostMapping("/setChecked")
|
||||
public Result setChecked(@RequestBody SearchEngine body){
|
||||
searchEngineService.setChecked(body.getId());
|
||||
return Result.success();
|
||||
}
|
||||
}
|
@ -1,12 +1,9 @@
|
||||
package com.fanxb.bookmark.business.user.controller;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.fanxb.bookmark.business.user.service.OauthService;
|
||||
import com.fanxb.bookmark.business.user.entity.LoginBody;
|
||||
import com.fanxb.bookmark.business.user.entity.RegisterBody;
|
||||
import com.fanxb.bookmark.business.user.service.UserService;
|
||||
import com.fanxb.bookmark.business.user.vo.LoginBody;
|
||||
import com.fanxb.bookmark.business.user.vo.OauthBody;
|
||||
import com.fanxb.bookmark.business.user.vo.RegisterBody;
|
||||
import com.fanxb.bookmark.business.user.service.impl.UserServiceImpl;
|
||||
import com.fanxb.bookmark.common.entity.Result;
|
||||
import com.fanxb.bookmark.common.util.UserContextHolder;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
@ -14,8 +11,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* 类功能简述:
|
||||
* 类功能详述:
|
||||
@ -27,16 +22,8 @@ import javax.validation.Valid;
|
||||
@RequestMapping("/user")
|
||||
public class UserController {
|
||||
|
||||
private final UserServiceImpl userServiceImpl;
|
||||
private final OauthService oAuthService;
|
||||
private final UserService userService;
|
||||
|
||||
@Autowired
|
||||
public UserController(UserServiceImpl userServiceImpl, OauthService oAuthService, UserService userService) {
|
||||
this.userServiceImpl = userServiceImpl;
|
||||
this.oAuthService = oAuthService;
|
||||
this.userService = userService;
|
||||
}
|
||||
private UserService userService;
|
||||
|
||||
/**
|
||||
* Description: 获取验证码
|
||||
@ -48,7 +35,7 @@ public class UserController {
|
||||
*/
|
||||
@GetMapping("/authCode")
|
||||
public Result getAuthCode(@Param("email") String email) {
|
||||
userServiceImpl.sendAuthCode(email);
|
||||
userService.sendAuthCode(email);
|
||||
return Result.success(null);
|
||||
}
|
||||
|
||||
@ -61,8 +48,9 @@ public class UserController {
|
||||
* @date 2019/7/6 16:34
|
||||
*/
|
||||
@PutMapping("")
|
||||
public Result register(@Valid @RequestBody RegisterBody body) {
|
||||
return Result.success(userServiceImpl.register(body));
|
||||
public Result register(@RequestBody RegisterBody body) {
|
||||
userService.register(body);
|
||||
return Result.success(null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -74,7 +62,7 @@ public class UserController {
|
||||
*/
|
||||
@GetMapping("/currentUserInfo")
|
||||
public Result currentUserInfo() {
|
||||
return Result.success(userServiceImpl.getUserInfo(UserContextHolder.get().getUserId()));
|
||||
return Result.success(userService.getUserInfo(UserContextHolder.get().getUserId()));
|
||||
}
|
||||
|
||||
|
||||
@ -85,7 +73,7 @@ public class UserController {
|
||||
*/
|
||||
@PostMapping("/icon")
|
||||
public Result pushIcon(@RequestParam("file") MultipartFile file) throws Exception {
|
||||
return Result.success(userServiceImpl.updateIcon(file));
|
||||
return Result.success(userService.updateIcon(file));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,7 +86,7 @@ public class UserController {
|
||||
*/
|
||||
@PostMapping("/login")
|
||||
public Result login(@RequestBody LoginBody body) {
|
||||
return Result.success(userServiceImpl.login(body));
|
||||
return Result.success(userService.login(body));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -111,7 +99,7 @@ public class UserController {
|
||||
*/
|
||||
@PostMapping("/resetPassword")
|
||||
public Result resetPassword(@RequestBody RegisterBody body) {
|
||||
userServiceImpl.resetPassword(body);
|
||||
userService.resetPassword(body);
|
||||
return Result.success(null);
|
||||
}
|
||||
|
||||
@ -125,7 +113,7 @@ public class UserController {
|
||||
*/
|
||||
@PostMapping("/checkPassword")
|
||||
public Result checkPassword(@RequestBody JSONObject obj) {
|
||||
return Result.success(userServiceImpl.checkPassword(obj.getString("password")));
|
||||
return Result.success(userService.checkPassword(obj.getString("password")));
|
||||
}
|
||||
|
||||
@GetMapping("/loginStatus")
|
||||
@ -133,54 +121,5 @@ public class UserController {
|
||||
return Result.success(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 第三方登陆
|
||||
*
|
||||
* @param body 入参
|
||||
* @return com.fanxb.bookmark.common.entity.Result
|
||||
* @author fanxb
|
||||
* @date 2021/3/10
|
||||
*/
|
||||
@PostMapping("oAuthLogin")
|
||||
public Result oAuthLogin(@RequestBody OauthBody body) {
|
||||
return Result.success(oAuthService.oAuthCheck(body));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户version
|
||||
*
|
||||
* @date 2021/3/11
|
||||
**/
|
||||
@GetMapping("/version")
|
||||
public Result getUserVersion() {
|
||||
return Result.success(userService.getCurrentUserVersion(UserContextHolder.get().getUserId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新所有人的icon数据
|
||||
*
|
||||
* @return com.fanxb.bookmark.common.entity.Result
|
||||
* @author fanxb
|
||||
* @date 2021/3/13
|
||||
**/
|
||||
@PostMapping("/updateAllUserIcon")
|
||||
public Result updateAllUserIcon() {
|
||||
userService.updateAllUserIcon();
|
||||
return Result.success(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理所有的问题书签数据
|
||||
*
|
||||
* @param obj obj
|
||||
* @return com.fanxb.bookmark.common.entity.Result
|
||||
* @author fanxb
|
||||
* @date 2021/3/17
|
||||
**/
|
||||
@PostMapping("/dealAllUserBookmark")
|
||||
public Result dealAllUserBookmark(@RequestBody JSONObject obj) {
|
||||
return Result.success(userService.dealAllUserBookmark(obj.getBoolean("delete")));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,27 +0,0 @@
|
||||
package com.fanxb.bookmark.business.user.dao;
|
||||
|
||||
import com.fanxb.bookmark.business.user.entity.Feedback;
|
||||
import org.apache.ibatis.annotations.Insert;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA
|
||||
*
|
||||
* @author fanxb
|
||||
* Date: 2020/3/10
|
||||
* Time: 23:14
|
||||
*/
|
||||
@Component
|
||||
public interface FeedbackDao {
|
||||
|
||||
/**
|
||||
* 功能描述: 插入一条记录
|
||||
*
|
||||
* @param feedback feedback
|
||||
* @author fanxb
|
||||
* @date 2020/3/10 23:16
|
||||
*/
|
||||
@Insert("insert into feedback(userId,type,content) value(#{userId},#{type},#{content})")
|
||||
void insertOne(Feedback feedback);
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
package com.fanxb.bookmark.business.user.dao;
|
||||
|
||||
import com.fanxb.bookmark.business.user.vo.UserNotifyAnnounceRes;
|
||||
import org.apache.ibatis.annotations.Insert;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author fanxb
|
||||
* @date 2021-10-17 14:19
|
||||
*/
|
||||
public interface NotifyAnnounceDao {
|
||||
|
||||
/**
|
||||
* 获取用户站内信
|
||||
*
|
||||
* @param userId userId
|
||||
* @param status status
|
||||
* @return java.util.List<com.fanxb.bookmark.business.user.vo.UserNotifyAnnounceRes>
|
||||
* @author fanxb
|
||||
* @date 2021/10/17 14:28
|
||||
*/
|
||||
List<UserNotifyAnnounceRes> queryUserAnnounce(@Param("userId") int userId, @Param("status") int status, @Param("date") long date);
|
||||
|
||||
/**
|
||||
* 处理某人的邮件
|
||||
*
|
||||
* @param userId userId
|
||||
* @author fanxb
|
||||
* @date 2021/10/17 15:05
|
||||
*/
|
||||
@Insert("insert into user_notify_announce(userId,notifyAnnounceId,status) select #{userId},notifyAnnounceId,0 from notify_announce a where a.createdDate > (select lastSyncAnnounceDate from user where userId=#{userId})")
|
||||
void dealNotifyAnnounceById(int userId);
|
||||
|
||||
/**
|
||||
* 标记为已读
|
||||
*
|
||||
* @param userId userId
|
||||
* @param notifyAnnounceId notifyAnnounceId
|
||||
* @author fanxb
|
||||
* @date 2021/10/17 15:26
|
||||
*/
|
||||
@Update("update user_notify_announce set status=1,readDate=#{readDate} where userId=#{userId} and notifyAnnounceId=#{notifyAnnounceId}")
|
||||
void markAsRead(@Param("userId") int userId, @Param("notifyAnnounceId") int notifyAnnounceId, @Param("readDate") long readDate);
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
package com.fanxb.bookmark.business.user.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.fanxb.bookmark.business.user.entity.SearchEngine;
|
||||
|
||||
public interface SearchEngineDao extends BaseMapper<SearchEngine> {
|
||||
|
||||
}
|
@ -1,14 +1,11 @@
|
||||
package com.fanxb.bookmark.business.user.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.fanxb.bookmark.common.entity.po.User;
|
||||
import com.fanxb.bookmark.common.entity.User;
|
||||
import com.fanxb.bookmark.common.entity.redis.UserBookmarkUpdate;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 类功能简述:
|
||||
* 类功能详述:
|
||||
@ -17,7 +14,7 @@ import java.util.List;
|
||||
* @date 2019/7/6 11:36
|
||||
*/
|
||||
@Component
|
||||
public interface UserDao extends BaseMapper<User> {
|
||||
public interface UserDao {
|
||||
|
||||
/**
|
||||
* Description: 新增一个用户
|
||||
@ -33,7 +30,7 @@ public interface UserDao extends BaseMapper<User> {
|
||||
*
|
||||
* @param name username
|
||||
* @param email email
|
||||
* @return com.fanxb.bookmark.common.entity.po.User
|
||||
* @return com.fanxb.bookmark.common.entity.User
|
||||
* @author fanxb
|
||||
* @date 2019/7/6 16:45
|
||||
*/
|
||||
@ -63,12 +60,11 @@ public interface UserDao extends BaseMapper<User> {
|
||||
* Description: 根据用户id查询用户信息
|
||||
*
|
||||
* @param userId userId
|
||||
* @param githubId githubId
|
||||
* @return com.fanxb.bookmark.common.entity.po.User
|
||||
* @return com.fanxb.bookmark.common.entity.User
|
||||
* @author fanxb
|
||||
* @date 2019/7/30 16:08
|
||||
*/
|
||||
User selectByUserIdOrGithubId(@Param("userId") Integer userId, @Param("githubId") Long githubId);
|
||||
User selectByUserId(int userId);
|
||||
|
||||
/**
|
||||
* Description: 更新用户icon
|
||||
@ -107,10 +103,10 @@ public interface UserDao extends BaseMapper<User> {
|
||||
* 更新用户新邮箱
|
||||
*
|
||||
* @param userId userId
|
||||
* @param newEmail email
|
||||
* @param newPassword userId
|
||||
*/
|
||||
@Update("update user set newEmail=#{newEmail} where userId= #{userId}")
|
||||
void updateNewEmailByUserId(@Param("userId") int userId, @Param("newEmail") String newEmail);
|
||||
@Update("update user set newEmail=#{newPassword} where userId= #{userId}")
|
||||
void updateNewEmailByUserId(@Param("userId") int userId, @Param("newPassword") String newPassword);
|
||||
|
||||
/**
|
||||
* 新邮箱校验成功,更新邮箱
|
||||
@ -123,78 +119,10 @@ public interface UserDao extends BaseMapper<User> {
|
||||
/**
|
||||
* 功能描述: 更新用户上次更新书签时间
|
||||
*
|
||||
* @param userId userId
|
||||
* @param item item
|
||||
* @author fanxb
|
||||
* @date 2020/1/26 下午3:47
|
||||
*/
|
||||
@Update("update user set version=version+1 where userId=#{userId}")
|
||||
void updateUserVersion(int userId);
|
||||
|
||||
/**
|
||||
* 功能描述: 更新所有用户的更新时间
|
||||
*
|
||||
* @author fanxb
|
||||
* @date 2020/3/29 18:18
|
||||
*/
|
||||
@Update("update user set version=version+1")
|
||||
void updateAllBookmarkUpdateVersion();
|
||||
|
||||
/**
|
||||
* 判断用户名是否存在
|
||||
*
|
||||
* @param name name
|
||||
* @return boolean
|
||||
* @author fanxb
|
||||
* @date 2021/3/11
|
||||
**/
|
||||
@Select("select count(1) from user where username=#{name}")
|
||||
boolean usernameExist(String name);
|
||||
|
||||
/**
|
||||
* 更新githubId
|
||||
*
|
||||
* @param user user
|
||||
* @author fanxb
|
||||
* @date 2021/3/11
|
||||
**/
|
||||
@Update("update user set githubId=#{githubId},email=#{email} where userId=#{userId}")
|
||||
void updateEmailAndGithubId(User user);
|
||||
|
||||
/**
|
||||
* 获取用户版本
|
||||
*
|
||||
* @param userId userId
|
||||
* @return int
|
||||
* @author fanxb
|
||||
* @date 2021/3/11
|
||||
**/
|
||||
@Select("select version from user where userId=#{userId}")
|
||||
int getUserVersion(int userId);
|
||||
|
||||
/**
|
||||
* 分页查询用户id列表
|
||||
*
|
||||
* @param start 开始
|
||||
* @param size 页大小
|
||||
* @return java.util.List<java.lang.Integer>
|
||||
* @author fanxb
|
||||
* @date 2021/3/13
|
||||
**/
|
||||
@Select("select userId from user order by userId limit #{start},#{size}")
|
||||
List<Integer> selectUserIdPage(@Param("start") int start, @Param("size") int size);
|
||||
|
||||
|
||||
/**
|
||||
* 更新一个字段-一个条件
|
||||
*
|
||||
* @param column 字段名
|
||||
* @param val 字段值
|
||||
* @param termColumn 条件字段名
|
||||
* @param termVal 条件字段值
|
||||
* @author fanxb
|
||||
* @date 2021/10/17 15:03
|
||||
*/
|
||||
@Update("update user set ${column} = #{val} where ${termColumn} = #{termVal}")
|
||||
void updateOneColumnByOneTerm(String column, Object val, String termColumn, Object termVal);
|
||||
|
||||
@Update("update user set bookmarkChangeTime=#{updateTime} where userId=#{userId}")
|
||||
void updateLastBookmarkUpdateTime(UserBookmarkUpdate item);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.fanxb.bookmark.business.user.vo;
|
||||
package com.fanxb.bookmark.business.user.entity;
|
||||
|
||||
import com.fanxb.bookmark.business.user.constant.ValidatedConstant;
|
||||
import lombok.Data;
|
||||
@ -17,7 +17,7 @@ import javax.validation.constraints.Pattern;
|
||||
@Data
|
||||
public class EmailUpdateBody {
|
||||
@NotNull(message = "参数不为空")
|
||||
private String oldPassword;
|
||||
private String actionId;
|
||||
@Email(message = "请输入有效邮箱地址")
|
||||
private String email;
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package com.fanxb.bookmark.business.user.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA
|
||||
*
|
||||
* @author fanxb
|
||||
* Date: 2020/3/10
|
||||
* Time: 23:13
|
||||
*/
|
||||
@Data
|
||||
public class Feedback {
|
||||
private int feedbackId;
|
||||
private int userId;
|
||||
private String type;
|
||||
@NotEmpty(message = "内容不能为空")
|
||||
private String content;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.fanxb.bookmark.business.user.vo;
|
||||
package com.fanxb.bookmark.business.user.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
@ -0,0 +1,20 @@
|
||||
package com.fanxb.bookmark.business.user.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 类功能简述:登录返回数据
|
||||
* 类功能详述:
|
||||
*
|
||||
* @author fanxb
|
||||
* @date 2019/7/6 16:52
|
||||
*/
|
||||
@Data
|
||||
public class LoginRes {
|
||||
private String token;
|
||||
private int userId;
|
||||
private String username;
|
||||
private String email;
|
||||
private String lastLoginTime;
|
||||
private String icon;
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package com.fanxb.bookmark.business.user.entity;
|
||||
|
||||
/**
|
||||
* @author fanxb
|
||||
* @date 2021-10-17 14:04
|
||||
*/
|
||||
public class NotifyAnnounce {
|
||||
/**
|
||||
* 通知id
|
||||
*/
|
||||
private int notifyAnnounceId;
|
||||
/**
|
||||
* 发送人id
|
||||
*/
|
||||
private int senderId;
|
||||
/**
|
||||
* 标题
|
||||
*/
|
||||
private String title;
|
||||
/**
|
||||
* 正文
|
||||
*/
|
||||
private String content;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Long createdDate;
|
||||
/**
|
||||
* 通知开始时间
|
||||
*/
|
||||
private Long startDate;
|
||||
/**
|
||||
* 通知结束时间
|
||||
*/
|
||||
private Long endDate;
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.fanxb.bookmark.business.user.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 类功能简述: 注册表单
|
||||
* 类功能详述:
|
||||
*
|
||||
* @author fanxb
|
||||
* @date 2019/7/6 11:23
|
||||
*/
|
||||
@Data
|
||||
public class RegisterBody {
|
||||
private String username;
|
||||
private String password;
|
||||
private String email;
|
||||
private String authCode;
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package com.fanxb.bookmark.business.user.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@TableName("search_engine")
|
||||
public class SearchEngine {
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Integer id;
|
||||
private Integer userId;
|
||||
private Integer checked;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* url
|
||||
*/
|
||||
private String url;
|
||||
/**
|
||||
* 图标
|
||||
*/
|
||||
private String icon;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.fanxb.bookmark.business.user.vo;
|
||||
package com.fanxb.bookmark.business.user.entity;
|
||||
|
||||
import com.fanxb.bookmark.business.user.constant.ValidatedConstant;
|
||||
import lombok.Data;
|
||||
@ -15,7 +15,7 @@ import javax.validation.constraints.Pattern;
|
||||
@Data
|
||||
public class UpdatePasswordBody {
|
||||
|
||||
private String oldPassword;
|
||||
private String actionId;
|
||||
@Pattern(regexp = ValidatedConstant.PASSWORD_REG, message = ValidatedConstant.PASSWORD_MESSAGE)
|
||||
private String password;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.fanxb.bookmark.business.user.vo;
|
||||
package com.fanxb.bookmark.business.user.entity;
|
||||
|
||||
import com.fanxb.bookmark.business.user.constant.ValidatedConstant;
|
||||
import lombok.Data;
|
@ -0,0 +1,38 @@
|
||||
package com.fanxb.bookmark.business.user.schedule;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.fanxb.bookmark.business.user.dao.UserDao;
|
||||
import com.fanxb.bookmark.common.constant.RedisConstant;
|
||||
import com.fanxb.bookmark.common.entity.redis.UserBookmarkUpdate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author fanxb
|
||||
* @date 2020/1/26 上午11:54
|
||||
*/
|
||||
@Component
|
||||
public class UserInfoUpdate {
|
||||
/**
|
||||
* 阻塞时间
|
||||
*/
|
||||
private static final int BLOCK_TIME = 15;
|
||||
|
||||
@Autowired
|
||||
private StringRedisTemplate redisTemplate;
|
||||
@Autowired
|
||||
private UserDao userDao;
|
||||
|
||||
@Scheduled(fixedDelay = 100000)
|
||||
public void userBookmarkUpdateTime() {
|
||||
String value;
|
||||
while ((value = redisTemplate.opsForList().rightPop(RedisConstant.BOOKMARK_UPDATE_TIME, BLOCK_TIME, TimeUnit.SECONDS)) != null) {
|
||||
UserBookmarkUpdate item = JSON.parseObject(value, UserBookmarkUpdate.class);
|
||||
userDao.updateLastBookmarkUpdateTime(item);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
/**
|
||||
* 定时调度类
|
||||
*
|
||||
* @author fanxb
|
||||
* @date 2021-10-17 14:37
|
||||
*/
|
||||
package com.fanxb.bookmark.business.user.schedule;
|
@ -1,25 +1,52 @@
|
||||
package com.fanxb.bookmark.business.user.service;
|
||||
|
||||
import com.fanxb.bookmark.business.user.vo.EmailUpdateBody;
|
||||
import com.fanxb.bookmark.business.user.vo.UpdatePasswordBody;
|
||||
import com.fanxb.bookmark.common.entity.po.User;
|
||||
import com.fanxb.bookmark.business.user.constant.RedisConstant;
|
||||
import com.fanxb.bookmark.business.user.dao.UserDao;
|
||||
import com.fanxb.bookmark.business.user.entity.EmailUpdateBody;
|
||||
import com.fanxb.bookmark.business.user.entity.UpdatePasswordBody;
|
||||
import com.fanxb.bookmark.common.constant.Constant;
|
||||
import com.fanxb.bookmark.common.entity.MailInfo;
|
||||
import com.fanxb.bookmark.common.exception.CustomException;
|
||||
import com.fanxb.bookmark.common.exception.FormDataException;
|
||||
import com.fanxb.bookmark.common.util.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* 个人信息修改
|
||||
* 类功能简述:
|
||||
* 类功能详述:
|
||||
*
|
||||
* @author fanxb
|
||||
* @date 2021/3/14
|
||||
**/
|
||||
public interface BaseInfoService {
|
||||
* @date 2019/9/18 15:54
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class BaseInfoService {
|
||||
|
||||
private static final String VERIFY_EMAIL = FileUtil.streamToString(BaseInfoService.class
|
||||
.getClassLoader().getResourceAsStream("verifyEmail.html"));
|
||||
|
||||
private static final String VERIFY_EMAIL_PATH = "/public/verifyEmail?key=";
|
||||
|
||||
@Autowired
|
||||
private UserDao userDao;
|
||||
|
||||
public void changePassword(UpdatePasswordBody body) {
|
||||
int userId = UserContextHolder.get().getUserId();
|
||||
String checkAuthKey = com.fanxb.bookmark.common.constant.RedisConstant.getPasswordCheckKey(userId, body.getActionId());
|
||||
String str = RedisUtil.get(checkAuthKey, String.class);
|
||||
if (str == null) {
|
||||
throw new CustomException("密码校验失败,无法更新密码");
|
||||
}
|
||||
userDao.updatePasswordByUserId(userId, HashUtil.getPassword(body.getPassword()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改密码
|
||||
*
|
||||
* @param body body
|
||||
* @author fanxb
|
||||
* @date 2021/3/14
|
||||
**/
|
||||
void changePassword(UpdatePasswordBody body);
|
||||
|
||||
/**
|
||||
* Description: 修改用户名
|
||||
@ -28,7 +55,9 @@ public interface BaseInfoService {
|
||||
* @author fanxb
|
||||
* @date 2019/9/20 16:18
|
||||
*/
|
||||
void updateUsername(String username);
|
||||
public void updateUsername(String username) {
|
||||
userDao.updateUsernameByUserId(UserContextHolder.get().getUserId(), username);
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能描述: 预备更新email,需要校验密码
|
||||
@ -37,7 +66,23 @@ public interface BaseInfoService {
|
||||
* @author fanxb
|
||||
* @date 2019/9/26 17:27
|
||||
*/
|
||||
void updateEmail(EmailUpdateBody body);
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateEmail(EmailUpdateBody body) {
|
||||
int userId = UserContextHolder.get().getUserId();
|
||||
String checkAuthKey = com.fanxb.bookmark.common.constant.RedisConstant.getPasswordCheckKey(userId, body.getActionId());
|
||||
String str = RedisUtil.get(checkAuthKey, String.class);
|
||||
if (str == null) {
|
||||
throw new CustomException("密码校验失败,无法更新email");
|
||||
}
|
||||
RedisUtil.delete(checkAuthKey);
|
||||
String secret = UUID.randomUUID().toString().replaceAll("-", "");
|
||||
String url = VERIFY_EMAIL.replaceAll("XXXX", Constant.serviceAddress + VERIFY_EMAIL_PATH + secret);
|
||||
log.debug(url);
|
||||
MailInfo info = new MailInfo(body.getEmail(), "验证邮箱", url);
|
||||
MailUtil.sendMail(info, true);
|
||||
RedisUtil.set(RedisConstant.getUpdateEmailKey(secret), String.valueOf(userId), TimeUtil.DAY_MS);
|
||||
userDao.updateNewEmailByUserId(userId, body.getEmail());
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能描述: 校验新邮箱,校验成功就更新
|
||||
@ -46,14 +91,13 @@ public interface BaseInfoService {
|
||||
* @author fanxb
|
||||
* @date 2019/11/11 23:24
|
||||
*/
|
||||
void verifyEmail(String secret);
|
||||
|
||||
/**
|
||||
* 修改用户默认搜索引擎
|
||||
*
|
||||
* @param user user
|
||||
* @author fanxb
|
||||
* @date 2021/3/14
|
||||
**/
|
||||
void changeDefaultSearchEngine(User user);
|
||||
public void verifyEmail(String secret) {
|
||||
String key = RedisConstant.getUpdateEmailKey(secret);
|
||||
Integer userId = RedisUtil.get(key, Integer.class);
|
||||
RedisUtil.delete(key);
|
||||
if (userId == null) {
|
||||
throw new CustomException("校验失败,请重试");
|
||||
}
|
||||
userDao.updateEmailByUserId(userId);
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +0,0 @@
|
||||
package com.fanxb.bookmark.business.user.service;
|
||||
|
||||
import com.fanxb.bookmark.business.user.entity.Feedback;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA
|
||||
*
|
||||
* @author fanxb
|
||||
* Date: 2020/3/10
|
||||
* Time: 23:17
|
||||
*/
|
||||
public interface FeedbackService {
|
||||
/**
|
||||
* 功能描述: 插入一条记录
|
||||
*
|
||||
* @param feedback feedback
|
||||
* @author fanxb
|
||||
* @date 2020/3/10 23:18
|
||||
*/
|
||||
void addOne(Feedback feedback);
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package com.fanxb.bookmark.business.user.service;
|
||||
|
||||
import com.fanxb.bookmark.business.user.entity.NotifyAnnounce;
|
||||
import com.fanxb.bookmark.business.user.vo.UserNotifyAnnounceRes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author fanxb
|
||||
* @date 2021-10-17 14:07
|
||||
*/
|
||||
public interface NotifyAnnounceService {
|
||||
|
||||
/**
|
||||
* 获取用户通知
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @param status 状态 0:未读,1:已读
|
||||
* @author fanxb
|
||||
* @date 2021/10/17 14:14
|
||||
*/
|
||||
List<UserNotifyAnnounceRes> getUserAnnounce(int userId, int status);
|
||||
|
||||
/**
|
||||
* 标记为已读
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @param notifyAnnounceId 通知id
|
||||
* @author fanxb
|
||||
* @date 2021/10/17 14:14
|
||||
*/
|
||||
void markAsRead(int userId, int notifyAnnounceId);
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package com.fanxb.bookmark.business.user.service;
|
||||
|
||||
import com.fanxb.bookmark.business.user.vo.OauthBody;
|
||||
|
||||
/**
|
||||
* @author fanxb
|
||||
* @date 2021/8/20 下午2:13
|
||||
*/
|
||||
public interface OauthService {
|
||||
/**
|
||||
* oauth登陆校验
|
||||
*
|
||||
* @param body body
|
||||
* @return java.lang.String
|
||||
* @author fanxb
|
||||
* @date 2021/8/20 下午2:13
|
||||
*/
|
||||
String oAuthCheck(OauthBody body);
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
package com.fanxb.bookmark.business.user.service;
|
||||
|
||||
import com.fanxb.bookmark.business.user.entity.SearchEngine;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface SearchEngineService {
|
||||
|
||||
/**
|
||||
* 列表查询
|
||||
*/
|
||||
List<SearchEngine> list();
|
||||
|
||||
/**
|
||||
* delete one by id
|
||||
*
|
||||
* @param id id
|
||||
*/
|
||||
void deleteOne(int id);
|
||||
|
||||
/**
|
||||
* insert one
|
||||
*
|
||||
* @param body body
|
||||
*/
|
||||
void insertOne(SearchEngine body);
|
||||
|
||||
|
||||
/**
|
||||
* edit one
|
||||
*
|
||||
* @param body body
|
||||
*/
|
||||
void editOne(SearchEngine body);
|
||||
|
||||
/**
|
||||
* 设为默认搜索项
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
void setChecked(Integer id);
|
||||
|
||||
/**
|
||||
* 新用户初始化
|
||||
*
|
||||
* @param userId userId
|
||||
*/
|
||||
void newUserInit(int userId);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user