导入浏览器书签
This commit is contained in:
		| @@ -9,6 +9,8 @@ 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.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; | ||||
| @@ -23,9 +25,12 @@ 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 java.util.Date; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.Map.Entry; | ||||
| import java.util.stream.Collectors; | ||||
|  | ||||
|  | ||||
| /** | ||||
| @@ -50,33 +55,54 @@ public class BrowserController extends BaseController { | ||||
|     @PreAuthorize("@ss.hasPermi('bookmark:bookmark:list')") | ||||
|     public AjaxResult importCollect(@RequestParam("htmlFile") MultipartFile htmlFile){ | ||||
|         logger.debug("开始上传状态是:"); | ||||
|  | ||||
|         SysUser sysUser=getAuthUser(); | ||||
|         Long userID= sysUser.getUserId(); | ||||
|         //防止重复上传 | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|         try { | ||||
|              Map<String, Map<String, String>> map = ImportHtml.parseHtml(htmlFile.getInputStream()); | ||||
|           //  Map<String, List<Map>> map = ImportHtml.importHtmlMore(htmlFile.getInputStream()); | ||||
|                 if(null == map || map.isEmpty()){ | ||||
|                     logger.info("未获取到url连接"); | ||||
|                     return AjaxResult.error("未获取到url连接,空书签"); | ||||
|             List<HtmlName> list =  ImportHtml.addMenuAndBookmark(htmlFile.getInputStream()); | ||||
|             if(null == list || list.isEmpty()){ | ||||
|                 return AjaxResult.error("未获取到url连接,空书签文件"); | ||||
|             } | ||||
|             //获取所有的 *目录*文件夹 | ||||
|             List<HtmlName> listMenu= list.stream().filter(m-> m.getState().equals("0")).collect(Collectors.toList()); | ||||
|             //id排序 防止已添加的父id漏修改 id升序 | ||||
|             listMenu.sort(Comparator.comparing(HtmlName::getId)); | ||||
|             //1.添加目录 | ||||
|             for (HtmlName h : listMenu) { | ||||
|                 String id=h.getId(); | ||||
|                 //添加 返回id | ||||
|                 SqMenu sqMenu = new SqMenu(userID,h.getTitle(),Long.valueOf(h.getParentId()), Const.MenuIocURL); | ||||
|                 int countId =  iSqMenuService.insertSqMenu(sqMenu); | ||||
|                 if(countId!=0){ | ||||
|                 Long k=Long.valueOf(sqMenu.getMenuId().toString()); | ||||
|                 //批量修改对应的父目录id | ||||
|                 listMenu = ImportHtml.listFilter(listMenu,k,id); | ||||
|                 //批量修改对应的书签id | ||||
|                 list = ImportHtml.listFilter(list,k,id); | ||||
|                 } | ||||
|  | ||||
|  | ||||
|                 for (Entry<String, Map<String, String>> entry : map.entrySet()) { | ||||
|                    String favoritesName = entry.getKey(); | ||||
|                    //添加目录 | ||||
|                     SqMenu sqMenu=new SqMenu(); | ||||
|                     sqMenu.setUserId(userID); | ||||
|                     sqMenu.setCreateTime(new Date()); | ||||
|                     sqMenu.setMenuName(favoritesName); | ||||
|                     sqMenu.setParentId(0L); | ||||
|                     iSqMenuService.insertSqMenu(sqMenu); | ||||
|  | ||||
|  | ||||
|                     importHtml(entry.getValue(), sqMenu.getMenuId(), userID); | ||||
|             } | ||||
|             //2.添加书签 | ||||
|             for (HtmlName h : list) { | ||||
|                 if (!h.getState().equals("0")&&h.getState().equals(Const.BOOKMARK_STATE_FLAG)) { | ||||
| 				SqBookmark sqBookmark =new SqBookmark(); | ||||
|                 sqBookmark.setUserid(userID); | ||||
|                 sqBookmark.setTitle(h.getTitle()); | ||||
|                 sqBookmark.setUrl(h.getUrl()); | ||||
|                 sqBookmark.setUrls(ImportHtml.Urlutils(new URL(h.getUrl()))); | ||||
|                 if(StringUtils.isBlank(h.getDescription())){ | ||||
|                     sqBookmark.setDescription(h.getTitle()); | ||||
|                 }else{ | ||||
|                     sqBookmark.setDescription(h.getDescription()); | ||||
|                 } | ||||
|                 sqBookmark.setMenuId(Long.valueOf(h.getParentId())); | ||||
|                 sqBookmark.setCreateTime(new Date()); | ||||
|                 iSqBookmarkService.insertSqBookmark(sqBookmark); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|         }catch (SSLHandshakeException e){ | ||||
|             logger.error("文章解析出错:",e); | ||||
| @@ -90,7 +116,6 @@ public class BrowserController extends BaseController { | ||||
|         catch (Exception e) { | ||||
|             logger.error("导入html异常:",e); | ||||
|         } | ||||
|  | ||||
|         return AjaxResult.success("导入成功"); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -9,7 +9,7 @@ ruoyi: | ||||
|   # 实例演示开关 | ||||
|   demoEnabled: true | ||||
|   # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) | ||||
|   profile: /home/ruoyi/uploadPath | ||||
|   profile: D:/ruoyi/uploadPath | ||||
|   # 获取ip地址开关 | ||||
|   addressEnabled: false | ||||
|   # 验证码类型 math 数组计算 char 字符验证 | ||||
|   | ||||
| @@ -29,6 +29,10 @@ public class Const { | ||||
|  | ||||
|     public static int COOKIE_TIMEOUT= 30*24*60*60; | ||||
|  | ||||
|     public static String MenuIocURL= "https://up.raindrop.io/collection/templates/social-media-logos-6/47social.png"; | ||||
|     //已修改父级id的书签 | ||||
|     public static String BOOKMARK_STATE_FLAG= "666"; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -0,0 +1,109 @@ | ||||
| package com.ruoyi.common.utils.bookmarkhtml; | ||||
|  | ||||
|  | ||||
|  | ||||
| public class HtmlName implements Cloneable,Comparable<HtmlName>{ | ||||
|  | ||||
| 	private String id; //id | ||||
| 	private String parentId; //父级id | ||||
| 	private String title; //标题 | ||||
| 	private String description; //简介 | ||||
| 	private String state;//状态 0目录 1书签 | ||||
| 	private String url;//书签地址 | ||||
| 	private String urls;//官网 | ||||
|  | ||||
|  | ||||
| 	public String getId() { | ||||
| 		return id; | ||||
| 	} | ||||
|  | ||||
| 	public void setId(String id) { | ||||
| 		this.id = id; | ||||
| 	} | ||||
|  | ||||
| 	public String getParentId() { | ||||
| 		return parentId; | ||||
| 	} | ||||
|  | ||||
| 	public void setParentId(String parentId) { | ||||
| 		this.parentId = parentId; | ||||
| 	} | ||||
|  | ||||
| 	public String getTitle() { | ||||
| 		return title; | ||||
| 	} | ||||
|  | ||||
| 	public void setTitle(String title) { | ||||
| 		this.title = title; | ||||
| 	} | ||||
|  | ||||
| 	public String getDescription() { | ||||
| 		return description; | ||||
| 	} | ||||
|  | ||||
| 	public void setDescription(String description) { | ||||
| 		this.description = description; | ||||
| 	} | ||||
|  | ||||
| 	public String getState() { | ||||
| 		return state; | ||||
| 	} | ||||
|  | ||||
| 	public void setState(String state) { | ||||
| 		this.state = state; | ||||
| 	} | ||||
|  | ||||
| 	public String getUrl() { | ||||
| 		return url; | ||||
| 	} | ||||
|  | ||||
| 	public void setUrl(String url) { | ||||
| 		this.url = url; | ||||
| 	} | ||||
|  | ||||
| 	public String getUrls() { | ||||
| 		return urls; | ||||
| 	} | ||||
|  | ||||
| 	public void setUrls(String urls) { | ||||
| 		this.urls = urls; | ||||
| 	} | ||||
|  | ||||
| 	public HtmlName() { | ||||
| 		super(); | ||||
| 	} | ||||
| 	public HtmlName(String id, String parentId, String title, String description, String state,String url) { | ||||
| 		super(); | ||||
| 		this.id = id; | ||||
| 		this.parentId = parentId; | ||||
| 		this.title = title; | ||||
| 		this.description = description; | ||||
| 		this.state = state; | ||||
| 		this.url = url; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public String toString() { | ||||
| 		return "HtmlName{" + | ||||
| 				"id='" + id + '\'' + | ||||
| 				", parentId='" + parentId + '\'' + | ||||
| 				", title='" + title + '\'' + | ||||
| 				", description='" + description + '\'' + | ||||
| 				", state='" + state + '\'' + | ||||
| 				", url='" + url + '\'' + | ||||
| 				", urls='" + urls + '\'' + | ||||
| 				'}'; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	protected HtmlName clone() throws CloneNotSupportedException { | ||||
| 		return (HtmlName) super.clone(); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public int compareTo(HtmlName o) { | ||||
| 		return  Integer.parseInt(this.getId()) - Integer.parseInt(o.getId()); | ||||
| 	} | ||||
|  | ||||
|  | ||||
| } | ||||
| @@ -10,12 +10,15 @@ import org.jsoup.select.Elements; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
|  | ||||
| import java.io.FileInputStream; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.net.MalformedURLException; | ||||
| import java.net.URL; | ||||
| import java.util.*; | ||||
| import java.util.regex.Matcher; | ||||
| import java.util.regex.Pattern; | ||||
| import java.util.stream.Collectors; | ||||
|  | ||||
| /** | ||||
|  * @Auther: Wang | ||||
| @@ -25,6 +28,7 @@ import java.util.regex.Pattern; | ||||
| public class ImportHtml { | ||||
|  | ||||
|     public static Logger logger =  LoggerFactory.getLogger(ImportHtml.class); | ||||
|     static int id = 1; | ||||
|     /** | ||||
|      * @param url | ||||
|      * @return | ||||
| @@ -359,4 +363,88 @@ public class ImportHtml { | ||||
|         String host = url.getHost();// 获取主机名 | ||||
|         return host; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      *获取导入书签的所有数据 | ||||
|      */ | ||||
|     public static List<HtmlName> addMenuAndBookmark(InputStream inputStream) { | ||||
|         Document doc = null; | ||||
|         List<HtmlName> list =null; | ||||
|         try { | ||||
|             doc = Jsoup.parse(inputStream, "UTF-8", ""); | ||||
|             Element metasdt = doc.selectFirst("dl"); | ||||
|             Elements metasdts = new Elements(); | ||||
|             metasdts.add(metasdt); | ||||
|             list = Htmlurl(metasdts, new ArrayList<HtmlName>(), "0"); | ||||
|         } catch (IOException e) { | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|         return list; | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * @param dt1s | ||||
|      * @param list | ||||
|      * @param parentId | ||||
|      * @return | ||||
|      */ | ||||
|     public static List<HtmlName> Htmlurl(Elements dt1s, List<HtmlName> list, String parentId) { | ||||
|         for (Element dt1 : dt1s) { | ||||
|             if ("h3".equalsIgnoreCase(dt1.nodeName())) { | ||||
|                 int a = id++; | ||||
|                 list.add(new HtmlName(a + "", parentId, dt1.text(), dt1.text(), "0","")); | ||||
|                 parentId = a + ""; | ||||
|             } else if ("dl".equalsIgnoreCase(dt1.nodeName())) { | ||||
|                 Elements dts = dt1.children(); | ||||
|                 for (Element dt11 : dts) { | ||||
|                     if ("dt".equals(dt11.nodeName())) { | ||||
|                         if ("a".equals(dt11.child(0).nodeName())) { | ||||
|                             String url = dt11.child(0).attr("href"); | ||||
|                             if (url.startsWith("http")) { | ||||
|                                 list.add(new HtmlName((id++) + "", parentId, | ||||
|                                         dt11.child(0) == null ? "" : dt11.child(0).text(), | ||||
|                                         dt11.child(0) == null ? "" : dt11.child(0).text(), "1",url)); | ||||
|                             } | ||||
|                         } | ||||
|                         if ("h3".equalsIgnoreCase(dt11.child(0).nodeName())) { | ||||
|                             Htmlurl(dt11.children(), list, parentId); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return list; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      */ | ||||
|     static Element htmlReplace(Element metasdt, String str) { | ||||
|         String metasdtStr = metasdt.toString(); | ||||
|         while (metasdtStr.indexOf(str) != -1) { | ||||
|             metasdtStr = metasdtStr.replace(str, ""); | ||||
|         } | ||||
|         return metasdt.after(metasdtStr); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 批量修改父级id | ||||
|      * @return | ||||
|      */ | ||||
|    public static List<HtmlName> listFilter(List<HtmlName> list,Long parentId,String htmlid){ | ||||
|         for (HtmlName h : list) { | ||||
|             if (h.getParentId().equals(htmlid)) { | ||||
|                 h.setParentId(parentId.toString()); | ||||
|                 if (!h.getState().equals("0")) | ||||
|                     h.setState(Const.BOOKMARK_STATE_FLAG);//标识符 | ||||
|             } | ||||
|         } | ||||
|         return list; | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -751,12 +751,12 @@ | ||||
|       getrecycleList() { | ||||
|         this.loading = true; | ||||
|         selectBydelete(this.queryParams).then(response => { | ||||
|           if (response.total != 0 &&response.code == 200) { | ||||
|           if (response.code == 200) { | ||||
|             this.bookmarkList = this.bookmarkList.concat(response.rows); | ||||
|             this.total = response.total; | ||||
|             this.listloading = false | ||||
|             this.loading = false; | ||||
|             console.log("请求完毕" + that.queryParams.pageNum) | ||||
|             console.log("请求完毕" + this.queryParams.pageNum) | ||||
|           } else { | ||||
|             //出错了加载完毕了 禁止滚动 | ||||
|             this.noMore = true; | ||||
| @@ -774,7 +774,7 @@ | ||||
|               this.total = response.total; | ||||
|               this.listloading = false | ||||
|               this.loading = false; | ||||
|               console.log("请求完毕" + that.queryParams.pageNum) | ||||
|               console.log("请求完毕" + this.queryParams.pageNum) | ||||
|             } else { | ||||
|               //出错了加载完毕了 禁止滚动 | ||||
|               this.noMore = true; | ||||
| @@ -827,16 +827,19 @@ | ||||
|       getList() { | ||||
|         this.loading = true; | ||||
|         selectBymenuIdUserID(this.queryParams).then(response => { | ||||
|           if (response.code == 200) { | ||||
|           if (response.total != 0 &&response.code == 200) { | ||||
|             this.bookmarkList = response.rows; | ||||
|             this.total = response.total; | ||||
|             this.loading = false; | ||||
|             if (this.bookmarkList==null||this.bookmarkList.length==0) { | ||||
|               this.showimg=true; | ||||
|             } | ||||
|             this.listloading = false | ||||
|           } else { | ||||
|             this.showbookmark = false; | ||||
|             this.showimg = true; | ||||
|             this.loading = false; | ||||
|             this.listloading = false | ||||
|           } | ||||
|         }); | ||||
|       }, | ||||
| @@ -880,7 +883,7 @@ | ||||
|             this.total = response.total; | ||||
|             this.listloading = false | ||||
|             this.loading = false; | ||||
|             console.log("请求完毕" + that.queryParams.pageNum) | ||||
|             console.log("请求完毕" + this.queryParams.pageNum) | ||||
|           } else { | ||||
|             //出错了加载完毕了 禁止滚动 | ||||
|             this.noMore = true; | ||||
|   | ||||
| @@ -29,9 +29,9 @@ | ||||
|         <div class="el-upload__tip title"   slot="tip">提示:仅允许导入".html"格式文件!</div> | ||||
|       </el-upload> | ||||
|       <div slot="footer" class="dialog-footer"> | ||||
|         <el-button type="primary" class="  mdui-text-center  mdui-btn mdui-btn-raised mdui-text-color-blue-900  mdui-color-light-blue-100" @click="submitFileForm">确 定</el-button> | ||||
| <!--        <el-button type="primary" class="  mdui-text-center  mdui-btn mdui-btn-raised mdui-text-color-blue-900  mdui-color-light-blue-100" @click="submitFileForm">确 定</el-button>--> | ||||
| <!--        <el-button @click="upload.open = false">取 消</el-button>--> | ||||
|         <button @click="submitUpload"  class="isbutton mdui-btn mdui-btn-block mdui-btn-raised mdui-btn-dense  mdui-color-blue-100  mdui-ripple">导 入 书 签</button> | ||||
|         <button @click="submitFileForm"  class="isbutton mdui-btn mdui-btn-block mdui-btn-raised mdui-btn-dense  mdui-color-blue-100  mdui-ripple">导 入 书 签</button> | ||||
|       </div> | ||||
|  | ||||
|     </div> | ||||
|   | ||||
| @@ -171,4 +171,14 @@ public class SqMenu | ||||
|             .append("updateTime", getUpdateTime()) | ||||
|             .toString(); | ||||
|     } | ||||
|     public SqMenu(){ | ||||
|         super(); | ||||
|     } | ||||
|  | ||||
|     public SqMenu( Long userId, String menuName, Long parentId,String menuIcon) { | ||||
|         this.userId = userId; | ||||
|         this.menuName = menuName; | ||||
|         this.parentId = parentId; | ||||
|         this.menuIcon = menuIcon; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -91,4 +91,13 @@ public interface SqMenuMapper extends MyMapper<SqMenu> | ||||
|     public int updateCountAdd(@Param("menuIds")Long[] menuIds,@Param("icount")int icount); | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      *添加书签目录 | ||||
|      * | ||||
|      * @param  userID | ||||
|      * @param  title | ||||
|      * @param  parentId | ||||
|      * @return | ||||
|      */ | ||||
|     public void addMenu(@Param("userId")Long userID, @Param("title")String title, @Param("parentId")Long parentId); | ||||
| } | ||||
|   | ||||
| @@ -104,4 +104,13 @@ public interface ISqMenuService | ||||
|      * @return 结果 | ||||
|      */ | ||||
|     public int deleteSqMenuById(Long menuId,Long userId); | ||||
|  | ||||
|  | ||||
|    /** | ||||
|     * 添加书签目录 | ||||
|     * | ||||
|     * @param | ||||
|     * @return | ||||
|     */ | ||||
|    public void addMenu(Long userID, String title, Long valueOf); | ||||
| } | ||||
|   | ||||
| @@ -158,6 +158,12 @@ public class SqMenuServiceImpl implements ISqMenuService | ||||
|         return sqMenuMapper.deleteSqMenuById(menuId,userId); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void addMenu(Long userID, String title, Long parentId) { | ||||
|              sqMenuMapper.addMenu(userID,title,parentId); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * 批量减少目录下书签数量 | ||||
|      * | ||||
|   | ||||
| @@ -40,7 +40,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | ||||
|         where menu_id = #{menuId} | ||||
|     </select> | ||||
|  | ||||
|     <insert id="insertSqMenu" parameterType="SqMenu" useGeneratedKeys="true" keyProperty="menuId"> | ||||
|     <insert id="insertSqMenu" parameterType="SqMenu" useGeneratedKeys="true" keyProperty="menuId" > | ||||
|         insert into sq_menu | ||||
|         <trim prefix="(" suffix=")" suffixOverrides=","> | ||||
|             <if test="userId != null">user_id,</if> | ||||
| @@ -105,4 +105,5 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | ||||
|     </update> | ||||
|  | ||||
|  | ||||
|  | ||||
| </mapper> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user