From 900076723f70dcc8e678e8af5d4bd9006bae6bf3 Mon Sep 17 00:00:00 2001
From: WangHao <43278047@qq.com>
Date: Mon, 26 Apr 2021 22:27:52 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=88=86=E7=B1=BB=E6=98=BE?=
 =?UTF-8?q?=E7=A4=BA=E5=9B=9E=E6=94=B6=E7=AB=99=20=E7=A8=8D=E5=90=8E?=
 =?UTF-8?q?=E7=9C=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../yunbookmark/BrowserController.java        |  70 ++---
 .../yunbookmark/SqBookmarkController.java     |  23 +-
 .../com/ruoyi/web/test/controller/22.html     |  36 +++
 .../ruoyi/web/test/controller/HtmlTest.java   | 136 ++++++++
 .../com/ruoyi/web/test/controller/模板.html   |  47 +++
 .../common/utils/bookmarkhtml/Const.java      |  18 ++
 .../web/service/SysLoginService.java          |  31 +-
 .../resources/mapper/system/SysUserMapper.xml |   2 +
 ruoyi-ui/src/api/bookmark/bookmark.js         |  15 +
 .../src/components/BookmarkList/index.vue     |  49 +--
 ruoyi-ui/src/utils/exportFile.js              |  15 +
 ruoyi-ui/src/views/bookmark/bkuser/index.vue  |   4 +-
 .../views/bookmark/bkuser/tool/exportHtml.vue | 106 ++++++-
 .../src/views/bookmark/bookmark/index.vue     |  68 +++-
 ruoyi-ui/src/views/bookmark/index/index.vue   | 296 +++++++++++-------
 .../views/bookmark/ztree/jquery.ztree.core.js |   2 +-
 ruoyi-ui/src/views/login.vue                  |   2 +-
 .../com/ruoyi/bookmark/domain/SqBookmark.java |  14 +
 .../bookmark/mapper/SqBookmarkMapper.java     |  10 +
 .../ruoyi/bookmark/mapper/SqMenuMapper.java   |   3 +
 .../bookmark/service/ISqBookmarkService.java  |  22 ++
 .../service/impl/SqBookmarkServiceImpl.java   | 182 ++++++++---
 .../service/impl/SqTagServiceImpl.java        |   2 +-
 .../mapper/bookmark/SqBookmarkMapper.xml      |  40 ++-
 24 files changed, 941 insertions(+), 252 deletions(-)
 create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/22.html
 create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/HtmlTest.java
 create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/模板.html
 create mode 100644 ruoyi-ui/src/utils/exportFile.js

diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/yunbookmark/BrowserController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/yunbookmark/BrowserController.java
index 86bff4298..1f80d6abe 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/yunbookmark/BrowserController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/yunbookmark/BrowserController.java
@@ -2,18 +2,16 @@ package com.ruoyi.web.controller.yunbookmark;
 
 
 
-import com.ruoyi.bookmark.domain.SqBookmark;
-import com.ruoyi.bookmark.domain.SqMenu;
+
+import cn.hutool.core.date.DateUtil;
 import com.ruoyi.bookmark.service.ISqBookmarkService;
 import com.ruoyi.bookmark.service.ISqMenuService;
 import com.ruoyi.common.core.controller.BaseController;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.domain.entity.SysUser;
-import com.ruoyi.common.core.redis.RedisUtil;
 import com.ruoyi.common.utils.bookmarkhtml.Const;
 import com.ruoyi.common.utils.bookmarkhtml.HtmlName;
 import com.ruoyi.common.utils.bookmarkhtml.ImportHtml;
-import com.ruoyi.common.utils.StringUtils;
 import org.jsoup.HttpStatusException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -25,13 +23,10 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
 import javax.net.ssl.SSLHandshakeException;
-import java.net.URL;
-import java.util.Comparator;
+import javax.servlet.http.HttpServletResponse;
+import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.stream.Collectors;
 
 
 /**
@@ -50,9 +45,9 @@ public class BrowserController extends BaseController {
     @Autowired
     private ISqBookmarkService iSqBookmarkService;
 
-
+    //导入
     @RequestMapping("/import")
-    @PreAuthorize("@ss.hasPermi('bookmark:browser:export')")
+    @PreAuthorize("@ss.hasPermi('bookmark:browser:import')")
     public AjaxResult importCollect(@RequestParam("htmlFile") MultipartFile htmlFile){
         long startTime = System.currentTimeMillis();
         logger.info("开始上传状态是:"+ startTime );
@@ -88,7 +83,7 @@ public class BrowserController extends BaseController {
         long endTime = System.currentTimeMillis();
 
         float seconds = (endTime - startTime) / 1000F;
-        logger.info("导入用时:"+ Float.toString(seconds) );
+        logger.info("导入用时:"+ seconds +"秒");
 
         return AjaxResult.success("导入成功");
 
@@ -96,34 +91,31 @@ public class BrowserController extends BaseController {
 
 
 
-//    /**
-//     * 导入收藏文章
-//     */
-//    public void importHtml(Map<String, String> map,Long menuID,Long userId){
-//        for(Entry<String, String> entry : map.entrySet()){
-//            try {
-//                //获取URL后查询最新的URL信息
-//                Map<String, String> result = ImportHtml.getCollectFromUrl(entry.getKey());
-//                SqBookmark sqBookmark =new SqBookmark();
-//                sqBookmark.setUserid(userId);
-//                sqBookmark.setTitle(entry.getValue());
-//                sqBookmark.setUrl(entry.getKey());
-//                sqBookmark.setUrls(ImportHtml.Urlutils(new URL(entry.getKey())));
-//                if(StringUtils.isBlank(result.get("description"))){
-//                    sqBookmark.setDescription(entry.getValue());
-//                }else{
-//                    sqBookmark.setDescription(result.get("description"));
-//                }
-//                sqBookmark.setMenuId(menuID);
-//                sqBookmark.setCreateTime(new Date());
-//                iSqBookmarkService.insertSqBookmark(sqBookmark);
-//            } catch (Exception e) {
-//                logger.error("导入存储异常:",e);
-//            }
-//        }
-//
-//    }
+    /**
+     *  导出全部书签
+     */
+    @RequestMapping("/export")
+//    @PreAuthorize("@ss.hasPermi('bookmark:browser:export')")
+    public void exportCollect(HttpServletResponse response) {
+        long startTime = System.currentTimeMillis();
+        logger.info("导出书签:" + startTime + "用户ID:" + getAuthUser().getUserId());
+        try {
+            String fileName = "cqy_" + DateUtil.now() + ".html";
+            StringBuilder sb = iSqBookmarkService.exportToHtml(getAuthUser().getUserId());
+            response.setContentType("application/octet-stream;charset=UTF-8");
+            response.setHeader("Access-Control-Expose-Headers", "content-disposition"); //Access-Control-Expose-Headers 让前端可以取Content-Disposition
+            response.setHeader("content-disposition", "attachment;filename=" + fileName);
+            response.setHeader("Pargam", "no-cache");
+            response.setHeader("Cache-Control", "no-cache");
+            response.getWriter().print(sb);
+        } catch (Exception e) {
+            logger.error("异常:", e);
+        }
 
+        long endTime = System.currentTimeMillis();
+        float seconds = (endTime - startTime) / 1000F;
+        logger.info("导出用时:" + seconds+"秒");
+    }
 
 
 }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/yunbookmark/SqBookmarkController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/yunbookmark/SqBookmarkController.java
index cb7985774..3e31d3847 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/yunbookmark/SqBookmarkController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/yunbookmark/SqBookmarkController.java
@@ -44,16 +44,6 @@ public class SqBookmarkController extends BaseController
     private ISqBookmarkService sqBookmarkService;
 
 
-//    /**
-//     * 测试通用mapper
-//     */
-//    @GetMapping("/selectByID")
-//    public TableDataInfo selectByID( Long userID) {
-//        List<SqBookmark> list = sqBookmarkService.selectByID(userID);
-//        return getDataTable(list);
-//    }
-
-
     /**
      *  删除重复的书签
      */
@@ -133,6 +123,19 @@ public class SqBookmarkController extends BaseController
         return getDataTable(list);
     }
 
+    /**
+     * 查询书签管理列表 聚合>> 星标 稍后看 最新书签
+     */
+//    @PreAuthorize("@ss.hasPermi('bookmark:bookmark:list')")
+    @GetMapping("/listByUserAndPolymerization")
+    public TableDataInfo listByUserAndPolymerization(SqBookmark sqBookmark)
+    {
+        sqBookmark.setUserid(getAuthUser().getUserId());
+        startPage();
+        List<SqBookmark> list = sqBookmarkService.listByUserAndPolymerization(sqBookmark);
+        return getDataTable(list);
+    }
+
 
     /**
      * 查询书签管理列表
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/22.html b/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/22.html
new file mode 100644
index 000000000..c4f9899f8
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/22.html
@@ -0,0 +1,36 @@
+<!DOCTYPE >
+<!-- This is an automatically generated file.
+     It will be read and overwritten.
+     DO NOT EDIT! -->
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
+<TITLE>Bookmarks</TITLE>
+<H1>Bookmarks</H1>
+<DL>
+    <DT><H3 ADD_DATE="1584277207" LAST_MODIFIED="0">收藏夹栏</H3>
+        <DL>
+            <DT><H3 ADD_DATE="1584277207" LAST_MODIFIED="0">一级2</H3>
+                <DL>
+                    <DT><A HREF="https://www.huodongxing.com/go/tl24" TARGET="_blank">第二十四届前端早早聊大会 | 前端搞算法 - 在线直播 预约</A>
+                </DL>
+            <DT><H3 ADD_DATE="1584277207" LAST_MODIFIED="0">一级</H3>
+                <DL>
+                    <DT><A HREF="https://juejin.cn/" TARGET="_blank">掘金 - 代码不止,掘金不停</A>
+                    <DT><H3 ADD_DATE="1584277207" LAST_MODIFIED="0">二级</H3>
+                        <DL>
+                            <DT><A HREF="https://juejin.cn/pin/6952704146197708837" TARGET="_blank">【掘金读书会】掘金x异步 -
+                                掘金</A>
+                        </DL>
+                </DL>
+            <DT><H3 ADD_DATE="1584277207" LAST_MODIFIED="0">一级3</H3>
+                <DL>
+                    <DT><A HREF="https://juejin.cn/post/6951649464637636622" TARGET="_blank">从 0 开始手把手带你搭建一套规范的 Vue3.x
+                        项目工程</A>
+                    <DT><H3 ADD_DATE="1584277207" LAST_MODIFIED="0">二级3-1</H3>
+                        <DL>
+                            <DT><A HREF="https://juejin.cn/post/6947987257034965000"
+                                   TARGET="_blank">我,是如何度过人生最艰难的时刻的</A>
+                        </DL>
+                </DL>
+        </DL>
+
+</dl>
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/HtmlTest.java b/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/HtmlTest.java
new file mode 100644
index 000000000..a5edddb6a
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/HtmlTest.java
@@ -0,0 +1,136 @@
+package com.ruoyi.web.test.controller;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.http.HtmlUtil;
+import com.ruoyi.bookmark.domain.SqBookmark;
+import com.ruoyi.bookmark.domain.SqMenu;
+import com.ruoyi.bookmark.service.ISqBookmarkService;
+import com.ruoyi.bookmark.service.ISqMenuService;
+import com.ruoyi.common.utils.StringUtils;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @Auther: Wang
+ * @Date: 2021/04/19 21:16
+ * 功能描述:
+ */
+public class HtmlTest extends BaseSpringBootTest {
+
+    @Autowired
+    private ISqMenuService iSqMenuService;
+    @Autowired
+    private ISqBookmarkService iSqBookmarkService;
+
+    @Test
+    public void test3() {
+        String favoritesId = "2";
+
+    if(StringUtils.isNotBlank(favoritesId))
+    {
+        HttpServletResponse response=null;
+        try {
+            String fileName = "cqy_" + DateUtil.now() + ".html";
+            StringBuilder sb = new StringBuilder();
+            sb.append("<!DOCTYPE NETSCAPE-Bookmark-file-1>\n" +
+                    "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\">\n" +
+                    "<TITLE>Bookmarks</TITLE>\n" +
+                    "<H1>Bookmarks</H1>");
+            sb.append("<DL>\n");
+            sb.append(exportToHtml(1L));
+            sb.append("</DL>\n");
+            //1:使用File类创建一个要操作的文件路径
+            File file = new File("D:" + File.separator + "demo" + File.separator + fileName);
+            if(!file.getParentFile().exists()){ //如果文件的目录不存在
+                file.getParentFile().mkdirs(); //创建目录
+
+            }
+            //2: 实例化OutputString 对象
+            OutputStream output = new FileOutputStream(file);
+
+            //3: 准备好实现内容的输出
+            //将字符串变为字节数组
+            byte data[] = sb.toString().getBytes();
+            output.write(data);
+            //4: 资源操作的最后必须关闭
+            output.close();
+
+        } catch (Exception e) {
+            logger.error("异常:", e);
+        }
+        }
+    }
+
+
+    /**
+     * 导出到html文件
+     * @param
+     */
+    public StringBuilder exportToHtml(Long userId){
+
+        SqMenu sqMenu=new SqMenu();
+        sqMenu.setUserId(userId);
+        SqBookmark sqBookmark = new SqBookmark();
+        sqBookmark.setUserid(userId);
+        //目录
+        List<SqMenu> menuList = iSqMenuService.selectSqMenuList(sqMenu);
+        Map<Long, List<SqMenu>> mapMenu =  menuList.stream().collect(Collectors.groupingBy(SqMenu::getParentId));
+        //书签
+        List<SqBookmark> bookMarkList = iSqBookmarkService.selectSqBookmarkList(sqBookmark);
+        Map<Long, List<SqBookmark>> mapBookMark  = bookMarkList.stream().collect(Collectors.groupingBy(SqBookmark::getMenuId));
+
+        List<SqMenu> sqMenuList = mapMenu.get(0L);
+        StringBuilder str = new StringBuilder();
+        str = traverseFile_recursion(sqMenuList,str,mapBookMark,mapMenu);
+        return str;
+    }
+
+
+
+
+    /**
+     * @Description:递归书签导出功能
+     *
+     * @param  * @param sqMenuList
+     * @param str
+     * @param mapBookMark
+     * @param mapMenu
+     * @return java.lang.StringBuilder
+     * @Date
+     * @author: wanghao
+     *
+     */
+    public StringBuilder traverseFile_recursion (List<SqMenu> sqMenuList,StringBuilder str,Map<Long, List<SqBookmark>> mapBookMark,Map<Long, List<SqMenu>> mapMenu) {
+
+        if (sqMenuList != null && !sqMenuList.isEmpty()) {
+            for (SqMenu f : sqMenuList) {
+                str.append("<DT><H3 ADD_DATE=\"1584277207\" LAST_MODIFIED=\"0\">").append(f.getMenuName()).append("</H3>\n");
+                str.append("<DL>\n");
+                List<SqBookmark> bookmarksList = mapBookMark.get(f.getMenuId());
+                if (bookmarksList != null && !bookmarksList.isEmpty()) {
+                    for (SqBookmark b : bookmarksList) {
+                        str.append("<DT><A HREF=\""+b.getUrl()+"\" TARGET=\"_blank\">"+b.getTitle()+"</A>\n");
+                    }
+                }
+                traverseFile_recursion(mapMenu.get(f.getMenuId()),str,mapBookMark,mapMenu);
+                str.append("</DL>\n");
+            }
+        }
+        return str;
+    }
+
+
+
+
+
+
+
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/模板.html b/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/模板.html
new file mode 100644
index 000000000..181883d95
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/模板.html
@@ -0,0 +1,47 @@
+<DL>
+    <DT><H3>收藏夹栏</H3>
+        <DL>
+            <DT>
+                <H3 ADD_DATE="1618847296" LAST_MODIFIED="1618847407">一级2</H3>
+                <DL>
+                    <DT>
+                        <A HREF="https://www.huodongxing.com/go/tl24" ADD_DATE="1618847403"
+                           ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAB6ElEQVQ4jU2SO2uUYRSEZ+b9NhtzMRcDigiKoJVgkSaNhUGxsLDQytIqlW38A/4CLdLZWVna2amNhDTxAkJYAwlGJCoxhuxu9pux+LIinPI8MOc5Q2xeQYAQIaJmGDGSBZS6BkxGsBJVDGMC/wFO6n4cJ7CAcWEkJixGVfJvu8B1cU5o6nz79BynTmn6ZJl+9Xvta+8H0UIIq0IIU6g8OFwcu/Z4bqnCSKe/c+j+z8He4sT8JCae7DyvNFY7PAYiosC+3LqwMHa1V/fXu52V3Rerv14vn3vUxihMotCB1YQWLaT0XdexoAczt99denZz9m6CkgIXRLESCRYwxKJCkei6R2JOs0euBcEFFiJaFa2hHDFEkERQkoFrpiSEBYrNDUlp8sAFEAiSAAAoJUFCuJCikahq3tEos+E4SQCKPdclpc0KFlTiMBIjWnRBNMq2KCMEHS+fvXd/7vrHg21gJCYhmFWjKCEyun6w2el+uzh6BoGRN3ufVrZfbvX/FI7XNQghFF3iUpsFY2/3PsyvP1zaePpu/7PIzuH3zv6W0mJEDDvGtRuNUFpMGTg46rU0cWdmYeNw9/3+l9IUKUKAiFq91Qg+Np1SXA2cetAF2i2OpKnqMcDhH6w0WFgnjNqajGljuE2AAP4CW2c6UNfg92YAAAAASUVORK5CYII=">第二十四届前端早早聊大会
+                            | 前端搞算法 - 在线直播 预约报名-前端早早聊活动-活动行</A>
+                </DL>
+
+
+            <DT><H3 ADD_DATE="1618847280" LAST_MODIFIED="1618847363">一级</H3>
+                <DL>
+                    <DT><H3 ADD_DATE="1618847339" LAST_MODIFIED="1618847379">二级</H3>
+                        <DL>
+                            <DT><A HREF="https://juejin.cn/pin/6952704146197708837" ADD_DATE="1618847363"
+                                   ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABU0lEQVQ4jcXSvUsVYBQG8N+5XpeuSBFNQTnkZERI0RIRiDi0KQnh1mB7mBDB9QWTkKB/oIaIBkNwdDAaBEGCaoqamvpAGhpL4upp8CJXvVfafKbD+zzn6zkvR43oyExlTc0z/PDJtMXYaierdCzQYwDDGDXg7P/PNJndu3HJPvfzZFuuLeo5rOQ3Ja8f4EqOKrmh5GDr894VKt7gBVaUvAtuZpeZnMeCbfNKfGhNCQ/ytKpJ4ZESm7vdeI5l6RTO2zZuNlab/HFM+eNxRbcTwgTWzOSZHUEsabiCi0JNw2BL8gW8k0ZU9VaU+IhL2MB79RwCD+Oz3y7jmrn43vTolrQurfrlqrn42rJNhpJFyb/qeW+fgVUlnyi5qZ539npw8BI3hJfCa9zGMemV0G/LmNl4e3iBnY7nsCR1oVf4gnElfu6XHv6VezxtejOtRKOj9kjxD4w4cYS3SWCbAAAAAElFTkSuQmCC">【掘金读书会】掘金x异步
+                                - 掘金</A>
+                        </DL>
+
+                    <DT><A HREF="https://juejin.cn/" ADD_DATE="1618847358"
+                           ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABU0lEQVQ4jcXSvUsVYBQG8N+5XpeuSBFNQTnkZERI0RIRiDi0KQnh1mB7mBDB9QWTkKB/oIaIBkNwdDAaBEGCaoqamvpAGhpL4upp8CJXvVfafKbD+zzn6zkvR43oyExlTc0z/PDJtMXYaierdCzQYwDDGDXg7P/PNJndu3HJPvfzZFuuLeo5rOQ3Ja8f4EqOKrmh5GDr894VKt7gBVaUvAtuZpeZnMeCbfNKfGhNCQ/ytKpJ4ZESm7vdeI5l6RTO2zZuNlab/HFM+eNxRbcTwgTWzOSZHUEsabiCi0JNw2BL8gW8k0ZU9VaU+IhL2MB79RwCD+Oz3y7jmrn43vTolrQurfrlqrn42rJNhpJFyb/qeW+fgVUlnyi5qZ539npw8BI3hJfCa9zGMemV0G/LmNl4e3iBnY7nsCR1oVf4gnElfu6XHv6VezxtejOtRKOj9kjxD4w4cYS3SWCbAAAAAElFTkSuQmCC">掘金
+                        - 代码不止,掘金不停</A>
+                </DL>
+
+
+            <DT><H3 ADD_DATE="1618847309" LAST_MODIFIED="1618847390">一级3</H3>
+                <DL>
+                    <DT>
+
+                        <H3 ADD_DATE="1618847324" LAST_MODIFIED="1618847403">二级3-1</H3>
+                        <DL>
+
+                            <DT><A HREF="https://juejin.cn/post/6947987257034965000" ADD_DATE="1618847390"
+                                   ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABU0lEQVQ4jcXSvUsVYBQG8N+5XpeuSBFNQTnkZERI0RIRiDi0KQnh1mB7mBDB9QWTkKB/oIaIBkNwdDAaBEGCaoqamvpAGhpL4upp8CJXvVfafKbD+zzn6zkvR43oyExlTc0z/PDJtMXYaierdCzQYwDDGDXg7P/PNJndu3HJPvfzZFuuLeo5rOQ3Ja8f4EqOKrmh5GDr894VKt7gBVaUvAtuZpeZnMeCbfNKfGhNCQ/ytKpJ4ZESm7vdeI5l6RTO2zZuNlab/HFM+eNxRbcTwgTWzOSZHUEsabiCi0JNw2BL8gW8k0ZU9VaU+IhL2MB79RwCD+Oz3y7jmrn43vTolrQurfrlqrn42rJNhpJFyb/qeW+fgVUlnyi5qZ539npw8BI3hJfCa9zGMemV0G/LmNl4e3iBnY7nsCR1oVf4gnElfu6XHv6VezxtejOtRKOj9kjxD4w4cYS3SWCbAAAAAElFTkSuQmCC">我,是如何度过人生最艰难的时刻的</A>
+                        </DL>
+
+                    <DT><A HREF="https://juejin.cn/post/6951649464637636622" ADD_DATE="1618847379"
+                           ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABU0lEQVQ4jcXSvUsVYBQG8N+5XpeuSBFNQTnkZERI0RIRiDi0KQnh1mB7mBDB9QWTkKB/oIaIBkNwdDAaBEGCaoqamvpAGhpL4upp8CJXvVfafKbD+zzn6zkvR43oyExlTc0z/PDJtMXYaierdCzQYwDDGDXg7P/PNJndu3HJPvfzZFuuLeo5rOQ3Ja8f4EqOKrmh5GDr894VKt7gBVaUvAtuZpeZnMeCbfNKfGhNCQ/ytKpJ4ZESm7vdeI5l6RTO2zZuNlab/HFM+eNxRbcTwgTWzOSZHUEsabiCi0JNw2BL8gW8k0ZU9VaU+IhL2MB79RwCD+Oz3y7jmrn43vTolrQurfrlqrn42rJNhpJFyb/qeW+fgVUlnyi5qZ539npw8BI3hJfCa9zGMemV0G/LmNl4e3iBnY7nsCR1oVf4gnElfu6XHv6VezxtejOtRKOj9kjxD4w4cYS3SWCbAAAAAElFTkSuQmCC">从
+                        0 开始手把手带你搭建一套规范的 Vue3.x 项目工程环境</A>
+                </DL>
+
+
+        </DL>
+</DL>
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/bookmarkhtml/Const.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/bookmarkhtml/Const.java
index 54642f41e..0c04bdced 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/bookmarkhtml/Const.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/bookmarkhtml/Const.java
@@ -37,6 +37,24 @@ public class Const {
     public static String PHONE_REGISTER= "phone_register";
 
 
+    //最新书签
+    public static String NEWEST = "newest";
+    //星标
+    public static String ASTERISK = "asterisk";
+    //稍后看
+    public static String SEEYOULATER = "seeYouLater";
+    //回收站
+    public static String RECYCLE = "recycle";
+
+
+
+
+    //是否书签删除状态 0 未删除 1表示删除
+    public static int BKDELETE = 0;
+
+    public static int BKNOTDELETE = 1;
+
+
 
 
 }
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
index 5ba65a80b..1c2e25788 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
@@ -9,6 +9,8 @@ import com.ruoyi.common.core.redis.RedisUtil;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.system.service.ISysUserService;
+import com.ruoyi.system.service.impl.SysUserServiceImpl;
+import com.sun.org.apache.bcel.internal.generic.NEW;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.authentication.BadCredentialsException;
@@ -26,6 +28,7 @@ import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
 import com.ruoyi.common.utils.MessageUtils;
 import com.ruoyi.framework.manager.AsyncManager;
 import com.ruoyi.framework.manager.factory.AsyncFactory;
+import org.springframework.transaction.annotation.Transactional;
 
 /**
  * 登录校验方法
@@ -141,11 +144,35 @@ public class SysLoginService
         SysUser user = new SysUser();
         user.setUserName(username);
         user.setPassword(SecurityUtils.encryptPassword(password));
-        user.setDeptId(100L);
+        user.setDeptId(110L);
         user.setNickName(username);
         user.setPhonenumber(phone);
         user.setCreateTime(DateUtil.date(System.currentTimeMillis()));
         user.setUpdateBy("admin");
-        return sysUserService.insertUser(user)!=0?Constants.LOGIN_SUCCESS:Constants.LOGIN_FAIL;
+        user.setSex("2");
+        user.setStatus("0");
+        user.setPostIds(new Long[]{4L});
+        user.setRoleIds(new Long[]{2L});//角色
+        user.setAvatar("/profile/avatar/2020/11/01/8a354c2d-1b5a-475e-a9aa-04cb4a769323.jpeg");
+        user.setUpdateTime(DateUtil.date(System.currentTimeMillis()));
+        return addUser(user);
+    }
+
+    /**
+     * 注册账号
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    @Transactional
+    public String addUser(SysUser user){
+
+      int row = sysUserService.insertUser(user);
+        SysUserServiceImpl sysUserService = new SysUserServiceImpl();
+        //新增用户岗位关联
+        sysUserService.insertUserPost(user);
+        // 新增用户与角色管理
+        sysUserService.insertUserRole(user);
+      return row!=0?Constants.LOGIN_SUCCESS:Constants.LOGIN_FAIL;
     }
 }
diff --git a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
index a71f7fc72..6d915c3ae 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
@@ -131,6 +131,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  			<if test="password != null and password != ''">password,</if>
  			<if test="status != null and status != ''">status,</if>
  			<if test="createBy != null and createBy != ''">create_by,</if>
+ 			<if test="updateBy != null and updateBy != ''">update_by,</if>
  			<if test="remark != null and remark != ''">remark,</if>
  			create_time
  		)values(
@@ -145,6 +146,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  			<if test="password != null and password != ''">#{password},</if>
  			<if test="status != null and status != ''">#{status},</if>
  			<if test="createBy != null and createBy != ''">#{createBy},</if>
+ 			<if test="updateBy != null and updateBy != ''">#{updateBy},</if>
  			<if test="remark != null and remark != ''">#{remark},</if>
  			sysdate()
  		)
diff --git a/ruoyi-ui/src/api/bookmark/bookmark.js b/ruoyi-ui/src/api/bookmark/bookmark.js
index 0f81974d3..347a16e63 100644
--- a/ruoyi-ui/src/api/bookmark/bookmark.js
+++ b/ruoyi-ui/src/api/bookmark/bookmark.js
@@ -36,6 +36,14 @@ export function selectByUseridList(query) {
     params: query
   })
 }
+//用户 最新书签 星标 稍后读
+export function listByUserAndPolymerization(query) {
+  return request({
+    url: '/bookmark/bookmark/listByUserAndPolymerization',
+    method: 'get',
+    params: query
+  })
+}
 
 
 
@@ -90,3 +98,10 @@ export function exportBookmark(query) {
     params: query
   })
 }
+// 导出用户个人的书签HTML
+export function exportBookmarkHTML() {
+  return request({
+    url: '/IO/export',
+    method: 'post',
+  })
+}
diff --git a/ruoyi-ui/src/components/BookmarkList/index.vue b/ruoyi-ui/src/components/BookmarkList/index.vue
index 4182cc4f6..03e560ad3 100644
--- a/ruoyi-ui/src/components/BookmarkList/index.vue
+++ b/ruoyi-ui/src/components/BookmarkList/index.vue
@@ -12,40 +12,38 @@
 
 
       <div class="bookmark-description" v-if="isdescription" >
-
         <span v-if="highlighted" v-html="highLight(bm.description,sousuo)"></span>
-
         <span v-if="!highlighted">{{bm.description}}</span>
       </div>
 
 
 
       <div class="info-wrap" v-if="isBookmarkIcon">
-        <div class="info">
-          <div class="bookmark-icon">
+        <div class="info" >
+          <div class="bookmark-icon bookmark-list-tag-top">
             <img :ng-src="'https://favicon.lucq.fun/?url=http://'+bm.urls"
                  :src="'https://favicon.lucq.fun/?url=http://'+bm.urls"
                  onerror="this.src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQEAYAAABPYyMiAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlzAAAASAAAAEgARslrPgAAAmVJREFUSMftlG1IU2EUx8+5jRHzg+5OiD64WTBBjSY5ZybUJMaMiIUICUKFIGmoIIogYWKFBmtDxN1tBKIWvlS6SR+iLFDBXqSMgmzbvQ7fkAjcINmQ5u7pQwyCiOvWx/p/fPj9/5znnPM8AP+VolRTjjHhTlmZipzEk9GYao4sVaMYxXp62NgIdpLBCuLP05mZZHOYZA3p5KgMjBcUwCmw4PfVVYiBGmbW1zMzOU4QCgtTvdAeRESEyNZyJbx+dDTjVv/9YFSjSScnfabsbPYMF+AbxsYS3F5TfwPZAacpMNfUBEAljK24mMJwlLIUClTAdfwok9FXWBTtc3Phzqv7c/RWa8KnrHZM8VltbRjC92AxGkEPRpSJInjJQPpIBJoZC6nn50M19dM5J/v6/lhRxgXXDX9Qp1POcmHh2sTEQbfbvVmrUCTbr4RPaeMe8Q0eTyI36VkrW50mftjrPWCyDn9oSUuTdj4Y/1Qpl7NdzkNC98iIqsIxHdQVFaU8eWW1U1guLy1lr3Acr3O7pXi227EhDLpcCZ8UL/kK8LIYjxtDIRhEP8xGIlI8bcAKvY3FGB/zYvf81pYUL/0PvGTKoTUvjzbgCx5ZWlJq3a5lQa1Ge3yTWnp64ASYqVcUoXn3Jtja2/EpRtHj89FF8Tb25ufDOwCo8/lSL0BF/eDPzcVXeA7WDAa6J9rES1VVdJqx41JHBwCE8BgA3JU9B+3AACziMwjv7MAaPQb/wgIAnP2rDpCWtpkncjm+Ro34bWgo3FkX0O6bnARARCT6hSR6YzazXa7DfLyigo7TNtObxNb/s/oB7V8JFvW/8IQAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjAtMDItMDJUMTg6MTE6NTgrMDg6MDCoc6tpAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIwLTAyLTAyVDE4OjExOjU4KzA4OjAw2S4T1QAAAGd0RVh0c3ZnOmJhc2UtdXJpAGZpbGU6Ly8vaG9tZS9hZG1pbi9pY29uLWZvbnQvdG1wL2ljb25fNWhyOG55Nmo1bWMvamluZ2RpYW5hbmxpX2tvbmd3dWppYW94aW5nX3Nob3VjYW5nLnN2Z4/vilwAAAAASUVORK5CYII='"
                  alt="" ng-show="bm.urls">
           </div>
-          <div class="bookmark-official">{{bm.urls}}&nbsp;·&nbsp;</div>
-          <div class="bookmark-time">{{bm.createTime|changeTime}}</div>
-          <div class="bookmark-time">{{bm.bookmarkStar}}</div>
-          <div class="bookmark-time" v-for="t in bm.sqTags" v-if="false">
-<!--            <el-tag class="bookmark-list-tag" data-bookmarkId="t.bookmarkId" data-tagId="t.tagId"-->
-<!--                    size="mini">-->
-<!--              {{t.name}}-->
-<!--            </el-tag>-->
+          <div class="bookmark-official bookmark-list-tag-top">{{bm.urls}}&nbsp;·&nbsp;</div>
+          <div class="bookmark-time bookmark-list-tag-top">{{bm.createTime|changeTime}}</div>
+          <div class="bookmark-time bookmark-list-tag-top">{{bm.bookmarkStar}}</div>
+
+          <div class="bookmark-time" v-if="bm.tagNameAll!=null&&bm.tagNameAll!=''"  >
+            <el-tag  v-for="item in JSON.parse(bm.tagNameAll)"  class="bookmark-list-tag bookmark-list-tag-top" style="float: left"  type="info"  data-tagid="item.tagId"  size="mini">
+              {{item.name}}
+            </el-tag>
           </div>
         </div>
       </div>
 
       <!--编辑  -->
       <div class="editAllBookMark"  v-show="seen&&bm.bookmarkId==current">
-          <el-button slot="reference" @click.stop="updateStarById(bm.bookmarkId,bm.bookmarkStar)"  type="info" v-bind:class="{ activeClass: bm.bookmarkStar ==1  }"   plain size="mini" icon="el-icon-star-off"></el-button>
-          <el-button type="info" plain size="mini" icon="el-icon-share" ></el-button>
-          <el-button type="info" plain size="mini" icon="el-icon-edit" @click.stop="handleUpdate(bm.bookmarkId)"></el-button>
-          <el-button type="danger" plain size="mini" icon="el-icon-delete" @click.stop="handleDelete(bm.bookmarkId)"></el-button>
+          <el-button slot="reference" @click.stop="updateStarById(bm.bookmarkId,bm.bookmarkStar)"   v-bind:class="{ activeClass: bm.bookmarkStar ==1  }"   plain size="mini" icon="el-icon-star-off"></el-button>
+          <el-button  plain size="mini" icon="el-icon-share" ></el-button>
+          <el-button  plain size="mini" icon="el-icon-edit" @click.stop="handleUpdate(bm.bookmarkId)"></el-button>
+          <el-button  plain size="mini" icon="el-icon-delete" @click.stop="handleDelete(bm.bookmarkId)"></el-button>
           <div style="width: 10px"></div>
       </div>
     </div>
@@ -208,7 +206,10 @@
       },
 
 
-      /**编辑**/
+      /**最新 星标 稍后看**/
+      selectByUseridList(){
+
+      },
 
 
     }
@@ -219,6 +220,14 @@
     color: red;
   }
 
+
+  .bookmark-list-tag-top{
+    margin-top: 4px;
+  }
+  .bookmark-list-tag{
+    margin-right: 10px;
+
+  }
   .bookmark-item {
     display: flex;
     height: 24px;
@@ -234,7 +243,7 @@
   }
 
   .bookmark:hover {
-    background-color: #E8E8E8;
+    background-color: #E6E6E6;
 
   }
 
@@ -280,6 +289,8 @@
     font-size: 0.95rem;
     display: flex;
     align-items: center;
+    flex-wrap:wrap;
+
   }
 
   .bookmark-icon {
@@ -297,7 +308,7 @@
     width: 200px;
     height: inherit;
     position: absolute;
-    right: 0px;
+    right: 15px;
     top: 10px;
     bottom: 10px;
     display:inline-flex;
diff --git a/ruoyi-ui/src/utils/exportFile.js b/ruoyi-ui/src/utils/exportFile.js
new file mode 100644
index 000000000..17273c7a1
--- /dev/null
+++ b/ruoyi-ui/src/utils/exportFile.js
@@ -0,0 +1,15 @@
+
+
+
+//导出文件流的文件 blob
+export function exportFileHTML(response,fileName) {
+  const blob = new Blob([res], { type: 'text/html' }) // 构造一个blob对象来处理数据
+  const elink = document.createElement('a') // 创建a标签
+  elink.download = fileName // a标签添加属性
+  elink.style.display = 'none'
+  elink.href = URL.createObjectURL(blob)
+  document.body.appendChild(elink)
+  elink.click() // 执行下载
+  URL.revokeObjectURL(elink.href) // 释放URL 对象
+  document.body.removeChild(elink) // 释放标签
+}
diff --git a/ruoyi-ui/src/views/bookmark/bkuser/index.vue b/ruoyi-ui/src/views/bookmark/bkuser/index.vue
index 1cce69caf..ee0dd2ecf 100644
--- a/ruoyi-ui/src/views/bookmark/bkuser/index.vue
+++ b/ruoyi-ui/src/views/bookmark/bkuser/index.vue
@@ -19,12 +19,14 @@
       <div class="mdui-btn-group head-tag-button">
 <!--        <div  :class="['classification',property=='0'?' classification-click':'']" @click="showopen(0)"><span>网页</span></div>-->
         <button @click="goRouter(1)" :class="['mdui-btn mdui-color-theme-accent mdui-ripple ',property=='1'?' mdui-btn-active mdui-color-blue-50 mdui-text-color-blue-600':'']">个人中心</button>
+        <button @click="goRouter(7)" :class="['mdui-btn mdui-color-theme-accent mdui-ripple ',property=='7'?' mdui-btn-active mdui-color-blue-50 mdui-text-color-blue-600':'']">外观设置</button>
         <button @click="goRouter(2)" :class="['mdui-btn mdui-color-theme-accent mdui-ripple ',property=='2'?' mdui-btn-active mdui-color-blue-50 mdui-text-color-blue-600':'']">系统设置</button>
         <button @click="goRouter(3)" :class="['mdui-btn mdui-color-theme-accent mdui-ripple ',property=='3'?' mdui-btn-active mdui-color-blue-50 mdui-text-color-blue-600':'']">导入书签</button>
         <button @click="goRouter(4)" :class="['mdui-btn mdui-color-theme-accent mdui-ripple ',property=='4'?' mdui-btn-active mdui-color-blue-50 mdui-text-color-blue-600':'']">备份导出</button>
         <button @click="goRouter(5)" :class="['mdui-btn mdui-color-theme-accent mdui-ripple ',property=='5'?' mdui-btn-active mdui-color-blue-50 mdui-text-color-blue-600':'']">更新日志</button>
         <button @click="goRouter(6)" :class="['mdui-btn mdui-color-theme-accent mdui-ripple ',property=='6'?' mdui-btn-active mdui-color-blue-50 mdui-text-color-blue-600':'']">关于我们</button>
 
+
       </div>
     </div>
 
@@ -145,7 +147,7 @@
   .head-tag-button {
     display: flex;
     justify-content: space-between;
-    width: 40%;
+    width: 45%;
     align-items: center;
     margin: 0 auto;
   }
diff --git a/ruoyi-ui/src/views/bookmark/bkuser/tool/exportHtml.vue b/ruoyi-ui/src/views/bookmark/bkuser/tool/exportHtml.vue
index 82bc4591a..3647a34f3 100644
--- a/ruoyi-ui/src/views/bookmark/bkuser/tool/exportHtml.vue
+++ b/ruoyi-ui/src/views/bookmark/bkuser/tool/exportHtml.vue
@@ -4,12 +4,43 @@
       <el-col :xs="24" :sm="{span: 16, push: 4}" :md="{span: 14, push: 5}"  :xl="{span: 10, push: 7}"  >
         <el-card class="box-card">
           <div slot="header" class="clearfix">
-            <span>备份导出</span>
+            <span>备份/导出</span>
           </div>
-          <div>
-            <ul class="list-group list-group-striped">
+          <div class="exportList">
+            <div class="exportList-main">
+              <div class="exportList-main-text">
+               <span class="listText"> 书签导出</span>
+              </div>
+              <div class="listText-button">
+
+                <el-button  plain @click="handleExport" size="mini">书签导出</el-button>
+
+              </div>
+            </div>
+
+            <div class="exportList-main">
+              <div class="exportList-main-text">
+                <span class="listText"> 自动备份</span>
+              </div>
+              <div class="listText-button" >
+                <el-switch style="float: right" v-model="bookMarkBackup" ></el-switch>
+              </div>
+            </div>
+
+            <div class="exportList-main">
+              <div class="exportList-main-text">
+                <span class="listText"> 备份方式</span>
+              </div>
+              <div class="listText-button">
+                <el-button  plain @click="handleExport" size="mini" style="width: 80px">   添 加   </el-button>
+
+              </div>
+            </div>
+
+
+
+
 
-            </ul>
           </div>
         </el-card>
       </el-col>
@@ -18,16 +49,79 @@
   </div>
 </template>
 <script>
+  import { exportBookmarkHTML } from "@/api/bookmark/bookmark";
     export default {
         name: 'areaTree',
         components: {},
 
         data: function () {
-            return {}
+            return {
+              bookMarkBackup:true
+            }
         },
-        methods: {}
+        methods: {
+          /** 导出按钮操作 */
+          handleExport() {
+            this.$confirm('是否确认导出所有书签数据项?', "警告", {
+              confirmButtonText: "确定",
+              cancelButtonText: "取消",
+              type: "warning"
+            }).then(function() {
+              return exportBookmarkHTML();
+            }).then(res => {
+              var oDate = new Date(); //实例一个时间对象;
+              oDate.getFullYear();   //获取系统的年;
+              oDate.getMonth()+1;   //获取系统月份,由于月份是从0开始计算,所以要加1
+              oDate.getDate(); // 获取系统日,
+              oDate.getHours(); //获取系统时,
+              oDate.getMinutes(); //分
+              oDate.getSeconds(); //秒
+              var time = oDate.getFullYear()+"年"+oDate.getMonth()+1+"月"+oDate.getDate() +"日 " +oDate.getHours()+"时"+oDate.getMinutes()+"分"+oDate.getSeconds()+"秒";
+              var name = "cqy_"+time;
+              const blob = new Blob([res], { type: 'text/html' }) // 构造一个blob对象来处理数据
+              const fileName = name + '.html' // 导出文件名
+              const elink = document.createElement('a') // 创建a标签
+              elink.download = fileName // a标签添加属性
+              elink.style.display = 'none'
+              elink.href = URL.createObjectURL(blob)
+              document.body.appendChild(elink)
+              elink.click() // 执行下载
+              URL.revokeObjectURL(elink.href) // 释放URL 对象
+              document.body.removeChild(elink) // 释放标签
+            }).then(res =>{
+              this.$message({
+                showClose: true,
+                message: '导出成功',
+                type: 'success'
+              });
+            }).catch(function() {
+              this.$message({
+                showClose: true,
+                message: '导出失败,系统错误!',
+                type: 'error'
+              });
+            });
+          }
+        }
     }
 </script>
 <style>
 
+  .exportList{
+    display:flex;flex-direction:column;
+  }
+  .exportList-main{
+    display:flex;height: 50px;width: 100%;
+  }
+  .exportList-main-text{
+    width: 90%;display:flex;align-items:center;
+  }
+  .listText{
+    color: black;font-weight: 400
+  }
+  .listText-button{
+    width: 10%;display:flex;align-items:center;
+    flex-direction:column-reverse;
+  }
+
 </style>
diff --git a/ruoyi-ui/src/views/bookmark/bookmark/index.vue b/ruoyi-ui/src/views/bookmark/bookmark/index.vue
index 3957e31d6..76c6371d5 100644
--- a/ruoyi-ui/src/views/bookmark/bookmark/index.vue
+++ b/ruoyi-ui/src/views/bookmark/bookmark/index.vue
@@ -239,7 +239,8 @@
     delBookmark,
     addBookmark,
     updateBookmark,
-    exportBookmark
+    exportBookmark,
+    listByUserAndPolymerization
   } from "@/api/bookmark/bookmark";
   import {
     selectBymenuNote,
@@ -286,6 +287,8 @@
           sqTags: [],
           sort: 0,
           sousuo: '',
+          type:'',
+          bkOrderBy:'',
         },
         inputVisible: false, //标签
         inputValue: '', //标签
@@ -407,14 +410,17 @@
         this.sousuo=sousuo
       }
 
+      console.log("routedata:"+routedata)
+      if (routedata == 'newest'||routedata == 'asterisk'||routedata == 'seeYouLater'||routedata == 'recycle') {
+        that.queryParams.menuId=null;
 
-      if (routedata == 'BOOKMARK') {
+        this.listByUserAndPolymerization(routedata);
         //全部书签
-        this.getBookmarkList();
-
-      } else if (routedata == 'RECYCLE') {
-        //回收站
-        this.getrecycleList();
+        // this.getBookmarkList();
+      //
+      // } else if (routedata == 'RECYCLE') {
+      //   //回收站
+      //   this.getrecycleList();
 
       } else {
         //根据menuId查询
@@ -426,7 +432,7 @@
       this.getHeight()
 
       //获取当前的用户信息
-      this.getUser();
+      // this.getUser();
 
     },
     mounted() {
@@ -539,8 +545,9 @@
         if (index > -1) {
           if (this.form.sqTags[index].tagId < 0) {
             this.form.sqTags.splice(index, 1);
+          }else{
+            this.form.sqTags[index].name = "TAGDELETE";
           }
-          this.form.sqTags[index].name = "TAGDELETE";
         }
         console.log(this.form.sqTags);
       },
@@ -552,12 +559,13 @@
       },
 
       handleInputConfirm() {
+
         let inputValue = this.inputValue;
         if (inputValue) {
           this.tagcount = this.tagcount - 1;
           //添加
           var updatetag = {name: inputValue, bookmarkId: this.form.bookmarkId, tagId: this.tagcount};
-
+          console.log("updatetag")
           this.form.sqTags.push(updatetag);
         }
         this.inputVisible = false;
@@ -581,6 +589,9 @@
         const ibookmarkId = bookmarkId || this.ids
         getBookmark(ibookmarkId).then(response => {
           this.form = response.data;
+          if(this.form.sqTags==null){
+            this.form.sqTags=[];
+          }
           this.open = true;
           this.title = "书签编辑管理";
         });
@@ -629,7 +640,7 @@
         this.open = false;
         this.reset();
       },
-      // 表单重置
+      // 统一的表单重置
       reset() {
         this.form = {
           bookmarkId: undefined,
@@ -712,6 +723,27 @@
             }
         });
       },
+      /** 最新 星标 回收站 稍后看**/
+      listByUserAndPolymerization(str) {
+        console.log(" 最新 星标 回收站 稍后看");
+        this.loading = true;
+        this.queryParams.type=str;
+        this.queryParams.bkOrderBy="";
+        listByUserAndPolymerization(this.queryParams).then(response => {
+            if (response.code == 200) {
+              this.bookmarkList = this.bookmarkList.concat(response.rows);
+              this.total = response.total;
+              this.listloading = false
+              this.loading = false;
+              console.log("请求完毕" + this.queryParams.pageNum)
+            } else {
+              //出错了加载完毕了 禁止滚动
+              this.noMore = true;
+              this.listloading = false
+              this.loading = false;
+            }
+        });
+      },
       /**根据条件查询*/
       getBypropertyList(e){
         switch(e) {
@@ -775,12 +807,14 @@
       getListConcat(){
         var that=this;
         this.loading = true;
-        if(this.queryParams.menuId=='BOOKMARK'){
-          //全部书签
-          this.getBookmarkList();
-        }else if (this.queryParams.menuId == 'RECYCLE') {
-          //回收站书签
-          this.getrecycleList();
+        var routedata = this.queryParams.menuId;
+        if(routedata == 'newest'||routedata == 'asterisk'||routedata == 'seeYouLater'||routedata == 'recycle'){
+          this.listByUserAndPolymerization(routedata);
+        //   //全部书签
+        //   this.getBookmarkList();
+        // }else if (this.queryParams.menuId == 'RECYCLE') {
+        //   //回收站书签
+        //   this.getrecycleList();
         }else{
           //查看目录下的书签
           this.getlistByMenuId();
diff --git a/ruoyi-ui/src/views/bookmark/index/index.vue b/ruoyi-ui/src/views/bookmark/index/index.vue
index 217560f46..ce4afc713 100644
--- a/ruoyi-ui/src/views/bookmark/index/index.vue
+++ b/ruoyi-ui/src/views/bookmark/index/index.vue
@@ -20,46 +20,99 @@
 
           <div class="main-right">
 <!--            <svg-icon icon-class="tool" class="svgicon"/>-->
-<!--             <div class="aside-title"><i class="el-icon-s-management"></i><span>发现</span></div>-->
             <div class="aside-title" @click="goRouter(8)"><i class="el-icon-folder"></i><span>最新</span></div>
-            <div class="aside-title"><i class="el-icon-star-off"></i><span>星标</span></div>
-            <div class="aside-title"><i class="el-icon-reading"></i><span>稍后看</span></div>
+            <div class="aside-title" @click="goRouter(9)"><i class="el-icon-star-off"></i><span>星标</span></div>
+            <div class="aside-title" @click="goRouter(10)"><i class="el-icon-reading"></i><span>稍后看</span></div>
             <div class="aside-title"><i class="el-icon-view"></i><span>发现</span></div>
-<!--            <div class="aside-title"><i class="el-icon-s-platform"></i><span>任意门</span></div>-->
-<!--            <div class="aside-title"><i class="el-icon-message-solid"></i><span>收件箱</span></div>-->
-            <div class="reminder">我的收藏 <svg-icon icon-class="sx" style="margin-left:5px" @click="refreshNode"/></div>
-            <div class="areaTree">
+            <div class="aside-title"><i class="el-icon-message"></i><span>收件箱</span></div>
+
+
+            <div class="aside-titleB"  @mouseenter="eidtMenuText=!eidtMenuText" @mouseleave="eidtMenuText=!eidtMenuText">
+              <i @click="menuListShowCk" :class="menuListShow ? 'el-icon-caret-bottom aside-titleB_childi_one':'el-icon-caret-right aside-titleB_childi_one'"   ></i>
+              <i class="el-icon-folder-opened aside-titleB_childi_two"></i>
+              <span >我的收藏</span>
+              <div style="margin-left: 40%" v-show="eidtMenuText">
+                <i class="el-icon-search" style="font-size: 19px;margin-left: 5px;margin-top: 7px" @click="searchBkMenuCk"></i>
+                <i class="el-icon-folder-add" style="font-size: 19px;margin-left: 5px;margin-top: 7px" @click="addBkMenuCk"></i>
+              </div>
+            </div>
+
+
+<!--            <div class="reminder" style="display: flex;">-->
+<!--              <span  @click="menuListShowCk">我的收藏</span>-->
+<!--              <div style="margin-left: 55%">-->
+<!--&lt;!&ndash;              <i class="el-icon-refresh" style="font-size: 19px;margin-left: 5px;margin-top: 7px" @click="refreshNode"></i>&ndash;&gt;-->
+<!--              <i class="el-icon-search" style="font-size: 19px;margin-left: 5px;margin-top: 7px" @click="searchBkMenuCk"></i>-->
+<!--              <i class="el-icon-folder-add" style="font-size: 19px;margin-left: 5px;margin-top: 7px" @click="addBkMenuCk"></i>-->
+<!--              </div>-->
+<!--            </div>-->
+
+
+            <div style="display: flex;justify-items: center;align-items: center">
+              <el-input
+                v-if="!addBkMenu"
+                placeholder="输入收藏夹名字"
+                v-model="input4"
+                size="mini"
+                style="width: 80%;margin-left: 5%"
+              >
+                <i slot="prefix" class="el-input__icon el-icon-circle-plus-outline"></i>
+              </el-input>
+              <i v-if="!addBkMenu" @click="addBkMenuCk" class="el-icon-close" style="font-size: 25px;margin-left: 5px;margin-bottom: 2px"></i>
+            </div>
+
+            <div style="display: flex;justify-items: center;align-items: center">
+              <el-input
+                v-if="!searchBkMenu"
+                placeholder="搜索目录"
+                v-model="input4"
+                size="mini"
+                style="width: 80%;margin-left: 5%"
+              >
+                <i slot="prefix" class="el-icon-search" style="margin-left: 5px"></i>
+              </el-input>
+              <i v-if="!searchBkMenu" @click="searchBkMenuCk" class="el-icon-close" style="font-size: 25px;margin-left: 5px;margin-bottom: 2px"></i>
+            </div>
+<!--            <transition name="el-zoom-in-top">-->
+            <!-- 目录-->
+            <div class="areaTree" v-show="menuListShow">
               <ul id="treeDemo" class="ztree"></ul>
             </div>
-            <div class="reminder" >工具箱</div>
+<!--            </transition>-->
+
+<!--            <div class="reminder" STYLE="">工具箱</div>-->
+
+            <div class="aside-titleB"  @mouseenter="eidtTAGText=!eidtTAGText" @mouseleave="eidtTAGText=!eidtTAGText">
+              <i @click="tagListShowCk" :class="tagListShow ? 'el-icon-caret-bottom aside-titleB_childi_one':'el-icon-caret-right aside-titleB_childi_one'"   ></i>
+              <i class="el-icon-price-tag aside-titleB_childi_two"></i>
+            <span >工具箱</span>
+              <div style="margin-left: 40%" v-show="eidtTAGText">
+                <i class="el-icon-search" style="font-size: 19px;margin-left: 5px;margin-top: 7px" @click="searchBkTagCk"></i>
+                <i class="el-icon-folder-add" style="font-size: 19px;margin-left: 5px;margin-top: 7px" @click="addBkTagCk"></i>
+              </div>
+            </div>
+
+
+
 <!--            <div class="aside-title"><i class="el-icon-s-flag" style="color: #569cd5"></i><span>RSS订阅</span></div>-->
             <div class="aside-title" @click="goRouter(7)"><i class="el-icon-collection"></i><span>标签管理</span></div>
             <div class="aside-title" @click="goRouter(6)"><i class="el-icon-delete" ></i><span>垃圾桶</span></div>
-<!--            <div class="aside-title" @click="goRouter(5)"><i class="el-icon-s-platform"></i><span>导入书签</span></div>-->
             <div class="aside-title"><i class="el-icon-chat-dot-square"></i><span>意见反馈</span></div>
-<!--            <div class="aside-title" @click="ceshi"><i class="el-icon-s-comment"></i><span>测试页面</span></div>-->
             <div class="aside-title" @click="goRouter(2)"><i class="el-icon-suitcase"></i><span>小工具</span></div>
-            <div class="aside-title " style="margin-bottom: 100px"  @click="goRouter(9)"><i class="el-icon-setting"></i><span>更多设置</span></div>
+            <div class="aside-title " style="margin-bottom: 100px"  @click="goRouter(11)"><i class="el-icon-setting"></i><span>更多设置</span></div>
 
           </div>
 
-          <div class="block">
-            <span class="demonstration">默认 Hover 指示器触发</span>
-            <el-carousel height="150px">
-              <el-carousel-item v-for="item in 4" :key="item">
-                <h3 class="small">{{ item }}</h3>
-              </el-carousel-item>
-            </el-carousel>
-          </div>
+
         </el-aside>
       </transition>
 
 
 
 
-
-      <div class="isresize" style="cursor:w-resize">
-      </div>
+      <!-- 拖拽 -->
+<!--      <div class="isresize" style="cursor:w-resize">-->
+<!--      </div>-->
 
 
 
@@ -90,97 +143,17 @@
           <div class="labelname">上级菜单</div>
           <treeselect class="menutreeselect" v-model="form.parentId" :options="menuOptions" :normalizer="normalizer"/>
         </el-form-item>
-<!--        <el-form-item prop="menuOrder">-->
-<!--          <div class="labelname">排序(小到大)</div>-->
-<!--          <br/>-->
-<!--          <el-input-number v-model="form.menuOrder" placeholder="计数器"></el-input-number>-->
-<!--        </el-form-item>-->
+
       </el-form>
       <div slot="footer" class="dialog-footer">
-        <el-button type="danger" style="background-color: #ff6c70"  @click="deleteMmenu(form.menuId)">删除</el-button>
-        <el-button type="primary" style="background-color: #09b1b9"  @click="submitForm">确定</el-button>
+        <el-button type="danger"  @click="deleteMmenu(form.menuId)">删除</el-button>
+        <el-button type="primary"   @click="submitForm">确定</el-button>
         <el-button  @click="cancel">取消</el-button>
       </div>
 
     </el-dialog>
 
 
-<!--    &lt;!&ndash; 添加链接&ndash;&gt;-->
-<!--    &lt;!&ndash; 添加或修改书签管理对话框 &ndash;&gt;-->
-<!--    <el-dialog title="添加连接" :visible.sync="addopen" width="500px" append-to-body>-->
-<!--      <el-form ref="form" :model="form" :rules="rules" label-width="80px">-->
-<!--        <el-form-item label="书签地址" prop="url">-->
-<!--          <el-input v-model="form.url" placeholder="请输入书签地址"/>-->
-<!--        </el-form-item>-->
-<!--        <el-form-item label="书签标题" prop="title">-->
-<!--          <el-input v-model="form.title" placeholder="请输入书签标题"/>-->
-<!--        </el-form-item>-->
-<!--        <el-form-item label="书签描述" prop="description">-->
-<!--          <el-input v-model="form.description" type="textarea" placeholder="请输入书签描述"-->
-<!--                    :autosize="{minRows: 3, maxRows:4}" :style="{width: '100%'}"></el-input>-->
-<!--        </el-form-item>-->
-
-<!--        <el-form-item prop="parentId">-->
-<!--          <div class="labelname">分类菜单</div>-->
-<!--          <treeselect class="menutreeselect" v-model="form.menuId" :options="menuOptions" :normalizer="normalizer"/>-->
-<!--        </el-form-item>-->
-
-<!--        <el-form-item label="书签标签" prop="label">-->
-<!--          <el-tag-->
-<!--            class="bookmarktag"-->
-<!--            v-for="tag in sqTags"-->
-<!--            :key="tag.tagId"-->
-<!--            closable-->
-<!--            type="success"-->
-<!--            :disable-transitions="false"-->
-<!--            @close="taghandleClose(tag.tagId)"-->
-<!--            v-if="tag.name!='TAGDELETE'"-->
-<!--          >-->
-<!--            {{tag.name}}-->
-<!--          </el-tag>-->
-<!--          <el-input-->
-<!--            class="input-new-tag"-->
-<!--            v-if="inputVisible"-->
-<!--            v-model="inputValue"-->
-<!--            ref="saveTagInput"-->
-<!--            size="small"-->
-<!--            @keyup.enter.native="handleInputConfirm"-->
-<!--            @blur="handleInputConfirm"-->
-<!--          >-->
-<!--          </el-input>-->
-<!--          <el-button v-else class="button-new-tag" size="small" @click="showInput">+ 新增标签</el-button>-->
-
-<!--        </el-form-item>-->
-
-<!--        &lt;!&ndash;        <el-form-item label="所属目录" prop="menuId">&ndash;&gt;-->
-<!--        &lt;!&ndash;          <el-input v-model="form.menuId" placeholder="请选择上级目录" />&ndash;&gt;-->
-<!--        &lt;!&ndash;        </el-form-item>&ndash;&gt;-->
-
-
-<!--        &lt;!&ndash;        0公开显示 1隐藏显示 2好友显示&ndash;&gt;-->
-<!--        <el-form-item label="选择状态" prop="start">-->
-<!--          <el-radio-group v-model="form.start" size="medium">-->
-<!--            <el-radio v-for="(item, index) in bookmarkstatus" :key="index" :label="item.value"-->
-<!--                      :disabled="item.disabled">{{item.name}}-->
-<!--            </el-radio>-->
-<!--          </el-radio-group>-->
-<!--        </el-form-item>-->
-<!--        &lt;!&ndash;           1.未读稍后再看 2 已读 2.續看&ndash;&gt;-->
-<!--        <el-form-item label="选择类型" prop="type">-->
-<!--          <el-radio-group v-model="form.type" size="medium">-->
-<!--            <el-radio v-for="(item, index) in bookmarktype" :key="index" :label="item.value"-->
-<!--                      :disabled="item.disabled">{{item.name}}-->
-<!--            </el-radio>-->
-<!--          </el-radio-group>-->
-<!--        </el-form-item>-->
-
-
-<!--      </el-form>-->
-<!--      <div slot="footer" class="dialog-footer">-->
-<!--        <el-button type="primary" @click="addbookmark">确 定</el-button>-->
-<!--        <el-button @click="bookmarkcancel">取 消</el-button>-->
-<!--      </div>-->
-<!--    </el-dialog>-->
     <!--背景特效-->
     <canvas id="evanyou"></canvas>
   </div>
@@ -209,6 +182,17 @@
 
     data: function () {
       return {
+        addBkMenu:true,//添加书签目录
+        searchBkMenu:true,//搜索目录
+        menuListShow:true,//目录list
+        eidtMenuText:false,//我的收藏
+
+        addBkTAG:true,//添加书TAG
+        searchBkTAG:true,//搜索TAG
+        tagListShow:false,//TAGlist
+        eidtTAGText:false,//我的TAG
+
+
         queryParams: {
           userId: undefined,
           menuName: undefined,
@@ -366,6 +350,45 @@
     },
 
     methods: {
+      /**添加书签目录**/
+      addBkMenuCk(){
+        this.addBkMenu = this.addBkMenu?false:true;
+        this.searchBkMenu = true;
+        this.menuListShow = true;
+      },
+      /**搜索书签目录**/
+      searchBkMenuCk(){
+        this.searchBkMenu = this.searchBkMenu?false:true;
+        this.addBkMenu = true;
+        this.menuListShow = true;
+      },
+      /**搜索书签目录**/
+      menuListShowCk(){
+        this.menuListShow = this.menuListShow?false:true;
+        this.addBkMenu = true;
+        this.searchBkMenu = true;
+      },
+
+
+      /**添加书签目录**/
+      addBkTagCk(){
+        this.addBkTAG = this.addBkTAG?false:true;
+        this.searchBkTAG = true;
+        this.tagListShow = true;
+      },
+      /**搜索书签目录**/
+      searchBkTagCk(){
+        this.searchBkMenu = this.searchBkTAG?false:true;
+        this.addBkTAG = true;
+        this.tagListShow = true;
+      },
+      /**搜索书签目录**/
+      tagListShowCk(){
+        this.tagListShow = this.tagListShow?false:true;
+        this.addBkTAG = true;
+        this.searchBkTAG = true;
+      },
+
       /**图片失败显示**/
       errorHandler() {
         return true
@@ -863,7 +886,7 @@
             that.$router.push({
               path: "/content",
               query: {
-                menuId: 'RECYCLE'
+                menuId: 'recycle'
               }
             })
             break;
@@ -874,16 +897,37 @@
             })
             break;
           case 8:
-            //全部书签
+            //全部最新书签
             that.$router.push({
               path: "/content",
               query: {
-                menuId: 'BOOKMARK'
+                menuId: 'newest',
+                t:Date.now(),
               }
             })
             break;
           case 9:
-            //个人中心
+            //星标
+            that.$router.push({
+              path: "/content",
+              query: {
+                menuId: 'asterisk',
+                t:Date.now(),
+              }
+            })
+            break;
+          case 10:
+            //稍后看
+            that.$router.push({
+              path: "/content",
+              query: {
+                menuId: 'seeYouLater',
+                t:Date.now(),
+              }
+            })
+            break;
+          case 11:
+            //用户中心
             that.$router.push({
               path: "/bkindex",
             })
@@ -892,7 +936,8 @@
             that.$router.push({
               path: "/content",
               query: {
-                menuId: 'BOOKMARK'
+                menuId: 'newest',
+                t:Date.now(),
               }
             })
         }
@@ -1033,13 +1078,40 @@
   /*.isaside{*/
   /*  cursor:w-resize*/
   /*}*/
+  .aside-titleB{
+    display: flex;
+    height: 32px;
+    align-items: center;
+    justify-items: center;
+  }
+  .aside-titleB:hover {
+    background-color: #e8e8e8;
+  }
+/**第一个元素**/
+  .aside-titleB_childi_one{
+    margin-left: 5px;
+    font-size: 15px;
+    margin-right: 11px;
+    vertical-align: middle;
+  }
+  /**第二个元素**/
+  .aside-titleB_childi_two{
+    margin-left: -4px;
+    font-size: 20px;
+    margin-right: 11px;
+    vertical-align: middle;
+  }
+  .aside-titleB span{
+    font-size: 14px;
+  }
+
 
   .aside-title {
     height: 32px;
   }
 
   .aside-title:hover {
-    background-color: #c5c5c5;
+    background-color: #e8e8e8;
   }
 
   .aside-title i {
@@ -1097,7 +1169,7 @@
     opacity: 0.7;
     font-size: 14px !important;
     font-weight: 500 !important;
-    margin-left: 27px !important;
+    margin-left: 27px ;
 
   }
 
diff --git a/ruoyi-ui/src/views/bookmark/ztree/jquery.ztree.core.js b/ruoyi-ui/src/views/bookmark/ztree/jquery.ztree.core.js
index 8a9fa030d..841ebe68e 100644
--- a/ruoyi-ui/src/views/bookmark/ztree/jquery.ztree.core.js
+++ b/ruoyi-ui/src/views/bookmark/ztree/jquery.ztree.core.js
@@ -1310,7 +1310,7 @@
       },
       // style='margin-top:-2px'
       makeDOMNodeLine: function (html, setting, node) {
-        html.push("<span id='", node.tId, consts.id.SWITCH, "' title='' class='", view.makeNodeLineClass(setting, node), "' treeNode", consts.id.SWITCH, "></span>");
+        html.push("<span id='", node.tId, consts.id.SWITCH, "' title='' style='margin-left: 20px' class='", view.makeNodeLineClass(setting, node), "' treeNode", consts.id.SWITCH, "></span>");
       },
       makeDOMNodeMainAfter: function (html, setting, node) {
         html.push("</li>");
diff --git a/ruoyi-ui/src/views/login.vue b/ruoyi-ui/src/views/login.vue
index 8535d58f5..54b2c0eaf 100644
--- a/ruoyi-ui/src/views/login.vue
+++ b/ruoyi-ui/src/views/login.vue
@@ -271,7 +271,7 @@ export default {
       this.h3 = this.loginFlag?"藏趣云":"用户注册";
       this.loginButton = this.loginFlag?"登 录":"注册";
       this.loginButtonMeg = this.loginFlag?"登 录 中...":"注 册 中...";
-      this.switchLoginText = this.loginFlag?"前往注册":"返回登陆";
+      this.switchLoginText = this.loginFlag?"账号注册":"账号登陆";
 
       this.$message({
         message: this.loginFlag?"返回登陆":"前往注册",
diff --git a/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/domain/SqBookmark.java b/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/domain/SqBookmark.java
index 2ea22746d..1f94e2f62 100644
--- a/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/domain/SqBookmark.java
+++ b/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/domain/SqBookmark.java
@@ -96,9 +96,23 @@ public class SqBookmark
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date createTime;
 
+    /**tag名称串**/
+    @Column(name = "tag_name_all")
+    private String tagNameAll;
+
+    /**是否稍后读 0不是 1是**/
+    @Column(name = "see_you_later")
+    private Integer seeYouLater;
+
     @Transient
     private Long parentId;
 
+    /** 书签的类型 星标 稍后看 最新书签 **/
+    @Transient
+    private String type;
+    /** 排序的方式 **/
+    @Transient
+    private String sort;
 
     private List<Map<String,Object>> sqTags;
 
diff --git a/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/mapper/SqBookmarkMapper.java b/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/mapper/SqBookmarkMapper.java
index 22f1cfd58..1a350b30a 100644
--- a/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/mapper/SqBookmarkMapper.java
+++ b/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/mapper/SqBookmarkMapper.java
@@ -110,4 +110,14 @@ public interface SqBookmarkMapper extends MyMapper<SqBookmark>
      *  获取重复的标签
      */
     List<SqBookmark> bookmarkRepetition(Long userId);
+
+    /**
+     * @Description: 查询 最新 稍后读 星标
+     *
+     * @param
+     * @return
+     * @author: wanghao
+     *
+     */
+    List<SqBookmark> listByUserAndPolymerization(SqBookmark sqBookmark);
 }
diff --git a/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/mapper/SqMenuMapper.java b/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/mapper/SqMenuMapper.java
index 06a59edfd..ea9fbd206 100644
--- a/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/mapper/SqMenuMapper.java
+++ b/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/mapper/SqMenuMapper.java
@@ -1,6 +1,8 @@
 package com.ruoyi.bookmark.mapper;
 
 import java.util.List;
+
+import com.ruoyi.bookmark.domain.SqBookmark;
 import com.ruoyi.bookmark.domain.SqMenu;
 import com.ruoyi.common.mybatisMapper.MyMapper;
 import org.apache.ibatis.annotations.Param;
@@ -128,4 +130,5 @@ public interface SqMenuMapper extends MyMapper<SqMenu>
     public int countByMenuUplinkSeriesAndMenu(@Param("menuUplinkSeries")String menuUplinkSeries, @Param("menuId")Long menuId);
 
 
+
 }
diff --git a/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/service/ISqBookmarkService.java b/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/service/ISqBookmarkService.java
index 88b4bd421..881f35d9d 100644
--- a/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/service/ISqBookmarkService.java
+++ b/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/service/ISqBookmarkService.java
@@ -148,4 +148,26 @@ public interface ISqBookmarkService
      *  重新计算目录下的书签数量和 目录的结构
      */
     public void bookmarkMenuCount(Long userId,Long menuId);
+
+    /**
+     * @Description: 导出书签文件html功能
+     *
+     * @param  userId
+     * @return StringBuilder
+     * @Date
+     * @author: wanghao
+     *
+     */
+    StringBuilder exportToHtml(Long userId);
+
+    /**
+     * @Description: 查询书签管理列表 聚合>> 星标 稍后看 最新书签
+     *
+     * @param
+     * @return
+     * @Date
+     * @author: wanghao
+     *
+     */
+    List<SqBookmark> listByUserAndPolymerization(SqBookmark sqBookmark);
 }
diff --git a/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/service/impl/SqBookmarkServiceImpl.java b/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/service/impl/SqBookmarkServiceImpl.java
index d7fd1ee44..6561f6939 100644
--- a/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/service/impl/SqBookmarkServiceImpl.java
+++ b/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/service/impl/SqBookmarkServiceImpl.java
@@ -8,6 +8,9 @@ import java.util.*;
 import java.util.stream.Collectors;
 
 import cn.hutool.core.date.DateUtil;
+import cn.hutool.json.JSON;
+import cn.hutool.json.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.github.pagehelper.PageHelper;
 import com.ruoyi.bookmark.domain.SqBookmarkTag;
 
@@ -29,7 +32,9 @@ import org.springframework.stereotype.Service;
 import com.ruoyi.bookmark.mapper.SqBookmarkMapper;
 import com.ruoyi.bookmark.domain.SqBookmark;
 import com.ruoyi.bookmark.service.ISqBookmarkService;
+import org.springframework.transaction.annotation.Transactional;
 import tk.mybatis.mapper.entity.Example;
+import tk.mybatis.mapper.genid.GenId;
 
 
 /**
@@ -87,7 +92,9 @@ public class SqBookmarkServiceImpl implements ISqBookmarkService
     @Override
     public SqBookmark selectSqBookmarkById(Long bookmarkId)
     {
-        return sqBookmarkMapper.selectSqBookmarkById(bookmarkId);
+        SqBookmark sqBookmark = sqBookmarkMapper.selectSqBookmarkById(bookmarkId);
+        sqBookmark.setSqTags(sqBookmarkTagMapper.selectSqTaListById(sqBookmark.getBookmarkId()));
+        return sqBookmark;
     }
 
     /**
@@ -109,8 +116,11 @@ public class SqBookmarkServiceImpl implements ISqBookmarkService
      * @return 结果
      */
     @Override
+    @Transactional
     public int insertSqBookmark(SqBookmark sqBookmark)
     {
+        JSONArray objects = new JSONArray();
+        JSONObject json = null;
         //获取官网urls
         try {
             sqBookmark.setUrls(ImportHtml.Urlutils(new URL(sqBookmark.getUrl())));
@@ -122,16 +132,13 @@ public class SqBookmarkServiceImpl implements ISqBookmarkService
         }
         //转换传入的父级ID
         sqBookmark.setMenuId(sqBookmark.getParentId());
-        int i= sqBookmarkMapper.insertSqBookmark(sqBookmark);
-
         //给对应目录 +1 并且设置为目录
         sqMenuMapper.updateCountAdd(new Long[]{sqBookmark.getMenuId()},1);
 
-
         //传入的标签
         List<Map<String, Object>> listmap = sqBookmark.getSqTags();
-        if (listmap==null||listmap.isEmpty()||listmap.size()==0){
-           return i;
+        if (listmap==null||listmap.isEmpty()||listmap.size()==0||listmap.size()>5){
+           return sqBookmarkMapper.insertSqBookmark(sqBookmark);
         }
 
         //给文章添加标签
@@ -140,30 +147,24 @@ public class SqBookmarkServiceImpl implements ISqBookmarkService
         SqBookmarkTag bookamrktag = new SqBookmarkTag();
 
         for (Map<String, Object> map : listmap) {
-            for (Map.Entry<String, Object> entry : map.entrySet()) {
                 //新增书签
                 if (Integer.parseInt(String.valueOf(map.get("tagId"))) < 0) {
                     Map<String, Object> tagmap = iSqTagService.addtag(String.valueOf(map.get("name")), sqBookmark.getUserid());
-                    for (Map.Entry<String, Object> tag : tagmap.entrySet()) {
                         bookmarkTag.put(Long.valueOf(tagmap.get("tagId").toString()),sqBookmark.getBookmarkId());
-                    }
-                }else {
-                    //原本就有的 标签
-                    bookmarkTag.put(Long.valueOf(map.get("tagId").toString()),sqBookmark.getBookmarkId());
+                        json.put("name",map.get("name").toString());
+                        json.put("tagId",map.get("tagId").toString());
+                        objects.add(json);
                 }
-            }
         }
-        //删除之前的标签
-        SqBookmarkTag sqBookmarkTag=new SqBookmarkTag();
-        sqBookmarkTag.setBookmarkId(sqBookmark.getBookmarkId());
-        sqBookmarkTagMapper.delete(sqBookmarkTag);
         //给文章添加书签
         for (Map.Entry<Long,Long> tag:bookmarkTag.entrySet()){
             bookamrktag.setBookmarkId(tag.getValue());
             bookamrktag.setTagId(tag.getKey());
             sqBookmarkTagMapper.insertSqBookmarkTag(bookamrktag);
         }
-        return i;
+        //TAG书签串
+        sqBookmark.setTagNameAll(objects.toString());
+        return sqBookmarkMapper.insertSqBookmark(sqBookmark);
     }
 
     /**
@@ -173,19 +174,12 @@ public class SqBookmarkServiceImpl implements ISqBookmarkService
      * @return 结果
      */
     @Override
+    @Transactional
     public int updateSqBookmark(SqBookmark sqBookmark) {
-//        //删除的书签ID
-//        String deletetag = "";
-//        //新增的书签ID
-//        String addtag = "";
+
         //未修改前的信息
         SqBookmark sqbm=sqBookmarkMapper.selectSqBookmarkById(sqBookmark.getBookmarkId());
-        //传入的标签
-        int i =sqBookmarkMapper.updateSqBookmark(sqBookmark);
-        List<Map<String, Object>> listmap = sqBookmark.getSqTags();
-        if (listmap==null||listmap.isEmpty()||listmap.size()==0){
-            return i;
-        }
+
 
         //是否移动目录
         if (!sqbm.getMenuId().toString().equals(sqBookmark.getMenuId().toString())){
@@ -194,28 +188,35 @@ public class SqBookmarkServiceImpl implements ISqBookmarkService
             //新目录 +1
             sqMenuMapper.updateCountAdd(new Long[]{sqBookmark.getMenuId()},1);
         }
-
-
-
+        List<Map<String, Object>> listmap = sqBookmark.getSqTags();
+        if (listmap==null||listmap.isEmpty()||listmap.size()==0||listmap.size()>5){
+            return sqBookmarkMapper.updateSqBookmark(sqBookmark); //修改书签信息
+        }
+        JSONArray objects = new JSONArray();
+        JSONObject json = null;
         //给文章添加标签
         HashMap<Long,Long> bookmarkTag=new HashMap<Long,Long>();
         //文章添加书签
         SqBookmarkTag bookamrktag = new SqBookmarkTag();
 
         for (Map<String, Object> map : listmap) {
-            for (Map.Entry<String, Object> entry : map.entrySet()) {
+            json = new JSONObject();
                 //新增书签
                 if (Integer.parseInt(String.valueOf(map.get("tagId"))) < 0) {
-                    Map<String, Object> tagmap = iSqTagService.addtag(String.valueOf(map.get("name")), sqBookmark.getUserid());
-                    for (Map.Entry<String, Object> tag : tagmap.entrySet()) {
+                    Map<String, Object> tagmap = iSqTagService.addtag(map.get("name").toString(), sqBookmark.getUserid());
                         bookmarkTag.put(Long.valueOf(tagmap.get("tagId").toString()),sqBookmark.getBookmarkId());
-                    }
+                    json.put("name",map.get("name").toString());
+                    json.put("tagId",map.get("tagId").toString());
+                    objects.add(json);
                 }else {
-                    //原本就有的 标签
+                    //修改前的书签 不包含已移除的
+                    if(!map.get("name").equals("TAGDELETE")){
+                        json.put("name",map.get("name").toString());
+                        json.put("tagId",map.get("tagId").toString());
+                        objects.add(json);
                     bookmarkTag.put(Long.valueOf(map.get("tagId").toString()),sqBookmark.getBookmarkId());
+                    }
                 }
-
-            }
         }
         //删除之前的标签
         SqBookmarkTag sqBookmarkTag=new SqBookmarkTag();
@@ -228,9 +229,10 @@ public class SqBookmarkServiceImpl implements ISqBookmarkService
             bookamrktag.setTagId(tag.getKey());
             sqBookmarkTagMapper.insertSqBookmarkTag(bookamrktag);
         }
+        //标签名称串
+        sqBookmark.setTagNameAll(objects.toString());
+        return sqBookmarkMapper.updateSqBookmark(sqBookmark); //修改书签信息
 
-
-        return i;
     }
 
     /**
@@ -418,5 +420,105 @@ public class SqBookmarkServiceImpl implements ISqBookmarkService
         }
     }
 
+    /**
+     * @Description: 导出书签文件html功能
+     *
+     * @param  userId
+     * @return StringBuilder
+     * @Date
+     * @author: wanghao
+     *
+     */
+    @Override
+    public StringBuilder exportToHtml(Long userId) {
+
+        SqMenu sqMenu=new SqMenu();
+        sqMenu.setUserId(userId);
+        SqBookmark sqBookmark = new SqBookmark();
+        sqBookmark.setUserid(userId);
+        //目录
+        List<SqMenu> menuList = sqMenuMapper.selectSqMenuList(sqMenu);
+        Map<Long, List<SqMenu>> mapMenu =  menuList.stream().collect(Collectors.groupingBy(SqMenu::getParentId));
+        //书签
+        List<SqBookmark> bookMarkList = sqBookmarkMapper.selectSqBookmarkList(sqBookmark);
+        Map<Long, List<SqBookmark>> mapBookMark  = bookMarkList.stream().collect(Collectors.groupingBy(SqBookmark::getMenuId));
+
+        List<SqMenu> sqMenuList = mapMenu.get(0L);
+        StringBuilder str = new StringBuilder();
+        str.append("<!DOCTYPE NETSCAPE-Bookmark-file-1>\n" +
+                "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\">\n" +
+                "<TITLE>Bookmarks</TITLE>\n" +
+                "<H1>Bookmarks</H1>");
+        str.append("<DL>\n");
+        str.append(traverseFile_recursion(sqMenuList,str,mapBookMark,mapMenu));
+        str.append("</DL>\n");
+        return str;
+    }
+
+
+    /**
+     * @Description:递归书签导出功能
+     *
+     * @param  * @param sqMenuList
+     * @param str
+     * @param mapBookMark
+     * @param mapMenu
+     * @return java.lang.StringBuilder
+     * @Date
+     * @author: wanghao
+     *
+     */
+    public StringBuilder traverseFile_recursion (List<SqMenu> sqMenuList,StringBuilder str,Map<Long, List<SqBookmark>> mapBookMark,Map<Long, List<SqMenu>> mapMenu) {
+
+        if (sqMenuList != null && !sqMenuList.isEmpty()) {
+            for (SqMenu f : sqMenuList) {
+                str.append("<DT><H3 ADD_DATE=\"1584277207\" LAST_MODIFIED=\"0\">").append(f.getMenuName()).append("</H3>\n");
+                str.append("<DL>\n");
+                List<SqBookmark> bookmarksList = mapBookMark.get(f.getMenuId());
+                if (bookmarksList != null && !bookmarksList.isEmpty()) {
+                    for (SqBookmark b : bookmarksList) {
+                        str.append("<DT><A HREF=\""+b.getUrl()+"\" TARGET=\"_blank\">"+b.getTitle()+"</A>\n");
+                    }
+                }
+                traverseFile_recursion(mapMenu.get(f.getMenuId()),str,mapBookMark,mapMenu);
+                str.append("</DL>\n");
+            }
+        }
+        return str;
+    }
+
+
+
+    /**
+     * @Description: 查询书签管理列表 聚合>> 星标 稍后看 最新书签
+     *
+     * @param
+     * @return
+     * @Date
+     * @author: wanghao
+     *
+     */
+    @Override
+    public List<SqBookmark> listByUserAndPolymerization(SqBookmark sqBookmark) {
+
+        SqBookmark searchBookmark = new  SqBookmark();
+        searchBookmark.setUserid(sqBookmark.getUserid());
+
+        if(sqBookmark.getType().equals(Const.RECYCLE)){
+            searchBookmark.setIdelete(Const.BKNOTDELETE);//删除的
+        }else{
+            searchBookmark.setIdelete(Const.BKDELETE);//未删除的
+        }
+
+        if (sqBookmark.getType().equals(Const.NEWEST)){//最新的
+            //无处理
+        }else if(sqBookmark.getType().equals(Const.ASTERISK)){
+            searchBookmark.setBookmarkStar(1);
+        }else if(sqBookmark.getType().equals(Const.SEEYOULATER)){//稍后看
+            searchBookmark.setSeeYouLater(1);
+        }
+        return sqBookmarkMapper.listByUserAndPolymerization(searchBookmark);
+    }
+
 
 }
diff --git a/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/service/impl/SqTagServiceImpl.java b/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/service/impl/SqTagServiceImpl.java
index 34f7b3a54..90fb0490c 100644
--- a/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/service/impl/SqTagServiceImpl.java
+++ b/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/service/impl/SqTagServiceImpl.java
@@ -127,7 +127,7 @@ public class SqTagServiceImpl implements ISqTagService
         }else {
            //不存在 >>创建 返回ID
            sqTagMapper.insertSqTag(sqTag);
-           logger.debug("传入的新标签 tagid="+sqTag.getId());
+//           logger.debug("传入的新标签 tagid="+sqTag.getId());
           map.put("tagId",sqTag.getId());
         }
         return map;
diff --git a/ruoyi-yunbookmark/src/main/resources/mapper/bookmark/SqBookmarkMapper.xml b/ruoyi-yunbookmark/src/main/resources/mapper/bookmark/SqBookmarkMapper.xml
index 47c08a795..8ff88b223 100644
--- a/ruoyi-yunbookmark/src/main/resources/mapper/bookmark/SqBookmarkMapper.xml
+++ b/ruoyi-yunbookmark/src/main/resources/mapper/bookmark/SqBookmarkMapper.xml
@@ -16,22 +16,22 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="menuId"    column="menu_id"    />
         <result property="zcount"    column="zcount"    />
         <result property="bookmarkStar"    column="bookmark_star"    />
+        <result property="tagNameAll"    column="tag_name_all"    />
         <result property="idelete"    column="idelete"    />
         <result property="start"    column="start"    />
         <result property="createTime"    column="create_time"    />
+        <result property="seeYouLater"    column="see_you_later"    />
 <!--        <collection property="sqTags"-->
 <!--                    javaType="java.util.ArrayList"-->
 <!--                    ofType="java.util.Map"-->
 <!--                    select="com.ruoyi.bookmark.mapper.SqBookmarkTagMapper.selectSqTaListById"-->
 <!--                    column="bookmark_id">-->
-
-
 <!--        </collection>-->
 
     </resultMap>
 
     <sql id="selectSqBookmarkVo">
-        select bookmark_id, userid, title, url, urls, description, image, Label, menu_id, zcount, IDelete, Start, create_time,bookmark_star from sq_bookmark
+        select bookmark_id, userid, title, url, urls, description, image, Label, menu_id, zcount, IDelete, Start, create_time,bookmark_star,tag_name_all from sq_bookmark
     </sql>
 
     <select id="selectSqBookmarkList" parameterType="SqBookmark" resultMap="SqBookmarkResult">
@@ -70,6 +70,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="zcount != null">zcount,</if>
             <if test="idelete != null">idelete,</if>
             <if test="start != null">start,</if>
+            <if test="tagNameAll != null">tag_name_all,</if>
             <if test="createTime != null">create_time,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
@@ -84,6 +85,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="zcount != null">#{zcount},</if>
             <if test="idelete != null">#{idelete},</if>
             <if test="start != null">#{start},</if>
+            <if test="tagNameAll != null">#{tagNameAll},</if>
             <if test="createTime != null">#{createTime},</if>
          </trim>
     </insert>
@@ -102,6 +104,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="zcount != null">zcount = #{zcount},</if>
             <if test="idelete != null">idelete = #{idelete},</if>
             <if test="start != null">start = #{start},</if>
+            <if test="tagNameAll != null">tag_name_all = #{tagNameAll},</if>
             <if test="bookmarkStar != null">bookmark_star = #{bookmarkStar},</if>
             <if test="createTime != null">create_time = #{createTime},</if>
         </trim>
@@ -173,4 +176,35 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             </otherwise>
         </choose>
     </select>
+
+
+
+
+    <select id="listByUserAndPolymerization" parameterType="SqBookmark" resultMap="SqBookmarkResult">
+        <include refid="selectSqBookmarkVo"/>
+        <where>
+            <if test="userid != null "> and userid = #{userid}</if>
+            <if test="idelete != null "> and idelete = #{idelete}</if>
+            <if test="bookmarkStar != null "> and bookmark_star = #{bookmarkStar}</if>
+            <if test="seeYouLater != null "> and see_you_later = #{seeYouLater}</if>
+            order by
+            <choose>
+                <when test="sort == 0">
+                    create_time desc
+                </when>
+                <when test="sort == 1">
+                    create_time asc
+                </when>
+                <when test="sort == 2">
+                    CONVERT(title USING GBK) asc
+                </when>
+                <when test="sort == 3">
+                    CONVERT(title USING GBK) desc
+                </when>
+                <otherwise>
+                    create_time desc
+                </otherwise>
+            </choose>
+        </where>
+    </select>
 </mapper>