书签导入功能
This commit is contained in:
@ -0,0 +1,132 @@
|
|||||||
|
package com.ruoyi.web.controller.yunbookmark;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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.core.controller.BaseController;
|
||||||
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
|
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||||
|
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;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.dao.DataIntegrityViolationException;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
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.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Auther: Wang
|
||||||
|
* @Date:
|
||||||
|
* 功能描述: 导入书签 导出书签
|
||||||
|
*/
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/IO")
|
||||||
|
public class BrowserController extends BaseController {
|
||||||
|
public static Logger logger = LoggerFactory.getLogger(BrowserController.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ISqMenuService iSqMenuService;
|
||||||
|
@Autowired
|
||||||
|
private ISqBookmarkService iSqBookmarkService;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@RequestMapping("/import")
|
||||||
|
@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连接,空书签");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}catch (SSLHandshakeException e){
|
||||||
|
logger.error("文章解析出错:",e);
|
||||||
|
}
|
||||||
|
catch (DataIntegrityViolationException e){
|
||||||
|
logger.error("导入存储异常:",e);
|
||||||
|
}
|
||||||
|
catch (HttpStatusException a){
|
||||||
|
logger.error("文档解析错误:",a);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
logger.error("导入html异常:",e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return AjaxResult.success("导入成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入收藏文章
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -11,7 +11,7 @@
|
|||||||
<pattern>${log.pattern}</pattern>
|
<pattern>${log.pattern}</pattern>
|
||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<!-- 系统日志输出 -->
|
<!-- 系统日志输出 -->
|
||||||
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
<file>${log.path}/sys-info.log</file>
|
<file>${log.path}/sys-info.log</file>
|
||||||
@ -34,7 +34,7 @@
|
|||||||
<onMismatch>DENY</onMismatch>
|
<onMismatch>DENY</onMismatch>
|
||||||
</filter>
|
</filter>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
<file>${log.path}/sys-error.log</file>
|
<file>${log.path}/sys-error.log</file>
|
||||||
<!-- 循环政策:基于时间创建日志文件 -->
|
<!-- 循环政策:基于时间创建日志文件 -->
|
||||||
@ -56,7 +56,7 @@
|
|||||||
<onMismatch>DENY</onMismatch>
|
<onMismatch>DENY</onMismatch>
|
||||||
</filter>
|
</filter>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<!-- 用户访问日志输出 -->
|
<!-- 用户访问日志输出 -->
|
||||||
<appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
<appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
<file>${log.path}/sys-user.log</file>
|
<file>${log.path}/sys-user.log</file>
|
||||||
@ -70,7 +70,7 @@
|
|||||||
<pattern>${log.pattern}</pattern>
|
<pattern>${log.pattern}</pattern>
|
||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<!-- 系统模块日志级别控制 -->
|
<!-- 系统模块日志级别控制 -->
|
||||||
<logger name="com.ruoyi" level="info" />
|
<logger name="com.ruoyi" level="info" />
|
||||||
<!-- Spring日志级别控制 -->
|
<!-- Spring日志级别控制 -->
|
||||||
@ -79,15 +79,15 @@
|
|||||||
<root level="info">
|
<root level="info">
|
||||||
<appender-ref ref="console" />
|
<appender-ref ref="console" />
|
||||||
</root>
|
</root>
|
||||||
|
|
||||||
<!--系统操作日志-->
|
<!--系统操作日志-->
|
||||||
<root level="info">
|
<root level="info">
|
||||||
<appender-ref ref="file_info" />
|
<appender-ref ref="file_info" />
|
||||||
<appender-ref ref="file_error" />
|
<appender-ref ref="file_error" />
|
||||||
</root>
|
</root>
|
||||||
|
|
||||||
<!--系统用户操作日志-->
|
<!--系统用户操作日志-->
|
||||||
<logger name="sys-user" level="info">
|
<logger name="sys-user" level="info">
|
||||||
<appender-ref ref="sys-user"/>
|
<appender-ref ref="sys-user"/>
|
||||||
</logger>
|
</logger>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
@ -125,6 +125,18 @@
|
|||||||
<version>2.1.5</version>
|
<version>2.1.5</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!--jsoup解析html-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jsoup</groupId>
|
||||||
|
<artifactId>jsoup</artifactId>
|
||||||
|
<version>1.13.1</version>
|
||||||
|
</dependency>
|
||||||
|
<!--常用工具包-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>3.5</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.ruoyi.common.utils.BookmarkHtml;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Auther: Wang
|
||||||
|
* @Date: 2020/08/22 23:03
|
||||||
|
* 功能描述:
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class Const {
|
||||||
|
|
||||||
|
public static String BASE_PATH;
|
||||||
|
|
||||||
|
public static String LOGIN_SESSION_KEY = "Favorites_user";
|
||||||
|
|
||||||
|
public static String PASSWORD_KEY = "@#$%^&*()OPG#$%^&*(HG";
|
||||||
|
|
||||||
|
public static String DES3_KEY = "9964DYByKL967c3308imytCB";
|
||||||
|
|
||||||
|
public static String default_logo="img/logo.jpg";
|
||||||
|
|
||||||
|
public static String userAgent="Mozilla";
|
||||||
|
|
||||||
|
public static String default_Profile=BASE_PATH+"/img/logo.jpg";
|
||||||
|
|
||||||
|
public static String LAST_REFERER = "LAST_REFERER";
|
||||||
|
|
||||||
|
public static int COOKIE_TIMEOUT= 30*24*60*60;
|
||||||
|
|
||||||
|
|
||||||
|
// @Autowired(required = true)
|
||||||
|
// public void setBasePath(@Value("${favorites.base.path}")String basePath) {
|
||||||
|
// Const.BASE_PATH = basePath;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,363 @@
|
|||||||
|
package com.ruoyi.common.utils.BookmarkHtml;
|
||||||
|
|
||||||
|
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import org.jsoup.Connection;
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.jsoup.nodes.Element;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Auther: Wang
|
||||||
|
* @Date: 2020/08/22 22:56
|
||||||
|
* 功能描述:
|
||||||
|
*/
|
||||||
|
public class ImportHtml {
|
||||||
|
|
||||||
|
public static Logger logger = LoggerFactory.getLogger(ImportHtml.class);
|
||||||
|
/**
|
||||||
|
* @param url
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
// public static String getImge(String url){
|
||||||
|
// String logo="";
|
||||||
|
// logo=getPageImg(url);
|
||||||
|
// if(StringUtils.isBlank(logo) || logo.length()>300){
|
||||||
|
// logo=Const.BASE_PATH + Const.default_logo;
|
||||||
|
// }
|
||||||
|
// return logo;
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param url
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
// public static String getPageImg(String url){
|
||||||
|
// String imgUrl="";
|
||||||
|
// Document doc;
|
||||||
|
// try {
|
||||||
|
// doc = Jsoup.connect(url).userAgent(Const.userAgent).get();
|
||||||
|
// Elements images = doc.select("img[src~=(?i)\\.(png|jpe?g|gif)]");
|
||||||
|
// for(Element image : images){
|
||||||
|
// imgUrl=image.attr("src");
|
||||||
|
// if(StringUtils.isNotBlank(imgUrl) ){
|
||||||
|
// if(imgUrl.startsWith("//")){
|
||||||
|
// imgUrl = "http:" + imgUrl;
|
||||||
|
// }else if(!imgUrl.startsWith("http") && !imgUrl.startsWith("/")){
|
||||||
|
// imgUrl=URLUtil.getDomainUrl(url) + "/" + imgUrl;
|
||||||
|
// }else if(!imgUrl.startsWith("http")){
|
||||||
|
// imgUrl=URLUtil.getDomainUrl(url)+imgUrl;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// // 判断图片大小
|
||||||
|
// String fileUrl = download(imgUrl);
|
||||||
|
// if(fileUrl!=null){
|
||||||
|
// File picture = new File(fileUrl);
|
||||||
|
// FileInputStream in = new FileInputStream(picture);
|
||||||
|
// BufferedImage sourceImg = ImageIO.read(in);
|
||||||
|
// String weight = String.format("%.1f",picture.length()/1024.0);
|
||||||
|
// int width = sourceImg.getWidth();
|
||||||
|
// int height = sourceImg.getHeight();
|
||||||
|
// // 删除临时文件
|
||||||
|
// if(picture.exists()){
|
||||||
|
// in.close();
|
||||||
|
// picture.delete();
|
||||||
|
// }
|
||||||
|
// if(Double.parseDouble(weight) <= 0 || width <=0 || height <= 0){
|
||||||
|
// logger.info("当前图片大小为0,继续获取图片链接");
|
||||||
|
// imgUrl="";
|
||||||
|
// }else{
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } catch (Exception e) {
|
||||||
|
//
|
||||||
|
// logger.warn("getPageImg 失败,url:"+url,e.getMessage());
|
||||||
|
// }
|
||||||
|
// return imgUrl;
|
||||||
|
// }
|
||||||
|
/**
|
||||||
|
* @auther: Wang
|
||||||
|
* @date: 2020/02/14 15:35
|
||||||
|
* 功能描述:查询URL的 最新信息
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static Map<String, String> getCollectFromUrl(String url){
|
||||||
|
Map<String, String> result = new HashMap<String, String>();
|
||||||
|
try {
|
||||||
|
result.put("url", url);
|
||||||
|
|
||||||
|
Connection connection = Jsoup.connect(url).userAgent(Const.userAgent);
|
||||||
|
connection.header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||||
|
connection.header("Accept-Encoding", "gzip, deflate, sdch");
|
||||||
|
connection.header("Accept-Language", "zh-CN,zh;q=0.8");
|
||||||
|
connection.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36");
|
||||||
|
Document doc = connection.get();
|
||||||
|
String title = doc.title();
|
||||||
|
if(StringUtils.isNotBlank(title)){
|
||||||
|
result.put("title", title);
|
||||||
|
}
|
||||||
|
String charset = doc.charset().name();
|
||||||
|
if(StringUtils.isBlank(charset)){
|
||||||
|
Elements eles = doc.select("meta[http-equiv=Content-Type]");
|
||||||
|
Iterator<Element> itor = eles.iterator();
|
||||||
|
while (itor.hasNext()){
|
||||||
|
charset = matchCharset(itor.next().toString().toUpperCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(StringUtils.isBlank(charset)){
|
||||||
|
result.put("charset", charset);
|
||||||
|
}
|
||||||
|
Elements metas = doc.head().select("meta");
|
||||||
|
for (Element meta : metas) {
|
||||||
|
String content = meta.attr("content");
|
||||||
|
if ("description".equalsIgnoreCase(meta.attr("name"))) {
|
||||||
|
result.put("description", content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//result.put("logoUrl", getImge(url));
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("文章解析出错:",e);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
/**
|
||||||
|
* 一层,只输出url及对应的title或描述
|
||||||
|
* @param in
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Map<String, String> parseHtmlOne(InputStream in){
|
||||||
|
Map<String, String> map = new HashMap<String, String>();
|
||||||
|
try {
|
||||||
|
Document doc = Jsoup.parse(in, "UTF-8", "");
|
||||||
|
Elements metas = doc.select("a");
|
||||||
|
for (Element meta : metas) {
|
||||||
|
String url = meta.attr("href");
|
||||||
|
if(url.startsWith("http")){
|
||||||
|
map.put(url, meta.text());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("解析html 文件异常:",e);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 两层(文件夹<url+title或描述>)
|
||||||
|
* @param HTML
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Map<String, Map<String, String>> parseHtml(InputStream HTML){
|
||||||
|
Map<String, Map<String, String>> resultMap = new HashMap<String, Map<String, String>>();
|
||||||
|
try {
|
||||||
|
Document doc = Jsoup.parse(HTML, "UTF-8", "");
|
||||||
|
Elements metasdts = doc.select("dt");
|
||||||
|
for(Element dt : metasdts){
|
||||||
|
String favoritesName = "";
|
||||||
|
Elements dtcs = dt.children();
|
||||||
|
Map<String, String> map = new HashMap<String, String>();
|
||||||
|
for(Element dt1 : dtcs){
|
||||||
|
if("h3".equalsIgnoreCase(dt1.nodeName())){
|
||||||
|
favoritesName = dt1.text();
|
||||||
|
}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")){
|
||||||
|
map.put(url, dt11.child(0).text());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(StringUtils.isNotBlank(favoritesName) && map.size() > 0){
|
||||||
|
resultMap.put(favoritesName, map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("解析html文件异常:",e);
|
||||||
|
}
|
||||||
|
return resultMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按照文档结构输出(TODO)
|
||||||
|
*/
|
||||||
|
public static Map<String, List<Map>> importHtmlMore(InputStream in){
|
||||||
|
Map<String, List<Map>> resultMap = new HashMap<String, List<Map>>();
|
||||||
|
try {
|
||||||
|
Document doc = Jsoup.parse(in, "UTF-8", "");
|
||||||
|
Elements bodys = doc.child(0).children();
|
||||||
|
|
||||||
|
for(Element body : bodys){
|
||||||
|
if("body".equalsIgnoreCase(body.nodeName())){
|
||||||
|
Elements dls = body.children();
|
||||||
|
for(Element dl : dls){
|
||||||
|
if("dl".equalsIgnoreCase(dl.nodeName())){
|
||||||
|
resultMap = parseElements(dl,resultMap);
|
||||||
|
System.out.println("resultMap:" + resultMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("解析html文件异常:",e);
|
||||||
|
}
|
||||||
|
return resultMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, List<Map>> parseElements(Element element,Map<String, List<Map>> resultMap){
|
||||||
|
Map<String, Map> favoritesMap = new HashMap<String, Map>();
|
||||||
|
Map<String, String> urlMap = new HashMap<String, String>();
|
||||||
|
String favoritesName = "";
|
||||||
|
Elements dts = element.children();
|
||||||
|
for(Element dt : dts){
|
||||||
|
if("dt".equalsIgnoreCase(dt.nodeName())){
|
||||||
|
Elements dtas = dt.children();
|
||||||
|
for(Element a : dtas){
|
||||||
|
if("a".equalsIgnoreCase(a.nodeName())){
|
||||||
|
String url = a.attr("href");
|
||||||
|
if(url.startsWith("http")){
|
||||||
|
urlMap.put(url, a.text());
|
||||||
|
favoritesName=a.parent().parent().parent().child(0).text();
|
||||||
|
System.out.println("目录:"+favoritesName);
|
||||||
|
logger.error("目录:",favoritesName);
|
||||||
|
}
|
||||||
|
}else if("dl".equalsIgnoreCase(a.nodeName())){
|
||||||
|
resultMap = parseElements(a,resultMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(StringUtils.isNotBlank(favoritesName)){
|
||||||
|
favoritesMap.put(favoritesName, urlMap);
|
||||||
|
}
|
||||||
|
List<Map> mapList = null;
|
||||||
|
Element parment = element.parent().parent().parent().child(0);
|
||||||
|
if("h3".equalsIgnoreCase(parment.nodeName())){
|
||||||
|
String name = parment.text();
|
||||||
|
if(resultMap.containsKey(name)){
|
||||||
|
mapList = resultMap.get(name);
|
||||||
|
mapList.add(favoritesMap);
|
||||||
|
}else{
|
||||||
|
mapList = new ArrayList<Map>();
|
||||||
|
mapList.add(favoritesMap);
|
||||||
|
}
|
||||||
|
resultMap.put(name, mapList);
|
||||||
|
}
|
||||||
|
return resultMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// public static StringBuilder exportHtml(String title,StringBuilder body){
|
||||||
|
// StringBuilder sb = new StringBuilder();
|
||||||
|
// sb.append("<HTML>");
|
||||||
|
// sb.append("<HEAD>");
|
||||||
|
// sb.append("<TITLE>"+title+"</TITLE>");
|
||||||
|
// sb.append("<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=utf-8\" />");
|
||||||
|
// sb.append("</HEAD>");
|
||||||
|
// sb.append("<BODY><H1>"+title+"</H1>");
|
||||||
|
// sb.append(body);
|
||||||
|
// sb.append("</BODY>");
|
||||||
|
//
|
||||||
|
// return sb;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
public static String matchCharset(String content) {
|
||||||
|
Pattern p = Pattern.compile("(?<=charset=)(.+)(?=\")");
|
||||||
|
Matcher m = p.matcher(content);
|
||||||
|
if (m.find()){
|
||||||
|
return m.group();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// // 图片下载
|
||||||
|
// private static String download(String url) {
|
||||||
|
// try {
|
||||||
|
// String imageName = url.substring(url.lastIndexOf("/") + 1,
|
||||||
|
// url.length());
|
||||||
|
//
|
||||||
|
// URL uri = new URL(url);
|
||||||
|
// InputStream in = uri.openStream();
|
||||||
|
// String dirName = "static/temp/";
|
||||||
|
// File dirFile = new File(dirName);
|
||||||
|
// if(!dirFile.isDirectory()){
|
||||||
|
// dirFile.mkdir();
|
||||||
|
// }
|
||||||
|
// String fileName = dirName+imageName;
|
||||||
|
// File file = new File(dirFile,imageName);
|
||||||
|
// FileOutputStream fo = new FileOutputStream(file);
|
||||||
|
// byte[] buf = new byte[1024];
|
||||||
|
// int length = 0;
|
||||||
|
// while ((length = in.read(buf, 0, buf.length)) != -1) {
|
||||||
|
// fo.write(buf, 0, length);
|
||||||
|
// }
|
||||||
|
// in.close();
|
||||||
|
// fo.close();
|
||||||
|
// return fileName;
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * 判断链接是否失效
|
||||||
|
// * @param url
|
||||||
|
// * @return
|
||||||
|
// */
|
||||||
|
// public static boolean isConnect(String url){
|
||||||
|
// HttpURLConnection connection;
|
||||||
|
// int counts = 0;
|
||||||
|
// boolean flag = false;
|
||||||
|
// if (url == null || url.length() <= 0) {
|
||||||
|
// return flag;
|
||||||
|
// }
|
||||||
|
// while (counts < 5) {
|
||||||
|
// try {
|
||||||
|
// connection = (HttpURLConnection) new URL(url).openConnection();
|
||||||
|
// int state = connection.getResponseCode();
|
||||||
|
// if (state == 200) {
|
||||||
|
// flag = true;
|
||||||
|
// }
|
||||||
|
// break;
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// counts++;
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return flag;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @auther: Wang
|
||||||
|
// * @date: 2020/02/15 14:44
|
||||||
|
// * 功能描述:分割书签URL 得到官网主机
|
||||||
|
// * @return
|
||||||
|
// */
|
||||||
|
public static String Urlutils(URL url) throws MalformedURLException {
|
||||||
|
String host = url.getHost();// 获取主机名
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
}
|
@ -159,6 +159,13 @@ export const constantRoutes = [
|
|||||||
meta:{
|
meta:{
|
||||||
requireAuth: false,//加该字段,表示进入这个路由是需要登录的true
|
requireAuth: false,//加该字段,表示进入这个路由是需要登录的true
|
||||||
},
|
},
|
||||||
|
},{
|
||||||
|
path: '/importHtml',
|
||||||
|
name: 'importHtml',
|
||||||
|
component: resolve => require(['../views/bookmark/common/ImportHtml.vue'], resolve),
|
||||||
|
meta:{
|
||||||
|
requireAuth: true,//加该字段,表示进入这个路由是需要登录的true
|
||||||
|
},
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
|
175
ruoyi-ui/src/views/bookmark/common/ImportHtml.vue
Normal file
175
ruoyi-ui/src/views/bookmark/common/ImportHtml.vue
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<!-- 用户导入对话框 -->
|
||||||
|
<!-- <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>-->
|
||||||
|
<el-upload
|
||||||
|
ref="upload"
|
||||||
|
:limit="1"
|
||||||
|
accept=".html"
|
||||||
|
:headers="upload.headers"
|
||||||
|
:action="upload.url + '?updateSupport=' + 222"
|
||||||
|
:disabled="upload.isUploading"
|
||||||
|
:on-progress="handleFileUploadProgress"
|
||||||
|
:on-success="handleFileSuccess"
|
||||||
|
:auto-upload="false"
|
||||||
|
name="htmlFile"
|
||||||
|
drag
|
||||||
|
class="upload-demo"
|
||||||
|
>
|
||||||
|
<i class="el-icon-upload"></i>
|
||||||
|
<div class="el-upload__text">
|
||||||
|
将文件拖到此处,或
|
||||||
|
<em>点击上传</em>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="el-upload__tip" slot="tip">-->
|
||||||
|
<!-- <el-checkbox v-model="upload.updateSupport" />是否更新已经存在的用户数据-->
|
||||||
|
<!-- <el-link type="info" style="font-size:12px" @click="importTemplate">下载模板</el-link>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<div class="el-upload__tip" style="color:red" slot="tip">提示:仅允许导入".html"格式文件!</div>
|
||||||
|
</el-upload>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="submitFileForm">确 定</el-button>
|
||||||
|
<!-- <el-button @click="upload.open = false">取 消</el-button>-->
|
||||||
|
</div>
|
||||||
|
<!-- </el-dialog>-->
|
||||||
|
|
||||||
|
<!-- <el-button-->
|
||||||
|
<!-- type="info"-->
|
||||||
|
<!-- icon="el-icon-upload2"-->
|
||||||
|
<!-- size="mini"-->
|
||||||
|
<!-- @click="handleImport"-->
|
||||||
|
<!-- v-hasPermi="['system:user:import']"-->
|
||||||
|
<!-- >导入</el-button>-->
|
||||||
|
|
||||||
|
<!-- <el-upload-->
|
||||||
|
<!-- ref="upload"-->
|
||||||
|
<!-- :limit="1"-->
|
||||||
|
<!-- accept=".html"-->
|
||||||
|
<!-- class="upload-demo"-->
|
||||||
|
<!-- :headers="upload.headers"-->
|
||||||
|
<!-- :action="upload.url + '?updateSupport=' + 22"-->
|
||||||
|
<!-- name="htmlFile"-->
|
||||||
|
<!-- :on-progress="handleFileUploadProgress"-->
|
||||||
|
<!-- :on-success="handleFileSuccess"-->
|
||||||
|
<!-- :auto-upload="false"-->
|
||||||
|
|
||||||
|
<!-- drag-->
|
||||||
|
<!-- >-->
|
||||||
|
<!--<!– v-hasPermi="['bookmark:bookmark:export']"–>-->
|
||||||
|
<!-- <i class="el-icon-upload"></i>-->
|
||||||
|
<!-- <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>-->
|
||||||
|
<!-- <div class="el-upload__tip" slot="tip">只能上传浏览器导出的.html后缀文件</div>-->
|
||||||
|
<!-- </el-upload>-->
|
||||||
|
|
||||||
|
<!-- <div class="structure">-->
|
||||||
|
<!-- <el-radio v-model="structure" label="0">按原目录导入</el-radio>-->
|
||||||
|
<!-- <el-radio v-model="structure" label="1" disabled>全部导入到一个新目录</el-radio>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!--<el-button type="primary" size="small" @click="submitUpload" plain><i-->
|
||||||
|
<!--class="el-icon-upload el-icon--right">开始导入书签</i></el-button>-->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="text">
|
||||||
|
<ul>
|
||||||
|
<li>注意事项</li>
|
||||||
|
<li style="color: #ff2a34">导入300书签需要大约8分钟,请勿短时间重复操作</li>
|
||||||
|
<li>
|
||||||
|
1、导入的方法是将浏览器里面收藏的网站导出<span style="color: red">HTML文件后缀</span>。然后将导出的HTML文件点击上面的<span style="color: red">开始导入书签</span>。
|
||||||
|
|
||||||
|
<li>2、目前只测试过谷歌浏览器书签导入。但是因为浏览器的标签是可以支持互相导入的。如果不成功,可以先将其他浏览器的书签导入谷歌浏览器再导出。</li>
|
||||||
|
|
||||||
|
<li>3、浏览器导出书签方法请百度</li>
|
||||||
|
|
||||||
|
<li>4、支持浏览器的目录结构,本站目录支持无限级别分类</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import { getToken } from "@/utils/auth";
|
||||||
|
export default {
|
||||||
|
name: "",
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 用户导入参数
|
||||||
|
upload: {
|
||||||
|
// 是否显示弹出层(用户导入)
|
||||||
|
open: false,
|
||||||
|
// 弹出层标题(用户导入)
|
||||||
|
title: "书签导入",
|
||||||
|
// 是否禁用上传
|
||||||
|
isUploading: false,
|
||||||
|
// 是否更新已经存在的用户数据
|
||||||
|
updateSupport: 0,
|
||||||
|
// 设置上传的请求头部
|
||||||
|
headers: { Authorization: "Bearer " + getToken() },
|
||||||
|
// 上传的地址
|
||||||
|
url: process.env.VUE_APP_BASE_API + "/IO/import"
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
/** 导入按钮操作 */
|
||||||
|
handleImport() {
|
||||||
|
this.upload.title = "书签导入";
|
||||||
|
this.upload.open = true;
|
||||||
|
},
|
||||||
|
// 文件上传中处理
|
||||||
|
handleFileUploadProgress(event, file, fileList) {
|
||||||
|
this.upload.isUploading = true;
|
||||||
|
},
|
||||||
|
// 文件上传成功处理
|
||||||
|
handleFileSuccess(response, file, fileList) {
|
||||||
|
this.upload.open = false;
|
||||||
|
this.upload.isUploading = false;
|
||||||
|
this.$refs.upload.clearFiles();
|
||||||
|
this.$alert(response.msg, "导入结果", { dangerouslyUseHTMLString: true });
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
// 提交上传文件
|
||||||
|
submitFileForm() {
|
||||||
|
this.$refs.upload.submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.text{
|
||||||
|
border: #6f7180 1px solid;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-top: 10px;
|
||||||
|
background-color: #e9e9e9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.structure {
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Import {
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Import el-button {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
ul{
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
li{
|
||||||
|
list-style:none;
|
||||||
|
}
|
||||||
|
</style>
|
@ -24,7 +24,11 @@
|
|||||||
<div class="reminder">工具箱</div>
|
<div class="reminder">工具箱</div>
|
||||||
<div class="aside-title"><i class="el-icon-s-tools"></i><span>收藏同步</span></div>
|
<div class="aside-title"><i class="el-icon-s-tools"></i><span>收藏同步</span></div>
|
||||||
<div class="aside-title"><i class="el-icon-help"></i><span>发现书签</span></div>
|
<div class="aside-title"><i class="el-icon-help"></i><span>发现书签</span></div>
|
||||||
<div class="aside-title"><i class="el-icon-s-platform"></i><span>任意门</span></div>
|
<router-link :to="{ name: 'importHtml' }">
|
||||||
|
<div class="aside-title">
|
||||||
|
<i class="el-icon-s-platform"></i><span>导入书签</span>
|
||||||
|
</div>
|
||||||
|
</router-link>
|
||||||
<div class="aside-title"><i class="el-icon-message-solid"></i><span>收件箱</span></div>
|
<div class="aside-title"><i class="el-icon-message-solid"></i><span>收件箱</span></div>
|
||||||
|
|
||||||
<!-- <el-footer class="aside-navigation">-->
|
<!-- <el-footer class="aside-navigation">-->
|
||||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user