From cd55a8b2a5aea88e630667e8456b690b9660369c Mon Sep 17 00:00:00 2001 From: WangHao <43278047@qq.com> Date: Sat, 20 Nov 2021 02:15:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E4=B9=A6=E7=AD=BE=E7=9A=84?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E5=92=8C=E8=87=AA=E5=8A=A8=E5=A4=87=E4=BB=BD?= =?UTF-8?q?=E5=88=B0=E7=99=BE=E5=BA=A6=E4=BA=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ruoyi-admin/pom.xml | 2 +- .../yunbookmark/SqBookmarkController.java | 15 +- .../web/test/controller/BaiDuWangPan.java | 143 ----- .../ruoyi/web/test/controller/HtmlTest.java | 136 ----- .../controller/baiduyunpan/BaiDuWangPan.java | 171 ++++++ .../test/controller/baiduyunpan/Constant.java | 58 ++ .../controller/baiduyunpan/FileSizeUtil.java | 183 ++++++ .../{ => baiduyunpan}/FileUtilsBaidu.java | 36 +- .../baiduyunpan/FileUtilsBaiduBeack.java | 558 +++++++++++++++++ .../test/controller/{ => bookmark}/22.html | 0 .../test/controller/bookmark/HtmlTest.java | 228 +++++++ .../test/controller/{ => bookmark}/模板.html | 0 .../src/main/resources/application-druid.yml | 6 +- .../ruoyi/common/utils/file/FileUtils.java | 32 +- .../common/utils/file/MimeTypeUtils.java | 8 +- .../ruoyi/common/utils/http/HttpUtils.java | 47 +- ruoyi-ui/build/index.js | 70 +-- ruoyi-ui/src/permission.js | 128 ++-- ruoyi-ui/src/views/daohang/index/index.vue | 107 +++- .../bookmark/service/ISqBookmarkService.java | 8 + .../service/impl/SqBookmarkServiceImpl.java | 19 + yunpan-baidu/pom.xml | 4 + .../main/java/com/ruoyi/BackupsYunPan.java | 27 + .../java/com/ruoyi/BackupsYunPanImpl.java | 19 + .../servise/BaiduWangPanServise.java | 2 +- .../servise/impl/BaiduWangPanServiseImpl.java | 4 +- .../ruoyi/baiduyunpan/utils}/Constant.java | 21 +- .../baiduyunpan/utils}/FileSizeUtil.java | 2 +- .../baiduyunpan/utils/FileUtilsBaidu.java | 569 ++++++++++++++++++ 29 files changed, 2142 insertions(+), 461 deletions(-) delete mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/BaiDuWangPan.java delete mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/HtmlTest.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/baiduyunpan/BaiDuWangPan.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/baiduyunpan/Constant.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/baiduyunpan/FileSizeUtil.java rename ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/{ => baiduyunpan}/FileUtilsBaidu.java (95%) create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/baiduyunpan/FileUtilsBaiduBeack.java rename ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/{ => bookmark}/22.html (100%) create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/bookmark/HtmlTest.java rename ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/{ => bookmark}/模板.html (100%) create mode 100644 yunpan-baidu/src/main/java/com/ruoyi/BackupsYunPan.java create mode 100644 yunpan-baidu/src/main/java/com/ruoyi/BackupsYunPanImpl.java rename yunpan-baidu/src/main/java/com/ruoyi/{baidu => baiduyunpan}/servise/BaiduWangPanServise.java (97%) rename yunpan-baidu/src/main/java/com/ruoyi/{baidu => baiduyunpan}/servise/impl/BaiduWangPanServiseImpl.java (95%) rename {ruoyi-admin/src/main/java/com/ruoyi/web/test/controller => yunpan-baidu/src/main/java/com/ruoyi/baiduyunpan/utils}/Constant.java (69%) rename {ruoyi-admin/src/main/java/com/ruoyi/web/test/controller => yunpan-baidu/src/main/java/com/ruoyi/baiduyunpan/utils}/FileSizeUtil.java (99%) create mode 100644 yunpan-baidu/src/main/java/com/ruoyi/baiduyunpan/utils/FileUtilsBaidu.java diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index 86e2edbd7..cd781ece1 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -102,7 +102,7 @@ <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> - <version>2.1.1.RELEASE</version> +<!-- <version>2.1.1.RELEASE</version>--> <configuration> <fork>true</fork> <!-- 如果没有该配置,devtools不会生效 --> </configuration> diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/yunbookmark/SqBookmarkController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/yunbookmark/SqBookmarkController.java index 1c317437a..ec54ef323 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/yunbookmark/SqBookmarkController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/yunbookmark/SqBookmarkController.java @@ -76,9 +76,9 @@ public class SqBookmarkController extends BaseController startPage(); List<SqBookmark> list = sqBookmarkService.selectByUrlUserID(url,getAuthUser().getUserId()); if (list!=null&&!list.isEmpty()){ - return AjaxResult.success(list.get(0)); + return AjaxResult.success(true); } - return AjaxResult.success(list); + return AjaxResult.success(false); } @@ -201,6 +201,17 @@ public class SqBookmarkController extends BaseController return toAjax(sqBookmarkService.deleteSqBookmarkByIds(bookmarkIds)); } + /** + * 删除书签 根据URL删除 + */ + @PreAuthorize("@ss.hasPermi('bookmark:bookmark:common:remove')") + @DeleteMapping("/deleteByurl") + public AjaxResult deleteByurl(String url) + { + return AjaxResult.success("success"); +// return sqBookmarkService.deleteByUrl(getAuthUser().getUserId(),url); + } + /** * 用户-根据标签查询书签分页 diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/BaiDuWangPan.java b/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/BaiDuWangPan.java deleted file mode 100644 index 458fee047..000000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/BaiDuWangPan.java +++ /dev/null @@ -1,143 +0,0 @@ -package com.ruoyi.web.test.controller; - - -import cn.hutool.http.HttpUtil; -import com.alibaba.fastjson.JSONObject; -import com.ruoyi.baidu.servise.BaiduWangPanServise; -import com.ruoyi.common.constant.BaiduUrl; -import org.apache.commons.codec.digest.DigestUtils; -import org.junit.Test; -import org.springframework.beans.factory.annotation.Autowired; - -import java.io.*; -import java.util.HashMap; - -/** - * @Auther: Wang - * @Date: 2021/07/24 22:37 - * 功能描述: - * //教程 - * //https://blog.csdn.net/admans/article/details/80653490 - */ -public class BaiDuWangPan extends BaseSpringBootTest{ - - @Autowired - private BaiduWangPanServise baiduWangPanServise; - - private static String access_token = "123.5f2c72c8c2106a3baa177de77331b1d1.YnelNhviWQotgsooAt63iCRbaqZrjEP0Qgj3nIx.jMfNkQ"; - - - // 获取用户信息 - @Test - public void getUser() { - String result = baiduWangPanServise.getUserInfo(access_token); - JSONObject object = JSONObject.parseObject(result); - System.out.println("result:" + result); - System.out.println("baidu_name:" + object.get("baidu_name")); - System.out.println("netdisk_name:" + object.get("netdisk_name")); - } - - // 获取容量 - @Test - public void getCapacity() { - String result = baiduWangPanServise.getCapacity(access_token); - System.out.println("result:" + result); - } - - - // 上传文件 - @Test - public void addFile() { - - //预上传、分片上传、创建文件 - String md5 = ""; - try { - md5 = DigestUtils.md5Hex(new FileInputStream(new File("D:\\Wang\\22.txt"))); - } catch (IOException e) { - e.printStackTrace(); - } - //预上传 获取ID - - HashMap<String, Object> paramMap = new HashMap<>(); - paramMap.put("access_token", access_token); - paramMap.put("path", "/apps/藏趣云/22.txt"); - paramMap.put("size", "1");//文件或目录的大小,单位B - paramMap.put("isdir", "0");//是否目录,0 文件、1 目录 - paramMap.put("block_list", "[\"" + md5 + "\"]"); - paramMap.put("autoinit", 1); - String result = HttpUtil.post("https://pan.baidu.com/rest/2.0/xpan/file?method=precreate&access_token" + access_token, paramMap); - System.out.println("result:" + result); - - JSONObject object = JSONObject.parseObject(result); - String uploadid = object.getString("uploadid"); - System.out.println("uploadid:" + uploadid); - - - //上传文件 - HashMap<String, Object> paramMap1 = new HashMap<>(); -// paramMap1.put("file", ReadFileToCharArray("D:\\Wang\\22.txt")); - paramMap1.put("file", new File("D:\\Wang\\22.txt")); - - System.out.println("file:" + paramMap1.get("file").toString()); - -// String result2 = HttpUtil.post("https://d.pcs.baidu.com/rest/2.0/pcs/superfile2?access_token=" + access_token + "&method=upload&type=tmpfile&path=%2Fapps%2F%E8%97%8F%E8%B6%A3%E4%BA%91%2F22.txt&partseq=0&uploadid=" + uploadid, paramMap1); -// System.out.println("result2:" + result2); - String url = Constant.SLICING_UPLOAD_FILE_URL + "?method=upload" + - "&access_token=" + Constant.ATOKEN + - "&type=tmpfile&partseq=0" + - "&path=" + Constant.APP_PATH + "22.txt" + - "&uploadid=" + uploadid; - String result2 = FileUtilsBaidu.sendFile(url,new File("D:\\Wang\\22.txt")); - System.out.println("result2:" + result2); - - //创建文件 - HashMap<String, Object> paramMap3 = new HashMap<>(); -// paramMap1.put("file", ReadFileToCharArray("D:\\Wang\\22.txt")); - paramMap3.put("path", "/apps/藏趣云/22.txt"); - paramMap3.put("size", 6); - paramMap3.put("isdir", 0); - - - String result3 = HttpUtil.post("https://pan.baidu.com/rest/2.0/xpan/file?method=create&access_token=" + access_token, paramMap3); - System.out.println("result3:" + result3); - - - } - - - - - - - - - - - - - - - - - - //将文件转换成char[]数组 - public static char[] ReadFileToCharArray(String filePath) throws IOException { - StringBuilder fileData = new StringBuilder(1000); - BufferedReader reader = new BufferedReader(new FileReader(filePath)); - - char[] buf = new char[10]; - int numRead = 0; - while ((numRead = reader.read(buf)) != -1) { - System.out.println(numRead); - String readData = String.valueOf(buf, 0, numRead); - fileData.append(readData); - buf = new char[1024]; - } - - reader.close(); - - return fileData.toString().toCharArray(); - } - - -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/HtmlTest.java b/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/HtmlTest.java deleted file mode 100644 index a5edddb6a..000000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/HtmlTest.java +++ /dev/null @@ -1,136 +0,0 @@ -package com.ruoyi.web.test.controller; - -import cn.hutool.core.date.DateUtil; -import cn.hutool.http.HtmlUtil; -import com.ruoyi.bookmark.domain.SqBookmark; -import com.ruoyi.bookmark.domain.SqMenu; -import com.ruoyi.bookmark.service.ISqBookmarkService; -import com.ruoyi.bookmark.service.ISqMenuService; -import com.ruoyi.common.utils.StringUtils; -import org.junit.Test; -import org.springframework.beans.factory.annotation.Autowired; - -import javax.servlet.http.HttpServletResponse; -import java.io.File; -import java.io.FileOutputStream; -import java.io.OutputStream; -import java.text.SimpleDateFormat; -import java.util.*; -import java.util.stream.Collectors; - -/** - * @Auther: Wang - * @Date: 2021/04/19 21:16 - * 功能描述: - */ -public class HtmlTest extends BaseSpringBootTest { - - @Autowired - private ISqMenuService iSqMenuService; - @Autowired - private ISqBookmarkService iSqBookmarkService; - - @Test - public void test3() { - String favoritesId = "2"; - - if(StringUtils.isNotBlank(favoritesId)) - { - HttpServletResponse response=null; - try { - String fileName = "cqy_" + DateUtil.now() + ".html"; - StringBuilder sb = new StringBuilder(); - sb.append("<!DOCTYPE NETSCAPE-Bookmark-file-1>\n" + - "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\">\n" + - "<TITLE>Bookmarks</TITLE>\n" + - "<H1>Bookmarks</H1>"); - sb.append("<DL>\n"); - sb.append(exportToHtml(1L)); - sb.append("</DL>\n"); - //1:使用File类创建一个要操作的文件路径 - File file = new File("D:" + File.separator + "demo" + File.separator + fileName); - if(!file.getParentFile().exists()){ //如果文件的目录不存在 - file.getParentFile().mkdirs(); //创建目录 - - } - //2: 实例化OutputString 对象 - OutputStream output = new FileOutputStream(file); - - //3: 准备好实现内容的输出 - //将字符串变为字节数组 - byte data[] = sb.toString().getBytes(); - output.write(data); - //4: 资源操作的最后必须关闭 - output.close(); - - } catch (Exception e) { - logger.error("异常:", e); - } - } - } - - - /** - * 导出到html文件 - * @param - */ - public StringBuilder exportToHtml(Long userId){ - - SqMenu sqMenu=new SqMenu(); - sqMenu.setUserId(userId); - SqBookmark sqBookmark = new SqBookmark(); - sqBookmark.setUserid(userId); - //目录 - List<SqMenu> menuList = iSqMenuService.selectSqMenuList(sqMenu); - Map<Long, List<SqMenu>> mapMenu = menuList.stream().collect(Collectors.groupingBy(SqMenu::getParentId)); - //书签 - List<SqBookmark> bookMarkList = iSqBookmarkService.selectSqBookmarkList(sqBookmark); - Map<Long, List<SqBookmark>> mapBookMark = bookMarkList.stream().collect(Collectors.groupingBy(SqBookmark::getMenuId)); - - List<SqMenu> sqMenuList = mapMenu.get(0L); - StringBuilder str = new StringBuilder(); - str = traverseFile_recursion(sqMenuList,str,mapBookMark,mapMenu); - return str; - } - - - - - /** - * @Description:递归书签导出功能 - * - * @param * @param sqMenuList - * @param str - * @param mapBookMark - * @param mapMenu - * @return java.lang.StringBuilder - * @Date - * @author: wanghao - * - */ - public StringBuilder traverseFile_recursion (List<SqMenu> sqMenuList,StringBuilder str,Map<Long, List<SqBookmark>> mapBookMark,Map<Long, List<SqMenu>> mapMenu) { - - if (sqMenuList != null && !sqMenuList.isEmpty()) { - for (SqMenu f : sqMenuList) { - str.append("<DT><H3 ADD_DATE=\"1584277207\" LAST_MODIFIED=\"0\">").append(f.getMenuName()).append("</H3>\n"); - str.append("<DL>\n"); - List<SqBookmark> bookmarksList = mapBookMark.get(f.getMenuId()); - if (bookmarksList != null && !bookmarksList.isEmpty()) { - for (SqBookmark b : bookmarksList) { - str.append("<DT><A HREF=\""+b.getUrl()+"\" TARGET=\"_blank\">"+b.getTitle()+"</A>\n"); - } - } - traverseFile_recursion(mapMenu.get(f.getMenuId()),str,mapBookMark,mapMenu); - str.append("</DL>\n"); - } - } - return str; - } - - - - - - - -} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/baiduyunpan/BaiDuWangPan.java b/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/baiduyunpan/BaiDuWangPan.java new file mode 100644 index 000000000..32ae0cb9e --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/baiduyunpan/BaiDuWangPan.java @@ -0,0 +1,171 @@ +package com.ruoyi.web.test.controller.baiduyunpan; + + +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSONObject; +import com.ruoyi.BackupsYunPan; +import com.ruoyi.baiduyunpan.servise.BaiduWangPanServise; +import com.ruoyi.common.utils.http.HttpUtils; +import com.ruoyi.web.test.controller.BaseSpringBootTest; +import org.apache.commons.codec.digest.DigestUtils; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.io.*; +import java.util.HashMap; + +/** + * @Auther: Wang + * @Date: 2021/07/24 22:37 + * 功能描述: + * //教程 + * + */ +public class BaiDuWangPan extends BaseSpringBootTest { + + @Autowired + private BaiduWangPanServise baiduWangPanServise; + @Autowired + private BackupsYunPan backupsYunPan; + + private static String access_token = Constant.ATOKEN; + + + @Test + public void ss(){ + //百度 备份 + backupsYunPan.BaiDuYunBackups("D:\\data\\ces\\","day4_MySQL性能优化总结.zip",Constant.ATOKEN); + } + + // 获取用户信息 + @Test + public void getUser() { + String result = baiduWangPanServise.getUserInfo(Constant.ATOKEN); + JSONObject object = JSONObject.parseObject(result); + System.out.println("result:" + result); + System.out.println("baidu_name:" + object.get("baidu_name")); + System.out.println("netdisk_name:" + object.get("netdisk_name")); + } + + // 获取容量 + @Test + public void getCapacity() { + String result = baiduWangPanServise.getCapacity(access_token); + System.out.println("result:" + result); + } + + + // 上传文件 + @Test + //预上传 >> 分片上传 >> 创建文件 + // 废弃 FileUtilsBaidu 参考这个 类 + public void addFile() { + + String fileName = "22.txt"; + String userPath = "D:\\Wang\\" + fileName; + String token = Constant.ATOKEN; + + + //第一步:预上传 + //对于大文件 需要吧他分成多份(小于4M),然后计算每份的MD5弄成数组 + String md5 = ""; + try { + md5 = DigestUtils.md5Hex(new FileInputStream(new File(userPath))); + + + HashMap<String, Object> postParamMap = new HashMap<>(); + postParamMap.put("access_token", token); + postParamMap.put("path", "/apps/藏趣云/22.txt"); + postParamMap.put("size", 7);//文件或目录的大小,单位B + postParamMap.put("isdir", "0");//是否目录,0 文件、1 目录 + postParamMap.put("block_list", "[\"" + md5 + "\"]"); + postParamMap.put("autoinit", 1); + + HashMap<String, String> getParamMap = new HashMap<>(); + getParamMap.put("method","precreate"); + getParamMap.put("access_token",token); + + String precreateUrl = HttpUtils.initUriPathParams(Constant.FILE_MANAGER_URL,getParamMap); + String result = HttpUtil.post(precreateUrl, postParamMap); + System.out.println("result:" + result); + String uploadid = JSONObject.parseObject(result).getString("uploadid"); + System.out.println("uploadid:" + uploadid); + + //第二步:分片上传 + HashMap<String, String> superfile2Map = new HashMap<>(); + superfile2Map.put("method", "upload"); + superfile2Map.put("access_token", token); + superfile2Map.put("type", "tmpfile"); + superfile2Map.put("partseq", "0"); + superfile2Map.put("path", Constant.APP_PATH +fileName); + superfile2Map.put("uploadid", uploadid); + + System.out.println("superfile2Map:"+superfile2Map.values().toString()); + + String url = HttpUtils.initUriPathParams(Constant.SLICING_UPLOAD_FILE_URL,superfile2Map); + String result2 = FileUtilsBaidu.sendFile(url,new File(userPath)); + System.out.println("result2:" + result2); + + + //第三步;创建文件 + HashMap<String, Object> postCreateMap = new HashMap<>(); + postCreateMap.put("path", "/apps/藏趣云/22.txt"); + postCreateMap.put("size", 7); + postCreateMap.put("isdir", 0); + postCreateMap.put("rtype", 2); + postCreateMap.put("uploadid", uploadid); + postCreateMap.put("block_list", "[\"" + md5 + "\"]"); + + HashMap<String, String> getCreateMap = new HashMap<>(); + getParamMap.put("method","create"); + getParamMap.put("access_token",token); + + String CreateUrl = HttpUtils.initUriPathParams(Constant.FILE_MANAGER_URL,getParamMap); + + String result3 = HttpUtil.post(CreateUrl, postCreateMap); + System.out.println("result3:" + result3); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + + + + + + + + + + + + + + + + + //将文件转换成char[]数组 + public static char[] ReadFileToCharArray(String filePath) throws IOException { + StringBuilder fileData = new StringBuilder(1000); + BufferedReader reader = new BufferedReader(new FileReader(filePath)); + + char[] buf = new char[10]; + int numRead = 0; + while ((numRead = reader.read(buf)) != -1) { + System.out.println(numRead); + String readData = String.valueOf(buf, 0, numRead); + fileData.append(readData); + buf = new char[1024]; + } + + reader.close(); + + return fileData.toString().toCharArray(); + } + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/baiduyunpan/Constant.java b/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/baiduyunpan/Constant.java new file mode 100644 index 000000000..d089d0327 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/baiduyunpan/Constant.java @@ -0,0 +1,58 @@ +package com.ruoyi.web.test.controller.baiduyunpan; + +/** + * @Auther: Wang + * @Date: 2021/07/25 02:03 + * 功能描述: + * + * 文档API https://www.wenjiangs.com/doc/leikdy8r + * + */ +public interface Constant { + String APP_ID="24066444"; + String APP_NAME="藏趣云"; + String APP_KEY="7NpRdcorSxoqxIKAkzLXuOhVr8NQekA9"; + String SECRET_KEY="RfvvGbkN95CuXlaoZVzzsvGiz9Her6qq"; + String SING_key="dBpomXW%duC2L8l6MW3yTpaXhX=-8oj0"; + String APP_PATH="/apps/"+APP_NAME+"/"; + + //https://openapi.baidu.com/oauth/2.0/authorize?response_type=code&client_id=7NpRdcorSxoqxIKAkzLXuOhVr8NQekA9&redirect_uri=https://www.baidu.com/&scope=basic,netdisk&display=tv&qrcode=1&force_login=1 + //https://openapi.baidu.com/oauth/2.0/token?grant_type=authorization_code&code=0a291eb3fd3ed6ccc74cc46bc5540191&client_id=7NpRdcorSxoqxIKAkzLXuOhVr8NQekA9&client_secret=RfvvGbkN95CuXlaoZVzzsvGiz9Her6qq&redirect_uri=oob + //单位mb + // 普通用户单个分片大小固定为4MB(文件大小如果小于4MB,无需切片,直接上传即可),单文件总大小上限为4G。 + //普通会员用户单个分片大小上限为16MB,单文件总大小上限为10G。 + //超级会员用户单个分片大小上限为32MB,单文件总大小上限为20G。 + Integer UNIT=4; + + //获取授权码,需要扫码登陆 + String GET_CODE_URL="https://openapi.baidu.com/oauth/2.0/authorize?response_type=code&client_id="+APP_KEY+"&redirect_uri=oob&scope=basic,netdisk&display=tv&qrcode=1&force_login=1"; + + //获取到的授权码 + String CODE="0a291eb3fd3ed6ccc74cc46bc5540191"; + + //根据授权码换取token + String GET_TOKEN_BY_CODE="https://openapi.baidu.com/oauth/2.0/token?grant_type=authorization_code&code="+CODE+"&client_id="+APP_KEY+"&client_secret="+SECRET_KEY+"&redirect_uri=oob"; + + //"refresh_token": "122.035106ef57234db73fa1d6077df6b2a4.YD6wvL7Qcuh-Jsz3KUYhob9bYABdvCAAwf6pX3e.9r3fbA", + //"access_token": "121.1bbdb55745ea8eebdc6fe83f0481c676.YsAIaraM0JxC1aw_DEbopy8wLGK7mdg6mTGeR8Y.6nzOlA", + + //获取到的TOKEN + String RTOKEN="122.fec5f9d6dd1644c2c57c89cc510f7ec8.YBMpVZwjo9y5kSMFnVmSMJL9dj25T5X02gjLwV8.1J2sEw"; + String ATOKEN="121.1bbdb55745ea8eebdc6fe83f0481c676.YsAIaraM0JxC1aw_DEbopy8wLGK7mdg6mTGeR8Y.6nzOlA"; + + //操作文件 method = copy, mover, rename, delete + String FILE_MANAGER_URL="https://pan.baidu.com/rest/2.0/xpan/file"; + + //预上传 + String GET_READY_FILE_URL="https://pan.baidu.com/rest/2.0/xpan/file"; + + //分片上传 + String SLICING_UPLOAD_FILE_URL="https://d.pcs.baidu.com/rest/2.0/pcs/superfile2"; + + //下载文件 + String DOWN_LOUE_URL="https://pan.baidu.com/rest/2.0/xpan/multimedia"; + + //文件搜索 + String FILE_SEARCH="https://pan.baidu.com/rest/2.0/xpan/file?method=search"; + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/baiduyunpan/FileSizeUtil.java b/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/baiduyunpan/FileSizeUtil.java new file mode 100644 index 000000000..a4ff9538a --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/baiduyunpan/FileSizeUtil.java @@ -0,0 +1,183 @@ +package com.ruoyi.web.test.controller.baiduyunpan; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.text.DecimalFormat; + +/** + * @Auther: Wang + * @Date: 2021/07/25 17:51 + * 功能描述: + */ +public class FileSizeUtil { + private static final String TAG=FileSizeUtil.class.getSimpleName(); + + public static final int SIZETYPE_B = 1;//获取文件大小单位为B的double值 + public static final int SIZETYPE_KB = 2;//获取文件大小单位为KB的double值 + public static final int SIZETYPE_MB = 3;//获取文件大小单位为MB的double值 + public static final int SIZETYPE_GB = 4;//获取文件大小单位为GB的double值 + + /** + * @param @param imgPath + * @param @return 根据图片地址返回图片大小kb或者 Mb + * @return String + * @throws + * @Title: pathSize + * @add (default no) + */ + public static String pathSize(String imgPath) { + File file = new File(imgPath); + FileInputStream fis; + int fileLen = 0; + try { + fis = new FileInputStream(file); + fileLen = fis.available(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return String.valueOf(fileLen); + } + + /** + * 获取文件指定文件的指定单位的大小 + * + * @param filePath 文件路径 + * @param sizeType 获取大小的类型1为B、2为KB、3为MB、4为GB + * @return double值的大小 + */ + public static double getFileOrFilesSize(String filePath, int sizeType) { + File file = new File(filePath); + long blockSize = 0; + try { + if (file.isDirectory()) { + blockSize = getFileSizes(file); + } else { + blockSize = getFileSize(file); + } + } catch (Exception e) { + e.printStackTrace(); +// LogUtil.E(TAG,"获取文件大小失败!"); + } + return FormetFileSize(blockSize, sizeType); + } + + /** + * 调用此方法自动计算指定文件或指定文件夹的大小 + * + * @param filePath 文件路径 + * @return 计算好的带B、KB、MB、GB的字符串 + */ + public static String getAutoFileOrFilesSize(String filePath) { + File file = new File(filePath); + long blockSize = 0; + try { + if (file.isDirectory()) { + blockSize = getFileSizes(file); + } else { + blockSize = getFileSize(file); + } + } catch (Exception e) { + e.printStackTrace(); +// LogUtil.E(TAG,"获取文件大小失败!"); + } + return FormetFileSize(blockSize); + } + + /** + * 获取指定文件大小 + * + * @param file + * @return + * @throws Exception + */ + private static long getFileSize(File file) throws Exception { + long size = 0; + if (file.exists()) { + FileInputStream fis = null; + fis = new FileInputStream(file); + size = fis.available(); + } else { + file.createNewFile(); +// LogUtil.E(TAG,"获取文件大小不存在!"); + } + return size; + } + + /** + * 获取指定文件夹 + * + * @param f + * @return + * @throws Exception + */ + private static long getFileSizes(File f) throws Exception { + long size = 0; + File flist[] = f.listFiles(); + for (int i = 0; i < flist.length; i++) { + if (flist[i].isDirectory()) { + size = size + getFileSizes(flist[i]); + } else { + size = size + getFileSize(flist[i]); + } + } + return size; + } + + /** + * 转换文件大小 + * + * @param fileS + * @return + */ + private static String FormetFileSize(long fileS) { + DecimalFormat df = new DecimalFormat("#.00"); + String fileSizeString = ""; + String wrongSize = "0B"; + if (fileS == 0) { + return wrongSize; + } + if (fileS < 1024) { + fileSizeString = df.format((double) fileS) + "B"; + } else if (fileS < 1048576) { + fileSizeString = df.format((double) fileS / 1024) + "KB"; + } else if (fileS < 1073741824) { + fileSizeString = df.format((double) fileS / 1048576) + "MB"; + } else { + fileSizeString = df.format((double) fileS / 1073741824) + "GB"; + } + return fileSizeString; + } + + /** + * 转换文件大小,指定转换的类型 + * + * @param fileS + * @param sizeType + * @return + */ + private static double FormetFileSize(long fileS, int sizeType) { + DecimalFormat df = new DecimalFormat("#.00"); + double fileSizeLong = 0; + switch (sizeType) { + case SIZETYPE_B: + fileSizeLong = Double.valueOf(df.format((double) fileS)); + break; + case SIZETYPE_KB: + fileSizeLong = Double.valueOf(df.format((double) fileS / 1024)); + break; + case SIZETYPE_MB: + fileSizeLong = Double.valueOf(df.format((double) fileS / 1048576)); + break; + case SIZETYPE_GB: + fileSizeLong = Double.valueOf(df.format((double) fileS / 1073741824)); + break; + default: + break; + } + return fileSizeLong; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/FileUtilsBaidu.java b/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/baiduyunpan/FileUtilsBaidu.java similarity index 95% rename from ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/FileUtilsBaidu.java rename to ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/baiduyunpan/FileUtilsBaidu.java index 024400287..24501616a 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/FileUtilsBaidu.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/baiduyunpan/FileUtilsBaidu.java @@ -1,15 +1,13 @@ -package com.ruoyi.web.test.controller; +package com.ruoyi.web.test.controller.baiduyunpan; -import cn.hutool.core.io.FileUtil; -import cn.hutool.http.HttpRequest; -import cn.hutool.http.HttpResponse; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; import cn.hutool.log.Log; import cn.hutool.log.LogFactory; +import com.ruoyi.web.test.controller.baiduyunpan.Constant; +import com.ruoyi.web.test.controller.baiduyunpan.FileSizeUtil; import lombok.SneakyThrows; -import org.apache.commons.codec.digest.DigestUtils; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; @@ -18,20 +16,15 @@ import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; -import org.apache.velocity.runtime.directive.Foreach; import java.io.*; -import java.math.BigInteger; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import java.nio.channels.FileChannel; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Arrays; import java.util.HashMap; -import java.util.LinkedList; /** * @Auther: Wang @@ -45,8 +38,10 @@ public class FileUtilsBaidu { public static void main(String[] args) { //不能有空格 - String filePath = "D:\\data\\ces\\"; - String fileName = "day4_MySQL性能优化总结.zip"; +// String filePath = "D:\\data\\ces\\"; +// String fileName = "day4_MySQL性能优化总结.zip"; + String filePath = "D:\\Wang\\"; + String fileName = "22.txt"; System.out.println(save(filePath, fileName)); } @@ -95,7 +90,7 @@ public class FileUtilsBaidu { Thread.sleep(3000); //创建文件 - log.info("创建文件 fileName{} 文件大小{} md5:{} ID:{}", fileName,FileSizeUtil.pathSize(absoluteFilePath),md5s.toString(),(String) new JSONObject(precreate).get("uploadid")); + log.info("创建文件 fileName{} 文件大小{} md5:{} ID:{}", fileName, FileSizeUtil.pathSize(absoluteFilePath),md5s.toString(),(String) new JSONObject(precreate).get("uploadid")); String create = create(fileName, fileMax, 0, md5s.toString(),(String) new JSONObject(precreate).get("uploadid")); log.info("创建文件{}", create); @@ -112,7 +107,9 @@ public class FileUtilsBaidu { * @param: fileName 文件名 */ private static String getDownUrl(String fileName) { - String fileSearch = HttpUtil.get(Constant.FILE_SEARCH + "&access_token=" + Constant.ATOKEN + "&key=" + fileName); + String fileSearch = HttpUtil.get(Constant.FILE_SEARCH + "&access_token=" + Constant.ATOKEN + "&key=" + fileName + "&recursion=1&dir=" + Constant.APP_PATH); + System.out.println("fileSearch:"+fileSearch); + JSONObject jsonObject = new JSONObject(fileSearch); JSONArray list = jsonObject.getJSONArray("list"); JSONObject listJSONObject = list.getJSONObject(0); @@ -136,15 +133,11 @@ public class FileUtilsBaidu { */ private static String create(String fileName, Long size, Integer isDir, String blockList, String uploadid) { String strURL = Constant.FILE_MANAGER_URL + "?method=create&access_token=" + Constant.ATOKEN; -// String params = "path=" + Constant.APP_PATH + fileName + "&size=" + size + "&autoinit=1&block_list=[\"" + blockList + "\"]&isdir=" + isDir +"&uploadid"+uploadid; -// return open(strURL, params, "POST"); -// -// //方式一 HashMap<String, Object> paramMap = new HashMap<>(); paramMap.put("path", Constant.APP_PATH + fileName); paramMap.put("size", size); -// paramMap.put("autoinit", 1); -// paramMap.put("rtype", 1); + paramMap.put("autoinit", 1); + paramMap.put("rtype", 2); String str ="[\"" +blockList +"\"]"; paramMap.put("block_list", str); paramMap.put("isdir",isDir); @@ -154,7 +147,6 @@ public class FileUtilsBaidu { System.out.println("block_list :" + paramMap.get("block_list")); System.out.println("uploadid :" + paramMap.get("uploadid")); System.out.println("path :" + paramMap.get("path")); -// return result; } @@ -183,9 +175,7 @@ public class FileUtilsBaidu { //方式二 String result = sendFile(url, files[i]); log.info("正在上传分片文件{}{}", result, i); -// Thread.sleep(3000); } - return path; } catch (Exception e) { e.printStackTrace(); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/baiduyunpan/FileUtilsBaiduBeack.java b/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/baiduyunpan/FileUtilsBaiduBeack.java new file mode 100644 index 000000000..bcddba1a9 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/baiduyunpan/FileUtilsBaiduBeack.java @@ -0,0 +1,558 @@ +package com.ruoyi.web.test.controller.baiduyunpan; + +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONObject; +import cn.hutool.log.Log; +import cn.hutool.log.LogFactory; +import lombok.SneakyThrows; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; + +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.nio.channels.FileChannel; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.util.HashMap; + +/** + * @Auther: Wang + * @Date: 2021/07/25 02:02 + * 功能描述: + */ +public class FileUtilsBaiduBeack { + + private static final Log log = LogFactory.get(); + + +// public static void main(String[] args) { +// //不能有空格 +//// String filePath = "D:\\data\\ces\\"; +//// String fileName = "day4_MySQL性能优化总结.zip"; +// String filePath = "D:\\Wang\\"; +// String fileName = "22.txt"; +// System.out.println(save(filePath, fileName)); +// } + + /** + * @Description: TODO 保存文件 + * @param: filePath 文件路径 + * @param: fileName 文件名称 + * return 文件下载地址 + */ + @SneakyThrows + private static String save(String filePath, String fileName) { + //本地文件地址 + String absoluteFilePath = filePath + fileName; + //云端文件地址 + String cloudPath = Constant.APP_PATH + fileName; + + //文件分片并获取md5值 + File file = new File(absoluteFilePath); + File[] separate = separate(absoluteFilePath, Constant.UNIT); + StringBuffer md5s = new StringBuffer(); + if (separate.length == 1) { + md5s.append(getMD5(separate[0])); +// md5s.append(DigestUtils.md5Hex(new FileInputStream(separate[0]))); + } + if (separate.length > 1) { + for (int i = 0; i < separate.length; i++) { + md5s.append(getMD5(separate[i]) + "\",\""); +// md5s.append(DigestUtils.md5Hex(new FileInputStream(separate[i])) + "\",\""); + log.info("正在分片,{}{}", separate[i].toString(), i); + } + String s = md5s.toString(); + md5s = new StringBuffer(s.substring(0, md5s.length() - 3)); + } + + Long fileMax = file.length(); + + //预上传 + String precreate = precreate(cloudPath,fileMax, 0, md5s.toString()); + log.info("预上传{} iploadid是 {} md5{}", precreate,(String) new JSONObject(precreate).get("uploadid"),md5s.toString()); + + //分片上传 + String upload = upload(cloudPath, (String) new JSONObject(precreate).get("uploadid"), separate); + log.info("分片上传{}", upload); + log.info(" >>>>>>>>>>>>>>>>>>>>>>>>>>"); + + Thread.sleep(3000); + //创建文件 + + log.info("创建文件 fileName{} 文件大小{} md5:{} ID:{}", fileName, FileSizeUtil.pathSize(absoluteFilePath),md5s.toString(),(String) new JSONObject(precreate).get("uploadid")); + String create = create(fileName, fileMax, 0, md5s.toString(),(String) new JSONObject(precreate).get("uploadid")); + log.info("创建文件{}", create); + + //获取下载地址 + String downUrl = getDownUrl(fileName); + log.info("获取下载地址{}", downUrl); + + return downUrl; + } + + + /** + * @Description: TODO 获取下载地址 + * @param: fileName 文件名 + */ + private static String getDownUrl(String fileName) { + String fileSearch = HttpUtil.get(Constant.FILE_SEARCH + "&access_token=" + Constant.ATOKEN + "&key=" + fileName + "&recursion=1&dir=" + Constant.APP_PATH); + System.out.println("fileSearch:"+fileSearch); + + JSONObject jsonObject = new JSONObject(fileSearch); + JSONArray list = jsonObject.getJSONArray("list"); + JSONObject listJSONObject = list.getJSONObject(0); + Long fs_id = listJSONObject.getLong("fs_id"); + String url = Constant.DOWN_LOUE_URL + "?method=filemetas&access_token=" + Constant.ATOKEN + "&fsids=[" + fs_id + "]&dlink=1"; + String s = HttpUtil.get(url); + JSONObject sJsonObject = new JSONObject(s); + JSONArray jsonArray = sJsonObject.getJSONArray("list"); + JSONObject jsonObjectClient = jsonArray.getJSONObject(0); + String dlink = jsonObjectClient.getStr("dlink"); + return dlink; + } + + /** + * @Description: TODO 创建文件 + * @param: fileName 文件名称 + * @param: size 文件大小 字节 + * @param: isDir 0文件 1目录(设置为目录是 size要设置为0) + * @param: blockList (文件的md5值) 可以把文件分为多个,然后分批上传 + * @return: java.lang.String + */ + private static String create(String fileName, Long size, Integer isDir, String blockList, String uploadid) { + String strURL = Constant.FILE_MANAGER_URL + "?method=create&access_token=" + Constant.ATOKEN; + HashMap<String, Object> paramMap = new HashMap<>(); + paramMap.put("path", Constant.APP_PATH + fileName); + paramMap.put("size", size); + paramMap.put("autoinit", 1); + paramMap.put("rtype", 2); + String str ="[\"" +blockList +"\"]"; + paramMap.put("block_list", str); + paramMap.put("isdir",isDir); + paramMap.put("uploadid",uploadid); +// paramMap.put("app_id",Constant.APP_ID); + String result= HttpUtil.post(strURL, paramMap); + System.out.println("block_list :" + paramMap.get("block_list")); + System.out.println("uploadid :" + paramMap.get("uploadid")); + System.out.println("path :" + paramMap.get("path")); + return result; + } + + /** + * @Description: TODO 分片上传 + * @param: path 上传到百度网盘的地址 + * @param: uploadid 上传的id + * @param: filePath 本地文件的地址 + * @return: java.lang.String + */ + private static String upload(String path, String uploadid, File[] files) { + try { + + for (int i = 0; i < files.length; i++) { + String url = Constant.SLICING_UPLOAD_FILE_URL + "?method=upload" + + "&access_token=" + Constant.ATOKEN + + "&type=tmpfile&partseq=" + i + + "&path=" + getURLEncoderString(path) + + "&uploadid=" + uploadid; + log.info("files : {} path {}",files[i], path); + //方式一 +// HashMap<String, Object> paramMap = new HashMap<>(); +// paramMap.put("file", FileUtil.file(files[i])); +// String result= HttpUtil.post(url, paramMap); + + //方式二 + String result = sendFile(url, files[i]); + log.info("正在上传分片文件{}{}", result, i); + } + return path; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + + /** + * @Description: TODO 预上传 + * @param: cloudPath 云端路径 + * @param: size 文件大小 字节 + * @param: isDir 0文件 1目录(设置为目录是 size要设置为0) + * @param: blockList (文件的md5值) 可以把文件分为多个,然后分批上传 + * @return: java.lang.String + */ + private static String precreate(String cloudPath, Long size, Integer isDir, String blockList) { + String strURL = Constant.GET_READY_FILE_URL + "?method=precreate&access_token=" + Constant.ATOKEN; + String params = "path=" + getURLEncoderString(cloudPath) + "&size=" + size + "&autoinit=1&block_list=[\"" + blockList + "\"]&isdir=" + isDir; + return open(strURL, params, "POST"); + } + + + /** + * @Description: TODO 获取md5值 + * String path 文件地址 + */ + private final static String[] strHex = {"0", "1", "2", "3", "4", "5", + "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}; + + private static String getMD5(File path) { + StringBuilder buffer = new StringBuilder(); + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] b = md.digest(org.apache.commons.io.FileUtils.readFileToByteArray(path)); + for (int value : b) { + int d = value; + if (d < 0) { + d += 256; + } + int d1 = d / 16; + int d2 = d % 16; + buffer.append(strHex[d1]).append(strHex[d2]); + } + return buffer.toString(); + } catch (Exception e) { + return null; + } + +// BigInteger bi = null; +// try { +// byte[] buffer = new byte[8192]; +// int len = 0; +// MessageDigest md = MessageDigest.getInstance("MD5"); +// +// FileInputStream fis = new FileInputStream(f); +// while ((len = fis.read(buffer)) != -1) { +// md.update(buffer, 0, len); +// } +// fis.close(); +// byte[] b = md.digest(); +// bi = new BigInteger(1, b); +// } catch (NoSuchAlgorithmException e) { +// e.printStackTrace(); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// return bi.toString(16); + } + + + /** + * @Description: TODO + * @param: strURL 网址,可以是 http://aaa?bbb=1&ccc=2 拼接的 + * @param: params 拼接的body参数也就是form表单的参数 ddd=1&eee=2 + * @param: method 请求方式 get/post/put/delte等 + * @return: java.lang.String + */ + private static String open(String strURL, String params, String method) { + try { + URL url = new URL(strURL);// 创建连接 + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setDoOutput(true); + connection.setDoInput(true); + connection.setUseCaches(false); + connection.setInstanceFollowRedirects(true); + connection.setRequestMethod(method); + connection.setRequestProperty("Accept", "application/json");// 设置接收数据的格式 + connection.setRequestProperty("Content-Type", "application/json");// 设置发送数据的格式 + connection.connect(); + OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), StandardCharsets.UTF_8);// utf-8编码 + out.append(params); + out.flush(); + out.close(); // 读取响应 + int length = connection.getContentLength();// 获取长度 + InputStream is = connection.getInputStream(); + if (length != -1) { + byte[] data = new byte[length]; + byte[] temp = new byte[512]; + int readLen = 0; + int destPos = 0; + while ((readLen = is.read(temp)) > 0) { + System.arraycopy(temp, 0, data, destPos, readLen); + destPos += readLen; + } + return new String(data, StandardCharsets.UTF_8); + } + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + + /** + * 向指定 URL 发送POST方法的请求 + * + * @param url 发送请求的 URL + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 + * @return 所代表远程资源的响应结果 + */ + public static String sendFile(String url, String param, String file) { + if (url == null || param == null) { + return url; + } + + PrintWriter out = null; + BufferedReader in = null; + String result = ""; + try { + URL realUrl = new URL(url); + // 打开和URL之间的连接 + URLConnection conn = realUrl.openConnection(); + // 设置通用的请求属性 + conn.setRequestProperty("accept", "*/*"); + conn.setRequestProperty("connection", "Keep-Alive"); + conn.setRequestProperty("user-agent", + "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); + // 发送POST请求必须设置如下两行 + conn.setDoOutput(true); + conn.setDoInput(true); + //设置链接超时时间为2秒 + conn.setConnectTimeout(1000); + //设置读取超时为2秒 + conn.setReadTimeout(1000); + // 获取URLConnection对象对应的输出流 + out = new PrintWriter(conn.getOutputStream()); + out.write(file); + // 发送请求参数 + out.print(param); + // flush输出流的缓冲 + out.flush(); + // 定义BufferedReader输入流来读取URL的响应 + in = new BufferedReader( + new InputStreamReader(conn.getInputStream())); + String line; + while ((line = in.readLine()) != null) { + result += line; + } + } catch (Exception e) { + System.out.println(e.getMessage() + "地址:" + url); + return null; + } + //使用finally块来关闭输出流、输入流 + finally { + try { + if (out != null) { + out.close(); + } + if (in != null) { + in.close(); + } + } catch (IOException ex) { + System.out.println(ex.getMessage()); + return null; + } + } + return result; + } + + + /** + * @param: filePath + * @param: unit 单个文件大小 + * @return: 返回文件的目录 + */ + private static File[] separate(Object obj, Integer unit) { + + try { + + InputStream bis = null;//输入流用于读取文件数据 + OutputStream bos = null;//输出流用于输出分片文件至磁盘 + File file = null; + if (obj instanceof String) { + file = new File((String) obj); + } + if (obj instanceof File) { + file = (File) obj; + } + + String filePath = file.getAbsolutePath(); + File newFile = new File(filePath.substring(0, filePath.lastIndexOf("\\") + 1)); + String directoryPath = newFile.getAbsolutePath(); + long splitSize = unit * 1024 * 1024;//单片文件大小,MB + if (file.length() < splitSize) { + log.info("文件小于单个分片大小,无需分片{}", file.length()); + return new File[]{file}; + } + + + //分片二 + RandomAccessFile in=null; + RandomAccessFile out =null; + long length=file.length();//文件大小 + long count=length%splitSize==0?(length/splitSize):(length/splitSize+1);//文件分片数 + byte[] bt=new byte[1024]; + in=new RandomAccessFile(file, "r"); + for (int i = 1; i <= count; i++) { + out = new RandomAccessFile(new File(filePath+"."+i), "rw");//定义一个可读可写且后缀名为.part的二进制分片文件 + long begin = (i-1)*splitSize; + long end = i* splitSize; + int len=0; + in.seek(begin); + while (in.getFilePointer()<end&&-1!=(len=in.read(bt))) { + out.write(bt, 0, len); + } + out.close(); + } + + + //分片一 +// bis = new BufferedInputStream(new FileInputStream(file)); +// long writeByte = 0;//已读取的字节数 +// int len = 0; +// byte[] bt = new byte[1024]; +// while (-1 != (len = bis.read(bt))) { +// if (writeByte % splitSize == 0) { +// if (bos != null) { +// bos.flush(); +// bos.close(); +// } +// bos = new BufferedOutputStream(new FileOutputStream(filePath + "." + (writeByte / splitSize + 1) + ".part")); +// } +// writeByte += len; +// bos.write(bt, 0, len); +// } + + + log.info("文件分片成功!"); + + //排除被分片的文件 + if (newFile.isDirectory()) { + File[] files = newFile.listFiles(); + File[] resultFiles = new File[files.length - 1]; + int j = 0; + for (int i = 0; i < files.length; i++) { + if (!files[i].equals(file)) { + resultFiles[j] = files[i]; + j++; + } + } + return resultFiles; + } + + bos.flush(); + bos.close(); + bis.close(); + return new File[0]; + } catch (Exception e) { + log.info("文件分片失败!"); + e.printStackTrace(); + } + return null; + } + + //splitNum:要分几片,currentDir:分片后存放的位置,subSize:按多大分片 + public static File[] nioSpilt(Object object, int splitNum, String currentDir, double subSize) { + try { + File file = null; + if (object instanceof String) { + file = new File((String) object); + } + if (object instanceof String) { + file = (File) object; + } + FileInputStream fis = new FileInputStream(file); + FileChannel inputChannel = fis.getChannel(); + FileOutputStream fos; + FileChannel outputChannel; + long splitSize = (long) subSize; + long startPoint = 0; + long endPoint = splitSize; + for (int i = 1; i <= splitNum; i++) { + fos = new FileOutputStream(currentDir + i); + outputChannel = fos.getChannel(); + inputChannel.transferTo(startPoint, splitSize, outputChannel); + startPoint += splitSize; + endPoint += splitSize; + outputChannel.close(); + fos.close(); + } + inputChannel.close(); + fis.close(); + File newFile = new File(file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf("\\") + 1)); + if (newFile.isDirectory()) { + return newFile.listFiles(); + } + } catch (Exception e) { + e.printStackTrace(); + } + return new File[0]; + } + + /** + * @Description: TODO 发送文件 + * @param: url 发送地址 + * @param: file 发送文件 + * @return: java.lang.String + */ + public static String sendFile(String url, File file) { + try { + MultipartEntityBuilder builder = MultipartEntityBuilder.create(); + builder.setContentType(ContentType.MULTIPART_FORM_DATA); + builder.addBinaryBody("file", file); + String body = ""; + //创建httpclient对象 + CloseableHttpClient client = HttpClients.createDefault(); + //创建post方式请求对象 + HttpPost httpPost = new HttpPost(url); + //设置请求参数 + HttpEntity httpEntity = builder.build(); + httpPost.setEntity(httpEntity); + //执行请求操作,并拿到结果(同步阻塞) + CloseableHttpResponse response = client.execute(httpPost); + //获取结果实体 + HttpEntity entity = response.getEntity(); + if (entity != null) { + //按指定编码转换结果实体为String类型 + body = EntityUtils.toString(entity, "utf-8"); + } + EntityUtils.consume(entity); + //释放链接 + response.close(); + return body; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + + + public static String getURLEncoderString(String str) { + String result = ""; + if (null == str) { + return ""; + } + try { + result = java.net.URLEncoder.encode(str, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + return result; + } + + public static String URLDecoderString(String str) { + String result = ""; + if (null == str) { + return ""; + } + try { + result = java.net.URLDecoder.decode(str, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + return result; + } + + + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/22.html b/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/bookmark/22.html similarity index 100% rename from ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/22.html rename to ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/bookmark/22.html diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/bookmark/HtmlTest.java b/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/bookmark/HtmlTest.java new file mode 100644 index 000000000..cd1ffda32 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/bookmark/HtmlTest.java @@ -0,0 +1,228 @@ +package com.ruoyi.web.test.controller.bookmark; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ZipUtil; +import com.ruoyi.BackupsYunPan; +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.file.FileUtils; +import com.ruoyi.common.utils.file.MimeTypeUtils; +import com.ruoyi.web.test.controller.BaseSpringBootTest; +import com.ruoyi.web.test.controller.baiduyunpan.Constant; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +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; + @Autowired + private BackupsYunPan backupsYunPan; + + @Test + public void ss(){ + try { + System.out.println(DateUtil.now()); + Thread.sleep(10000); +//共享数据10;每一个线程里面-1 + MyRunner2 myRunner2=new MyRunner2(); + for(int i=0;i<10;i++){ + Thread thread2=new Thread(myRunner2); + //不同的线程传入同一个对象,达到线程共享的目的 + thread2.start(); + //无序,由操作系统来调度 + } + + Thread.sleep(1000000000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + //百度 备份 +// backupsYunPan.BaiDuYunBackups("D:\\data\\ces\\","day4_MySQL性能优化总结.zip",Constant.ATOKEN); + } + + class MyRunner2 implements Runnable{ + + @Override + public void run() { + + + int max=100,min=1; + long randomNum = System.currentTimeMillis(); + int ran3 = (int) (randomNum%(max-min)+min); + + Long beginTime = new Date().getTime(); + + String filePath = "D:/demo/" + "user_1/" + ran3+"/bookmark_bacpks/"; + String filePathZip = "D:/demo/" + "user_1/"+ran3 + "/bookmark_zip/"; + String fileName = "藏趣云_" + DateUtil.format(DateUtil.date(), "yyyy_MM_dd"); + + try { + 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"); + + File file = new File(filePath + fileName + MimeTypeUtils.HTML); + if (!file.getParentFile().exists()) { //如果文件的目录不存在 + file.getParentFile().mkdirs(); //创建目录 + } + if (file.exists()) { + //文件存在 + } + OutputStream output = new FileOutputStream(file); + + //3: 准备好实现内容的输出 将字符串变为字节数组 + byte data[] = sb.toString().getBytes(); + output.write(data); + output.close(); + //打包 + ZipUtil.zip(filePath, filePathZip + fileName + MimeTypeUtils.ZIP); + + String downUrl = backupsYunPan.BaiDuYunBackups(filePathZip, fileName + MimeTypeUtils.ZIP, Constant.ATOKEN); + //删除目录内文件 + FileUtils.deleteFile(filePathZip + fileName + MimeTypeUtils.ZIP); + FileUtils.deleteFile(filePath + fileName + MimeTypeUtils.HTML); + //备份成功了 存数据库 + + } catch (Exception e) { + logger.error("异常:", e); + } + + System.out.println("耗时:"+(new Date().getTime()-beginTime)); + } + } + + + @Test + public void test3() { + Long beginTime = new Date().getTime(); + + String filePath = "D:/demo/" + "user_1" + "/bookmark_bacpks/"; + String filePathZip = "D:/demo/" + "user_1" + "/bookmark_zip/"; + String fileName = "藏趣云_" + DateUtil.format(DateUtil.date(), "yyyy_MM_dd"); + + try { + 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"); + + File file = new File(filePath + fileName + MimeTypeUtils.HTML); + if (!file.getParentFile().exists()) { //如果文件的目录不存在 + file.getParentFile().mkdirs(); //创建目录 + } + if (file.exists()) { + //文件存在 + } + OutputStream output = new FileOutputStream(file); + + //3: 准备好实现内容的输出 将字符串变为字节数组 + byte data[] = sb.toString().getBytes(); + output.write(data); + output.close(); + //打包 + ZipUtil.zip(filePath, filePathZip + fileName + MimeTypeUtils.ZIP); + + String downUrl = backupsYunPan.BaiDuYunBackups(filePathZip, fileName + MimeTypeUtils.ZIP, Constant.ATOKEN); + //删除目录内文件 + FileUtils.deleteFile(filePathZip + fileName + MimeTypeUtils.ZIP); + FileUtils.deleteFile(filePath + fileName + MimeTypeUtils.HTML); + //备份成功了 存数据库 + + } catch (Exception e) { + logger.error("异常:", e); + } + + System.out.println("耗时:"+(new Date().getTime()-beginTime)); + } + + + /** + * 导出到html文件 + * @param + */ + public StringBuilder exportToHtml(Long userId){ + + SqMenu sqMenu=new SqMenu(); + sqMenu.setUserId(userId); + SqBookmark sqBookmark = new SqBookmark(); + sqBookmark.setUserid(userId); + //目录 + List<SqMenu> menuList = iSqMenuService.selectSqMenuList(sqMenu); + Map<Long, List<SqMenu>> mapMenu = menuList.stream().collect(Collectors.groupingBy(SqMenu::getParentId)); + //书签 + List<SqBookmark> bookMarkList = iSqBookmarkService.selectSqBookmarkList(sqBookmark); + Map<Long, List<SqBookmark>> mapBookMark = bookMarkList.stream().collect(Collectors.groupingBy(SqBookmark::getMenuId)); + + List<SqMenu> sqMenuList = mapMenu.get(0L); + StringBuilder str = new StringBuilder(); + str = traverseFile_recursion(sqMenuList,str,mapBookMark,mapMenu); + return str; + } + + + + + /** + * @Description:递归书签导出功能 + * + * @param * @param sqMenuList + * @param str + * @param mapBookMark + * @param mapMenu + * @return java.lang.StringBuilder + * @Date + * @author: wanghao + * + */ + public StringBuilder traverseFile_recursion (List<SqMenu> sqMenuList,StringBuilder str,Map<Long, List<SqBookmark>> mapBookMark,Map<Long, List<SqMenu>> mapMenu) { + + if (sqMenuList != null && !sqMenuList.isEmpty()) { + for (SqMenu f : sqMenuList) { + str.append("<DT><H3 ADD_DATE=\"1584277207\" LAST_MODIFIED=\"0\">").append(f.getMenuName()).append("</H3>\n"); + str.append("<DL>\n"); + List<SqBookmark> bookmarksList = mapBookMark.get(f.getMenuId()); + if (bookmarksList != null && !bookmarksList.isEmpty()) { + for (SqBookmark b : bookmarksList) { + str.append("<DT><A HREF=\""+b.getUrl()+"\" TARGET=\"_blank\">"+b.getTitle()+"</A>\n"); + } + } + traverseFile_recursion(mapMenu.get(f.getMenuId()),str,mapBookMark,mapMenu); + str.append("</DL>\n"); + } + } + return str; + } + + + + + + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/模板.html b/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/bookmark/模板.html similarity index 100% rename from ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/模板.html rename to ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/bookmark/模板.html diff --git a/ruoyi-admin/src/main/resources/application-druid.yml b/ruoyi-admin/src/main/resources/application-druid.yml index 869692ebe..bb617313c 100644 --- a/ruoyi-admin/src/main/resources/application-druid.yml +++ b/ruoyi-admin/src/main/resources/application-druid.yml @@ -6,9 +6,9 @@ spring: druid: # 主库数据源 master: - url: jdbc:mysql://localhost:3306/dqsj?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true - username: root - password: root + url: jdbc:mysql://localhost:3306/dqsj?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true + username: root + password: root # 从库数据源 slave: # 从数据源开关/默认关闭 diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java index f0dee601b..38c030fdc 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java @@ -11,7 +11,7 @@ import javax.servlet.http.HttpServletRequest; /** * 文件处理工具类 - * + * * @author ruoyi */ public class FileUtils extends org.apache.commons.io.FileUtils @@ -20,7 +20,7 @@ public class FileUtils extends org.apache.commons.io.FileUtils /** * 输出指定文件的byte数组 - * + * * @param filePath 文件路径 * @param os 输出流 * @return @@ -76,7 +76,7 @@ public class FileUtils extends org.apache.commons.io.FileUtils /** * 删除文件 - * + * * @param filePath 文件 * @return */ @@ -93,9 +93,31 @@ public class FileUtils extends org.apache.commons.io.FileUtils return flag; } + /** + * 递归删除目录下的所有文件及子目录下所有文件 + * @param dir 将要删除的文件目录 + * @return boolean Returns "true" if all deletions were successful. + * If a deletion fails, the method stops attempting to + * delete and returns "false". + */ + public static boolean deleteDir(File dir) { + if (dir.isDirectory()) { + String[] children = dir.list(); + //递归删除目录中的子目录下 + for (int i=0; i<children.length; i++) { + boolean success = deleteDir(new File(dir, children[i])); + if (!success) { + return false; + } + } + } + // 目录此时为空,可以删除 + return dir.delete(); + } + /** * 文件名称验证 - * + * * @param filename 文件名称 * @return true 正常 false 非法 */ @@ -106,7 +128,7 @@ public class FileUtils extends org.apache.commons.io.FileUtils /** * 下载文件名重新编码 - * + * * @param request 请求对象 * @param fileName 文件名 * @return 编码后的文件名 diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/MimeTypeUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/MimeTypeUtils.java index d179a9188..a17a3c751 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/MimeTypeUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/MimeTypeUtils.java @@ -2,11 +2,15 @@ package com.ruoyi.common.utils.file; /** * 媒体类型工具类 - * + * * @author ruoyi */ public class MimeTypeUtils { + public static final String HTML = ".html"; + + public static final String ZIP = ".zip"; + public static final String IMAGE_PNG = "image/png"; public static final String IMAGE_JPG = "image/jpg"; @@ -16,7 +20,7 @@ public class MimeTypeUtils public static final String IMAGE_BMP = "image/bmp"; public static final String IMAGE_GIF = "image/gif"; - + public static final String[] IMAGE_EXTENSION = { "bmp", "gif", "jpg", "jpeg", "png" }; public static final String[] FLASH_EXTENSION = { "swf", "flv" }; diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java index 200374328..5ea0a49c3 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java @@ -1,15 +1,10 @@ package com.ruoyi.common.utils.http; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.net.ConnectException; -import java.net.SocketTimeoutException; -import java.net.URL; -import java.net.URLConnection; +import java.io.*; +import java.net.*; import java.security.cert.X509Certificate; +import java.util.Locale; +import java.util.Map; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; @@ -22,7 +17,7 @@ import com.ruoyi.common.constant.Constants; /** * 通用http发送方法 - * + * * @author ruoyi */ public class HttpUtils @@ -259,4 +254,34 @@ public class HttpUtils return true; } } -} \ No newline at end of file + + + + + + /** + * 格式化路径参数 可选参数 + * + * @param uri uri + * @param map map + * @return initUriPathParams + * @throws UnsupportedEncodingException 异常 + */ + public static String initUriPathParams(String uri, Map<String, String> map) throws UnsupportedEncodingException { + String key; + String value; + StringBuilder builder = new StringBuilder(); + builder.append(uri); + builder.append("?"); + for (Map.Entry<String, String> entry : map.entrySet()) { + key = entry.getKey(); + value = entry.getValue(); + String tmpKv; + tmpKv = String.format(Locale.ROOT, "%s=%s&", URLEncoder.encode(key, "UTF-8"), + URLEncoder.encode(value, "UTF-8")); + builder.append(tmpKv); + } + return builder.toString(); + } + +} diff --git a/ruoyi-ui/build/index.js b/ruoyi-ui/build/index.js index 385da08e5..0c57de2aa 100644 --- a/ruoyi-ui/build/index.js +++ b/ruoyi-ui/build/index.js @@ -1,35 +1,35 @@ -const { run } = require('runjs') -const chalk = require('chalk') -const config = require('../vue.config.js') -const rawArgv = process.argv.slice(2) -const args = rawArgv.join(' ') - -if (process.env.npm_config_preview || rawArgv.includes('--preview')) { - const report = rawArgv.includes('--report') - - run(`vue-cli-service build ${args}`) - - const port = 9526 - const publicPath = config.publicPath - - var connect = require('connect') - var serveStatic = require('serve-static') - const app = connect() - - app.use( - publicPath, - serveStatic('./dist', { - index: ['index.html', '/'] - }) - ) - - app.listen(port, function () { - console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`)) - if (report) { - console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`)) - } - - }) -} else { - run(`vue-cli-service build ${args}`) -} +const { run } = require('runjs') +const chalk = require('chalk') +const config = require('../vue.config.js') +const rawArgv = process.argv.slice(2) +const args = rawArgv.join(' ') + +if (process.env.npm_config_preview || rawArgv.includes('--preview')) { + const report = rawArgv.includes('--report') + + run(`vue-cli-service build ${args}`) + + const port = 9526 + const publicPath = config.publicPath + + var connect = require('connect') + var serveStatic = require('serve-static') + const app = connect() + + app.use( + publicPath, + serveStatic('./dist', { + index: ['index.html', '/'] + }) + ) + + app.listen(port, function () { + console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`)) + if (report) { + console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`)) + } + + }) +} else { + run(`vue-cli-service build ${args}`) +} diff --git a/ruoyi-ui/src/permission.js b/ruoyi-ui/src/permission.js index 17e5b3d54..00c2f3ee4 100644 --- a/ruoyi-ui/src/permission.js +++ b/ruoyi-ui/src/permission.js @@ -1,64 +1,64 @@ -import router from './router' -import store from './store' -import { Message } from 'element-ui' -import NProgress from 'nprogress' -import 'nprogress/nprogress.css' -import { getToken } from '@/utils/auth' - -NProgress.configure({ showSpinner: false }) - -const whiteList = ['/login', '/auth-redirect', '/bind', '/register'] - -router.beforeEach((to, from, next) => { - NProgress.start() - if (getToken()) { - /* has token*/ - if (to.path === '/login') { - next({ path: '/' }) - NProgress.done() - } else { - if (store.getters.roles.length === 0) { - // 判断当前用户是否已拉取完user_info信息 - store.dispatch('GetInfo').then(res => { - // 拉取user_info - const roles = res.roles - store.dispatch('GenerateRoutes', { roles }).then(accessRoutes => { - // 测试 默认静态页面 - // store.dispatch('permission/generateRoutes', { roles }).then(accessRoutes => { - // 根据roles权限生成可访问的路由表 - router.addRoutes(accessRoutes) // 动态添加可访问路由表 - next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 - }) - }) - .catch(err => { - store.dispatch('FedLogOut').then(() => { - Message.error(err) - next({ path: '/' }) - }) - }) - } else { - next() - // 没有动态改变权限的需求可直接next() 删除下方权限判断 ↓ - // if (hasPermission(store.getters.roles, to.meta.roles)) { - // next() - // } else { - // next({ path: '/401', replace: true, query: { noGoBack: true }}) - // } - // 可删 ↑ - } - } - } else { - // 没有token - if (whiteList.indexOf(to.path) !== -1) { - // 在免登录白名单,直接进入 - next() - } else { - next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页 - NProgress.done() - } - } -}) - -router.afterEach(() => { - NProgress.done() -}) +import router from './router' +import store from './store' +import { Message } from 'element-ui' +import NProgress from 'nprogress' +import 'nprogress/nprogress.css' +import { getToken } from '@/utils/auth' + +NProgress.configure({ showSpinner: false }) + +const whiteList = ['/login', '/auth-redirect', '/bind', '/register'] + +router.beforeEach((to, from, next) => { + NProgress.start() + if (getToken()) { + /* has token*/ + if (to.path === '/login') { + next({ path: '/' }) + NProgress.done() + } else { + if (store.getters.roles.length === 0) { + // 判断当前用户是否已拉取完user_info信息 + store.dispatch('GetInfo').then(res => { + // 拉取user_info + const roles = res.roles + store.dispatch('GenerateRoutes', { roles }).then(accessRoutes => { + // 测试 默认静态页面 + // store.dispatch('permission/generateRoutes', { roles }).then(accessRoutes => { + // 根据roles权限生成可访问的路由表 + router.addRoutes(accessRoutes) // 动态添加可访问路由表 + next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 + }) + }) + .catch(err => { + store.dispatch('FedLogOut').then(() => { + Message.error(err) + next({ path: '/' }) + }) + }) + } else { + next() + // 没有动态改变权限的需求可直接next() 删除下方权限判断 ↓ + // if (hasPermission(store.getters.roles, to.meta.roles)) { + // next() + // } else { + // next({ path: '/401', replace: true, query: { noGoBack: true }}) + // } + // 可删 ↑ + } + } + } else { + // 没有token + if (whiteList.indexOf(to.path) !== -1) { + // 在免登录白名单,直接进入 + next() + } else { + next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页 + NProgress.done() + } + } +}) + +router.afterEach(() => { + NProgress.done() +}) diff --git a/ruoyi-ui/src/views/daohang/index/index.vue b/ruoyi-ui/src/views/daohang/index/index.vue index a9c6d8d33..c90c6c74a 100644 --- a/ruoyi-ui/src/views/daohang/index/index.vue +++ b/ruoyi-ui/src/views/daohang/index/index.vue @@ -56,13 +56,32 @@ <el-header height="200px" class="header-below"> - <!-- <el-input v-model="input" placeholder="请输入内容"></el-input>--> <div style="min-width: 500px;margin-top: 80px"> - <el-input placeholder="百度一下" v-model="sousou" class="sousoucss notcopy " ref="sousouref"> - <img @click="IsCord()" slot="prefix" :src="sousouicon" - style="width: 20px;height: 20px;position: absolute;top: 50%;margin-top: -10px;"> + + <img @click="IsCord()" slot="prefix" :src="sousouicon" + style="" class="sousou-img"> + <input placeholder="百度一下" v-model="sousou" class="search" ref="sousouref"> + </input> +<!-- <template slot="prepend">--> + +<!-- </template>--> +<!-- --> + +<!-- <el-select v-model="select" slot="prepend" placeholder="请选择" style="width: 130px">--> +<!-- <el-option label="餐厅名" value="1"></el-option>--> +<!-- <el-option label="订单号" value="2"></el-option>--> +<!-- <el-option label="用户电话" value="3"></el-option>--> +<!-- </el-select>--> +<!-- <el-button slot="append" icon="el-icon-search"></el-button>--> + + + + + <!-- <el-button type="primary" slot="append" icon="el-icon-search" style="width: 80px" @click="getUrl"></el-button>--> - </el-input> + + + </div> </el-header> @@ -72,7 +91,7 @@ <el-aside class="mains-left mbl" width="400px"> <div class="label-title"> <div class="title"> - <el-dropdown trigger="click" @command="handleCommand"> + <el-dropdown trigger="click" @command="handleCommand"> <span class="el-dropdown-link menu-list"> 最新收藏<i class="el-icon-caret-bottom el-icon--right"></i> </span> @@ -209,6 +228,7 @@ } from "@/api/bookmark/bookmark"; export default { + name: 'app', components: {draggable}, data: function () { return { @@ -283,17 +303,17 @@ sqTags: [], sort: 0, sousuo: '', - type:'', - bkOrderBy:'', + type: '', + bkOrderBy: '', }, - bookmarkList:[], - sortState:true,//是否进行请求书签的拼接,切换排序规则时,不能进行拼接,重新渲染数据 false表示切换了 true没切换 + bookmarkList: [], + sortState: true,//是否进行请求书签的拼接,切换排序规则时,不能进行拼接,重新渲染数据 false表示切换了 true没切换 } }, methods: { - goRouter(e){ - var flag=e; + goRouter(e) { + var flag = e; var that = this; switch (flag) { case 1: @@ -317,7 +337,7 @@ path: "/content", query: { menuId: 'newest', - t:Date.now(), + t: Date.now(), } }) } @@ -326,21 +346,21 @@ listByUserAndPolymerization(str) { console.log(" 最新 星标 回收站 稍后看"); // this.loading = true; - this.queryParams.type=str; - this.queryParams.bkOrderBy=""; + this.queryParams.type = str; + this.queryParams.bkOrderBy = ""; listByUserAndPolymerization(this.queryParams).then(response => { if (response.code == 200) { //如果进行了排序切换 就不能进行拼接 - if (this.sortState){ + if (this.sortState) { this.bookmarkList = this.bookmarkList.concat(response.rows); - }else{ + } else { this.bookmarkList = response.rows; this.sortState = false; } this.total = response.total; this.listloading = false this.loading = false; - if (response.total == 0){ + if (response.total == 0) { this.showimg = true;//空提示 } console.log("请求完毕" + this.queryParams.pageNum) @@ -355,11 +375,11 @@ }, /**切换排序规则**/ handleCommand(command) { - if (this.queryParams.sort != command){ + if (this.queryParams.sort != command) { this.sortState = false;//是否切换了新的排序规则方式 false表示切换了 true没切换 } this.queryParams.sort = command; - this.bookmarkList=[] + this.bookmarkList = [] this.listByUserAndPolymerization(command) }, @@ -428,7 +448,7 @@ <style scoped> .bookmarkUrl { margin-bottom: 10px; - margin-left: 11px; + margin-left: 10px; height: 70px; border-radius: 4px; line-height: 50px; @@ -699,6 +719,19 @@ <style scoped> + .search{ + width: 500px; + height: 45px; + border: 0; + border-radius: 50px; + background: rgba(255, 255, 255, 0.5); + padding-left: 64px ; + } + .search:focus { + outline:none; + } + + .main { /*font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif;*/ /*display: flex;*/ @@ -719,7 +752,7 @@ /*}*/ /*.sousoucss{*/ - /* opacity: 0.6;*/ + /* background: rgba(255, 255, 255, 0.5);*/ /*}*/ /*.sousoucss input{*/ /* border:0;*/ @@ -732,6 +765,33 @@ /* background-color: #1f2d3d!important;*/ /* opacity: 0.7;*/ /*}*/ + .sousoucss >>> .el-select { + background: rgba(255, 255, 255, 0.5) !important; + border: none !important; + } + .sousoucss >>> .el-input--suffix { + background: rgba(255, 255, 255, 0.5) !important; + border: none !important; + } + .sousoucss >>> .el-input__inner { + background: rgba(255, 255, 255, 0.5) !important; + border: none !important; + /*width: 500px !important;*/ + /*-moz-border-radius-topright: 50px !important;*/ + /*-moz-border-radius-bottomright: 50px !important;*/ + /*color: #666c74 !important;*/ + /*font-size: 16px !important;*/ + /*height: 40px !important;*/ + } + + .sousou-img { + width: 30px; + height: 30px; + position: relative; + border-radius:50%; + top: 10px; + left: 45px; + } .choice { @@ -833,7 +893,8 @@ ::-webkit-scrollbar-track { width: 6px; /*background-color: #fff;*/ - background: rgba(255, 255, 255, 0.2); + /*滚动条的背景颜色*/ + /*background: rgba(255, 255, 255, 0.2);*/ -webkit-border-radius: 2em; -moz-border-radius: 2em; border-radius: 2em; diff --git a/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/service/ISqBookmarkService.java b/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/service/ISqBookmarkService.java index 703f959e1..e5b6c228e 100644 --- a/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/service/ISqBookmarkService.java +++ b/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/service/ISqBookmarkService.java @@ -3,6 +3,7 @@ package com.ruoyi.bookmark.service; import java.util.List; import com.ruoyi.bookmark.domain.SqBookmark; import com.ruoyi.bookmark.pojo.SqBookmarkReq; +import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.utils.bookmarkhtml.HtmlName; /** @@ -179,4 +180,11 @@ public interface ISqBookmarkService * */ List<SqBookmark> getlistByTag(SqBookmarkReq sqBookmarkReq); + + /** + * 根据URL 删除书签 + * @param + * + */ + AjaxResult deleteByUrl(Long userId, String url); } diff --git a/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/service/impl/SqBookmarkServiceImpl.java b/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/service/impl/SqBookmarkServiceImpl.java index 15de7982b..b0186e6b5 100644 --- a/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/service/impl/SqBookmarkServiceImpl.java +++ b/ruoyi-yunbookmark/src/main/java/com/ruoyi/bookmark/service/impl/SqBookmarkServiceImpl.java @@ -22,6 +22,7 @@ import com.ruoyi.bookmark.mapper.SqTagMapper; import com.ruoyi.bookmark.pojo.SqBookmarkReq; import com.ruoyi.bookmark.service.ISqTagService; +import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.bookmarkhtml.Const; import com.ruoyi.common.utils.bookmarkhtml.HtmlName; @@ -544,5 +545,23 @@ public class SqBookmarkServiceImpl implements ISqBookmarkService return sqBookmarkMapper.getlistByTag(sqBookmarkReq); } + @Override + public AjaxResult deleteByUrl(Long userId, String url) { + //1.根据URL查询书签 会有多条 + + //2.移动到回收站 + + + //3.修改多个书签目录的数量 + +// //给原目录 -1 +// sqMenuMapper.updateCountReduce(new Long[]{sqBookmark.getMenuId()},1); + + + + + return AjaxResult.success("success"); + } + } diff --git a/yunpan-baidu/pom.xml b/yunpan-baidu/pom.xml index 3bbed169c..342deb9ff 100644 --- a/yunpan-baidu/pom.xml +++ b/yunpan-baidu/pom.xml @@ -21,6 +21,10 @@ <groupId>com.ruoyi</groupId> <artifactId>ruoyi-common</artifactId> </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpmime</artifactId> + </dependency> </dependencies> </project> diff --git a/yunpan-baidu/src/main/java/com/ruoyi/BackupsYunPan.java b/yunpan-baidu/src/main/java/com/ruoyi/BackupsYunPan.java new file mode 100644 index 000000000..5d9937c26 --- /dev/null +++ b/yunpan-baidu/src/main/java/com/ruoyi/BackupsYunPan.java @@ -0,0 +1,27 @@ +package com.ruoyi; + +import org.springframework.stereotype.Service; + +/** + * @Auther: Wang + * @Date: 2021/11/20 00:19 + * 功能描述: + */ + +public interface BackupsYunPan { + + + /** + * @Description: + * + * @param filePath 文件路徑 + * @param fileName 文件名称 + * @param atoken acc token + * @return + * @Date + * @author: wanghao + * + */ + public String BaiDuYunBackups(String filePath,String fileName ,String atoken); + +} diff --git a/yunpan-baidu/src/main/java/com/ruoyi/BackupsYunPanImpl.java b/yunpan-baidu/src/main/java/com/ruoyi/BackupsYunPanImpl.java new file mode 100644 index 000000000..3a2a1c83d --- /dev/null +++ b/yunpan-baidu/src/main/java/com/ruoyi/BackupsYunPanImpl.java @@ -0,0 +1,19 @@ +package com.ruoyi; + +import com.ruoyi.baiduyunpan.utils.FileUtilsBaidu; +import org.springframework.stereotype.Service; + +/** + * @Auther: Wang + * @Date: 2021/11/20 00:19 + * 功能描述: + */ +@Service +public class BackupsYunPanImpl implements BackupsYunPan{ + + + @Override + public String BaiDuYunBackups(String filePath, String fileName, String token) { + return FileUtilsBaidu.save(filePath, fileName,token); + } +} diff --git a/yunpan-baidu/src/main/java/com/ruoyi/baidu/servise/BaiduWangPanServise.java b/yunpan-baidu/src/main/java/com/ruoyi/baiduyunpan/servise/BaiduWangPanServise.java similarity index 97% rename from yunpan-baidu/src/main/java/com/ruoyi/baidu/servise/BaiduWangPanServise.java rename to yunpan-baidu/src/main/java/com/ruoyi/baiduyunpan/servise/BaiduWangPanServise.java index 094298883..62dc90373 100644 --- a/yunpan-baidu/src/main/java/com/ruoyi/baidu/servise/BaiduWangPanServise.java +++ b/yunpan-baidu/src/main/java/com/ruoyi/baiduyunpan/servise/BaiduWangPanServise.java @@ -1,4 +1,4 @@ -package com.ruoyi.baidu.servise; +package com.ruoyi.baiduyunpan.servise; diff --git a/yunpan-baidu/src/main/java/com/ruoyi/baidu/servise/impl/BaiduWangPanServiseImpl.java b/yunpan-baidu/src/main/java/com/ruoyi/baiduyunpan/servise/impl/BaiduWangPanServiseImpl.java similarity index 95% rename from yunpan-baidu/src/main/java/com/ruoyi/baidu/servise/impl/BaiduWangPanServiseImpl.java rename to yunpan-baidu/src/main/java/com/ruoyi/baiduyunpan/servise/impl/BaiduWangPanServiseImpl.java index 5b66a2945..afd11f3b1 100644 --- a/yunpan-baidu/src/main/java/com/ruoyi/baidu/servise/impl/BaiduWangPanServiseImpl.java +++ b/yunpan-baidu/src/main/java/com/ruoyi/baiduyunpan/servise/impl/BaiduWangPanServiseImpl.java @@ -1,7 +1,7 @@ -package com.ruoyi.baidu.servise.impl; +package com.ruoyi.baiduyunpan.servise.impl; import cn.hutool.http.HttpUtil; -import com.ruoyi.baidu.servise.BaiduWangPanServise; +import com.ruoyi.baiduyunpan.servise.BaiduWangPanServise; import com.ruoyi.common.constant.BaiduUrl; import org.springframework.stereotype.Service; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/Constant.java b/yunpan-baidu/src/main/java/com/ruoyi/baiduyunpan/utils/Constant.java similarity index 69% rename from ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/Constant.java rename to yunpan-baidu/src/main/java/com/ruoyi/baiduyunpan/utils/Constant.java index beafd389d..4571cd866 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/Constant.java +++ b/yunpan-baidu/src/main/java/com/ruoyi/baiduyunpan/utils/Constant.java @@ -1,9 +1,12 @@ -package com.ruoyi.web.test.controller; +package com.ruoyi.baiduyunpan.utils; /** * @Auther: Wang * @Date: 2021/07/25 02:03 * 功能描述: + * + * 文档API https://www.wenjiangs.com/doc/leikdy8r + * */ public interface Constant { String APP_ID="24066444"; @@ -13,15 +16,14 @@ public interface Constant { String SING_key="dBpomXW%duC2L8l6MW3yTpaXhX=-8oj0"; String APP_PATH="/apps/"+APP_NAME+"/"; -// https://openapi.baidu.com/oauth/2.0/authorize?response_type=code&client_id=7NpRdcorSxoqxIKAkzLXuOhVr8NQekA9&redirect_uri=https://www.baidu.com/&scope=basic,netdisk&display=tv&qrcode=1&force_login=1 - // https://openapi.baidu.com/oauth/2.0/token?grant_type=authorization_code&code=0a291eb3fd3ed6ccc74cc46bc5540191&client_id=7NpRdcorSxoqxIKAkzLXuOhVr8NQekA9&client_secret=RfvvGbkN95CuXlaoZVzzsvGiz9Her6qq&redirect_uri=oob + //https://openapi.baidu.com/oauth/2.0/authorize?response_type=code&client_id=7NpRdcorSxoqxIKAkzLXuOhVr8NQekA9&redirect_uri=https://www.baidu.com/&scope=basic,netdisk&display=tv&qrcode=1&force_login=1 + //https://openapi.baidu.com/oauth/2.0/token?grant_type=authorization_code&code=0a291eb3fd3ed6ccc74cc46bc5540191&client_id=7NpRdcorSxoqxIKAkzLXuOhVr8NQekA9&client_secret=RfvvGbkN95CuXlaoZVzzsvGiz9Her6qq&redirect_uri=oob //单位mb // 普通用户单个分片大小固定为4MB(文件大小如果小于4MB,无需切片,直接上传即可),单文件总大小上限为4G。 //普通会员用户单个分片大小上限为16MB,单文件总大小上限为10G。 //超级会员用户单个分片大小上限为32MB,单文件总大小上限为20G。 Integer UNIT=4; - //获取授权码,需要扫码登陆 String GET_CODE_URL="https://openapi.baidu.com/oauth/2.0/authorize?response_type=code&client_id="+APP_KEY+"&redirect_uri=oob&scope=basic,netdisk&display=tv&qrcode=1&force_login=1"; @@ -31,13 +33,15 @@ public interface Constant { //根据授权码换取token String GET_TOKEN_BY_CODE="https://openapi.baidu.com/oauth/2.0/token?grant_type=authorization_code&code="+CODE+"&client_id="+APP_KEY+"&client_secret="+SECRET_KEY+"&redirect_uri=oob"; + //"refresh_token": "122.035106ef57234db73fa1d6077df6b2a4.YD6wvL7Qcuh-Jsz3KUYhob9bYABdvCAAwf6pX3e.9r3fbA", + //"access_token": "121.1bbdb55745ea8eebdc6fe83f0481c676.YsAIaraM0JxC1aw_DEbopy8wLGK7mdg6mTGeR8Y.6nzOlA", + //获取到的TOKEN String RTOKEN="122.fec5f9d6dd1644c2c57c89cc510f7ec8.YBMpVZwjo9y5kSMFnVmSMJL9dj25T5X02gjLwV8.1J2sEw"; - String ATOKEN="121.d8ab3687bd67e9b245b6a10f7af7afc3.YCQGBie5JO6U7nCl-ZLVC3pX-sTUFIgnV6hH1Rw.3zI4rQ"; + String ATOKEN="121.1bbdb55745ea8eebdc6fe83f0481c676.YsAIaraM0JxC1aw_DEbopy8wLGK7mdg6mTGeR8Y.6nzOlA"; - - //操作文件 copy, mover, rename, delete - String FILE_MANAGER_URL=" https://pan.baidu.com/rest/2.0/xpan/file"; + //操作文件 method = copy, mover, rename, delete + String FILE_MANAGER_URL="https://pan.baidu.com/rest/2.0/xpan/file"; //预上传 String GET_READY_FILE_URL="https://pan.baidu.com/rest/2.0/xpan/file"; @@ -51,5 +55,4 @@ public interface Constant { //文件搜索 String FILE_SEARCH="https://pan.baidu.com/rest/2.0/xpan/file?method=search"; - } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/FileSizeUtil.java b/yunpan-baidu/src/main/java/com/ruoyi/baiduyunpan/utils/FileSizeUtil.java similarity index 99% rename from ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/FileSizeUtil.java rename to yunpan-baidu/src/main/java/com/ruoyi/baiduyunpan/utils/FileSizeUtil.java index 39a2cc6ba..e78722a8f 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/test/controller/FileSizeUtil.java +++ b/yunpan-baidu/src/main/java/com/ruoyi/baiduyunpan/utils/FileSizeUtil.java @@ -1,4 +1,4 @@ -package com.ruoyi.web.test.controller; +package com.ruoyi.baiduyunpan.utils; import java.io.File; import java.io.FileInputStream; diff --git a/yunpan-baidu/src/main/java/com/ruoyi/baiduyunpan/utils/FileUtilsBaidu.java b/yunpan-baidu/src/main/java/com/ruoyi/baiduyunpan/utils/FileUtilsBaidu.java new file mode 100644 index 000000000..996038d2e --- /dev/null +++ b/yunpan-baidu/src/main/java/com/ruoyi/baiduyunpan/utils/FileUtilsBaidu.java @@ -0,0 +1,569 @@ +package com.ruoyi.baiduyunpan.utils; + +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONObject; +import cn.hutool.log.Log; +import cn.hutool.log.LogFactory; +import com.ruoyi.baiduyunpan.utils.Constant; +import com.ruoyi.baiduyunpan.utils.FileSizeUtil; +import lombok.SneakyThrows; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; + +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.nio.channels.FileChannel; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.util.HashMap; + +/** + * @Auther: Wang + * @Date: 2021/07/25 02:02 + * 功能描述: + */ +public class FileUtilsBaidu { + + private static final Log log = LogFactory.get(); + + +// public static void main(String[] args) { +// //不能有空格 +//// String filePath = "D:\\data\\ces\\"; +//// String fileName = "day4_MySQL性能优化总结.zip"; +// String filePath = "D:\\Wang\\"; +// String fileName = "22.txt"; +// System.out.println(save(filePath, fileName)); +// } + + /** + * @Description: TODO 保存文件 + * @param: filePath 文件路径 + * @param: fileName 文件名称 + * return 文件下载地址 + */ + @SneakyThrows + public static String save(String filePath, String fileName, String token) { + //本地文件地址 + String absoluteFilePath = filePath + fileName; + //云端文件地址 + String cloudPath = Constant.APP_PATH + fileName; + + //文件分片并获取md5值 + File file = new File(absoluteFilePath); + File[] separate = separate(absoluteFilePath, Constant.UNIT); + StringBuffer md5s = new StringBuffer(); + if (separate.length == 1) { + md5s.append(getMD5(separate[0])); +// md5s.append(DigestUtils.md5Hex(new FileInputStream(separate[0]))); + } + if (separate.length > 1) { + for (int i = 0; i < separate.length; i++) { + md5s.append(getMD5(separate[i]) + "\",\""); +// md5s.append(DigestUtils.md5Hex(new FileInputStream(separate[i])) + "\",\""); + log.info("正在分片,{}{}", separate[i].toString(), i); + } + String s = md5s.toString(); + md5s = new StringBuffer(s.substring(0, md5s.length() - 3)); + } + + Long fileMax = file.length(); + + //预上传 + String precreate = precreate(cloudPath,fileMax, 0, md5s.toString(),token); + log.info("预上传{} iploadid是 {} md5{}", precreate,(String) new JSONObject(precreate).get("uploadid"),md5s.toString()); + + //分片上传 + String upload = upload(cloudPath, (String) new JSONObject(precreate).get("uploadid"), separate,token); + log.info("分片上传{}", upload); + log.info(" >>>>>>>>>>>>>>>>>>>>>>>>>>"); + + Thread.sleep(3000); + //创建文件 + + log.info("创建文件 fileName{} 文件大小{} md5:{} ID:{}", fileName, FileSizeUtil.pathSize(absoluteFilePath),md5s.toString(),(String) new JSONObject(precreate).get("uploadid")); + String create = create(fileName, fileMax, 0, md5s.toString(),(String) new JSONObject(precreate).get("uploadid"),token); + log.info("创建文件{}", create); + + //获取下载地址 + String downUrl = getDownUrl(fileName,token); + log.info("获取下载地址{}", downUrl); + + return downUrl; + } + + + /** + * @Description: TODO 获取下载地址 + * @param: fileName 文件名 + * @param: token token + */ + private static String getDownUrl(String fileName,String token) { + String fileSearch = HttpUtil.get(Constant.FILE_SEARCH + "&access_token=" + token + "&key=" + fileName + "&recursion=1&dir=" + Constant.APP_PATH); + System.out.println("fileSearch:"+fileSearch); + + JSONObject jsonObject = new JSONObject(fileSearch); + JSONArray list = jsonObject.getJSONArray("list"); + JSONObject listJSONObject = list.getJSONObject(0); + Long fs_id = listJSONObject.getLong("fs_id"); + String url = Constant.DOWN_LOUE_URL + "?method=filemetas&access_token=" + token + "&fsids=[" + fs_id + "]&dlink=1"; + String s = HttpUtil.get(url); + JSONObject sJsonObject = new JSONObject(s); + JSONArray jsonArray = sJsonObject.getJSONArray("list"); + JSONObject jsonObjectClient = jsonArray.getJSONObject(0); + String dlink = jsonObjectClient.getStr("dlink"); + return dlink; + } + + /** + * @Description: TODO 创建文件 + * @param: fileName 文件名称 + * @param: size 文件大小 字节 + * @param: isDir 0文件 1目录(设置为目录是 size要设置为0) + * @param: blockList (文件的md5值) 可以把文件分为多个,然后分批上传 + * @param: token token + * @return: java.lang.String + */ + private static String create(String fileName, Long size, Integer isDir, String blockList, String uploadid,String token) { + String strURL = Constant.FILE_MANAGER_URL + "?method=create&access_token=" + token; + HashMap<String, Object> paramMap = new HashMap<>(); + paramMap.put("path", Constant.APP_PATH + fileName); + paramMap.put("size", size); + paramMap.put("autoinit", 1); +// 文件命名策略,默认0 +// 0 为不重命名,返回冲突 +// 1 为只要path冲突即重命名 +// 2 为path冲突且block_list不同才重命名 +// 3 为覆盖 + paramMap.put("rtype", 1); + String str ="[\"" +blockList +"\"]"; + paramMap.put("block_list", str); + paramMap.put("isdir",isDir); + paramMap.put("uploadid",uploadid); +// paramMap.put("app_id",Constant.APP_ID); + String result= HttpUtil.post(strURL, paramMap); + System.out.println("block_list :" + paramMap.get("block_list")); + System.out.println("uploadid :" + paramMap.get("uploadid")); + System.out.println("path :" + paramMap.get("path")); + return result; + } + + /** + * @Description: TODO 分片上传 + * @param: path 上传到百度网盘的地址 + * @param: uploadid 上传的id + * @param: filePath 本地文件的地址 + * @param: token token + * @return: java.lang.String + */ + private static String upload(String path, String uploadid, File[] files,String token) { + try { + + for (int i = 0; i < files.length; i++) { + String url = Constant.SLICING_UPLOAD_FILE_URL + "?method=upload" + + "&access_token=" + token + + "&type=tmpfile&partseq=" + i + + "&path=" + getURLEncoderString(path) + + "&uploadid=" + uploadid; + log.info("files : {} path {}",files[i], path); + //方式一 +// HashMap<String, Object> paramMap = new HashMap<>(); +// paramMap.put("file", FileUtil.file(files[i])); +// String result= HttpUtil.post(url, paramMap); + + //方式二 + String result = sendFile(url, files[i]); + log.info("正在上传分片文件{}{}", result, i); + } + return path; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + + /** + * @Description: TODO 预上传 + * @param: cloudPath 云端路径 + * @param: size 文件大小 字节 + * @param: isDir 0文件 1目录(设置为目录是 size要设置为0) + * @param: blockList (文件的md5值) 可以把文件分为多个,然后分批上传 + * @param: token acc token + * @return: java.lang.String + */ + private static String precreate(String cloudPath, Long size, Integer isDir, String blockList,String token) { + String strURL = Constant.GET_READY_FILE_URL + "?method=precreate&access_token=" + token; + String params = "path=" + getURLEncoderString(cloudPath) + "&size=" + size + "&autoinit=1&block_list=[\"" + blockList + "\"]&isdir=" + isDir; + return open(strURL, params, "POST"); + } + + + /** + * @Description: TODO 获取md5值 + * String path 文件地址 + */ + private final static String[] strHex = {"0", "1", "2", "3", "4", "5", + "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}; + + private static String getMD5(File path) { + StringBuilder buffer = new StringBuilder(); + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] b = md.digest(org.apache.commons.io.FileUtils.readFileToByteArray(path)); + for (int value : b) { + int d = value; + if (d < 0) { + d += 256; + } + int d1 = d / 16; + int d2 = d % 16; + buffer.append(strHex[d1]).append(strHex[d2]); + } + return buffer.toString(); + } catch (Exception e) { + return null; + } + +// BigInteger bi = null; +// try { +// byte[] buffer = new byte[8192]; +// int len = 0; +// MessageDigest md = MessageDigest.getInstance("MD5"); +// +// FileInputStream fis = new FileInputStream(f); +// while ((len = fis.read(buffer)) != -1) { +// md.update(buffer, 0, len); +// } +// fis.close(); +// byte[] b = md.digest(); +// bi = new BigInteger(1, b); +// } catch (NoSuchAlgorithmException e) { +// e.printStackTrace(); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// return bi.toString(16); + } + + + /** + * @Description: TODO + * @param: strURL 网址,可以是 http://aaa?bbb=1&ccc=2 拼接的 + * @param: params 拼接的body参数也就是form表单的参数 ddd=1&eee=2 + * @param: method 请求方式 get/post/put/delte等 + * @return: java.lang.String + */ + private static String open(String strURL, String params, String method) { + try { + URL url = new URL(strURL);// 创建连接 + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setDoOutput(true); + connection.setDoInput(true); + connection.setUseCaches(false); + connection.setInstanceFollowRedirects(true); + connection.setRequestMethod(method); + connection.setRequestProperty("Accept", "application/json");// 设置接收数据的格式 + connection.setRequestProperty("Content-Type", "application/json");// 设置发送数据的格式 + connection.connect(); + OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), StandardCharsets.UTF_8);// utf-8编码 + out.append(params); + out.flush(); + out.close(); // 读取响应 + int length = connection.getContentLength();// 获取长度 + InputStream is = connection.getInputStream(); + if (length != -1) { + byte[] data = new byte[length]; + byte[] temp = new byte[512]; + int readLen = 0; + int destPos = 0; + while ((readLen = is.read(temp)) > 0) { + System.arraycopy(temp, 0, data, destPos, readLen); + destPos += readLen; + } + return new String(data, StandardCharsets.UTF_8); + } + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + + /** + * 向指定 URL 发送POST方法的请求 + * + * @param url 发送请求的 URL + * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 + * @return 所代表远程资源的响应结果 + */ + public static String sendFile(String url, String param, String file) { + if (url == null || param == null) { + return url; + } + + PrintWriter out = null; + BufferedReader in = null; + String result = ""; + try { + URL realUrl = new URL(url); + // 打开和URL之间的连接 + URLConnection conn = realUrl.openConnection(); + // 设置通用的请求属性 + conn.setRequestProperty("accept", "*/*"); + conn.setRequestProperty("connection", "Keep-Alive"); + conn.setRequestProperty("user-agent", + "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); + // 发送POST请求必须设置如下两行 + conn.setDoOutput(true); + conn.setDoInput(true); + //设置链接超时时间为2秒 + conn.setConnectTimeout(1000); + //设置读取超时为2秒 + conn.setReadTimeout(1000); + // 获取URLConnection对象对应的输出流 + out = new PrintWriter(conn.getOutputStream()); + out.write(file); + // 发送请求参数 + out.print(param); + // flush输出流的缓冲 + out.flush(); + // 定义BufferedReader输入流来读取URL的响应 + in = new BufferedReader( + new InputStreamReader(conn.getInputStream())); + String line; + while ((line = in.readLine()) != null) { + result += line; + } + } catch (Exception e) { + System.out.println(e.getMessage() + "地址:" + url); + return null; + } + //使用finally块来关闭输出流、输入流 + finally { + try { + if (out != null) { + out.close(); + } + if (in != null) { + in.close(); + } + } catch (IOException ex) { + System.out.println(ex.getMessage()); + return null; + } + } + return result; + } + + + /** + * @param: filePath + * @param: unit 单个文件大小 + * @return: 返回文件的目录 + */ + private static File[] separate(Object obj, Integer unit) { + + try { + + InputStream bis = null;//输入流用于读取文件数据 + OutputStream bos = null;//输出流用于输出分片文件至磁盘 + File file = null; + if (obj instanceof String) { + file = new File((String) obj); + } + if (obj instanceof File) { + file = (File) obj; + } + + String filePath = file.getAbsolutePath(); + File newFile = new File(filePath.substring(0, filePath.lastIndexOf("\\") + 1)); + String directoryPath = newFile.getAbsolutePath(); + long splitSize = unit * 1024 * 1024;//单片文件大小,MB + if (file.length() < splitSize) { + log.info("文件小于单个分片大小,无需分片{}", file.length()); + return new File[]{file}; + } + + + //分片二 + RandomAccessFile in=null; + RandomAccessFile out =null; + long length=file.length();//文件大小 + long count=length%splitSize==0?(length/splitSize):(length/splitSize+1);//文件分片数 + byte[] bt=new byte[1024]; + in=new RandomAccessFile(file, "r"); + for (int i = 1; i <= count; i++) { + out = new RandomAccessFile(new File(filePath+"."+i), "rw");//定义一个可读可写且后缀名为.part的二进制分片文件 + long begin = (i-1)*splitSize; + long end = i* splitSize; + int len=0; + in.seek(begin); + while (in.getFilePointer()<end&&-1!=(len=in.read(bt))) { + out.write(bt, 0, len); + } + out.close(); + } + + + //分片一 +// bis = new BufferedInputStream(new FileInputStream(file)); +// long writeByte = 0;//已读取的字节数 +// int len = 0; +// byte[] bt = new byte[1024]; +// while (-1 != (len = bis.read(bt))) { +// if (writeByte % splitSize == 0) { +// if (bos != null) { +// bos.flush(); +// bos.close(); +// } +// bos = new BufferedOutputStream(new FileOutputStream(filePath + "." + (writeByte / splitSize + 1) + ".part")); +// } +// writeByte += len; +// bos.write(bt, 0, len); +// } + + + log.info("文件分片成功!"); + + //排除被分片的文件 + if (newFile.isDirectory()) { + File[] files = newFile.listFiles(); + File[] resultFiles = new File[files.length - 1]; + int j = 0; + for (int i = 0; i < files.length; i++) { + if (!files[i].equals(file)) { + resultFiles[j] = files[i]; + j++; + } + } + return resultFiles; + } + + bos.flush(); + bos.close(); + bis.close(); + return new File[0]; + } catch (Exception e) { + log.info("文件分片失败!"); + e.printStackTrace(); + } + return null; + } + + //splitNum:要分几片,currentDir:分片后存放的位置,subSize:按多大分片 + public static File[] nioSpilt(Object object, int splitNum, String currentDir, double subSize) { + try { + File file = null; + if (object instanceof String) { + file = new File((String) object); + } + if (object instanceof String) { + file = (File) object; + } + FileInputStream fis = new FileInputStream(file); + FileChannel inputChannel = fis.getChannel(); + FileOutputStream fos; + FileChannel outputChannel; + long splitSize = (long) subSize; + long startPoint = 0; + long endPoint = splitSize; + for (int i = 1; i <= splitNum; i++) { + fos = new FileOutputStream(currentDir + i); + outputChannel = fos.getChannel(); + inputChannel.transferTo(startPoint, splitSize, outputChannel); + startPoint += splitSize; + endPoint += splitSize; + outputChannel.close(); + fos.close(); + } + inputChannel.close(); + fis.close(); + File newFile = new File(file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf("\\") + 1)); + if (newFile.isDirectory()) { + return newFile.listFiles(); + } + } catch (Exception e) { + e.printStackTrace(); + } + return new File[0]; + } + + /** + * @Description: TODO 发送文件 + * @param: url 发送地址 + * @param: file 发送文件 + * @return: java.lang.String + */ + public static String sendFile(String url, File file) { + try { + MultipartEntityBuilder builder = MultipartEntityBuilder.create(); + builder.setContentType(ContentType.MULTIPART_FORM_DATA); + builder.addBinaryBody("file", file); + String body = ""; + //创建httpclient对象 + CloseableHttpClient client = HttpClients.createDefault(); + //创建post方式请求对象 + HttpPost httpPost = new HttpPost(url); + //设置请求参数 + HttpEntity httpEntity = builder.build(); + httpPost.setEntity(httpEntity); + //执行请求操作,并拿到结果(同步阻塞) + CloseableHttpResponse response = client.execute(httpPost); + //获取结果实体 + HttpEntity entity = response.getEntity(); + if (entity != null) { + //按指定编码转换结果实体为String类型 + body = EntityUtils.toString(entity, "utf-8"); + } + EntityUtils.consume(entity); + //释放链接 + response.close(); + return body; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + + + public static String getURLEncoderString(String str) { + String result = ""; + if (null == str) { + return ""; + } + try { + result = java.net.URLEncoder.encode(str, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + return result; + } + + public static String URLDecoderString(String str) { + String result = ""; + if (null == str) { + return ""; + } + try { + result = java.net.URLDecoder.decode(str, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + return result; + } + + + + +}