diff --git a/DEPLOY.md b/DEPLOY.md index f5cc0a2..d1e9e4e 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -1,12 +1,20 @@ 本程序基于 docker 来进行部署,使用 docker-compose 管理服务。 -部署过程如下: +**注意,仅在 x86 环境下测试,arm 下不保证可用性(目前测试可用)** -**注意,仅在 x86 环境下测试,arm下不保证可用性(目前测试可用)** +## 首次部署 -1. 安装新版的 docker,docker-compose,zip(注意:以下操作均在项目根目录下执行) -2. 修改.env 文件中的参数,改为你的实际配置 -3. 修改`浏览器插件/bookmarkBrowserPlugin/static/js/config.js`中的 bookmarkHost,改为你的实际部署路径 -4. 修改`浏览器插件/bookmarkBrowserPlugin/tab/index.html`中的``,将 url 改为你的实际部署地址 -5. 执行`build.sh`编译前后端代码 -6. root 权限运行 `docker-compose up -d` 启动服务。 +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`中的``,将 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` 启动服务 diff --git a/bookMarkService/business/bookmark/pom.xml b/bookMarkService/business/bookmark/pom.xml index 8e70e40..3f038db 100644 --- a/bookMarkService/business/bookmark/pom.xml +++ b/bookMarkService/business/bookmark/pom.xml @@ -29,6 +29,11 @@ pinyin 0.3.1 + + org.xerial + sqlite-jdbc + 3.44.1.0 + diff --git a/bookMarkService/business/bookmark/src/main/java/com/fanxb/bookmark/business/bookmark/controller/BookmarkController.java b/bookMarkService/business/bookmark/src/main/java/com/fanxb/bookmark/business/bookmark/controller/BookmarkController.java index 440acd6..14b7ba9 100644 --- a/bookMarkService/business/bookmark/src/main/java/com/fanxb/bookmark/business/bookmark/controller/BookmarkController.java +++ b/bookMarkService/business/bookmark/src/main/java/com/fanxb/bookmark/business/bookmark/controller/BookmarkController.java @@ -69,7 +69,7 @@ public class BookmarkController { */ @RequestMapping("/uploadBookmarkFile") public Result uploadFile(@RequestParam("file") MultipartFile file, @RequestParam("path") String path) throws Exception { - bookmarkService.parseBookmarkFile(UserContextHolder.get().getUserId(), file.getInputStream(), path); + bookmarkService.parseBookmarkFile(UserContextHolder.get().getUserId(), file, path); return Result.success(null); } diff --git a/bookMarkService/business/bookmark/src/main/java/com/fanxb/bookmark/business/bookmark/service/BookmarkService.java b/bookMarkService/business/bookmark/src/main/java/com/fanxb/bookmark/business/bookmark/service/BookmarkService.java index 9e21f06..3e62d96 100644 --- a/bookMarkService/business/bookmark/src/main/java/com/fanxb/bookmark/business/bookmark/service/BookmarkService.java +++ b/bookMarkService/business/bookmark/src/main/java/com/fanxb/bookmark/business/bookmark/service/BookmarkService.java @@ -3,6 +3,7 @@ package com.fanxb.bookmark.business.bookmark.service; 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 java.io.InputStream; import java.util.List; @@ -54,7 +55,7 @@ public interface BookmarkService { * @author fanxb * @date 2019/7/9 18:44 */ - void parseBookmarkFile(int userId, InputStream stream, String path) throws Exception; + void parseBookmarkFile(int userId, MultipartFile file, String path) throws Exception; /** * Description: 详情 diff --git a/bookMarkService/business/bookmark/src/main/java/com/fanxb/bookmark/business/bookmark/service/impl/BookmarkServiceImpl.java b/bookMarkService/business/bookmark/src/main/java/com/fanxb/bookmark/business/bookmark/service/impl/BookmarkServiceImpl.java index e212e03..f1f4eaa 100644 --- a/bookMarkService/business/bookmark/src/main/java/com/fanxb/bookmark/business/bookmark/service/impl/BookmarkServiceImpl.java +++ b/bookMarkService/business/bookmark/src/main/java/com/fanxb/bookmark/business/bookmark/service/impl/BookmarkServiceImpl.java @@ -2,10 +2,8 @@ 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.ArrayUtil; -import cn.hutool.core.util.CharsetUtil; +import cn.hutool.core.util.*; import cn.hutool.core.util.HashUtil; -import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSON; import com.fanxb.bookmark.business.api.UserApi; import com.fanxb.bookmark.business.bookmark.constant.FileConstant; @@ -38,7 +36,9 @@ 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; @@ -49,6 +49,10 @@ 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; @@ -81,18 +85,25 @@ public class BookmarkServiceImpl implements BookmarkService { @Override @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"); + public void parseBookmarkFile(int userId, MultipartFile file, String path) throws Exception { + List bookmarks = new ArrayList<>(); //获取当前层sort最大值 Integer sortBase = bookmarkDao.selectMaxSort(userId, path); if (sortBase == null) { sortBase = 0; } - List bookmarks = new ArrayList<>(); - for (int i = 0, length = elements.size(); i < length; i++) { - dealBookmark(userId, elements.get(i), path, sortBase + i, bookmarks); + 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 tempList = new ArrayList<>(1000); for (int i = 0; i < bookmarks.size(); i++) { @@ -151,6 +162,57 @@ public class BookmarkServiceImpl implements BookmarkService { } } + /** + * 处理oneenv的导出 + * + * @param bookmarks 书签列表 + * @param userId 用户id + * @param file file + * @param path path + * @param sort sort + */ + private void readFromOneEnv(List 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 folderMap = new HashMap<>(); + Map 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: 插入一条书签,如果已经存在同名书签将跳过 * @@ -288,7 +350,7 @@ public class BookmarkServiceImpl implements BookmarkService { int size = 100; int start = 0; List deal; - while ((deal = bookmarkDao.selectUserNoIcon(userId, start, size)).size() > 0) { + while (!(deal = bookmarkDao.selectUserNoIcon(userId, start, size)).isEmpty()) { start += size; deal.forEach(item -> { String icon = getIconPath(item.getUrl(), null, null); diff --git a/bookMarkService/common/src/main/java/com/fanxb/bookmark/common/service/impl/ConfigServiceImpl.java b/bookMarkService/common/src/main/java/com/fanxb/bookmark/common/service/impl/ConfigServiceImpl.java index ca2e562..39812cd 100644 --- a/bookMarkService/common/src/main/java/com/fanxb/bookmark/common/service/impl/ConfigServiceImpl.java +++ b/bookMarkService/common/src/main/java/com/fanxb/bookmark/common/service/impl/ConfigServiceImpl.java @@ -2,8 +2,11 @@ package com.fanxb.bookmark.common.service.impl; import cn.hutool.core.date.DateUnit; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; +import com.fanxb.bookmark.common.constant.CommonConstant; import com.fanxb.bookmark.common.constant.NumberConstant; import com.fanxb.bookmark.common.constant.RedisConstant; import com.fanxb.bookmark.common.dao.GlobalConfigDao; @@ -12,11 +15,16 @@ import com.fanxb.bookmark.common.entity.vo.GlobalConfigVo; import com.fanxb.bookmark.common.service.ConfigService; import com.fanxb.bookmark.common.util.HttpUtil; import lombok.extern.slf4j.Slf4j; +import okhttp3.Request; +import okhttp3.Response; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; +import java.io.File; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -61,21 +69,23 @@ public class ConfigServiceImpl implements ConfigService { return str; } str = getBingImg(); - if (str != null) { - stringRedisTemplate.opsForValue().set(RedisConstant.BING_IMG, str, 2, TimeUnit.HOURS); - } + stringRedisTemplate.opsForValue().set(RedisConstant.BING_IMG, str, 2, TimeUnit.HOURS); return str; } private String getBingImg() { - try { - JSONObject bingObj = HttpUtil.getObj(bingHost + bingUrl, null, false); - String path = bingObj.getJSONArray("images").getJSONObject(0).getString("url"); - return bingHost + path; + JSONObject bingObj = HttpUtil.getObj(bingHost + bingUrl, null, false); + String path = bingObj.getJSONArray("images").getJSONObject(0).getString("url"); + String picUrl = bingHost + path; + Request request = new Request.Builder().url(picUrl).build(); + try (Response res = HttpUtil.getClient(false).newCall(request).execute()) { + byte[] bytes = res.body().bytes(); + String filePath = CommonConstant.fileSavePath + "/files/public/bing.jpg"; + FileUtil.writeBytes(bytes, filePath); } catch (Exception e) { log.error("获取bing每日一图错误:{}", e.getLocalizedMessage(), e); } - return null; + return "/files/public/bing.jpg"; } diff --git a/bookmark_front/src/App.vue b/bookmark_front/src/App.vue index be76731..224082b 100644 --- a/bookmark_front/src/App.vue +++ b/bookmark_front/src/App.vue @@ -6,12 +6,21 @@ diff --git a/bookmark_front/vue.config.js b/bookmark_front/vue.config.js index c99fcfd..7d32099 100644 --- a/bookmark_front/vue.config.js +++ b/bookmark_front/vue.config.js @@ -1,20 +1,21 @@ module.exports = { - lintOnSave: false, - configureWebpack: { - devtool: "source-map" - }, - devServer: { - proxy: { - "/bookmark/api": { - //这里最好有一个 / - target: "http://localhost:8088", // 服务器端接口地址 - ws: true, //如果要代理 websockets,配置这个参数 - // 如果是https接口,需要配置这个参数 - changeOrigin: true, //是否跨域 - pathRewrite: { - "^/bookmark/api": "/bookmark/api" - } - } - } - } + lintOnSave: false, + configureWebpack: { + devtool: "source-map" + }, + devServer: { + port: 4531, + proxy: { + "/bookmark/api": { + //这里最好有一个 / + target: "http://localhost:8088", // 服务器端接口地址 + ws: true, //如果要代理 websockets,配置这个参数 + // 如果是https接口,需要配置这个参数 + changeOrigin: true, //是否跨域 + pathRewrite: { + "^/bookmark/api": "/bookmark/api" + } + } + } + } }; diff --git a/docker-compose.yml b/docker-compose.yml index 9910664..ef55f68 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -14,6 +14,7 @@ services: - ./data/mysql/my.cnf:/etc/mysql/my.cnf - /etc/localtime:/etc/localtime - ./data/timezone:/etc/timezone + restart: unless-stopped environment: - MYSQL_ROOT_PASSWORD=${MYSQL_PASSWORD} - MYSQL_DATABASE=bookmark @@ -25,6 +26,7 @@ services: - /etc/localtime:/etc/localtime - ./data/timezone:/etc/timezone - ./data/redis:/data + restart: unless-stopped networks: - bookmark @@ -38,6 +40,7 @@ services: - ./bookmark_front/dist:/opt/dist - ./data/nginx/nginx.conf:/etc/nginx/nginx.conf - ${BOOKMARK_FILE_SAVE_PATH}/files/public:/opt/files/public + restart: unless-stopped ports: - 8080:8080 @@ -60,6 +63,7 @@ services: - ./bookMarkService/web/target/bookmark-web-1.0-SNAPSHOT.jar:/opt/app/service.jar - ${BOOKMARK_FILE_SAVE_PATH}:/opt/files working_dir: /opt/app + restart: unless-stopped command: - /bin/bash - -c