添加分类显示回收站 稍后看

This commit is contained in:
WangHao 2021-04-26 22:27:52 +08:00
parent 4131d8bdca
commit 900076723f
24 changed files with 941 additions and 252 deletions

View File

@ -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+"");
}
}

View File

@ -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);
}
/**
* 查询书签管理列表

View File

@ -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>

View File

@ -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;
}
}

View File

@ -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>

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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()
)

View File

@ -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',
})
}

View File

@ -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;

View File

@ -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) // 释放标签
}

View File

@ -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;
}

View File

@ -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; //01
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>

View File

@ -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();

View File

@ -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 ;
}

View File

@ -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>");

View File

@ -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?"返回登陆":"前往注册",

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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>