From 9e5d20a305970d016bfbacf7acb903c9dc6cb248 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E8=B6=85?= <1162714483@qq.com> Date: Tue, 22 Oct 2019 21:45:35 +0800 Subject: [PATCH] init --- .gitignore | 29 +- file-common/pom.xml | 72 ++++ file-common/scp-common.iml | 133 ++++++ .../java/com/mac/common/cbb/CollectUtil.java | 60 +++ .../java/com/mac/common/cbb/DateUtil.java | 124 ++++++ .../com/mac/common/cbb/HibernateUtil.java | 31 ++ .../java/com/mac/common/cbb/HttpRequest.java | 121 ++++++ .../java/com/mac/common/cbb/MiniuiUtil.java | 15 + .../java/com/mac/common/cbb/MyBatisUtil.java | 39 ++ .../java/com/mac/common/cbb/RestResult.java | 41 ++ .../java/com/mac/common/cbb/ScpConstant.java | 6 + .../main/java/com/mac/common/cbb/Test.java | 127 ++++++ .../java/com/mac/common/cbb/Uploader.java | 208 +++++++++ .../java/com/mac/common/domain/ProxyBean.java | 64 +++ .../java/com/mac/common/domain/TableData.java | 51 +++ .../com/mac/common/domain/TableQueryBean.java | 72 ++++ .../com/mac/common/domain/TaskProcess.java | 45 ++ .../com/mac/common/domain/UploadFile.java | 74 ++++ .../java/com/mac/common/domain/sigarBean.java | 11 + .../java/com/mac/common/http/HttpsUtils.java | 246 +++++++++++ .../common/operation/EncryptOperation.java | 14 + .../mac/common/operation/FileOperation.java | 284 +++++++++++++ .../mac/common/operation/ImageOperation.java | 43 ++ .../common/operation/ReflectOperation.java | 9 + .../com/mac/common/proxy/ProxyConstant.java | 30 ++ .../com/mac/common/proxy/ProxyOrigin.java | 50 +++ .../java/com/mac/common/proxy/ProxyUtil.java | 23 + .../java/com/mac/common/util/FileUtil.java | 95 +++++ .../com/mac/common/util/PasswordUtil.java | 19 + .../java/com/mac/common/util/PathUtil.java | 93 ++++ .../src/main/resources/conf/settings.xml | 264 ++++++++++++ file-common/src/main/resources/mybatis.xml | 34 ++ .../com/mac/common/cbb/CollectUtil.class | Bin 0 -> 1817 bytes .../classes/com/mac/common/cbb/DateUtil.class | Bin 0 -> 2571 bytes .../com/mac/common/cbb/HibernateUtil.class | Bin 0 -> 1233 bytes .../com/mac/common/cbb/HttpRequest.class | Bin 0 -> 5793 bytes .../com/mac/common/cbb/MiniuiUtil.class | Bin 0 -> 775 bytes .../com/mac/common/cbb/MyBatisUtil.class | Bin 0 -> 1676 bytes .../com/mac/common/cbb/RestResult.class | Bin 0 -> 1639 bytes .../com/mac/common/cbb/ScpConstant.class | Bin 0 -> 362 bytes .../classes/com/mac/common/cbb/Test.class | Bin 0 -> 2669 bytes .../classes/com/mac/common/cbb/Uploader.class | Bin 0 -> 8353 bytes .../classes/com/mac/common/cbb/checkIp.class | Bin 0 -> 5546 bytes .../com/mac/common/domain/ProxyBean.class | Bin 0 -> 1592 bytes .../com/mac/common/domain/TableData.class | Bin 0 -> 1860 bytes .../mac/common/domain/TableQueryBean.class | Bin 0 -> 1597 bytes .../com/mac/common/domain/TaskProcess.class | Bin 0 -> 1250 bytes .../com/mac/common/domain/UploadFile.class | Bin 0 -> 1849 bytes .../com/mac/common/domain/sigarBean.class | Bin 0 -> 464 bytes .../com/mac/common/http/HttpsUtils$1.class | Bin 0 -> 865 bytes .../com/mac/common/http/HttpsUtils$2.class | Bin 0 -> 759 bytes .../com/mac/common/http/HttpsUtils.class | Bin 0 -> 9248 bytes .../common/operation/EncryptOperation.class | Bin 0 -> 742 bytes .../mac/common/operation/FileOperation.class | Bin 0 -> 6969 bytes .../mac/common/operation/ImageOperation.class | Bin 0 -> 1437 bytes .../common/operation/ReflectOperation.class | Bin 0 -> 897 bytes .../com/mac/common/proxy/ProxyConstant.class | Bin 0 -> 2276 bytes .../com/mac/common/proxy/ProxyOrigin.class | Bin 0 -> 3141 bytes .../com/mac/common/proxy/ProxyUtil.class | Bin 0 -> 1006 bytes .../com/mac/common/util/FileUtil.class | Bin 0 -> 2931 bytes .../com/mac/common/util/PasswordUtil.class | Bin 0 -> 964 bytes .../com/mac/common/util/PathUtil.class | Bin 0 -> 2724 bytes file-common/target/classes/conf/settings.xml | 264 ++++++++++++ file-common/target/classes/mybatis.xml | 34 ++ .../target/file-common-0.0.1-SNAPSHOT.jar | Bin 0 -> 48632 bytes .../target/maven-archiver/pom.properties | 4 + .../compile/default-compile/createdFiles.lst | 30 ++ .../compile/default-compile/inputFiles.lst | 27 ++ file-web/.gitignore | 29 ++ file-web/pom.xml | 197 +++++++++ file-web/src/main/docker/Dockerfile | 4 + .../java/com/mac/scp/FileApplication.java | 28 ++ .../java/com/mac/scp/api/IFileService.java | 24 ++ .../com/mac/scp/api/IFiletransferService.java | 71 ++++ .../java/com/mac/scp/api/IUserService.java | 123 ++++++ .../scp/config/cors/MyCorsRegistration.java | 15 + .../scp/config/exception/ExceptionConfig.java | 24 ++ .../config/exception/MyExceptionHandler.java | 28 ++ .../com/mac/scp/config/redis/RedisConfig.java | 45 ++ .../mac/scp/config/shiro/MyShiroRealm.java | 108 +++++ .../com/mac/scp/config/shiro/ShiroConfig.java | 143 +++++++ .../scp/config/shiro/ShiroLoginFilter.java | 51 +++ .../mac/scp/controller/FileController.java | 399 ++++++++++++++++++ .../controller/FiletransferController.java | 327 ++++++++++++++ .../mac/scp/controller/HomeController.java | 26 ++ .../mac/scp/controller/UserController.java | 244 +++++++++++ .../java/com/mac/scp/domain/FileBean.java | 135 ++++++ .../java/com/mac/scp/domain/Permission.java | 102 +++++ .../main/java/com/mac/scp/domain/Role.java | 79 ++++ .../java/com/mac/scp/domain/StorageBean.java | 47 +++ .../java/com/mac/scp/domain/TreeNode.java | 66 +++ .../java/com/mac/scp/domain/UserBean.java | 254 +++++++++++ .../com/mac/scp/domain/UserImageBean.java | 66 +++ .../java/com/mac/scp/mapper/FileMapper.java | 25 ++ .../mac/scp/mapper/FiletransferMapper.java | 32 ++ .../java/com/mac/scp/mapper/UserMapper.java | 63 +++ .../java/com/mac/scp/service/FileService.java | 141 +++++++ .../mac/scp/service/FiletransferService.java | 171 ++++++++ .../com/mac/scp/service/RequestListener.java | 24 ++ .../java/com/mac/scp/service/UserService.java | 277 ++++++++++++ .../src/main/resources/application.properties | 52 +++ .../src/main/resources/config/ehcache3.xml | 29 ++ file-web/src/main/resources/database/data.sql | 15 + .../resources/mybatis/mapper/FileMapper.xml | 105 +++++ .../mybatis/mapper/FiletransferMapper.xml | 54 +++ .../resources/mybatis/mapper/UserMapper.xml | 160 +++++++ .../main/resources/mybatis/mybatis-config.xml | 12 + .../src/main/resources/script/startWeb.bat | 2 + file-web/src/main/resources/static/index.html | 10 + .../java/com/mac/scp/ScpApplicationTests.java | 16 + .../com/mac/scp/config/redis/TestRedis.java | 42 ++ install.bat | 2 + pom.xml | 125 ++++++ 113 files changed, 6855 insertions(+), 23 deletions(-) create mode 100644 file-common/pom.xml create mode 100644 file-common/scp-common.iml create mode 100644 file-common/src/main/java/com/mac/common/cbb/CollectUtil.java create mode 100644 file-common/src/main/java/com/mac/common/cbb/DateUtil.java create mode 100644 file-common/src/main/java/com/mac/common/cbb/HibernateUtil.java create mode 100644 file-common/src/main/java/com/mac/common/cbb/HttpRequest.java create mode 100644 file-common/src/main/java/com/mac/common/cbb/MiniuiUtil.java create mode 100644 file-common/src/main/java/com/mac/common/cbb/MyBatisUtil.java create mode 100644 file-common/src/main/java/com/mac/common/cbb/RestResult.java create mode 100644 file-common/src/main/java/com/mac/common/cbb/ScpConstant.java create mode 100644 file-common/src/main/java/com/mac/common/cbb/Test.java create mode 100644 file-common/src/main/java/com/mac/common/cbb/Uploader.java create mode 100644 file-common/src/main/java/com/mac/common/domain/ProxyBean.java create mode 100644 file-common/src/main/java/com/mac/common/domain/TableData.java create mode 100644 file-common/src/main/java/com/mac/common/domain/TableQueryBean.java create mode 100644 file-common/src/main/java/com/mac/common/domain/TaskProcess.java create mode 100644 file-common/src/main/java/com/mac/common/domain/UploadFile.java create mode 100644 file-common/src/main/java/com/mac/common/domain/sigarBean.java create mode 100644 file-common/src/main/java/com/mac/common/http/HttpsUtils.java create mode 100644 file-common/src/main/java/com/mac/common/operation/EncryptOperation.java create mode 100644 file-common/src/main/java/com/mac/common/operation/FileOperation.java create mode 100644 file-common/src/main/java/com/mac/common/operation/ImageOperation.java create mode 100644 file-common/src/main/java/com/mac/common/operation/ReflectOperation.java create mode 100644 file-common/src/main/java/com/mac/common/proxy/ProxyConstant.java create mode 100644 file-common/src/main/java/com/mac/common/proxy/ProxyOrigin.java create mode 100644 file-common/src/main/java/com/mac/common/proxy/ProxyUtil.java create mode 100644 file-common/src/main/java/com/mac/common/util/FileUtil.java create mode 100644 file-common/src/main/java/com/mac/common/util/PasswordUtil.java create mode 100644 file-common/src/main/java/com/mac/common/util/PathUtil.java create mode 100644 file-common/src/main/resources/conf/settings.xml create mode 100644 file-common/src/main/resources/mybatis.xml create mode 100644 file-common/target/classes/com/mac/common/cbb/CollectUtil.class create mode 100644 file-common/target/classes/com/mac/common/cbb/DateUtil.class create mode 100644 file-common/target/classes/com/mac/common/cbb/HibernateUtil.class create mode 100644 file-common/target/classes/com/mac/common/cbb/HttpRequest.class create mode 100644 file-common/target/classes/com/mac/common/cbb/MiniuiUtil.class create mode 100644 file-common/target/classes/com/mac/common/cbb/MyBatisUtil.class create mode 100644 file-common/target/classes/com/mac/common/cbb/RestResult.class create mode 100644 file-common/target/classes/com/mac/common/cbb/ScpConstant.class create mode 100644 file-common/target/classes/com/mac/common/cbb/Test.class create mode 100644 file-common/target/classes/com/mac/common/cbb/Uploader.class create mode 100644 file-common/target/classes/com/mac/common/cbb/checkIp.class create mode 100644 file-common/target/classes/com/mac/common/domain/ProxyBean.class create mode 100644 file-common/target/classes/com/mac/common/domain/TableData.class create mode 100644 file-common/target/classes/com/mac/common/domain/TableQueryBean.class create mode 100644 file-common/target/classes/com/mac/common/domain/TaskProcess.class create mode 100644 file-common/target/classes/com/mac/common/domain/UploadFile.class create mode 100644 file-common/target/classes/com/mac/common/domain/sigarBean.class create mode 100644 file-common/target/classes/com/mac/common/http/HttpsUtils$1.class create mode 100644 file-common/target/classes/com/mac/common/http/HttpsUtils$2.class create mode 100644 file-common/target/classes/com/mac/common/http/HttpsUtils.class create mode 100644 file-common/target/classes/com/mac/common/operation/EncryptOperation.class create mode 100644 file-common/target/classes/com/mac/common/operation/FileOperation.class create mode 100644 file-common/target/classes/com/mac/common/operation/ImageOperation.class create mode 100644 file-common/target/classes/com/mac/common/operation/ReflectOperation.class create mode 100644 file-common/target/classes/com/mac/common/proxy/ProxyConstant.class create mode 100644 file-common/target/classes/com/mac/common/proxy/ProxyOrigin.class create mode 100644 file-common/target/classes/com/mac/common/proxy/ProxyUtil.class create mode 100644 file-common/target/classes/com/mac/common/util/FileUtil.class create mode 100644 file-common/target/classes/com/mac/common/util/PasswordUtil.class create mode 100644 file-common/target/classes/com/mac/common/util/PathUtil.class create mode 100644 file-common/target/classes/conf/settings.xml create mode 100644 file-common/target/classes/mybatis.xml create mode 100644 file-common/target/file-common-0.0.1-SNAPSHOT.jar create mode 100644 file-common/target/maven-archiver/pom.properties create mode 100644 file-common/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst create mode 100644 file-common/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst create mode 100644 file-web/.gitignore create mode 100644 file-web/pom.xml create mode 100644 file-web/src/main/docker/Dockerfile create mode 100644 file-web/src/main/java/com/mac/scp/FileApplication.java create mode 100644 file-web/src/main/java/com/mac/scp/api/IFileService.java create mode 100644 file-web/src/main/java/com/mac/scp/api/IFiletransferService.java create mode 100644 file-web/src/main/java/com/mac/scp/api/IUserService.java create mode 100644 file-web/src/main/java/com/mac/scp/config/cors/MyCorsRegistration.java create mode 100644 file-web/src/main/java/com/mac/scp/config/exception/ExceptionConfig.java create mode 100644 file-web/src/main/java/com/mac/scp/config/exception/MyExceptionHandler.java create mode 100644 file-web/src/main/java/com/mac/scp/config/redis/RedisConfig.java create mode 100644 file-web/src/main/java/com/mac/scp/config/shiro/MyShiroRealm.java create mode 100644 file-web/src/main/java/com/mac/scp/config/shiro/ShiroConfig.java create mode 100644 file-web/src/main/java/com/mac/scp/config/shiro/ShiroLoginFilter.java create mode 100644 file-web/src/main/java/com/mac/scp/controller/FileController.java create mode 100644 file-web/src/main/java/com/mac/scp/controller/FiletransferController.java create mode 100644 file-web/src/main/java/com/mac/scp/controller/HomeController.java create mode 100644 file-web/src/main/java/com/mac/scp/controller/UserController.java create mode 100644 file-web/src/main/java/com/mac/scp/domain/FileBean.java create mode 100644 file-web/src/main/java/com/mac/scp/domain/Permission.java create mode 100644 file-web/src/main/java/com/mac/scp/domain/Role.java create mode 100644 file-web/src/main/java/com/mac/scp/domain/StorageBean.java create mode 100644 file-web/src/main/java/com/mac/scp/domain/TreeNode.java create mode 100644 file-web/src/main/java/com/mac/scp/domain/UserBean.java create mode 100644 file-web/src/main/java/com/mac/scp/domain/UserImageBean.java create mode 100644 file-web/src/main/java/com/mac/scp/mapper/FileMapper.java create mode 100644 file-web/src/main/java/com/mac/scp/mapper/FiletransferMapper.java create mode 100644 file-web/src/main/java/com/mac/scp/mapper/UserMapper.java create mode 100644 file-web/src/main/java/com/mac/scp/service/FileService.java create mode 100644 file-web/src/main/java/com/mac/scp/service/FiletransferService.java create mode 100644 file-web/src/main/java/com/mac/scp/service/RequestListener.java create mode 100644 file-web/src/main/java/com/mac/scp/service/UserService.java create mode 100644 file-web/src/main/resources/application.properties create mode 100644 file-web/src/main/resources/config/ehcache3.xml create mode 100644 file-web/src/main/resources/database/data.sql create mode 100644 file-web/src/main/resources/mybatis/mapper/FileMapper.xml create mode 100644 file-web/src/main/resources/mybatis/mapper/FiletransferMapper.xml create mode 100644 file-web/src/main/resources/mybatis/mapper/UserMapper.xml create mode 100644 file-web/src/main/resources/mybatis/mybatis-config.xml create mode 100644 file-web/src/main/resources/script/startWeb.bat create mode 100644 file-web/src/main/resources/static/index.html create mode 100644 file-web/src/test/java/com/mac/scp/ScpApplicationTests.java create mode 100644 file-web/src/test/java/com/mac/scp/config/redis/TestRedis.java create mode 100644 install.bat create mode 100644 pom.xml diff --git a/.gitignore b/.gitignore index a1c2a23..381550d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,6 @@ -# Compiled class file -*.class - -# Log file -*.log - -# BlueJ files -*.ctxt - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.nar -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* +/.idea +/scp-config/*.iml +/release +/scp-common/target +/scp-config/target +/*.log diff --git a/file-common/pom.xml b/file-common/pom.xml new file mode 100644 index 0000000..92e0396 --- /dev/null +++ b/file-common/pom.xml @@ -0,0 +1,72 @@ + + + + com.qiwen + file + 1.0-SNAPSHOT + + 4.0.0 + com.qiwen + file-common + 0.0.1-SNAPSHOT + jar + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.0.0 + + + + + + + commons-fileupload + commons-fileupload + 1.3.3 + + + + + net.coobird + thumbnailator + 0.4.8 + + + + org.jsoup + jsoup + 1.12.1 + + + net.sourceforge.htmlunit + htmlunit + 2.36.0 + + + + + + + \ No newline at end of file diff --git a/file-common/scp-common.iml b/file-common/scp-common.iml new file mode 100644 index 0000000..1522e4a --- /dev/null +++ b/file-common/scp-common.iml @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/file-common/src/main/java/com/mac/common/cbb/CollectUtil.java b/file-common/src/main/java/com/mac/common/cbb/CollectUtil.java new file mode 100644 index 0000000..5be43ee --- /dev/null +++ b/file-common/src/main/java/com/mac/common/cbb/CollectUtil.java @@ -0,0 +1,60 @@ +package com.mac.common.cbb; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; +import java.io.UnsupportedEncodingException; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * 通信工具类 + * + * @author ma116 + */ +public class CollectUtil { + + private static final Logger LOG = LoggerFactory.getLogger(CollectUtil.class); + + /** + * java 后台获取访问客户端ip地址 + * @param request HttpServletRequest请求 + * @return IP地址 + */ + public String getClientIpAddress(HttpServletRequest request) { + String clientIp = request.getHeader("x-forwarded-for"); + if (clientIp == null || clientIp.length() == 0 + || "unknown".equalsIgnoreCase(clientIp)) { + clientIp = request.getHeader("Proxy-Client-IP"); + } + if (clientIp == null || clientIp.length() == 0 + || "unknown".equalsIgnoreCase(clientIp)) { + clientIp = request.getHeader("WL-Proxy-Client-IP"); + } + if (clientIp == null || clientIp.length() == 0 + || "unknown".equalsIgnoreCase(clientIp)) { + clientIp = request.getRemoteAddr(); + } + return clientIp; + } + + /** + * 获取本地IP + * @return IP地址 + */ + public String getLocalIp() { + InetAddress addr = null; + String ip = ""; + try { + addr = InetAddress.getLocalHost(); + } catch (UnknownHostException e) { + LOG.error("获取本地IP失败"); + } + if (addr != null) { + ip = addr.getHostAddress().toString(); + } + return ip; + } + +} diff --git a/file-common/src/main/java/com/mac/common/cbb/DateUtil.java b/file-common/src/main/java/com/mac/common/cbb/DateUtil.java new file mode 100644 index 0000000..75d3207 --- /dev/null +++ b/file-common/src/main/java/com/mac/common/cbb/DateUtil.java @@ -0,0 +1,124 @@ +package com.mac.common.cbb; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +public class DateUtil { + /** + * 获取系统当前时间 + * + * @return 系统当前时间 + */ + public static String getCurrentTime() { + Date date = new Date(); + String stringDate = String.format("%tF % proxyBeans = new ArrayList<>(); + public HttpRequest(){ + String proxyRequest = getProxyRequestResult(ProxyConstant.SERVER_PROXY_COUNT); + JSONObject resultObj = JSONObject.parseObject(proxyRequest); + String requestJson = JSON.toJSONString(resultObj.getObject( "data", List.class)); + proxyBeans = JSONArray.parseArray(requestJson, ProxyBean.class); + } + + public String sendGet(String url, Map param){ + ProxyBean proxyBean = null; + int currentRandomIndex = 0; + if (proxyBeans.size() <= 1) { + return "没有可用的代理"; + } else{ + currentRandomIndex = new Random().nextInt(proxyBeans.size()); + proxyBean = (ProxyBean) proxyBeans.get(currentRandomIndex); + } + + boolean isRequestSuccess = false; + Document doc = null; + + try { + doc = Jsoup.connect(url) + .timeout(5000) + .proxy(proxyBean.getProxyip(), proxyBean.getProxyport()) + .data(param) + .ignoreContentType(true) + .userAgent(ProxyConstant.userAgentArr[new Random().nextInt(ProxyConstant.userAgentArr.length)]) + .header("referer","http://www.sse.com.cn/assortment/stock/list/share/")//这个来源记得换.. + .get(); + isRequestSuccess = true; + } catch (IOException e){ + isRequestSuccess = false; + proxyBeans.remove(currentRandomIndex); + System.out.println("此代理不通,正在重试。。" + JSON.toJSONString(proxyBean)); + } + if (!isRequestSuccess){ + return sendGet(url, param); + } + + return doc.text(); + } + + /** + * 获取代理列表 + * @return 返回代理列表 + */ + public static String getProxyRequestResult(int count) { + StringBuffer requestResult = new StringBuffer(); + BufferedReader in = null; + + try { + URL realUrl = new URL("http://"+ProxyConstant.SERVER_IP+"/api/proxy/getproxylist?count="+count); + // 打开和URL之间的连接 + URLConnection connection = realUrl.openConnection(); + // 设置通用的请求属性 + connection.setRequestProperty("accept", "*/*"); + connection.setRequestProperty("connection", "Keep-Alive"); + connection.setRequestProperty("user-agent", + "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); + // 建立实际的连接 + connection.connect(); + // 定义 BufferedReader输入流来读取URL的响应 + in = new BufferedReader(new InputStreamReader( + connection.getInputStream(), "utf-8")); + String line; + while ((line = in.readLine()) != null) { + requestResult.append(line); + } + } + // 使用finally块来关闭输入流 + catch (MalformedURLException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (in != null) { + in.close(); + } + } catch (Exception e2) { + e2.printStackTrace(); + } + } + + + return requestResult.toString(); + } + + + public static void main(String[] args) { + //初始化对象 + HttpRequest httpRequest = new HttpRequest(); + //参数 + Map param = new HashMap<>(); + param.put("v", "3.1.9y"); + //发送请求 + String result = httpRequest.sendGet("http://www.sse.com.cn/home/public/querySearch/queryConfig/map.js", param); + System.out.println(result); + } +} \ No newline at end of file diff --git a/file-common/src/main/java/com/mac/common/cbb/MiniuiUtil.java b/file-common/src/main/java/com/mac/common/cbb/MiniuiUtil.java new file mode 100644 index 0000000..91433b8 --- /dev/null +++ b/file-common/src/main/java/com/mac/common/cbb/MiniuiUtil.java @@ -0,0 +1,15 @@ +package com.mac.common.cbb; + + +import com.mac.common.domain.TableQueryBean; + +public class MiniuiUtil { + + public static TableQueryBean getMiniuiTablePageQuery(TableQueryBean tableQueryBean) { + int pageIndex = tableQueryBean.getPage(); + int pageSize = tableQueryBean.getLimit(); + int beginCount = (pageIndex - 1) * pageSize; + tableQueryBean.setBeginCount(beginCount); + return tableQueryBean; + } +} diff --git a/file-common/src/main/java/com/mac/common/cbb/MyBatisUtil.java b/file-common/src/main/java/com/mac/common/cbb/MyBatisUtil.java new file mode 100644 index 0000000..a3ea306 --- /dev/null +++ b/file-common/src/main/java/com/mac/common/cbb/MyBatisUtil.java @@ -0,0 +1,39 @@ +package com.mac.common.cbb; + +import org.apache.ibatis.io.Resources; +import org.apache.ibatis.session.SqlSessionFactory; +import org.apache.ibatis.session.SqlSessionFactoryBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.Reader; + +public class MyBatisUtil { + private static SqlSessionFactory sqlSessionFactory = null; + private static final Logger LOG = LoggerFactory.getLogger(MyBatisUtil.class); + + static { + String resource = "mybatis.xml"; + Reader reader = null; + try { + reader = Resources.getResourceAsReader(resource); + sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); + } catch (IOException e) { + LOG.error("mybatis读取资源文件失败!"); + } finally { + try { + if (reader != null) { + reader.close(); + } + } catch (IOException e) { + LOG.error("mybatis读取资源文件失败!"); + } + } + + } + + public static SqlSessionFactory getSqlSessionFactory() { + return sqlSessionFactory; + } +} diff --git a/file-common/src/main/java/com/mac/common/cbb/RestResult.java b/file-common/src/main/java/com/mac/common/cbb/RestResult.java new file mode 100644 index 0000000..641a4ab --- /dev/null +++ b/file-common/src/main/java/com/mac/common/cbb/RestResult.java @@ -0,0 +1,41 @@ +package com.mac.common.cbb; + +public class RestResult { + private boolean success = true; + private String errorCode; + private String errorMessage; + private T data; + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public String getErrorCode() { + return errorCode; + } + + public void setErrorCode(String errorCode) { + this.errorCode = errorCode; + } + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + +} diff --git a/file-common/src/main/java/com/mac/common/cbb/ScpConstant.java b/file-common/src/main/java/com/mac/common/cbb/ScpConstant.java new file mode 100644 index 0000000..fbeac9b --- /dev/null +++ b/file-common/src/main/java/com/mac/common/cbb/ScpConstant.java @@ -0,0 +1,6 @@ +package com.mac.common.cbb; + +public class ScpConstant { + + public static final String DOT = "."; +} diff --git a/file-common/src/main/java/com/mac/common/cbb/Test.java b/file-common/src/main/java/com/mac/common/cbb/Test.java new file mode 100644 index 0000000..f8a0508 --- /dev/null +++ b/file-common/src/main/java/com/mac/common/cbb/Test.java @@ -0,0 +1,127 @@ +package com.mac.common.cbb; + +import java.io.IOException; +import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import com.alibaba.fastjson.JSONObject; + +import org.jsoup.Connection; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.select.Elements; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class Test { + //获取代理ip,记得更换,我用的是蘑菇代理的,可以换成其他的网站的 + private final static String GET_IP_URL = "http://www.goubanjia.com/"; + + public static void main(String[] args) throws InterruptedException { + List addrs = new LinkedList(); + Map addr_map = new HashMap(); + Map ipmap = new HashMap(); + ExecutorService exe = Executors.newFixedThreadPool(10); + for (int i=0 ;i<1;i++) { + Document doc = null; + try { + Connection conn = Jsoup.connect(GET_IP_URL); + Thread.sleep(1000); + doc = conn.get(); + } catch (IOException e) { + continue; + } + Elements eleTable = doc.getElementsByClass("port CFACE"); + System.out.println(eleTable); + + for (int j = 0; j < eleTable.size(); j++){ + System.out.println(eleTable.get(j).text()); + } + //System.out.println(eleTable); + //JSONObject jsonObject = JSONObject.parseObject(doc.text()); + //List> list = (List>) jsonObject.get("msg"); + //int count = list.size(); + +// for (Map map : list ) { +// String ip = (String)map.get("ip"); +// String port = (String)map.get("port") ; +// ipmap.put(ip,"1"); +// checkIp a = new checkIp("120.78.225.5", 3128,count); +// exe.execute(a); +// } + checkIp a = new checkIp("124.161.160.187", 8085,1); + exe.execute(a); + exe.shutdown(); + Thread.sleep(1000); + } + } +} + + +class checkIp implements Runnable { + private static Logger logger = LoggerFactory.getLogger(checkIp.class); + private static int suc=0; + private static int total=0; + private static int fail=0; + + private String ip ; + private int port; + private int count; + public checkIp(String ip, int port,int count) { + super(); + this.ip = ip; + this.port = port; + this.count = count; + } + + @Override + public void run() { + Random r = new Random(); + String[] ua = {"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0", + "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36 OPR/37.0.2178.32", + "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2", + "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586", + "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko", + "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)", + "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)", + "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0)", + "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 BIDUBrowser/8.3 Safari/537.36", + "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36 Core/1.47.277.400 QQBrowser/9.4.7658.400", + "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 UBrowser/5.6.12150.8 Safari/537.36", + "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 SE 2.X MetaSr 1.0", + "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36 TheWorld 7", + "Mozilla/5.0 (Windows NT 6.1; W…) Gecko/20100101 Firefox/60.0"}; + int i = r.nextInt(14); + logger.info("检测中------ {}:{}",ip,port ); + Map map = new HashMap(); + map.put("waybillNo","DD1838768852"); + try { + total ++ ; + long a = System.currentTimeMillis(); + //爬取的目标网站,url记得换下。。。!!! + Document doc = Jsoup.connect("http://query.sse.com.cn/security/stock/getStockListData2.do?isPagination=true&stockCode=&csrcCode=&areaName=&stockType=1&pageHelp.cacheSize=1&pageHelp.beginPage=1&pageHelp.pageSize=3000&pageHelp.pageNo=1&_=1553181823571") + .timeout(5000) + .proxy(ip, port) + .data(map) + .ignoreContentType(true) + .userAgent(ua[i]) + .header("referer","http://www.sse.com.cn/assortment/stock/list/share/")//这个来源记得换.. + .post(); + System.out.println(ip+":"+port+"访问时间:"+(System.currentTimeMillis() -a) + " 访问结果: "+doc.text()); + suc ++ ; + } catch (IOException e) { + e.printStackTrace(); + fail ++ ; + }finally { + if (total == count ) { + System.out.println("总次数:"+total); + System.out.println("成功次数:"+suc); + System.out.println("失败次数:"+fail); + } + } + } + +} diff --git a/file-common/src/main/java/com/mac/common/cbb/Uploader.java b/file-common/src/main/java/com/mac/common/cbb/Uploader.java new file mode 100644 index 0000000..493a900 --- /dev/null +++ b/file-common/src/main/java/com/mac/common/cbb/Uploader.java @@ -0,0 +1,208 @@ +package com.mac.common.cbb; + +import com.mac.common.domain.UploadFile; +import com.mac.common.operation.ImageOperation; +import com.mac.common.util.FileUtil; +import com.mac.common.util.PathUtil; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.apache.commons.fileupload.util.Streams; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest; + +import javax.servlet.http.HttpServletRequest; +import java.io.*; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * 文件上传辅助类 + */ +public class Uploader { + private static final Logger LOG = LoggerFactory.getLogger(Uploader.class); + + + public static final String ROOT_PATH = "upload"; + + private StandardMultipartHttpServletRequest request = null; + + // 文件允许格式 + private String[] allowFiles = {".rar", ".doc", ".docx", ".zip", ".pdf", ".txt", ".swf", ".wmv", ".gif", ".png", ".jpg", ".jpeg", ".bmp", "blob", ".mp4"}; + + + // 文件大小限制,单位KB + private int maxSize = 10000000; + + List saveUploadFileList = new ArrayList(); + + public Uploader(HttpServletRequest request) { + this.request = (StandardMultipartHttpServletRequest) request; + saveUploadFileList = new ArrayList<>(); + } + + public List upload() { + + // 判断enctype属性是否为multipart/form-data + boolean isMultipart = ServletFileUpload.isMultipartContent(this.request); + if (!isMultipart) { + UploadFile uploadFile = new UploadFile(); + uploadFile.setSuccess(0); + uploadFile.setMessage("未包含文件上传域"); + saveUploadFileList.add(uploadFile); + return saveUploadFileList; + } + DiskFileItemFactory dff = new DiskFileItemFactory();//1、创建工厂 + String savePath = getSaveFilePath(ROOT_PATH); + dff.setRepository(new File(savePath)); + try { + ServletFileUpload sfu = new ServletFileUpload(dff);//2、创建文件上传解析器 + sfu.setSizeMax(this.maxSize * 1024L); + sfu.setHeaderEncoding("utf-8");//3、解决文件名的中文乱码 + Iterator iter = this.request.getFileNames(); + while (iter.hasNext()) { + UploadFile uploadFile = new UploadFile(); + MultipartFile multipartfile = this.request.getFile(iter.next()); + InputStream inputStream = multipartfile.getInputStream(); + + String originalName = multipartfile.getOriginalFilename(); +// if (!this.checkFileType(originalName)) { +// uploadFile.setSuccess(0); +// uploadFile.setMessage("未包含文件上传域"); +// saveUploadFileList.add(uploadFile); +// continue; +// } + String fileName = getFileName(originalName); + String timeStampName = getTimeStampName(); + String fileType = FileUtil.getFileType(originalName); + uploadFile.setFileName(fileName); + uploadFile.setFileType(fileType); + uploadFile.setTimeStampName(timeStampName); + + String saveFilePath = savePath + File.separator + timeStampName + "." + fileType; + String minFilePath = savePath + File.separator + timeStampName + "_min" + "." + fileType; + uploadFile.setUrl(saveFilePath); + File file = new File(PathUtil.getStaticPath() + File.separator + saveFilePath); + File minFile = new File(PathUtil.getStaticPath() + File.separator + minFilePath); + BufferedInputStream in = null; + FileOutputStream out = null; + BufferedOutputStream output = null; + + try { + in = new BufferedInputStream(inputStream); + out = new FileOutputStream(file); + output = new BufferedOutputStream(out); + Streams.copy(in, output, true); + if (FileUtil.isImageFile(uploadFile.getFileType())){ + ImageOperation.thumbnailsImage(file, minFile, 300); + } + + } catch (FileNotFoundException e) { + LOG.error("文件没有发现" + e); + } catch (IOException e) { + LOG.error("文件读取失败" + e); + } finally { + closeStream(in, out, output); + } + uploadFile.setSuccess(1); + uploadFile.setMessage("上传成功"); + uploadFile.setFileSize(file.length()); + saveUploadFileList.add(uploadFile); + + } + } catch (IOException e) { + UploadFile uploadFile = new UploadFile(); + uploadFile.setSuccess(1); + uploadFile.setMessage("未知错误"); + saveUploadFileList.add(uploadFile); + e.printStackTrace(); + } + + return saveUploadFileList; + } + + + + private void closeStream(BufferedInputStream in, FileOutputStream out, + BufferedOutputStream output) throws IOException { + if (in != null) { + in.close(); + } + if (out != null) { + out.close(); + } + if (output != null) { + output.close(); + } + } + + /** + * 文件类型判断 + * + * @param fileName + * @return + */ + private boolean checkFileType(String fileName) { + Iterator type = Arrays.asList(this.allowFiles).iterator(); + while (type.hasNext()) { + String ext = type.next(); + if (fileName.toLowerCase().endsWith(ext)) { + return true; + } + } + return false; + } + + + + private String getFileName(String fileName){ + return fileName.substring(0, fileName.lastIndexOf(".")); + } + + /** + * 依据原始文件名生成新文件名 + * + * @return + */ + private String getTimeStampName() { + try { + SecureRandom number = SecureRandom.getInstance("SHA1PRNG"); + return "" + number.nextInt(10000) + + System.currentTimeMillis(); + } catch (NoSuchAlgorithmException e) { + LOG.error("生成安全随机数失败"); + } + return "" + + System.currentTimeMillis(); + + } + + /** + * 根据字符串创建本地目录 并按照日期建立子目录返回 + * + * @param path + * @return + */ + private String getSaveFilePath(String path) { + SimpleDateFormat formater = new SimpleDateFormat("yyyyMMdd"); + path = File.separator + path + File.separator + formater.format(new Date()); + File dir = new File(PathUtil.getStaticPath() + path); + LOG.error(PathUtil.getStaticPath() + path); + if (!dir.exists()) { + try { + boolean isSuccessMakeDir = dir.mkdirs(); + if (!isSuccessMakeDir) { + LOG.error("文件创建失败:" + PathUtil.getStaticPath() + path); + } + } catch (Exception e) { + LOG.error("目录创建失败" + PathUtil.getStaticPath() + path); + return ""; + } + } + return path; + } + +} diff --git a/file-common/src/main/java/com/mac/common/domain/ProxyBean.java b/file-common/src/main/java/com/mac/common/domain/ProxyBean.java new file mode 100644 index 0000000..cfb8dea --- /dev/null +++ b/file-common/src/main/java/com/mac/common/domain/ProxyBean.java @@ -0,0 +1,64 @@ +package com.mac.common.domain; + +import javax.persistence.*; + +/** + * 代理实体类 + */ + +public class ProxyBean { + private long proxyid; + private String proxyip; + private int proxyport; + private int testresult; + private String testtime; + + public ProxyBean(){ + + } + + public ProxyBean(String proxyip, int proxyport) { + this.proxyip = proxyip; + this.proxyport = proxyport; + } + + public String getProxyip() { + return proxyip; + } + + public void setProxyip(String proxyip) { + this.proxyip = proxyip; + } + + public long getProxyid() { + return proxyid; + } + + public void setProxyid(long proxyid) { + this.proxyid = proxyid; + } + + public int getProxyport() { + return proxyport; + } + + public void setProxyport(int proxyport) { + this.proxyport = proxyport; + } + + public int getTestresult() { + return testresult; + } + + public void setTestresult(int testresult) { + this.testresult = testresult; + } + + public String getTesttime() { + return testtime; + } + + public void setTesttime(String testtime) { + this.testtime = testtime; + } +} diff --git a/file-common/src/main/java/com/mac/common/domain/TableData.java b/file-common/src/main/java/com/mac/common/domain/TableData.java new file mode 100644 index 0000000..706bddf --- /dev/null +++ b/file-common/src/main/java/com/mac/common/domain/TableData.java @@ -0,0 +1,51 @@ +package com.mac.common.domain; + +public class TableData { + private T data; + private int count; + private String msg; + private boolean success = true; + private int code = 0; + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + +} diff --git a/file-common/src/main/java/com/mac/common/domain/TableQueryBean.java b/file-common/src/main/java/com/mac/common/domain/TableQueryBean.java new file mode 100644 index 0000000..930a833 --- /dev/null +++ b/file-common/src/main/java/com/mac/common/domain/TableQueryBean.java @@ -0,0 +1,72 @@ +package com.mac.common.domain; + +public class TableQueryBean { + //key, pageIndex, pageSize, sortField, sortOrder + + private int page; + private int limit; + private int beginCount; + + /** + * 搜索关键词 + */ + private String key; + + /** + * 排序字段 + */ + private String field; + /** + * 排序规则 + */ + private String order; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getField() { + return field; + } + + public void setField(String field) { + this.field = field; + } + + public String getOrder() { + return order; + } + + public void setOrder(String order) { + this.order = order; + } + + public int getPage() { + return page; + } + + public void setPage(int page) { + this.page = page; + } + + public int getLimit() { + return limit; + } + + public void setLimit(int limit) { + this.limit = limit; + } + + public int getBeginCount() { + return beginCount; + } + + public void setBeginCount(int beginCount) { + this.beginCount = beginCount; + } + +} diff --git a/file-common/src/main/java/com/mac/common/domain/TaskProcess.java b/file-common/src/main/java/com/mac/common/domain/TaskProcess.java new file mode 100644 index 0000000..8ad3e1c --- /dev/null +++ b/file-common/src/main/java/com/mac/common/domain/TaskProcess.java @@ -0,0 +1,45 @@ +package com.mac.common.domain; + +public class TaskProcess { + private int totalCount; + private int completeCount; + private String taskInfo; + /** + * 是否任务运行 + */ + private boolean isRunTask; + + public int getTotalCount() { + return totalCount; + } + + public void setTotalCount(int totalCount) { + this.totalCount = totalCount; + } + + public int getCompleteCount() { + return completeCount; + } + + public void setCompleteCount(int completeCount) { + this.completeCount = completeCount; + } + + public String getTaskInfo() { + return taskInfo; + } + + public void setTaskInfo(String taskInfo) { + this.taskInfo = taskInfo; + } + + public boolean isRunTask() { + return isRunTask; + } + + public void setRunTask(boolean isRunTask) { + this.isRunTask = isRunTask; + } + + +} diff --git a/file-common/src/main/java/com/mac/common/domain/UploadFile.java b/file-common/src/main/java/com/mac/common/domain/UploadFile.java new file mode 100644 index 0000000..04eca2c --- /dev/null +++ b/file-common/src/main/java/com/mac/common/domain/UploadFile.java @@ -0,0 +1,74 @@ +package com.mac.common.domain; + +/** + * md-edit插件上传图片返回数据实体类 + * + * @author ma116 + */ +public class UploadFile { + private String fileName; + private String fileType; + private long fileSize; + private String timeStampName; + private int success; + private String message; + private String url; + + public long getFileSize() { + return fileSize; + } + + public void setFileSize(long fileSize) { + this.fileSize = fileSize; + } + + public String getTimeStampName() { + return timeStampName; + } + + public void setTimeStampName(String timeStampName) { + this.timeStampName = timeStampName; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public String getFileType() { + return fileType; + } + + public void setFileType(String fileType) { + this.fileType = fileType; + } + + public int getSuccess() { + return success; + } + + public void setSuccess(int success) { + this.success = success; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + +} diff --git a/file-common/src/main/java/com/mac/common/domain/sigarBean.java b/file-common/src/main/java/com/mac/common/domain/sigarBean.java new file mode 100644 index 0000000..a2e3d7f --- /dev/null +++ b/file-common/src/main/java/com/mac/common/domain/sigarBean.java @@ -0,0 +1,11 @@ +package com.mac.common.domain; + +public class sigarBean { + private String userName; + private String computerName; + private String userDomain; + private String hostAddress; + private String hostName; + private String totalMemory; + private String freeMemory; +} diff --git a/file-common/src/main/java/com/mac/common/http/HttpsUtils.java b/file-common/src/main/java/com/mac/common/http/HttpsUtils.java new file mode 100644 index 0000000..d66c4a5 --- /dev/null +++ b/file-common/src/main/java/com/mac/common/http/HttpsUtils.java @@ -0,0 +1,246 @@ +package com.mac.common.http; + + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.TrustStrategy; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.ssl.SSLContextBuilder; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.Charset; +import java.security.GeneralSecurityException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Created by xslde on 2018/7/21 + */ +public class HttpsUtils { + private static PoolingHttpClientConnectionManager connMgr; + private static RequestConfig requestConfig; + private static final int MAX_TIMEOUT = 7000; + + private static final Logger logger = LoggerFactory.getLogger(HttpsUtils.class); + + static { + // 设置连接池 + connMgr = new PoolingHttpClientConnectionManager(); + // 设置连接池大小 + connMgr.setMaxTotal(100); + connMgr.setDefaultMaxPerRoute(connMgr.getMaxTotal()); + // Validate connections after 1 sec of inactivity + connMgr.setValidateAfterInactivity(1000); + RequestConfig.Builder configBuilder = RequestConfig.custom(); + // 设置连接超时 + configBuilder.setConnectTimeout(MAX_TIMEOUT); + // 设置读取超时 + configBuilder.setSocketTimeout(MAX_TIMEOUT); + // 设置从连接池获取连接实例的超时 + configBuilder.setConnectionRequestTimeout(MAX_TIMEOUT); + + requestConfig = configBuilder.build(); + } + + /** + * 发送 GET 请求(HTTP),不带输入数据 + * + * @param url + * @return + */ + public static String doGet(String url) { + return doGet(url, new HashMap()); + } + + /** + * 发送 GET 请求(HTTP),K-V形式 + * + * @param url + * @param params + * @return + */ + public static String doGet(String url, Map params) { + String apiUrl = url; + StringBuffer param = new StringBuffer(); + int i = 0; + for (String key : params.keySet()) { + if (i == 0) + param.append("?"); + else + param.append("&"); + param.append(key).append("=").append(params.get(key)); + i++; + } + apiUrl += param; + String result = null; + HttpClient httpClient = null; + if (apiUrl.startsWith("https")) { + httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()) + .setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build(); + } else { + httpClient = HttpClients.createDefault(); + } + try { + HttpGet httpGet = new HttpGet(apiUrl); + HttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + result = EntityUtils.toString(entity, "UTF-8"); +// if (entity != null) { +// InputStream instream = entity.getContent(); +// result = new BufferedReader(new InputStreamReader(instream)).lines().collect(Collectors.joining(System.lineSeparator())); +// } + } catch (IOException e) { + logger.error(e.getMessage()); + } + return result; + } + + /** + * 发送 POST 请求(HTTP),不带输入数据 + * + * @param apiUrl + * @return + */ + public static String doPost(String apiUrl) { + return doPost(apiUrl, new HashMap()); + } + + /** + * 发送 POST 请求,K-V形式 + * + * @param apiUrl API接口URL + * @param params 参数map + * @return + */ + public static String doPost(String apiUrl, Map params) { + CloseableHttpClient httpClient = null; + if (apiUrl.startsWith("https")) { + httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()) + .setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build(); + } else { + httpClient = HttpClients.createDefault(); + } + String httpStr = null; + HttpPost httpPost = new HttpPost(apiUrl); + CloseableHttpResponse response = null; + + try { + httpPost.setConfig(requestConfig); + List pairList = new ArrayList<>(params.size()); + for (Map.Entry entry : params.entrySet()) { + NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry.getValue().toString()); + pairList.add(pair); + } + httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("UTF-8"))); + response = httpClient.execute(httpPost); + HttpEntity entity = response.getEntity(); + httpStr = EntityUtils.toString(entity, "UTF-8"); + } catch (IOException e) { + logger.error(e.getMessage()); + } finally { + if (response != null) { + try { + EntityUtils.consume(response.getEntity()); + } catch (IOException e) { + logger.error(e.getMessage()); + } + } + } + return httpStr; + } + + /** + * 发送 POST 请求,JSON形式 + * + * @param apiUrl + * @param json json对象 + * @return + */ + public static String doPost(String apiUrl, Object json) { + CloseableHttpClient httpClient = null; + if (apiUrl.startsWith("https")) { + httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()) + .setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build(); + } else { + httpClient = HttpClients.createDefault(); + } + String httpStr = null; + HttpPost httpPost = new HttpPost(apiUrl); + CloseableHttpResponse response = null; + + try { + httpPost.setConfig(requestConfig); + StringEntity stringEntity = new StringEntity(json.toString(), "UTF-8");// 解决中文乱码问题 + stringEntity.setContentEncoding("UTF-8"); + stringEntity.setContentType("application/json"); + httpPost.setEntity(stringEntity); + response = httpClient.execute(httpPost); + HttpEntity entity = response.getEntity(); + httpStr = EntityUtils.toString(entity, "UTF-8"); + } catch (IOException e) { + logger.error(e.getMessage()); + } finally { + if (response != null) { + try { + EntityUtils.consume(response.getEntity()); + } catch (IOException e) { + logger.error(e.getMessage()); + } + } + } + return httpStr; + } + + /** + * 创建SSL安全连接 + * + * @return + */ + private static SSLConnectionSocketFactory createSSLConnSocketFactory() { + SSLConnectionSocketFactory sslsf = null; + try { + SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { + + public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { + return true; + } + }).build(); + sslsf = new SSLConnectionSocketFactory(sslContext, new HostnameVerifier() { + + @Override + public boolean verify(String arg0, SSLSession arg1) { + return true; + } + }); + } catch (GeneralSecurityException e) { + logger.error(e.getMessage()); + } + return sslsf; + } +} diff --git a/file-common/src/main/java/com/mac/common/operation/EncryptOperation.java b/file-common/src/main/java/com/mac/common/operation/EncryptOperation.java new file mode 100644 index 0000000..09743f9 --- /dev/null +++ b/file-common/src/main/java/com/mac/common/operation/EncryptOperation.java @@ -0,0 +1,14 @@ +package com.mac.common.operation; + +import org.springframework.util.DigestUtils; + +import java.io.UnsupportedEncodingException; +import java.security.NoSuchAlgorithmException; + +public class EncryptOperation { + + public static String encodeByMd5(String string) throws UnsupportedEncodingException { + return DigestUtils.md5DigestAsHex(string.getBytes("utf-8")); + } + +} \ No newline at end of file diff --git a/file-common/src/main/java/com/mac/common/operation/FileOperation.java b/file-common/src/main/java/com/mac/common/operation/FileOperation.java new file mode 100644 index 0000000..6f06114 --- /dev/null +++ b/file-common/src/main/java/com/mac/common/operation/FileOperation.java @@ -0,0 +1,284 @@ +package com.mac.common.operation; + +import com.mac.common.util.FileUtil; +import com.mac.common.util.PathUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.sql.Array; +import java.sql.SQLOutput; +import java.util.*; + +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +/** + * 文件操作 + */ +public class FileOperation { + private static Logger logger = LoggerFactory.getLogger(FileOperation.class); + /** + * 创建文件 + * + * @param fileUrl 文件路径 + * @return 新文件 + */ + public static File newFile(String fileUrl) { + File file = new File(fileUrl); + return file; + } + + /** + * 删除文件 + * @param file 文件 + * @return 是否删除成功 + */ + public static boolean deleteFile(File file) { + if (file == null) { + return false; + } + + if (!file.exists()) { + return false; + + } + + if (file.isFile()){ + return file.delete(); + } else { + for (File newfile: file.listFiles()){ + deleteFile(newfile); + } + } + return file.delete(); + } + + /** + * 删除文件 + * @param fileUrl 文件路径 + * @return 删除是否成功 + */ + public static boolean deleteFile(String fileUrl) { + File file = newFile(fileUrl); + return deleteFile(file); + } + + /** + * 得到文件大小 + * + * @param fileUrl 文件路径 + * @return 文件大小 + */ + public static long getFileSize(String fileUrl) { + File file = newFile(fileUrl); + if (file.exists()){ + return file.length(); + } + return 0; + } + + /** + * 得到文件大小 + * + * @param file 文件 + * @return 文件大小 + */ + public static long getFileSize(File file) { + if (file == null) { + return 0; + } + return file.length(); + } + + /** + * 创建目录 + * @param file 文件 + * @return 是否创建成功 + */ + public static boolean mkdir(File file) { + if (file == null) { + return false; + } + + if (file.exists()) { + return true; + } + + return file.mkdirs(); + } + + /** + * 创建目录 + * @param fileUrl 文件路径 + * @return 是否创建成功 + */ + public static boolean mkdir(String fileUrl) { + if (fileUrl == null) { + return false; + } + File file = newFile(fileUrl); + if (file.exists()) { + return true; + } + + return file.mkdirs(); + } + + /** + * 拷贝文件 + * @param fileInputStream 文件输入流 + * @param fileOutputStream 文件输出流 + * @throws IOException io异常 + */ + public static void copyFile(FileInputStream fileInputStream, FileOutputStream fileOutputStream) throws IOException { + try { + byte[] buf = new byte[4096]; //8k的缓冲区 + + int len = fileInputStream.read(buf); //数据在buf中,len代表向buf中放了多少个字节的数据,-1代表读不到 + while (len != -1) { + + fileOutputStream.write(buf, 0, len); //读多少个字节,写多少个字节 + + len = fileInputStream.read(buf); + } + + } finally { + if (fileInputStream != null) { + try { + fileInputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + if (fileOutputStream != null) { + try { + fileOutputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + + } + + + } + + /** + * 拷贝文件 + * @param src 源文件 + * @param dest 目的文件 + * @throws IOException io异常 + */ + public static void copyFile(File src, File dest) throws IOException { + FileInputStream in = new FileInputStream(src); + FileOutputStream out = new FileOutputStream(dest); + + copyFile(in, out); + + + } + + /** + * 拷贝文件 + * @param srcUrl 源路径 + * @param destUrl 目的路径 + * @throws IOException io异常 + */ + public static void copyFile(String srcUrl, String destUrl) throws IOException { + if (srcUrl == null || destUrl == null) { + return; + } + File srcFile = newFile(srcUrl); + File descFile = newFile(destUrl); + copyFile(srcFile, descFile); + } + + /** + * 文件解压缩 + * @param file 需要解压的文件 + * @param destDirPath 目的路径 + * @return 解压目录列表 + */ + public static List unzip(File file, String destDirPath) { + ZipFile zipFile = null; + Set set = new HashSet(); + // set.add("/"); + List fileEntryNameList = new ArrayList<>(); + try { + zipFile = new ZipFile(file); + Enumeration entries = zipFile.entries(); + while (entries.hasMoreElements()) { + ZipEntry entry = (ZipEntry) entries.nextElement(); + + String[] nameStrArr = entry.getName().split("/"); + String nameStr = "/"; + for (int i = 0; i < nameStrArr.length; i++){ + if (!"".equals(nameStrArr[i])){ + nameStr =nameStr + "/" + nameStrArr[i]; + set.add(nameStr); + } + + } + + logger.info("解压" + entry.getName()); + String zipPath = "/" + entry.getName(); + fileEntryNameList.add(zipPath); + //如果是文件夹,就创建个文件夹 + if (entry.isDirectory()) { + String dirPath = destDirPath + File.separator + entry.getName(); + File dir = FileOperation.newFile(dirPath); + + dir.mkdir(); + } else { + //如果是文件,就先创建一个文件,然后用io流把内容拷过去 + File targetFile = new File(destDirPath + "/" + entry.getName()); + // 保证这个文件的父文件夹必须要存在 + if (!targetFile.getParentFile().exists()) { + targetFile.getParentFile().mkdirs(); + } + targetFile.createNewFile(); + // 将压缩文件内容写入到这个文件中 + InputStream is = zipFile.getInputStream(entry); + FileOutputStream fos = new FileOutputStream(targetFile); + int len; + byte[] buf = new byte[2048]; + while ((len = is.read(buf)) != -1) { + fos.write(buf, 0, len); + } + // 关流顺序,先打开的后关闭 + fos.close(); + is.close(); + } + } + } catch (Exception e) { + throw new RuntimeException("unzip error from ZipUtils", e); + } finally { + if (zipFile != null) { + try { + zipFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + List res = new ArrayList<>(set); + return res ; + } + + public static long deleteFileFromDisk(String fileurl){ + String fileUrl = PathUtil.getStaticPath() + fileurl; + String extendName = FileUtil.getFileType(fileUrl); + String minFileUrl = fileUrl.replace("." + extendName, "_min." + extendName); + long filesize = getFileSize(fileUrl); + + FileOperation.deleteFile(fileUrl); + FileOperation.deleteFile(minFileUrl); + + return filesize; + } + + +} diff --git a/file-common/src/main/java/com/mac/common/operation/ImageOperation.java b/file-common/src/main/java/com/mac/common/operation/ImageOperation.java new file mode 100644 index 0000000..477ccd8 --- /dev/null +++ b/file-common/src/main/java/com/mac/common/operation/ImageOperation.java @@ -0,0 +1,43 @@ +package com.mac.common.operation; + +import net.coobird.thumbnailator.Thumbnails; + +import java.io.File; +import java.io.IOException; + +public class ImageOperation { + /** + * 左旋 + * @param inFile 源文件 + * @param outFile 目的文件 + * @param angle 角度 + * @throws IOException io异常 + */ + public static void leftTotation(File inFile, File outFile, int angle) throws IOException { + Thumbnails.of(inFile).scale(1).outputQuality(1).rotate(-angle).toFile(outFile); + } + + /** + * 右旋 + * @param inFile 源文件 + * @param outFile 目的文件 + * @param angle 角度 + * @throws IOException io异常 + */ + public static void rightTotation(File inFile, File outFile, int angle) throws IOException { + Thumbnails.of(inFile).scale(1).outputQuality(1).rotate(angle).toFile(outFile); + } + + /** + * 压缩 + * @param inFile 源文件 + * @param outFile 目的文件 + * @throws IOException io异常 + */ + public static void thumbnailsImage(File inFile, File outFile, int imageSize) throws IOException { + + Thumbnails.of(inFile).size(imageSize, imageSize) + .toFile(outFile); + + } +} diff --git a/file-common/src/main/java/com/mac/common/operation/ReflectOperation.java b/file-common/src/main/java/com/mac/common/operation/ReflectOperation.java new file mode 100644 index 0000000..a99476b --- /dev/null +++ b/file-common/src/main/java/com/mac/common/operation/ReflectOperation.java @@ -0,0 +1,9 @@ +package com.mac.common.operation; + +public class ReflectOperation { + + public static Object createObjectByClassName(String classname) throws ClassNotFoundException, IllegalAccessException, InstantiationException { + Class object = Class.forName(classname); + return object.newInstance(); + } +} diff --git a/file-common/src/main/java/com/mac/common/proxy/ProxyConstant.java b/file-common/src/main/java/com/mac/common/proxy/ProxyConstant.java new file mode 100644 index 0000000..dc5ffee --- /dev/null +++ b/file-common/src/main/java/com/mac/common/proxy/ProxyConstant.java @@ -0,0 +1,30 @@ +package com.mac.common.proxy; + +public class ProxyConstant { + public static final String[] userAgentArr = {"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0", + "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36 OPR/37.0.2178.32", + "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2", + "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586", + "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko", + "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)", + "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)", + "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0)", + "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 BIDUBrowser/8.3 Safari/537.36", + "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36 Core/1.47.277.400 QQBrowser/9.4.7658.400", + "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 UBrowser/5.6.12150.8 Safari/537.36", + "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 SE 2.X MetaSr 1.0", + "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36 TheWorld 7", + "Mozilla/5.0 (Windows NT 6.1; W…) Gecko/20100101 Firefox/60.0"}; + + /** + * 获取代理IP列表的服务器地址 + */ + public static final String SERVER_IP = "123.56.9.174"; + + /** + * 获取代理IP的数量 + */ + public static final int SERVER_PROXY_COUNT = 100; + +} diff --git a/file-common/src/main/java/com/mac/common/proxy/ProxyOrigin.java b/file-common/src/main/java/com/mac/common/proxy/ProxyOrigin.java new file mode 100644 index 0000000..0b6b149 --- /dev/null +++ b/file-common/src/main/java/com/mac/common/proxy/ProxyOrigin.java @@ -0,0 +1,50 @@ +package com.mac.common.proxy; + +import com.gargoylesoftware.htmlunit.BrowserVersion; +import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController; +import com.gargoylesoftware.htmlunit.WebClient; +import com.gargoylesoftware.htmlunit.html.HtmlPage; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.select.Elements; + +import java.util.ArrayList; +import java.util.List; + +public class ProxyOrigin { + public static List getConnectProxyList(){ + + final WebClient webClient = new WebClient(BrowserVersion.CHROME);//新建一个模拟谷歌Chrome浏览器的浏览器客户端对象 + + webClient.getOptions().setThrowExceptionOnScriptError(false);//当JS执行出错的时候是否抛出异常, 这里选择不需要 + webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);//当HTTP的状态非200时是否抛出异常, 这里选择不需要 + webClient.getOptions().setActiveXNative(false); + webClient.getOptions().setCssEnabled(false);//是否启用CSS, 因为不需要展现页面, 所以不需要启用 + webClient.getOptions().setJavaScriptEnabled(true); //很重要,启用JS + webClient.setAjaxController(new NicelyResynchronizingAjaxController());//很重要,设置支持AJAX + + HtmlPage page = null; + try { + page = webClient.getPage("http://www.goubanjia.com/");//尝试加载上面图片例子给出的网页 + webClient.waitForBackgroundJavaScript(1000);//异步JS执行需要耗时,所以这里线程要阻塞30秒,等待异步JS执行结束 + } catch (Exception e) { + e.printStackTrace(); + }finally { + webClient.close(); + } + String pageXml = page.asXml();//直接将加载完成的页面转换成xml格式的字符串 + + pageXml = pageXml.replaceAll("<[a-z]+ style=\"display *: *none;\">[^<>]*", " "); + + Document document = Jsoup.parse(pageXml);//获取html文档 + Elements ipElements = document.getElementsByClass("ip"); + List proxyList = new ArrayList(); + for (int i = 0; i < ipElements.size(); i++){ + proxyList.add(ipElements.get(i).text().replaceAll(" ", "")); + + System.out.println(ipElements.get(i).text().replaceAll(" ", "")); + } + + return proxyList; + } +} diff --git a/file-common/src/main/java/com/mac/common/proxy/ProxyUtil.java b/file-common/src/main/java/com/mac/common/proxy/ProxyUtil.java new file mode 100644 index 0000000..74f1a0e --- /dev/null +++ b/file-common/src/main/java/com/mac/common/proxy/ProxyUtil.java @@ -0,0 +1,23 @@ +package com.mac.common.proxy; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; + +import java.io.IOException; + +public class ProxyUtil { + + + public static boolean connectTest(String ip, int port){ + boolean isTestSuccess = true; + try { + Document doc = Jsoup.connect("http://www.ityouknow.com/") + .timeout(5000) + .proxy(ip, port) + .get(); + } catch (IOException e) { + isTestSuccess = false; + } + return isTestSuccess; + } +} diff --git a/file-common/src/main/java/com/mac/common/util/FileUtil.java b/file-common/src/main/java/com/mac/common/util/FileUtil.java new file mode 100644 index 0000000..dc72e7b --- /dev/null +++ b/file-common/src/main/java/com/mac/common/util/FileUtil.java @@ -0,0 +1,95 @@ +package com.mac.common.util; + +import java.io.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class FileUtil { + + public static final String[] IMG_FILE = {"bmp", "jpg", "png", "tif", "gif", "jpeg"}; + public static final String[] DOC_FILE = {"doc", "docx", "txt", "hlp", "wps", "rtf", "html", "pdf"}; + public static final String[] VIDEO_FILE = {"avi", "mp4", "mpg", "mov", "swf"}; + public static final String[] MUSIC_FILE = {"wav", "aif", "au", "mp3", "ram", "wma", "mmf", "amr", "aac", "flac"}; + public static final int IMAGE_TYPE = 1; + public static final int DOC_TYPE = 2; + public static final int VIDEO_TYPE = 3; + public static final int MUSIC_TYPE = 4; + + public static List getFileExtendsByType(int fileType) { + + List fileExtends; + switch (fileType) { + case IMAGE_TYPE: + fileExtends = Arrays.asList(IMG_FILE); + break; + + case DOC_TYPE: + fileExtends = Arrays.asList(DOC_FILE); + break; + case VIDEO_TYPE: + fileExtends = Arrays.asList(VIDEO_FILE); + break; + case MUSIC_TYPE: + fileExtends = Arrays.asList(MUSIC_FILE); + break; + default: + fileExtends = new ArrayList<>(); + break; + + + } + return fileExtends; + } + + /** + * 判断是否为图片文件 + * + * @param extendName 文件扩展名 + * @return 是否为图片文件 + */ + public static boolean isImageFile(String extendName) { + for (int i = 0; i < IMG_FILE.length; i++) { + if (extendName.equalsIgnoreCase(IMG_FILE[i])) { + return true; + } + } + return false; + } + + + + public static String pathSplitFormat(String filePath) { + String path = filePath.replace("///", "/") + .replace("//", "/") + .replace("\\\\\\", "\\") + .replace("\\\\", "\\"); + return path; + } + + /** + * 获取文件扩展名 + * @param fileName 文件名 + * @return 文件扩展名 + */ + public static String getFileType(String fileName) { + if (fileName.lastIndexOf(".") == -1) { + return ""; + //这里暂时用jpg,后续应该去获取真实的文件类型 + } + return fileName.substring(fileName.lastIndexOf(".") + 1); + } + + /** + * 获取不包含扩展名的文件名 + * + * @param fileName 文件名 + * @return 文件名(不带扩展名) + */ + public static String getFileNameNotExtend(String fileName) { + String fileType = getFileType(fileName); + return fileName.replace("." + fileType, ""); + } + + +} diff --git a/file-common/src/main/java/com/mac/common/util/PasswordUtil.java b/file-common/src/main/java/com/mac/common/util/PasswordUtil.java new file mode 100644 index 0000000..4ab86f2 --- /dev/null +++ b/file-common/src/main/java/com/mac/common/util/PasswordUtil.java @@ -0,0 +1,19 @@ +package com.mac.common.util; + +import java.util.Random; + +public class PasswordUtil { + public static String getSaltValue(){ + Random r = new Random(); + StringBuilder sb = new StringBuilder(16); + sb.append(r.nextInt(99999999)).append(r.nextInt(99999999)); + int len = sb.length(); + if (len < 16){ + for (int i = 0; i < 16 - len; i++){ + sb.append("0"); + } + } + String salt = sb.toString(); + return salt; + } +} diff --git a/file-common/src/main/java/com/mac/common/util/PathUtil.java b/file-common/src/main/java/com/mac/common/util/PathUtil.java new file mode 100644 index 0000000..af44c48 --- /dev/null +++ b/file-common/src/main/java/com/mac/common/util/PathUtil.java @@ -0,0 +1,93 @@ +package com.mac.common.util; + +import org.springframework.util.ResourceUtils; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; + +public class PathUtil { + /** + * 获取项目所在的根目录路径 resources路径 + * @return + */ + public static String getProjectRootPath() { + String absolutePath = null; + try { + String url = ResourceUtils.getURL("classpath:").getPath(); + absolutePath = urlDecode(new File(url).getAbsolutePath()) + File.separator; + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + + return absolutePath; + } + + /** + * 路径解码 + * @param url + * @return + */ + public static String urlDecode(String url){ + String decodeUrl = null; + try { + decodeUrl = URLDecoder.decode(url, "utf-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + return decodeUrl; + } + + /** + * 得到static路径 + * + * @return + */ + public static String getStaticPath() { + String projectRootAbsolutePath = getProjectRootPath(); + + int index = projectRootAbsolutePath.indexOf("file:"); + if (index != -1){ + projectRootAbsolutePath = projectRootAbsolutePath.substring(0, index); + } + + return projectRootAbsolutePath + "static" + File.separator; + + + } + + /** + * 依据原始文件名生成新文件名 + * + * @return + */ + public static String getFileName(String fileName) { + String getfileName = ""; + try { + SecureRandom number = SecureRandom.getInstance("SHA1PRNG"); + return getfileName = "" + number.nextInt(10000) + + System.currentTimeMillis() + getFileExt(fileName); + } catch (NoSuchAlgorithmException e) { + //LOG.error("生成安全随机数失败"); + } + return getfileName = "" + + System.currentTimeMillis() + getFileExt(fileName); + + } + + /** + * 获取文件扩展名 + * + * @return string + */ + private static String getFileExt(String fileName) { + if (fileName.lastIndexOf(".") == -1) { + return ".png"; + //这里暂时用jpg,后续应该去获取真实的文件类型 + } + return fileName.substring(fileName.lastIndexOf(".")); + } +} diff --git a/file-common/src/main/resources/conf/settings.xml b/file-common/src/main/resources/conf/settings.xml new file mode 100644 index 0000000..c1dc96b --- /dev/null +++ b/file-common/src/main/resources/conf/settings.xml @@ -0,0 +1,264 @@ + + + + + + + + D:\maven-repository + + + + + + + + + + com.spotify + + + + + + + + + + + + + + + + + + +  alimaven +  aliyun maven +  http://maven.aliyun.com/nexus/content/groups/public/ +  central + + + + + + + + + + + + diff --git a/file-common/src/main/resources/mybatis.xml b/file-common/src/main/resources/mybatis.xml new file mode 100644 index 0000000..c98dc27 --- /dev/null +++ b/file-common/src/main/resources/mybatis.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/file-common/target/classes/com/mac/common/cbb/CollectUtil.class b/file-common/target/classes/com/mac/common/cbb/CollectUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..35e69f46d4f9eee0ba4a64d0ea6e24f5ea7a3c14 GIT binary patch literal 1817 zcma)6U2_yg6g|D!?9A@YhByfX(MV7eHrXVD5I{&oaV2DR^Fcy_q9T*sW;0=SW}Tft z_!IhOl~p`q`Qihh6^IW$^58%42gKq>SnBDSB!pBzcdMqmZ{NQ6oO@6A?|=XL8-Nkm z8FXSq$H^>C;dBP?;*5^7Y8=%ursF+jKd0mU3_iel4IidqqNwAeEG}SN880g52@RzT zKE@{+$^tFr>5Bqp*$-+~)4egWY?b|5O$MU^sWHcM!gKV=_b&(}i+)uK>?=E-oLZ?b z%HXoS=+eT&7292~14peljmdDyX$tg|D}LRo+ZBsr-S@1@;-XdbT~}7Z`OtBh#;nP( z=sMC1OO5l@Y9O0DH<~Xm+qdjht0{w9t_-cEFl<;8{LICMS^4#fY=)!#k)P$-Ud@^d z1IMc|q!z@x0!RO67y-Sqi9r!kxp&3P&4qU5=A_+-2x^!VXrGkfl3$&%1G_Fm84!1d zWTJAE8Umg9J<$o)>~NgIBeQw$rsv=GCj4f2VYMO~q2qhxkhEC~fdkJROZ46>5cd;K zgN@WM#YPkT7~#j=%FOvIK}C)`syFRBYCWu28R)`6c5!v+h9BIvgQ~2mnTBZtGq^-v z24*qG8m`2+3|z)M56lGq>YbsuQA4E}R_RK4XqVBz0`dYNDg#&WsX%vB$rsTyupb9l zr>EaM+W7XnKkxpuarb^{X5-$2r@#E5;WGnQ@wtI7kT>w93jD^)#iZeyfv<3#w4XI_ zdU2Urd(IT=gn75Y?I^84uQLCq@&wZC^@Oyml5OgX_4=G<_H2I2m0m4eiY`@&s3=t1 zZI)`DAIPHJWXtyN73!)$j_GD)-4CS_fq=0kHKiPZgIi)##oob(Qfc3PxdmEf5cmwT zXEI*)HpPu`w=bj~`dek|+8u7(u7rMYC$32Re6Wf;X%t<%+2mc_eR32>_(pZ|c@sFK z#K2jSb83{|SGlq{Qc-9fcm(l)lLQ@sRAg+&Yn&Ug171frS5yfO(@P!xgJTQF>jg8h zj+O)_2cMv0a1F`tVVJF)q&O*<+RHZe7j9+>>qrX*z0Vvi5w2lmIX{Fnk#$9gy3t2G zBj~|dk}cvbT*BMD9KE=PqY?g|7~>{>qNVQ<@<`L`P5LM359E;g3*8!e^$xuw#h|PS z-&YQN<&fuBF@8wzB*$J+HZzltkuCp-wyB56nQiOXmq6hOvV}FYui+I1n?hh3gZ~(Q zA6Kg82^{0jajs5s?*x;Nkj^Q>JxxGoBG>~=ltTvn7>Ee;ZW2h)qkzFEb`OTO33Q?5 vAC*YMum+1nAT%7yWTE4o?RG2P>X$an$LRPOIn{EdjjfiOTpi~sffN4%am=Va literal 0 HcmV?d00001 diff --git a/file-common/target/classes/com/mac/common/cbb/DateUtil.class b/file-common/target/classes/com/mac/common/cbb/DateUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..c872b48137ee84ef2828120a5b64c85fcb3f2b55 GIT binary patch literal 2571 zcmb7GT~kw66kR7@H@RLQ35E(nORKbesIgUJtzcCU4JKe4pvLb@a)FDaTl}Qu5)fauws@Yg@T{Q=-Csyc$W zp&_lqhZ|umXt=2(gRF){9U7K&+`?C3e63>uIq9^lVMRv|R;A?|`M50~c^!vwM?UUq zxF^T^8XgFQrftV|FA4a^CsqXlvz4MH(3i0tYjL~0X4RI>wGu7yOr>C!R?V6%-)hx$dw#x)NJU)@xGQTyG zCDYkR=G>a?Y|t-IWQ;)6Tia%^Lg9*DS3VL`Qt1+#U=F!_wJ~3*l}*m8|7%R*JXGnpw77tHxp- zA<^8EQa7&W{twsslXi8&rHZrRs>+H5CY7bI*Vips@Hw-=q{o`boeg?B=)6y)1+*fg z7$6|zTeW6+1&^5Pg?36x%D{U#Lb)n=wM!!q9&_hM$EMw7*0v+PrL`@q;A(hez{Hxs zkXllj$l2v;Nfpmih6FBXC>pS^PP_&`*=&*T$1!GL1Dm9x!dqRH5w?LVm@zOdA9J{7 zU<;28lu+gw=x}UR#DIf}z|nV{MXIkulA^3zZN0v=wbtPYd1pZ2LKkJ;-FJ+b+&?4$xGmPx3GOekTDd2Y`=G@@B*Xw1LF%4{1DA)r|z0gfmj2r z`$jdjRWKP{Z$)>}A7T82k(lX;G(O}l8sw!6gdwC-_#EV0lB3`loO}iG3nxAd@flLa z2##`Ycn%oG2;U-jA0N;ngO>^E<9OsXeEC=K-;4(WzayCUPv-Uz%1r&tH4m>Be$Jyz z9wU*s!X4mRn6^=p1Fb%MgkwaGNL|riW-vJhIL2N>%adX_dtz!Ak;Rk$g&tAF`bbSu zp7et7F#+W#)`kw_6O1!eAHOoO9}`>;FzqC!IE(lg1iH(ep1{c_j}^K|9{q8BY7d8Y zVO)8Qp8V)5^mdrYA21L_XP{&;%3y}HS@btq=!8DS%KP4x`!qhK18X1_IBEp?VR8?B zGfdxiiL+=bz-crU92qX|Ad(0s0>zj9RA_kQIkJh+4idwAi2a1#m~gn13cbMTws}XI z%T4p3=V<)-3?bpXKtxT-&wS#=n_m;5MDS56lnA{f1HaP70{aJ?XYW7fRxhxFU$A@A z)W-}rc$vMs!eU-U3bUNeA&YCcjd?u8b!;NdgMJe(7V$lnRGDsYcVo!oGn}FBxKIA) zAQd5J=QtD0)F9d!)M;Kqc4dI57dQ)&2gpKuLmD9s7x^dn0se+h93AKj z23svYOUHBkM&$M6l^ORq%6`T7_!~Vnxr_d(XlNISnPItgPsVX2f_r@4XY2!#c(||A zaiu7!re0jamn0r#++{^vYAYz{Ad~W9Y$m$}NZ>o(84Z=!yAB3b Y4ycj`;qTFesx7xTOK8D%%bH#P7m$brF#rGn literal 0 HcmV?d00001 diff --git a/file-common/target/classes/com/mac/common/cbb/HibernateUtil.class b/file-common/target/classes/com/mac/common/cbb/HibernateUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..00a41bb10162541e140305a1e67d92f7e3f39736 GIT binary patch literal 1233 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 LxQ9zT_|*RZ7YZ(3 literal 0 HcmV?d00001 diff --git a/file-common/target/classes/com/mac/common/cbb/MiniuiUtil.class b/file-common/target/classes/com/mac/common/cbb/MiniuiUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..e99ae733ea9fd471edd443ba0e6f30186debace2 GIT binary patch literal 775 zcma)4O>fgc6r6ROI5BBcTA)B1TA);k5BS2ZrH58Rij)UkGfCQ>^MzPvum-s#N(w;AC)>oS9teBCZSTqC+K%z2WuB1eUEk;BTV9 z?sb`+w>;LU$kclQF%oDy|4e`6^kJf=x;QdbVFgx>m7SUFRF*PVR+Zd9cxI|HRWGz# zRqxN}PtWB$*+qbMfbA|G;!zimo!P+?f&PEj#zu}E&t)-g|df#P2&$n!wFB;r z-9-U$iCzcG=uyOx4bdmAN0;#SX&TQr{A_b}5cMzNN1vGT;N2~XVsWs^ literal 0 HcmV?d00001 diff --git a/file-common/target/classes/com/mac/common/cbb/MyBatisUtil.class b/file-common/target/classes/com/mac/common/cbb/MyBatisUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..91eaeb2bc8cc95a76b2cb14d93f0ea7ae610c9a5 GIT binary patch literal 1676 zcmb7FT~ixn6n@@(upul2LPPxmTMRW2V6oy?`KUlkX}gq8gUop2%x1d{8#h_pU9^ne zIOB|$devW`!+52%+ScOKJ1_hlw!@vjpxWo%Y#=Qi$7Uvb&U>D7&U?;tPBwr3bMHQY zN$6>0P;5sWqYB2-7>6bg6Dhor#!0-XU^0yqit_PR8gJtr1@ETtUI$KLO2M>1kN=5N zvV7lm>x+gNxZak)nC^NN&Db!^bxX6$MqvAz-|*2&PrFYE#PyYP0@*OicdkuVHQlXL zERRszv|YD@S^5-)*8~y^?o~@5quX`s(q^q}d8*UWNRTi%+Nb$t-n4zD>?{0c#Sb6B;81;%)3Ou`Bk!^dHanorHgf{HUZD{%5T#yr1iJM2isBF?d36-&qo^ge?gfx+muy&rcUd~;*(m#-e)`}X0D zum9S;{ouQuy`R7T`?oI@oL6xH7un?jeJkavWd=`}8jK2bH7{z=*t|JpeRbV)KWnVf zQQ1-J3hwW8J2#}Ul>$SB##F-S1;_CHsm7kPMsiXEhxy?qT!}`{&Fp2;=5fw%mX>c# zAFagj;XO!}C8YwVBlj@1+?uGE|Nr|-nvUzsg?YMrfu!YmF846^teVzvoG*(E-y|`l z4F|l)6hJ#(#w)bQU@7G% zaTBqhC`C)`5MNCF&1=LD%$uag7vdIT+4x-~ZXua%yD0RLyHNC9q&~cZ_Tp`%i5LHX zLbYQXE6X?O*7+;CV%Wx9%jv+U*kavA|D^*YbBcvE!^eK#VOM#KvSpQoG=RQ8a>KK7R_y9hX@n193c6y*84g0YA?|*$=Yw`Er?>|JeM=x?@&~BD8Wb^Wbm#4fuGw8WN zdxDHk*Kt&*BS@SI$|~RY{5Rg25;R}AkYA+Tl`88Q@hM7G_HczDQ z@;we}!MO{{V#V=Vc1t=o_LkSSoqFB=q&flqx=qeos0_XS`nl(@IsNHA7!R1+?Noa; z0Vt}H>!_d~(yUX4pF2{)xp#Ifec4ih@_}YHRPb(4zXhu_v4Sv5s1~hp5&P$RX8l^{ zdk^~&1DdyC1BP?;TcBH|uwdR^a9?_KU$ ze$azmo*R>H(Y#4FC~H!VZklBBGDEY1R;P9lr5(&&l%Ccxu?7ZOqZB*hlw#9xhi|yU znt&0W=b#Y`fb}*ahtLb`x$-X(W$ltuKX6Oa0>|(jpEZ0IaWW$%6=(^!J42DXxCvUO zmDu++cJ|fFKPmMMhsZJ$26G8Jeawy{k=;F71p;FpV`rF5d1V6PEa~`pj97?Nu_yFl zQA7eZ6T7cLtqXk3+(o*Nl@leo)87$Da?f9rd!07MxOXloJzClVxRjdHJnyLbgR58V`QGvt0qTXBJs_0~tZH?GAU4fZy&T2w;6xQ(Z< xkLCq+*GKucz`uP3fAr77!#$WKo<^Rf8Ja_ucyeYCic*)6Dmv}ZBScg5_&WZu|~lhzfo z>hu@~gz(x}<8HX@?7SfO^X5Slb~9u3eOH&dUCOdzCCwTot3tM>=ij359?gbulBuQ^ zwN!#*-B_W@QsnCCryF;U^QLQ+zB9eo^v~O@A2Y!iTZH5PZMg7vr$xEe$`NRWQ+T{T xKsbVrfMdwaL&O>N&WtfDV&Fh<@d|nwzHBpwEQ1Xa#$?C?Ot8a@@4)C``UUUgPO$(0 literal 0 HcmV?d00001 diff --git a/file-common/target/classes/com/mac/common/cbb/Test.class b/file-common/target/classes/com/mac/common/cbb/Test.class new file mode 100644 index 0000000000000000000000000000000000000000..97f8126f3757ad3ae2b8c7c440e264fb57118424 GIT binary patch literal 2669 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 NiYNU!y$Ekx{{iFj^-=%; literal 0 HcmV?d00001 diff --git a/file-common/target/classes/com/mac/common/domain/TableQueryBean.class b/file-common/target/classes/com/mac/common/domain/TableQueryBean.class new file mode 100644 index 0000000000000000000000000000000000000000..efaedba12c6bab58b5f2436e6754d46233c3173c GIT binary patch literal 1597 zcma)*TTc^F5Xa~Avc0gC(gKPIT7}vc>577hQAvc*gjfZG;eFd4%VKxeEL#)4lMk9m zOnmSI_@RvdIjt?Mr-?5!XXec1cV>2f{r>Tjh&E{}OBs5Qp){?tsI#zGJY=!K;!%no zr)X19;-lS_g2cX{WY2M(P*AodyN5sJx1kSzk|xtO~;dO`ff`G@9b6&oy5MZ427TO>J=R4B&(A?4wV1uB|!jiyb?vzTF#r74q47CD*{wDLbg z#0bVqJ!qZEc1R_B8X0^;2F180PBAX4G%72N)=Hzh(g1+Y5f)2D$XQqxw17_5zLWT> z!sZ|i<&4uj&gLM1uG0-zf)?l||N=2FWz|@$) Q#Q*S!DW{lfYDsH<0CR literal 0 HcmV?d00001 diff --git a/file-common/target/classes/com/mac/common/domain/TaskProcess.class b/file-common/target/classes/com/mac/common/domain/TaskProcess.class new file mode 100644 index 0000000000000000000000000000000000000000..abb07e3add859cc71c41e831f9c4c14ad0e293bb GIT binary patch literal 1250 zcmaiy&u-H|5XQfCoTPDV>V~G!mI7&MaZ#M(Wr;sHjYW%#x}AYo{9rV zR7f0n03Hf4;|8~J9C4ZPj_1#BzTMw{e*OaR63;bMaZp1APuW;(+H5*i99Hp6Kuf|z zPP*YVNCZSrz;HtU)5J~OS!^Yd@ntXg7z#A{7xJ^TCo&k@CrRW5<5vPTFa9tM29!kg zX9AViUf?B10wt?`Dxh}5kt?v;_X79b)E~OhKn^DqY4k%!PEKXy@p%?hlXEW?*y|I7 z?Mufd?}vds3VrDXHcvT@LdT6`nrw{SWN?d~1~Pv^315u%HSNc-8aq6je>Zv{X z8tCp|l3k;dONhjVy!bKEoIul!vdYuuk=%)-TsNZQ^@oPk11vaY1-O!PBpq6x&r z7k&Ugl<|LVw@%Al%#w5Nx#!$_e)oTG_v`nMpG34uFLcuB$q)_EDx0Tl*4V7GdB)~B zn+=UNHQG`r_ug$f2bSk3RIHv^A1t$JwHjtE4BS>@vztHsc#ga%t+}5tRQ41a4qeZw zg_d_7E!Wx|+jiP*WOo(PJPfS{YEzw{sZe&yZMoq#!t&y=Lh09j9l4RJ+j0&%-iZ?& zS|?4+6sx{%HIJ>p<+wYU4o_X|J6E-R&-5(Yg!lZGS@%85ZJ9^sP2Z~T;2;3bH=K}% z5h%I=HQ)YwE?wSZgu=cPp8EB7R)EuoPJjjltUdhqRO97EnJfkDn5dj6UoGT5J)lUX z9!fXr!bSr3a#5rsSL;cNb3jxbUE`^Ad6&26vi+XcTo4CYWR8UPm=y!P=63?yVR@i^ zU$$kwc!MTr(x7WJVo-q$gYs;K*^E-rpfMhelcCU^|6K!=>_4TqCufcw(kxz`jyI~2 z$~$AE^5(*$r|@ViJo*WbmcpYe{0J$G2zwoo39rCsD&I-@CdzKWX2oQVZenai1vEv| zh!na-w_&5jYLu&7koqODxF}sbLnRRN;%!RdhgOx+C8_<^I`Ra*463;Oq=>WK_Ke2o zgnYsPOLH+(??4xn`ii7V{R2%&neNiPm`RPgRhBL(m1LR$Q)vJbYaTNd1k-&f zQ##2sCuN$KGo_PE^I%#Sz{Kw(X37hu1u0V|$yAXtmE}yCB-1jO%mGaNR%51N!L&#f z$=zi?C+==V%CtleuH4=9C1sOLYhYR*z{KB4%rq*P9!ho6k~(cjnU>``X-TGSFufeW r#NTYpG$xo#DN`=V^h(O~NY0c?GVOrr%>X9;|A?8!1=C}3Nh^Ngv7uP;71`Y zX$m8YpL@^e_s;kA{qYIl3Pfp6UXk93y{3S#E=y=M| zxUmVf?v0d@<6O_Adla*@9LB~XoeHN4T_qcSp{UbvL_={cVouc7@T44wXKF6owG@Wt z4ktEuvAk1-+2-%fY4ODf5xNYA|F|&p{}%EvTgupDh#GAV2#5_dDXO7WF{s$CxKS~z s*eS_COGTH?O?u6VjMzMR2YV~+dUUqRWF38qqg4U6Fd)UST~_V<0I$Vmp#T5? literal 0 HcmV?d00001 diff --git a/file-common/target/classes/com/mac/common/http/HttpsUtils$1.class b/file-common/target/classes/com/mac/common/http/HttpsUtils$1.class new file mode 100644 index 0000000000000000000000000000000000000000..791747f7ab9b3ab7419f05bfbfde7212b85decfb GIT binary patch literal 865 zcma)4+iFum6kU^~JxPqF)_c_&>n-uYsi25PLPJ+4r?Ci}~{X(`Nv8aHWbO&PTWq;bMe!hUJIa=!rWB!DMe;IV@uikDmRJ8B8i4SVP@SwRLABeYtdnG4MhbfoJ1^(*p=KT&C`n8rK zsP?QT6=ul0!D%yWxAqv8WFoX-xb|N?7|LQ2lHPQj-;_^1+>xQW^-ijB(AM|}ml#%_ zsgT&g3*p2_1?A|#YS&JjRNFcuroK4rR@ROpTSlhV(}FW-ghmaQu~EYkmKhrVVuxlf z_IlnwP%|Td?tRL08i^31XgFoK@f#)&vH0^khV{QM!muWtqORR; z+@WDzE8nQFEo88c=G<$x;y>;*htTH4<1fHAHc_BINMDUUWPu)$LS94`C(W|R&5vLo z@^qPGmIl6}Lb5h1K$R?zeH6#2Sq6SgUXgU6^gfeVAiw3v#w0IB`W}>K)}-^3pj(bq)Rx5H5?(UO2yd)K=}t^%GnVB literal 0 HcmV?d00001 diff --git a/file-common/target/classes/com/mac/common/http/HttpsUtils$2.class b/file-common/target/classes/com/mac/common/http/HttpsUtils$2.class new file mode 100644 index 0000000000000000000000000000000000000000..12bcf607bcda57d61cb43bedcb4e555225dcdc24 GIT binary patch literal 759 zcmah{%WhLK5Is&p(}qAwc^4=VVv(@G1tGBrLP!x+kuDGELKf^C*CZ}Cc4fO2{1Y2i zNG$jOK7|FJfH+QyB7}g&9nYMZGd?rdUw?f50^lCHE!1(jiOnXiG;vj6<$-lJJrt<- z`XhnH(C-<6PGOySb~qcG@KTK{A{&L*sv4g{|5 zk;hI~K2q9(+QhXsws5_T6Ic=G{%>C1xzzf6yl-?8*vimy$Xy?kqo7gVi#34-|8C1E zbucO!u4m|-E4_Ye(vH%}2k!NLuV45uk?KI{sagC3&9Yw`%@pe3Qhy^3u#Fnu2v^Am zQ{%@G88zuio+2Z+K0$n(r&non8u*4a+V-LVEqb7T3a8m5lOHjv^Q<*KWQ!&9`<&Tb tWRID-qJ#B$w;Il1gYjAN)-ntNVEMUuqw~1Hvw@4agp>4IBxT*e>Q4f?wjuxk literal 0 HcmV?d00001 diff --git a/file-common/target/classes/com/mac/common/http/HttpsUtils.class b/file-common/target/classes/com/mac/common/http/HttpsUtils.class new file mode 100644 index 0000000000000000000000000000000000000000..39499ab91d1f911428759d4f72064b89eaea4626 GIT binary patch literal 9248 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 literal 0 HcmV?d00001 diff --git a/file-common/target/classes/com/mac/common/operation/FileOperation.class b/file-common/target/classes/com/mac/common/operation/FileOperation.class new file mode 100644 index 0000000000000000000000000000000000000000..29eb37ea8adbc7cf99b537a52c45dbafd587fa34 GIT binary patch literal 6969 zcmb7I33wFM9sj+(W_NaSC%_^oqG&FNB7)rjDg+crKn;g@)nzk;h0X4EcOzhHwN`7b z)v7%#6pyNH)T$M%35bHlt6HnI9`)?$Ra;wYYpa%${{Azwo7p7&zIMNF-@NyK|M$O- zH}m9y`}Y8tp{DCN3EMU7(BZ+oGWkjJcv#l^t4>kNlA&^XWcbi#->h^TDyCs)gJ7axIy9I0I?(9S=k)NyJt#4SV;G3WB zG8HP?6Df0PZ_gStyF9igNeBH?IMA|wh=xd3)BAXQc zBd{s0Y%7!xKUUdc=GUdWPKjk>J!am_QbxVYOmb@Tu5x%67&V+>OJ&(aE8#-bc zOG^#^RHz$GSRM*@n|UGGnK++vjEc3Gk*hF*<6;GW&xWo9{Su6)Gn;L}W|j)JD3$5W z(>7+Tr?o`KWxe^K9r2rYP48L-&zbW$O`0hMwTOR_sd#SDvIU#sW=7mX%T|c4F8T_Q zBBsdV+9GzPV7r+rj4wfV@3m@J%Y4)D5fhC$M&lPb(-Vi3>R75+tEEgX8>e%-%v_#2 zC8&)z-OK5bqjF1RC)ZMC^%eVA*L!pydpZl4O);Vvu@W>ho{AF~r^_(a3MH0)>j*Kmb~ zf3q?xggO)5saU=@%WPZtf5*|N{8;XW%GJVbx~DCX+d$`vF?*#N>gJ}rnd%aoa?z7W zi5sji4+>7sDo2VnCOA8ubPBxQneNTToeEej2a1Jxn$%VUi?Kw(u5Q}t9%Ad$7%zo;xt3~Rlrc1Yy?%vP`U~m$`DdD1yZikW2iFO8e7;BIb5}d3{^SP z!M*LSEe7J~lA)KeWg%G^d2%ebjy^81v|!Aa*k(K8>V_~~VQb(jRY7+es#1inQq>H> z5tvp$8LCFrGUHnq35KduV-$E|tQuF)#1&TadK1YmGi#`b8gHnBR4wDiP!rTR11E!3 zIq**3EpJ|Rg{CGN>R=pTNEzx75nvLQ8(1T=L)BzM9VWBG)fC2AL9fz8Wev8ZwVc-WM;GJ?4-2}qDf~YGAmfWa$@8oWH?e&^@eJoh^o<0O{$qHPGeE} zG$U%7p{A;72F}5!#o1>o9Pz((c}=w#>L_(I6Maa$Woy=(aj6ha{VH_c63v#c%ceKl z*A3TE`);66Hsl)1)#XF$5ngr`i2?_5bj8_!Y1Yy@%uOr$;#Ac)j8G`R{@ZPJg!%?%V8H6~#PzX_chR`@XU=P282C446M53rxL&kK+MYk2 zOy>xx$nY}6w$Dq*@@y4P9ql2Pk^uD5|=;Q!x#! z%TUBkettTcq#kmGlZcrxEF&!ur2R{p+uAXV@`<>8B^VW56t~d}m)YfPyv+7dgdFJ) ziJGjLNm^mr<~}liT`b#4@0+Q(>D=)wKbF8pB{+7tBNxUBuA}YkHy4E|CCrksT#l~~ z!%w#IJ!=799|5*WDZiYRbIwl3v7M_HK3UA+ZybQy&WQ&d90L}x21_|NYy>RBDO`o5 z=@Cl~&xe;YAiNu%)g<6;Z@Py|n}od2f$wi2Oti?1u~E^9<%G-2-wLcG=~Z0$6~O{z zSLKG#zMD@!pC>dv4!`%##(wy=IurjE1i20fP-}16Gsio3;)I(~+ca@{)EDvXL~zw5 zUe!1Fo`pmjUQ4G&ngBQgKE9X+(1!gS7#!LfX{VrEg`7Gj=3F?}M5 zB`|O%=aujWg5d)QX*f%%k5E@oV+A)wjk6s!=21hjgWk9kq4p-qb|+VE3ms22Pbe}Z zreh&L;iFiH{m3C5<5Ni2*raJ7+NG%<`dy*B2)323wnSe{T1)82c2tp*IMwz>O_5i* z!%LJ4LhVPDhI0!_*}gdk!cly)kWUGku=pl)7tO2>aV#fi&;mZXGC*Sug;3aKKrd9F zK;E|5nxgAZCvhQPJLLK;@cYEwVX>aA*%&K4y2!^QpLKL+g6>SZ_|>}j`QQlzhchfV zDdRXP;xM#aW!aNlX;Bx~@#F>clIwY#Z9*8E`6=amenz>#W!H#f*D$lq_MzC7F(25E zvJr;mm5w^muxfyGg?_545)TAB8k_rJ%$?}D5j9QC-iiGvvmt$he{OsX6|_frAA%jk zs%&};t(3H?4>PQFADW{+B30Q)dek5B+h|obS^*OA?cGkEQ_z5B+V5C=3bXkHD@Pm0 z#nkFluFqmL#QAKa^964EAj|v)zRdGqVRT)==(>`hkG{sUUnj+HlIFKb^;?*V>u@x_ zL+aO){!Qd?1LojHoXB|_aTgPJDRECFZYOb1C+=CqJ(v4&;+n)=k6Y1$KFi9dF-8MS zS`%v-iU!lKn-Sn8A0MM&Jz;Z-vrfi|!2HB6%xGb3V64b5MXD(VfOu#Y!vBV$A+0_} zEx%l3d@`J*;WLBe;@6PXkOR1e;zmGr10RuHo`-!TQelNy$V2KNUGX{Z>b7^u&r2j= z+-_7$xvc5fjoQ^s1E^ctJas3=43%FyYwzLd?ToH_F&6!n-i`Ko#@bRG|EB^Earm}NG3j8P3RyCZ6`5>b+mXMQ zmVbyO_A#;_MhzaJ43D~Gi{P_XeJ4qLjx&CpVvbxuDLupv;Pae$En71qgBU60XUXt$ zmXsIbB3nv!2OmQV>M2Ewjaxl{$kN>y&*wo=-)>A0TTYayKUkuC7x*@@MV%$HNs7WA z8Vy7O{g_;RSU(PrYSo8DgWj2;x==*hb2H{tPl;%Cq3QiNVk;VV<497ij|BVCAm|Ow zUPC_`qrs_>;4UYqior=t0OvNFKSc;S!|-^k#MBEA2V0aEMvi`j2Mw}Z(SK{PT$}=5rd^g1en!# z;HKus@F^PmxIRpGs!AW~qyF89uC8v4_y;h1Z?u9)RW_0yt&CK%^h7H5iqobJV2&KS zhfV)-b)~wRprJ zca;Z!RDQgt8t@l21MjOj_(09a-_;U)s8;gp=h^s3ZNSHB6ZWeM_%eDizXx2(j{ukR z&HqZi^Ixq3>RNsPxQ_F!>|ERUso*y5-_89Ugx$ye0q#G*PXl{ZSUth71JV?K#U{K2 z^Y8_ht`Mau!^KP(oiYXRMW#uZ60OE1oavNh7B0n?2wO>AFJpoms+$E+%3c{IoMM&2 zavY}?vm9Se3T86?;?Lsxdyf;@KD1gJ~D7>W{%042$Q1ybHSa>g*r7bDfn@TNLKP1e9d;SAE;!q6$ literal 0 HcmV?d00001 diff --git a/file-common/target/classes/com/mac/common/operation/ImageOperation.class b/file-common/target/classes/com/mac/common/operation/ImageOperation.class new file mode 100644 index 0000000000000000000000000000000000000000..5c99dca438b3583dbd986cba4af746852f2c7c7a GIT binary patch literal 1437 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 literal 0 HcmV?d00001 diff --git a/file-common/target/classes/com/mac/common/proxy/ProxyUtil.class b/file-common/target/classes/com/mac/common/proxy/ProxyUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..4f24698a89c8499665a5f9343f9e0f2044677618 GIT binary patch literal 1006 zcmaJ7vXCra37|-XfQU)Zj31~~B3@9dVug>YAO~;DG8G20J6oGs1OLE( z;)RPR#e+Y?dx6j*rsP~pC9yAFOVjYkZ~1jo(nSt=hUo*Xqi3A=dcC^T zCn`A#Rj+Q^cW}=|9pvx3cz}m49%04BV?1FfrlK!*#4!8+sgcBsUbprRX?mAJ{khSu zRNUr=U6n-qjj;^Q`LG#kR}8w^ya25Cx6&W*#8q)((=re$q2kk(#y`OW>CPFJuc-KM zl-(A@TdMp?8`2Bx@|Vg_0uky}%wv$AviU5~j*uto(utF2!9Jze!(_8*a1bN( z@AeZgiZMD3VH^b_G2m0!$dF&mtQD*;u*ZuZ&XBQCn>oXPjWc8!Ha{Y}X|I(|iN!(* zb8rY{YAmIKT#Am6pi$x-!xY&PCMc_bGKyHhWU8S?b;^`kq&wSGr1%th^LGu`Q|<*! k;|Ar-P?Qw@Bof;}iBW?NZd#b7_>e_F5CjC7BWt1j3;wv{)c^nh literal 0 HcmV?d00001 diff --git a/file-common/target/classes/com/mac/common/util/FileUtil.class b/file-common/target/classes/com/mac/common/util/FileUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..5ebcfadeca4798ed8fb47af48a000e6654d09098 GIT binary patch literal 2931 zcmaJ?33n4!6#gbjlb1AwI)x$y+adyO5F%37RuoFXXiCwPVpzm!GEGymIhjClUvS^| zeP3`v#d=Qh=#d}bU+@R`A3PlOyEBuL((0V^?z{KCyWjiX{QmbZ=K%C!CW0GqG>q#} zh@gm)U}XUn0r!SrMG(T#2s%(zuoY^89#c53Fs*Px;XZ}?h4+BMgR(yqq2j|KJQ6{> zD7NEK0gr|7xWY+=ClsDkcuL`Eg=Z9=Rd`O}d4(4gUQ~EV;bnza6kb($P2qKgHx%Af zcuV1Jg?AL*Rd`R~eT5GcK2-Qf;o}fK3E@)>DlxqK$gV_kNJHDf1fE}pWj zd@0vYft@3RoCGGEounaq@n@uHE5b1#-l@tU14#CPQj<~}0Kaaqo^g&dl;%~H0y z(D3dBeh(|HF23zM3c+Ia3nXu)Jqs z1ic5?%sjhdI(6AYhf?T8hGc2QuqRWMLf+n0wu*+WVf|wE7E^VqwU_E_u2^A#y>7TA zbk1GZ^)?B$r)<03;#du23f_=JQstVJ@ltA$%%sDcCE_R&xGjns(I3L+QG9_fqZmMc z6gLUj23EVx$;|2XcFQtONW-Hzg~Ob_cs$Nx#H08MUu*CQWoI%bL%al;Vz69w5;|KAmxm*U9yl$l|uODIVK zoX7V(%zqJ^3r5vWl(OdZ2y3zE#o-GWuGYq@&Lb)^^@n7>rJzx%@WIirsWCF|>0RjC z8y!xnvdgX%->#m8g8f*-|H%z}WffM+$P-&B)9&mXcxUI#JNwPJ1sb*!_hAR+1{>&| zq=y>lU8Hw6(6{nOr^(GCyqy-}+<61g6gvy;N5^E6Fz7H9hKWaA0qnsDsWA594){e` zTgw1^8wp2j{>eQ5G*jLq2)%(WqyYeO(sQ?UKiY(cO)%4&D zSxp*!00+2yILI0v!eL_40Gp9W4ZHmVt5~LUpJGLf`>LyF5q<|vfzu~7?bJVi`cG5F z?^L9nkx6_JT*JCt%ewTTlfxsuYNst9D|ENha$3a^+(W*^6@mXe|KiL4qP`c@5wgQD zFzyADtp^j+BYN{JqI!$FEzy?>)#_|+dwdPS+{_`l1#O(k4o+kzC$b)lgphGU=%kM< zF|F=A<2dJ|>p9;?=Nfq(G5wNR=)R8;)Z5O)Tq#cc#)Iy(^Vg zdUxt4_*#`KwML{a7pb)(b%jW+6RGv7bZb!GKp4_{s1fiKdPN~73L8b?N>SLv^QP8_ zYjLv(#6{pL5!fOESBu51j>SI5;x&Xyzm_npUq|hrJPn%DaotHIg7v(Zcd_r&Y=DNm IQ>Uqa0VHf+V*mgE literal 0 HcmV?d00001 diff --git a/file-common/target/classes/com/mac/common/util/PasswordUtil.class b/file-common/target/classes/com/mac/common/util/PasswordUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..312d6a160a06b06fa0e324d5884d7669969542d7 GIT binary patch literal 964 zcmah{-A)rh6#izn?Uu60Qb7cZ0xFhPSWx_}aDj>1Sio3?a5-%^WpTSpwp;Z9d=hTF z)tiz?;sf{+`UKv2nnd}K{;k58%6dc|cCeX*nr#=mQG_WWKXxY?) zI-c8u_}Dp4Qzj0bILp1+-49}jRu9f$m>w1U6*?a%u(l6va}WB{eZ)2`YY*{KK9^3k zVYHDv+HB<8=vmBI)-Fc%r7_FO)OKOz)2TLkH{R*u{lRx4%+;9>OsPY)kwc2oK$3r& zrKf1;(TjODRUo5f>L=u~!gf@v3yAX;hj1Pv%#g%mjN$_QX)GdxF}9t@6!>LkLR1)@sErsGyOsn1D*{HcSQ>NoLZ?M6vr~t=;$b zvc2m?Z)h(fPko;LfL`?vwe~$T0YgoFc$l+&%lp0G_nnhJ|M~q708iit6^D?HVnW3v zrc_MhqJoTy2BZ~aRVbK|pIH?>xFokP$GE&AXLAakSMeCGM)87*7x9vUmsP}ZRm#2+ zg|1>AhWzBBFr!$AVo}8sEcv-6Ei9|ZqabIt)NvFPqj*(nxKWhk=qV^GxGvCm%Car* z8G&$b-z9;_87F57w4^QDoGcgSO?O70&vPf9b__j#Np~%|u5L!WC95Q`D{VN1WI;EQ z91D(}EPGZyIjwt3vz!c5dC~NyUFVu-J(Y>$#S_NZD}N z%}aN6js$V+4h}3QIcDX}Nyi&=%64va#W0JW<=8Z!>GLHgU-rzvO>@@MjpYfw=wnuJ zgX{{#=;f?w_`&w{KJ2V6w4M#$vv#RmEIO`d=0xxo@E3mJBttK8QFxt!LoDaihxK7G*QbBn|7Ew+fR_djsRE5G|H~! z-ArcX#LVb+&MAL4nTyrtEat%I8d%De+ILIg_T|)bJJtH9Uor8s5e`8s5cG z4ev=aJ8Oj>O0b6aC6I=)w{YZyf?FCsz-@s8>q?KxjE1Ci&>$Hg{u>%T#2pPE;bW3n z^0OfT5|%wbGBll;Jg49j4WHsO4WHu+3G_<^UupOn-^j(c8d5kZ(Bu2wV1LrdmW`#6 z{G!8TEEP8Df+-x(@Ez{3%La<}qICQ{llQ3JVeRcY-8C}bvzfHOzW*#_?LE+Y10M(MA?^ww!vSB=j^%M1+^+;P}kg|1*s&gbBQv~}T8wwibw&^Pa=fTTK(hq0G0&>_BwKqGsL*9gA}u96(tZfHo{h4__| z5c;b^fQG}IYk>fcV1TQbY~QN#FNjbcI4;KHp*4gnh@|hKVeT#(??IXCzl&%Eu{Ed_ zH2nsR-wK+?e?~OjUqMS^m1aUTJIH4??7Q8?*B5+bL)d~QY~@)OPdhM#P8>tG4`&Z$ zo3M|2N2xzV2#@onmzIw4?vQA$RAn`4+`yGSSEt!rpY z6V$}v3flVvP%%awuY&3(Wx#%_9Hfz6p7fxZWVVq+$&Uoo?86wQ42}BGB$I78<%5)f z+9e**}n__lPsdkxzssu<$i=>Krrq1Fm^RIqamyDHe7Si_zm*>maDO_Fua={W2& zwzmqshn|76T#a#d4!d!l=jRAE#Z;%s(*!PZT<1Q2>;t=<_ zUBmtPb?V0`tjZUJ>asGjRF(bEm5A@FV1MW*G{z6CCW2K32OlsjYZkan?JG?GRUb~! VDqU3&l22M|uJt8wfx97${|i3JbCdu8 literal 0 HcmV?d00001 diff --git a/file-common/target/classes/conf/settings.xml b/file-common/target/classes/conf/settings.xml new file mode 100644 index 0000000..c1dc96b --- /dev/null +++ b/file-common/target/classes/conf/settings.xml @@ -0,0 +1,264 @@ + + + + + + + + D:\maven-repository + + + + + + + + + + com.spotify + + + + + + + + + + + + + + + + + + +  alimaven +  aliyun maven +  http://maven.aliyun.com/nexus/content/groups/public/ +  central + + + + + + + + + + + + diff --git a/file-common/target/classes/mybatis.xml b/file-common/target/classes/mybatis.xml new file mode 100644 index 0000000..c98dc27 --- /dev/null +++ b/file-common/target/classes/mybatis.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/file-common/target/file-common-0.0.1-SNAPSHOT.jar b/file-common/target/file-common-0.0.1-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..22e6708bec68985eaae152eabd2ec1f8ff88cfa4 GIT binary patch literal 48632 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 pL+=4R5Pl>(7yo~d0VVTeSS%wB0kB7&JYfX + + 4.0.0 + + com.qiwen + file + 1.0-SNAPSHOT + + com.qiwen + file-web + 0.0.1-SNAPSHOT + web + www.qiwenshare.com/file + jar + + 1.8 + Greenwich.SR1 + true + scp + target/../../release + ${project.artifactId}-${project.version} + + + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-server + + + org.springframework.cloud + spring-cloud-config-client + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.0.0 + + + org.springframework.boot + spring-boot-starter-websocket + + + + org.springframework + spring-context-support + RELEASE + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + + org.apache.shiro + shiro-spring + 1.4.0 + + + + + org.codehaus.jackson + jackson-mapper-asl + 1.9.13 + + + + org.fusesource + sigar + 1.6.4 + + + + + commons-fileupload + commons-fileupload + 1.3.3 + + + com.mac + scp-common + 0.0.1-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-data-redis + + + org.apache.commons + commons-pool2 + + + + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + org.apache.maven.plugins + maven-jar-plugin + + + static/** + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + package + + run + + + + + + + + + + + + + + + + + + + + + + com.spotify + docker-maven-plugin + 1.0.0 + + ${docker.image.prefix}/${project.artifactId} + src/main/docker + + + / + ${project.build.directory} + ${project.build.finalName}.jar + + + + + + + + + + + + diff --git a/file-web/src/main/docker/Dockerfile b/file-web/src/main/docker/Dockerfile new file mode 100644 index 0000000..8f99fa5 --- /dev/null +++ b/file-web/src/main/docker/Dockerfile @@ -0,0 +1,4 @@ +FROM openjdk:8-jdk-alpine +VOLUME /tmp +ADD scp-web-0.0.1-SNAPSHOT.jar app.jar +ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] \ No newline at end of file diff --git a/file-web/src/main/java/com/mac/scp/FileApplication.java b/file-web/src/main/java/com/mac/scp/FileApplication.java new file mode 100644 index 0000000..74fd21c --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/FileApplication.java @@ -0,0 +1,28 @@ +package com.mac.scp; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.context.annotation.Bean; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.web.client.RestTemplate; + +@SpringBootApplication//(exclude={DataSourceAutoConfiguration.class}) +//@EnableCaching //开启ehcache缓存 +@MapperScan("com.mac.scp.mapper") +@EnableScheduling //启用定时任务 +public class FileApplication { + + public static void main(String[] args) { + SpringApplication.run(FileApplication.class, args); + //SocketManager.getInstance(); + } + + + @Bean + @LoadBalanced + RestTemplate restTemplate() { + return new RestTemplate(); + } +} diff --git a/file-web/src/main/java/com/mac/scp/api/IFileService.java b/file-web/src/main/java/com/mac/scp/api/IFileService.java new file mode 100644 index 0000000..621c40b --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/api/IFileService.java @@ -0,0 +1,24 @@ +package com.mac.scp.api; + +import com.mac.common.cbb.RestResult; +import com.mac.scp.domain.*; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +public interface IFileService { + + void insertFile(FileBean fileBean); + void batchInsertFile(List fileBeanList); + void updateFile(FileBean fileBean); + FileBean selectFileById(FileBean fileBean); + List selectFilePathTreeByUserid(FileBean fileBean); + List selectFileList(FileBean fileBean); + List selectFileListByIds(List fileidList); + + List selectFileTreeListLikeFilePath(String filePath); + void deleteFile(FileBean fileBean); + void deleteFileByIds(List fileidList); + void updateFilepathByFilepath(String oldfilepath, String newfilepath, String filename, String extendname); + List selectFileByExtendName(List filenameList, long userid); +} diff --git a/file-web/src/main/java/com/mac/scp/api/IFiletransferService.java b/file-web/src/main/java/com/mac/scp/api/IFiletransferService.java new file mode 100644 index 0000000..1c0643a --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/api/IFiletransferService.java @@ -0,0 +1,71 @@ +package com.mac.scp.api; + +import com.mac.common.cbb.RestResult; +import com.mac.scp.domain.*; + +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +public interface IFiletransferService { + + + /** + * 删除用户头像通过id + * + * @param userImageBean 用户头像信息 + */ + void deleteUserImageById(UserImageBean userImageBean); + + + /** + * 用户头像插入数据库 + * + * @param userImageBean 用户头像信息 + * @return 插入结果 + */ + RestResult insertUserImage(UserImageBean userImageBean); + + + /** + * 上传头像 + * + * @param request 请求 + * @return 结果 + */ + RestResult uploadUserImage(HttpServletRequest request); + + /** + * 上传文件 + * @param request 请求 + * @param fileBean 文件信息 + */ + void uploadFile(HttpServletRequest request, FileBean fileBean); + + /** + * 选择用户头像 + * + * @param userId 用户id + * @return 返回用户头像列表 + */ + RestResult> selectUserImage(long userId); + + /** + * 选择用户头像通过url + * + * @param url url路径 + * @return 头像列表 + */ + List selectUserImageByUrl(String url); + + + void deleteUserImageByIds(List imageidList); + + StorageBean selectStorageBean(StorageBean storageBean); + + void insertStorageBean(StorageBean storageBean); + + void updateStorageBean(StorageBean storageBean); + + StorageBean selectStorageByUser(StorageBean storageBean); +} diff --git a/file-web/src/main/java/com/mac/scp/api/IUserService.java b/file-web/src/main/java/com/mac/scp/api/IUserService.java new file mode 100644 index 0000000..ca6d88d --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/api/IUserService.java @@ -0,0 +1,123 @@ +package com.mac.scp.api; + +import com.mac.common.cbb.RestResult; +import com.mac.common.domain.TableQueryBean; +import com.mac.scp.domain.*; + +import java.util.List; + +public interface IUserService { + + /** + * 用户注册 + * + * @param userBean 用户信息 + * @return 结果 + */ + RestResult registerUser(UserBean userBean); + + /** + * 添加用户 + * @param userBean + * @return + */ + RestResult addUser(UserBean userBean); + + /** + * 用户登陆 + * + * @param userBean 用户信息 + * @return 结果 + */ + UserBean loginUser(UserBean userBean); + + /** + * 选择admin用户 + * + * @return 用户列表 + */ + List selectAdminUserList(); + + /** + * 删除用户信息 + * + * @param userBean 用户信息 + */ + void deleteUserInfo(UserBean userBean); + + + /** + * 获取用户信息 + * + * @param userId 用户id + * @return 用户信息 + */ + UserBean getUserInfoById(long userId); + + /** + * 通過openid得到用戶信息 + * @param openid + * @return + */ + UserBean selectUserByopenid(String openid); + + /** + * 通过用户名获取用户信息 + * + * @param UserName 用户名 + * @return 用户信息 + */ + UserBean findUserInfoByName(String UserName); + + /** + * 通过用户名和密码获取用户信息 + * + * @param userName 用户名 + * @param password 密码 + * @return 用户信息 + */ + UserBean findUserInfoByNameAndPassword(String userName, String password); + + /** + * 修改用户信息 + * + * @param userBean 用户信息 + * @return 结果 + */ + RestResult updateUserInfo(UserBean userBean); + + /** + * 选择所有用户列表 + * + * @return 所有用户列表 + */ + List selectAllUserList(); + + /** + * 选择所有用户列表 + * @param tableQueryBean 查询条件 + * @return 用户列表 + */ + List selectUserList(TableQueryBean tableQueryBean); + + /** + * 选择所有用户角色 + * + * @return 角色列表 + */ + List selectRoleList(); + + /** + * 选择所有用户角色 + * @param tableQueryBean 查询条件 + * @return 权限列表 + */ + List selectPermissionList(TableQueryBean tableQueryBean); + + /** + * 获取用户数量 + * @param tableQueryBean 查询条件 + * @return 用户数量 + */ + int selectUserCountByCondition(TableQueryBean tableQueryBean); +} diff --git a/file-web/src/main/java/com/mac/scp/config/cors/MyCorsRegistration.java b/file-web/src/main/java/com/mac/scp/config/cors/MyCorsRegistration.java new file mode 100644 index 0000000..20132bc --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/config/cors/MyCorsRegistration.java @@ -0,0 +1,15 @@ +package com.mac.scp.config.cors; + +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.servlet.config.annotation.CorsRegistration; + +public class MyCorsRegistration extends CorsRegistration { + public MyCorsRegistration(String pathPattern) { + super(pathPattern); + } + + @Override + public CorsConfiguration getCorsConfiguration() { + return super.getCorsConfiguration(); + } +} \ No newline at end of file diff --git a/file-web/src/main/java/com/mac/scp/config/exception/ExceptionConfig.java b/file-web/src/main/java/com/mac/scp/config/exception/ExceptionConfig.java new file mode 100644 index 0000000..e65d91e --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/config/exception/ExceptionConfig.java @@ -0,0 +1,24 @@ +package com.mac.scp.config.exception; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver; + +import java.util.Properties; + +@Configuration +public class ExceptionConfig { + + /** + * springMVC全局异常处理框架 + * @return + */ + @Bean + public SimpleMappingExceptionResolver resolver() { + SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver(); + Properties properties = new Properties(); + properties.setProperty("org.apache.shiro.authz.UnauthorizedException", "/403"); + resolver.setExceptionMappings(properties); + return resolver; + } +} \ No newline at end of file diff --git a/file-web/src/main/java/com/mac/scp/config/exception/MyExceptionHandler.java b/file-web/src/main/java/com/mac/scp/config/exception/MyExceptionHandler.java new file mode 100644 index 0000000..9a6f4c9 --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/config/exception/MyExceptionHandler.java @@ -0,0 +1,28 @@ +package com.mac.scp.config.exception; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +/** + * 全局异常捕获 + */ +//@ControllerAdvice +//public class MyExceptionHandler { +// private static Logger logger = LoggerFactory.getLogger(MyExceptionHandler.class); +// @ExceptionHandler(value = Exception.class) +// public void defaultExceptionHandler(HttpServletRequest req, HttpSession session,Exception e){ +// //String errorSource= session.getAttribute("errorSource").toString(); +// logger.error(e.getMessage()); +// //根据抓获的异常类型,做逻辑处理,并打印日志信息 +// +// e.printStackTrace(); +// System.out.println("全局异常捕获中"); +// } +// +// +//} \ No newline at end of file diff --git a/file-web/src/main/java/com/mac/scp/config/redis/RedisConfig.java b/file-web/src/main/java/com/mac/scp/config/redis/RedisConfig.java new file mode 100644 index 0000000..d32fe00 --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/config/redis/RedisConfig.java @@ -0,0 +1,45 @@ +package com.mac.scp.config.redis; + +import org.springframework.cache.CacheManager; +import org.springframework.cache.annotation.CachingConfigurerSupport; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.cache.interceptor.KeyGenerator; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.cache.RedisCacheManager; +import org.springframework.data.redis.cache.RedisCacheWriter; +import org.springframework.data.redis.connection.RedisConnectionFactory; + +import java.lang.reflect.Method; +import java.time.Duration; + +@Configuration +@EnableCaching +public class RedisConfig extends CachingConfigurerSupport { + + @Bean + public KeyGenerator keyGenerator() { + return new KeyGenerator() { + @Override + public Object generate(Object target, Method method, Object... params) { + StringBuilder sb = new StringBuilder(); + sb.append(target.getClass().getName()); + sb.append(method.getName()); + for (Object obj : params) { + sb.append(obj.toString()); + } + return sb.toString(); + } + }; + } + + @Bean + public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { + RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() + .entryTtl(Duration.ofHours(1)); // 设置缓存有效期一小时 + return RedisCacheManager + .builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory)) + .cacheDefaults(redisCacheConfiguration).build(); + } +} \ No newline at end of file diff --git a/file-web/src/main/java/com/mac/scp/config/shiro/MyShiroRealm.java b/file-web/src/main/java/com/mac/scp/config/shiro/MyShiroRealm.java new file mode 100644 index 0000000..f4ebd42 --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/config/shiro/MyShiroRealm.java @@ -0,0 +1,108 @@ +package com.mac.scp.config.shiro; + +import com.alibaba.fastjson.JSON; +import com.mac.scp.domain.Permission; +import com.mac.scp.domain.Role; +import com.mac.scp.domain.UserBean; +import com.mac.scp.service.UserService; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.AuthenticationInfo; +import org.apache.shiro.authc.AuthenticationToken; +import org.apache.shiro.authc.SimpleAuthenticationInfo; +import org.apache.shiro.authz.AuthorizationInfo; +import org.apache.shiro.authz.SimpleAuthorizationInfo; +import org.apache.shiro.realm.AuthorizingRealm; +import org.apache.shiro.subject.PrincipalCollection; +import org.apache.shiro.util.ByteSource; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.Map; + +public class MyShiroRealm extends AuthorizingRealm { + @Resource + private UserService userInfoService; + + public static Map qqLoginInfoMap = new HashMap<>(); + + @Override + protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { + System.out.println("权限配置-->MyShiroRealm.doGetAuthorizationInfo()"); + SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); + UserBean userInfo = (UserBean) principals.getPrimaryPrincipal(); + for (Role role : userInfo.getRoleList()) { + authorizationInfo.addRole(role.getRole()); + for (Permission p : role.getPermissions()) { + authorizationInfo.addStringPermission(p.getPermission()); + } + } + return authorizationInfo; + } + + /*主要是用来进行身份认证的,也就是说验证用户输入的账号和密码是否正确。*/ + @Override + protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) + throws AuthenticationException { + System.out.println("MyShiroRealm.doGetAuthenticationInfo()"); + //获取用户的输入的账号. + String username = (String) token.getPrincipal(); + String password = new String((char[]) token.getCredentials()); + //String tempsalt = PasswordUtil.getSaltValue(); + //String newPassword = new SimpleHash("MD5", password, tempsalt, 1024).toHex(); + UserBean qquserinfo = qqLoginInfoMap.get(username + password); + SimpleAuthenticationInfo authenticationInfo = null; + if (qquserinfo != null){ //qq登录 + System.out.println(JSON.toJSONString(qquserinfo)); +// UserBean userInfo = new UserBean(); +// userInfo.setUsername(qquserinfo.getNickname()); +// userInfo.setAddrprovince(qquserinfo.getProvince()); +// userInfo.setAddrcity(qquserinfo.getCity()); +// userInfo.setBirthday(qquserinfo.getYear()); +// userInfo.setSex(qquserinfo.getGender()); +// ByteSource byteSourceSalt = ByteSource.Util.bytes(tempsalt); +// authenticationInfo = new SimpleAuthenticationInfo( +// userInfo, //用户名 +// newPassword, //密码 +// byteSourceSalt, +// getName() //realm name +// ); + UserBean userInfo = userInfoService.selectUserByopenid(password); + System.out.println("----->>userInfo=" + userInfo); + if (userInfo == null) { + return null; + } + + ByteSource byteSourceSalt = ByteSource.Util.bytes(userInfo.getSalt()); + authenticationInfo = new SimpleAuthenticationInfo( + userInfo, //用户名 + userInfo.getPassword(), //密码 + byteSourceSalt, + getName() //realm name + ); + }else { + + UserBean userInfo = userInfoService.findUserInfoByName(username); + System.out.println("----->>userInfo=" + userInfo); + if (userInfo == null) { + return null; + } + + ByteSource byteSourceSalt = ByteSource.Util.bytes(userInfo.getSalt()); + authenticationInfo = new SimpleAuthenticationInfo( + userInfo, //用户名 + userInfo.getPassword(), //密码 + byteSourceSalt, + getName() //realm name + ); + } + + + //mailService.sendLoginSafeMail(userInfo); //登录邮件 + + return authenticationInfo; + } + + + + +} \ No newline at end of file diff --git a/file-web/src/main/java/com/mac/scp/config/shiro/ShiroConfig.java b/file-web/src/main/java/com/mac/scp/config/shiro/ShiroConfig.java new file mode 100644 index 0000000..dbb4126 --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/config/shiro/ShiroConfig.java @@ -0,0 +1,143 @@ +package com.mac.scp.config.shiro; + +import com.mac.scp.config.cors.MyCorsRegistration; +import org.apache.shiro.authc.credential.HashedCredentialsMatcher; +import org.apache.shiro.mgt.SecurityManager; +import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; +import org.apache.shiro.spring.web.ShiroFilterFactoryBean; +import org.apache.shiro.web.mgt.DefaultWebSecurityManager; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; +import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Properties; + +@Configuration +public class ShiroConfig { + @Bean + public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) { + System.out.println("ShiroConfiguration.shirFilter()" + "mac"); + ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); + shiroFilterFactoryBean.setSecurityManager(securityManager); + //拦截器. + Map filterChainDefinitionMap = new LinkedHashMap(); + + //配置退出过滤器 + filterChainDefinitionMap.put("/logout", "logout"); + + // + filterChainDefinitionMap.put("/user/userlogin", "authc"); + + // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面 + shiroFilterFactoryBean.setLoginUrl("/user/userlogin"); + // 登录成功后要跳转的链接 + shiroFilterFactoryBean.setSuccessUrl("/index"); + //未授权界面; + shiroFilterFactoryBean.setUnauthorizedUrl("/403"); + //filterChainDefinitionMap.put("/**", "perms"); + shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); + return shiroFilterFactoryBean; + } + + /** + * 凭证匹配器 + * (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了 + * ) + * + * @return + */ + @Bean + public HashedCredentialsMatcher hashedCredentialsMatcher() { + HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); + hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法; + hashedCredentialsMatcher.setHashIterations(1024);//散列的次数,比如散列两次,相当于 md5(md5("")); + return hashedCredentialsMatcher; + } + + @Bean + public MyShiroRealm myShiroRealm() { + MyShiroRealm myShiroRealm = new MyShiroRealm(); + myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher()); + return myShiroRealm; + } + + + @Bean + public SecurityManager securityManager() { + DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); + securityManager.setRealm(myShiroRealm()); + return securityManager; + } + +// @Bean +// public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){ +// DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); +// advisorAutoProxyCreator.setProxyTargetClass(true); +// return advisorAutoProxyCreator; +// } + + /** + * 开启shiro aop注解支持. + * 使用代理方式;所以需要开启代码支持; + * + * @param securityManager + * @return + */ + @Bean + public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { + AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); + authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); + return authorizationAttributeSourceAdvisor; + } + + @Bean(name = "simpleMappingExceptionResolver") + public SimpleMappingExceptionResolver + createSimpleMappingExceptionResolver() { + SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver(); + Properties mappings = new Properties(); + mappings.setProperty("DatabaseException", "databaseError");//数据库异常处理 + mappings.setProperty("UnauthorizedException", "403"); + r.setExceptionMappings(mappings); // None by default + r.setDefaultErrorView("error"); // No default + r.setExceptionAttribute("ex"); // Default is "exception" + //r.setWarnLogCategory("example.MvcLogger"); // No default + return r; + } + + @Bean + public FilterRegistrationBean filterRegistrationBean() { + // 对响应头进行CORS授权 + MyCorsRegistration corsRegistration = new MyCorsRegistration("*"); + + corsRegistration + //允许向该服务器提交请求的URI,*表示全部允许 + .allowedOrigins("*") + //允许提交请求的方法,*表示全部允许 + .allowedMethods("*") + //允许的头信息,*标识全部允许 + .allowedHeaders("*") + //暴露的头信息 + .exposedHeaders("access-control-allow-headers", + "access-control-allow-methods", + "access-control-allow-origin", + "access-control-max-age", + "X-Frame-Options") + //允许Cookie跨域,在做登录校验的时候有用CrossOrigin.DEFAULT_ALLOW_CREDENTIALS + .allowCredentials(true); + + // 注册CORS过滤器 + UrlBasedCorsConfigurationSource configurationSource = new UrlBasedCorsConfigurationSource(); + //第一个参数表示过滤的url,*表示过滤所有 + configurationSource.registerCorsConfiguration("/**", corsRegistration.getCorsConfiguration()); + CorsFilter corsFilter = new CorsFilter(configurationSource); + + return new FilterRegistrationBean(corsFilter); + } + + +} \ No newline at end of file diff --git a/file-web/src/main/java/com/mac/scp/config/shiro/ShiroLoginFilter.java b/file-web/src/main/java/com/mac/scp/config/shiro/ShiroLoginFilter.java new file mode 100644 index 0000000..a049372 --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/config/shiro/ShiroLoginFilter.java @@ -0,0 +1,51 @@ +package com.mac.scp.config.shiro; + +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import javax.servlet.*; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@Order(-100) +@Component +@ServletComponentScan +@WebFilter(urlPatterns = "/*",filterName = "shiroLoginFilter") +public class ShiroLoginFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { + HttpServletResponse response = (HttpServletResponse) servletResponse; + HttpServletRequest request = (HttpServletRequest) servletRequest; + // 允许哪些Origin发起跨域请求 + String orgin = request.getHeader("Origin"); + // response.setHeader( "Access-Control-Allow-Origin", config.getInitParameter( "AccessControlAllowOrigin" ) ); + response.setHeader( "Access-Control-Allow-Origin", orgin ); + // 允许请求的方法 + response.setHeader( "Access-Control-Allow-Methods", "POST,GET,OPTIONS,DELETE,PUT" ); + //多少秒内,不需要再发送预检验请求,可以缓存该结果 + response.setHeader( "Access-Control-Max-Age", "3600" ); + // 表明它允许跨域请求包含xxx头 + response.setHeader( "Access-Control-Allow-Headers", "x-auth-token,Origin,Access-Token,X-Requested-With,Content-Type, Accept" ); + //是否允许浏览器携带用户身份信息(cookie) + response.setHeader( "Access-Control-Allow-Credentials", "true" ); + //prefight请求 + if (request.getMethod().equals( "OPTIONS" )) { + response.setStatus( 200 ); + return; + } + chain.doFilter( servletRequest, response ); + } + + @Override + public void destroy() { + + } +} \ No newline at end of file diff --git a/file-web/src/main/java/com/mac/scp/controller/FileController.java b/file-web/src/main/java/com/mac/scp/controller/FileController.java new file mode 100644 index 0000000..101122a --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/controller/FileController.java @@ -0,0 +1,399 @@ +package com.mac.scp.controller; + +import com.alibaba.fastjson.JSON; +import com.mac.common.cbb.DateUtil; +import com.mac.common.cbb.RestResult; +import com.mac.common.operation.FileOperation; +import com.mac.common.util.FileUtil; +import com.mac.common.util.PathUtil; +import com.mac.scp.api.IFileService; +import com.mac.scp.api.IFiletransferService; +import com.mac.scp.domain.*; +import org.apache.shiro.SecurityUtils; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.ModelAndView; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.util.*; + +import static com.mac.common.util.FileUtil.getFileExtendsByType; + +@RestController +@RequestMapping("/file") +public class FileController { + + @Resource + IFileService fileService; + @Resource + IFiletransferService filetransferService; + + /** + * 是否开启共享文件模式 + */ + public static Boolean isShareFile = true; + + public static long treeid = 0; + + /** + * @return + */ + @RequestMapping("/fileindex") + @ResponseBody + public ModelAndView essayIndex() { + ModelAndView mv = new ModelAndView("/file/fileIndex.html"); + return mv; + } + + /** + * 创建文件 + * + * + * @return + */ + @RequestMapping("/createfile") + @ResponseBody + public RestResult createFile(FileBean fileBean) { + RestResult restResult = new RestResult<>(); + if (!operationCheck().isSuccess()){ + return operationCheck(); + } + + UserBean sessionUserBean = (UserBean) SecurityUtils.getSubject().getPrincipal(); + fileBean.setUserid(sessionUserBean.getUserId()); + + fileBean.setUploadtime(DateUtil.getCurrentTime()); + + fileService.insertFile(fileBean); + restResult.setSuccess(true); + return restResult; + } + + @RequestMapping("/getfilelist") + @ResponseBody + public RestResult> getFileList(FileBean fileBean){ + RestResult> restResult = new RestResult<>(); + UserBean sessionUserBean = (UserBean) SecurityUtils.getSubject().getPrincipal(); + if(isShareFile){ + fileBean.setUserid(2); + }else { + fileBean.setUserid(sessionUserBean.getUserId()); + } + + fileBean.setFilepath(PathUtil.urlDecode(fileBean.getFilepath())); + List fileList = fileService.selectFileList(fileBean); + + if ("/".equals(fileBean.getFilepath())){ + FileBean albumFile = new FileBean(); + albumFile.setFilename("我的相册"); + + albumFile.setFilepath("/"); + albumFile.setIsdir(1); + fileList.add(albumFile); + } + + + restResult.setData(fileList); + restResult.setSuccess(true); + return restResult; + } + + /** + * 批量删除文件 + * + * @return + */ + @RequestMapping("/batchdeletefile") + @ResponseBody + public String deleteImageByIds(String files) { + RestResult result = new RestResult(); + if (!operationCheck().isSuccess()){ + return JSON.toJSONString(operationCheck()); + } + + List fileList = JSON.parseArray(files, FileBean.class); + + for (FileBean fileBean : fileList) { + fileService.deleteFile(fileBean); + } + + result.setData("批量删除文件成功"); + result.setSuccess(true); + String resultJson = JSON.toJSONString(result); + return resultJson; + } + + /** + * 删除文件 + * + * @return + */ + @RequestMapping("/deletefile") + @ResponseBody + public String deleteFile(FileBean fileBean) { + RestResult result = new RestResult(); + if (!operationCheck().isSuccess()){ + return JSON.toJSONString(operationCheck()); + } + + fileService.deleteFile(fileBean); + + result.setSuccess(true); + String resultJson = JSON.toJSONString(result); + return resultJson; + } + + /** + * 解压文件 + * + * @return + */ + @RequestMapping("/unzipfile") + @ResponseBody + public String unzipFile(FileBean fileBean){ + RestResult result = new RestResult(); + if (!operationCheck().isSuccess()){ + return JSON.toJSONString(operationCheck()); + } + + String zipFileUrl = PathUtil.getStaticPath() + fileBean.getFileurl(); + File file = FileOperation.newFile(zipFileUrl); + String unzipUrl = file.getParent(); + + List fileEntryNameList = FileOperation.unzip(file, unzipUrl); + + List fileBeanList = new ArrayList<>(); + UserBean sessionUserBean = (UserBean) SecurityUtils.getSubject().getPrincipal(); + for (int i = 0; i < fileEntryNameList.size(); i++){ + String entryName = fileEntryNameList.get(i); + String totalFileUrl = unzipUrl + entryName; + File currentFile = FileOperation.newFile(totalFileUrl); + + FileBean tempFileBean = new FileBean(); + tempFileBean.setUploadtime(DateUtil.getCurrentTime()); + tempFileBean.setUserid(sessionUserBean.getUserId()); + tempFileBean.setFilepath(FileUtil.pathSplitFormat(fileBean.getFilepath() + entryName.replace(currentFile.getName(), ""))); + if (currentFile.isDirectory()){ + + tempFileBean.setIsdir(1); + + tempFileBean.setFilename(currentFile.getName()); + tempFileBean.setTimestampname(currentFile.getName()); + //tempFileBean.setFileurl(File.separator + (file.getParent() + File.separator + currentFile.getName()).replace(PathUtil.getStaticPath(), "")); + }else{ + + tempFileBean.setIsdir(0); + + tempFileBean.setExtendname(FileUtil.getFileType(totalFileUrl)); + tempFileBean.setFilename(FileUtil.getFileNameNotExtend(currentFile.getName())); + tempFileBean.setFilesize(currentFile.length()); + tempFileBean.setTimestampname(FileUtil.getFileNameNotExtend(currentFile.getName())); + tempFileBean.setFileurl(File.separator + (currentFile.getPath()).replace(PathUtil.getStaticPath(), "")); + } + fileBeanList.add(tempFileBean); + } + fileService.batchInsertFile(fileBeanList); + result.setSuccess(true); + String resultJson = JSON.toJSONString(result); + return resultJson; + } + + /** + * 文件移动 + * @param oldfilepath 源路径 + * @param newfilepath 目的路径 + * @param filename 文件名 + * @return 返回前台移动结果 + */ + @RequestMapping("/movefile") + @ResponseBody + public RestResult moveFile(String oldfilepath, String newfilepath, String filename, String extendname){ + RestResult result = new RestResult(); + if (!operationCheck().isSuccess()){ + return operationCheck(); + } + + fileService.updateFilepathByFilepath(oldfilepath, newfilepath, filename, extendname); + result.setSuccess(true); + return result; + } + + /** + * 批量移动文件 + * @param newfilepath 目的路径 + * @param files 需要移动的文件列表 + * @return 返回前台移动结果 + */ + @RequestMapping("/batchmovefile") + @ResponseBody + public RestResult batchMoveFile(String newfilepath, String files){ + + RestResult result = new RestResult(); + if (!operationCheck().isSuccess()){ + return operationCheck(); + } + + List fileList = JSON.parseArray(files, FileBean.class); + + for (FileBean fileBean : fileList) { + fileService.updateFilepathByFilepath(fileBean.getFilepath(), newfilepath, fileBean.getFilename(), fileBean.getExtendname()); + } + + result.setData("批量移动文件成功"); + result.setSuccess(true); + return result; + } + + public RestResult operationCheck(){ + RestResult result = new RestResult(); + UserBean sessionUserBean = (UserBean) SecurityUtils.getSubject().getPrincipal(); + if (sessionUserBean == null){ + result.setSuccess(false); + result.setErrorMessage("未登录"); + return result; + } + if (isShareFile){ + if (sessionUserBean.getUserId() > 2){ + result.setSuccess(false); + result.setErrorMessage("没权限,请联系管理员!"); + return result; + } + } + result.setSuccess(true); + return result; + } + + /** + * 通过文件类型选择文件 + * @param fileType 文件类型 + * @return + */ + @RequestMapping("/selectfilebyfiletype") + @ResponseBody + public RestResult> selectFileByFileType(int fileType){ + RestResult> result = new RestResult>(); + UserBean sessionUserBean = (UserBean) SecurityUtils.getSubject().getPrincipal(); + long userid = sessionUserBean.getUserId(); + if (isShareFile){ + userid = 2; + } + List file = fileService.selectFileByExtendName(getFileExtendsByType(fileType), userid); + result.setData(file); + result.setSuccess(true); + return result; + } + + /** + * 获取文件树 + * @return + */ + @RequestMapping("/getfiletree") + @ResponseBody + public RestResult getFileTree(){ + RestResult result = new RestResult(); + FileBean fileBean = new FileBean(); + UserBean sessionUserBean = (UserBean) SecurityUtils.getSubject().getPrincipal(); + if (isShareFile){ + fileBean.setUserid(2); + }else{ + fileBean.setUserid(sessionUserBean.getUserId()); + } + + List filePathList = fileService.selectFilePathTreeByUserid(fileBean); + TreeNode resultTreeNode = new TreeNode(); + resultTreeNode.setNodeName("/"); + + for (int i = 0; i < filePathList.size(); i++){ + String filePath = filePathList.get(i).getFilepath() + filePathList.get(i).getFilename() + "/"; + + Queue queue = new LinkedList<>(); + + String[] strArr = filePath.split("/"); + for (int j = 0; j < strArr.length; j++){ + if (!"".equals(strArr[j]) && strArr[j] != null){ + queue.add(strArr[j]); + } + + } + if (queue.size() == 0){ + continue; + } + resultTreeNode = insertTreeNode(resultTreeNode,"/", queue); + + + } + result.setSuccess(true); + result.setData(resultTreeNode); + return result; + + } + + public TreeNode insertTreeNode(TreeNode treeNode, String filepath, Queue nodeNameQueue){ + + List childrenTreeNodes = treeNode.getChildren(); + String currentNodeName = nodeNameQueue.peek(); + if (currentNodeName == null){ + return treeNode; + } + + Map map = new HashMap<>(); + filepath = filepath + currentNodeName + "/"; + map.put("filepath", filepath); + + if (!isExistPath(childrenTreeNodes, currentNodeName)){ //1、判断有没有该子节点,如果没有则插入 + //插入 + TreeNode resultTreeNode = new TreeNode(); + + + resultTreeNode.setAttributes(map); + resultTreeNode.setNodeName(nodeNameQueue.poll()); + resultTreeNode.setId(treeid++); + + childrenTreeNodes.add(resultTreeNode); + + }else{ //2、如果有,则跳过 + nodeNameQueue.poll(); + } + + if (nodeNameQueue.size() != 0) { + for (int i = 0; i < childrenTreeNodes.size(); i++) { + + TreeNode childrenTreeNode = childrenTreeNodes.get(i); + if (currentNodeName.equals(childrenTreeNode.getLabel())){ + childrenTreeNode = insertTreeNode(childrenTreeNode, filepath, nodeNameQueue); + childrenTreeNodes.remove(i); + childrenTreeNodes.add(childrenTreeNode); + treeNode.setChildNode(childrenTreeNodes); + } + + } + }else{ + treeNode.setChildNode(childrenTreeNodes); + } + + return treeNode; + + } + + public boolean isExistPath(List childrenTreeNodes, String path){ + boolean isExistPath = false; + + try { + for (int i = 0; i < childrenTreeNodes.size(); i++){ + if (path.equals(childrenTreeNodes.get(i).getLabel())){ + isExistPath = true; + } + } + }catch (Exception e){ + e.printStackTrace(); + } + + + return isExistPath; + } + + +} diff --git a/file-web/src/main/java/com/mac/scp/controller/FiletransferController.java b/file-web/src/main/java/com/mac/scp/controller/FiletransferController.java new file mode 100644 index 0000000..cb83f10 --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/controller/FiletransferController.java @@ -0,0 +1,327 @@ +package com.mac.scp.controller; + +import com.alibaba.fastjson.JSON; +import com.mac.common.operation.FileOperation; +import com.mac.common.util.PathUtil; +import com.mac.common.cbb.RestResult; +import com.mac.common.operation.ImageOperation; +import com.mac.scp.api.IFileService; +import com.mac.scp.api.IFiletransferService; +import com.mac.scp.domain.*; +import org.apache.shiro.SecurityUtils; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.net.URLDecoder; +import java.util.List; + +@RestController +@RequestMapping("/filetransfer") +public class FiletransferController { + + @Resource + IFiletransferService filetransferService; + @Resource + IFileService fileService; + + /** + * 删除用户头像 + * + * @param request 请求 + * @return 删除结果 + */ + @RequestMapping("/deleteuserimage") + @ResponseBody + public String deleteUserImage(HttpServletRequest request, UserImageBean userImageBean) { + RestResult result = new RestResult(); + String servletPath = request.getServletPath(); + String realPath = request.getSession().getServletContext().getRealPath(servletPath); + + List userImageList = filetransferService.selectUserImageByUrl(userImageBean.getImageurl().replace("filetransfer/", "")); + if (userImageList.size() <= 0) { + result.setSuccess(false); + result.setErrorMessage("文件路径不正确"); + return JSON.toJSONString(result); + } + String fileRealPath = new File(new File(realPath).getParent()).getParent() + "/" + userImageBean.getImageurl(); + File file = new File(fileRealPath); + filetransferService.deleteUserImageById(userImageBean); + + if (file.isFile() && file.exists()) { + boolean isDeleteSuccess = file.delete(); + if (isDeleteSuccess) { + result.setSuccess(true); + } else { + result.setSuccess(false); + result.setErrorMessage("文件删除失败"); + } + } else { + result.setSuccess(true); + result.setErrorMessage("文件不存在"); + } + + String resultJson = JSON.toJSONString(result); + return resultJson; + } + + /** + * 旋转图片 + * @param direction 方向 + * @param imageid 图片id + * @return 返回结果 + */ + @RequestMapping("/totationimage") + @ResponseBody + public RestResult totationImage(String direction, int imageid){ + RestResult result = new RestResult(); + FileBean fileBean = new FileBean(); + fileBean.setFileid(imageid); + fileBean = fileService.selectFileById(fileBean); + String imageUrl = fileBean.getFileurl(); + String extendName = fileBean.getExtendname(); + File file = FileOperation.newFile(PathUtil.getStaticPath() + imageUrl); + File minfile = FileOperation.newFile(PathUtil.getStaticPath() + imageUrl.replace("." + extendName, "_min." + extendName)); + if ("left".equals(direction)){ + try { + ImageOperation.leftTotation(file, file, 90); + ImageOperation.leftTotation(minfile, minfile, 90); + } catch (IOException e) { + e.printStackTrace(); + } + }else if ("right".equals(direction)){ + try { + ImageOperation.rightTotation(file, file, 90); + ImageOperation.rightTotation(minfile, minfile, 90); + } catch (IOException e) { + e.printStackTrace(); + } + } + result.setSuccess(true); + return result; + } + + /** + * 批量删除图片 + * + * @return + */ + @RequestMapping("/deleteimagebyids") + @ResponseBody + public String deleteImageByIds(String imageids) { + RestResult result = new RestResult(); + List imageidList = JSON.parseArray(imageids, Integer.class); + UserBean sessionUserBean = (UserBean) SecurityUtils.getSubject().getPrincipal(); + + long sessionUserId = sessionUserBean.getUserId(); + +// List imageBeanList = filetransferService.selectUserImageByIds(imageidList); +// filetransferService.deleteUserImageByIds(imageidList); + List fileList = fileService.selectFileListByIds(imageidList); + fileService.deleteFileByIds(imageidList); + long totalFileSize = 0; + for (FileBean fileBean : fileList) { + String imageUrl = PathUtil.getStaticPath() + fileBean.getFileurl(); + String minImageUrl = imageUrl.replace("." + fileBean.getExtendname(), "_min." + fileBean.getExtendname()); + totalFileSize += FileOperation.getFileSize(imageUrl); + FileOperation.deleteFile(imageUrl); + FileOperation.deleteFile(minImageUrl); + } + StorageBean storageBean = filetransferService.selectStorageBean(new StorageBean(sessionUserId)); + if (storageBean != null){ + long updateFileSize = storageBean.getStoragesize() - totalFileSize; + if (updateFileSize < 0){ + updateFileSize = 0; + } + storageBean.setStoragesize(updateFileSize); + filetransferService.updateStorageBean(storageBean); + + } + + result.setData("删除文件成功"); + result.setSuccess(true); + String resultJson = JSON.toJSONString(result); + return resultJson; + } + + /** + * 删除图片 + * + * @param request + * @return + */ + @RequestMapping("/deleteimage") + @ResponseBody + public String deleteImage(HttpServletRequest request, FileBean fileBean) { + RestResult result = new RestResult(); + UserBean sessionUserBean = (UserBean) SecurityUtils.getSubject().getPrincipal(); + long sessionUserId = sessionUserBean.getUserId(); + String imageUrl = PathUtil.getStaticPath() + fileBean.getFileurl(); + String minImageUrl = imageUrl.replace("." + fileBean.getExtendname(), "_min." + fileBean.getExtendname()); + long fileSize = FileOperation.getFileSize(imageUrl); + fileBean.setIsdir(0); + //filetransferService.deleteImageById(fileBean); + fileService.deleteFile(fileBean); + + FileOperation.deleteFile(imageUrl); + FileOperation.deleteFile(minImageUrl); + + + StorageBean storageBean = filetransferService.selectStorageBean(new StorageBean(sessionUserId)); + if (storageBean != null){ + long updateFileSize = storageBean.getStoragesize() - fileSize; + if (updateFileSize < 0){ + updateFileSize = 0; + } + storageBean.setStoragesize(updateFileSize); + filetransferService.updateStorageBean(storageBean); + + } + + String resultJson = JSON.toJSONString(result); + return resultJson; + } + + + + /** + * 上传头像 + * + * @param request + * @return + */ + @RequestMapping("/uploadimg") + @ResponseBody + public String uploadImg(HttpServletRequest request) { + RestResult restResult = filetransferService.uploadUserImage(request); + String resultJson = JSON.toJSONString(restResult); + return resultJson; + } + + /** + * 上传文件 + * + * @param request + * @return + */ + @RequestMapping("/uploadfile") + @ResponseBody + public String uploadFile(HttpServletRequest request, FileBean fileBean) { + RestResult restResult = new RestResult(); + UserBean sessionUserBean = (UserBean) SecurityUtils.getSubject().getPrincipal(); + RestResult operationCheckResult = new FileController().operationCheck(); + if (!operationCheckResult.isSuccess()){ + return JSON.toJSONString(operationCheckResult); + } + + fileBean.setUserid(sessionUserBean.getUserId()); + + filetransferService.uploadFile(request, fileBean); + + restResult.setSuccess(true); + String resultJson = JSON.toJSONString(restResult); + return resultJson; + } + /** + * 下载文件 + * + * @return + */ + @RequestMapping("/downloadfile") + public String downloadFile(HttpServletResponse response, FileBean fileBean){ + RestResult restResult = new RestResult<>(); + String fileName = null;// 文件名 + try { + fileName = new String(fileBean.getFilename().getBytes("utf-8"), "ISO-8859-1"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + if (fileName != null) { + fileName = fileName + "." + fileBean.getExtendname(); + //设置文件路径 + File file = FileOperation.newFile(PathUtil.getStaticPath() + fileBean.getFileurl()); + if (file.exists()) { + response.setContentType("application/force-download");// 设置强制下载不打开 + response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);// 设置文件名 + byte[] buffer = new byte[1024]; + FileInputStream fis = null; + BufferedInputStream bis = null; + try { + fis = new FileInputStream(file); + bis = new BufferedInputStream(fis); + OutputStream os = response.getOutputStream(); + int i = bis.read(buffer); + while (i != -1) { + os.write(buffer, 0, i); + i = bis.read(buffer); + } + + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (bis != null) { + try { + bis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (fis != null) { + try { + fis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + } + return null; + + } + + /** + * 得到用户头像列表 + * + * @return + */ + @RequestMapping("/getuploadimglist") + @ResponseBody + public RestResult> getUploadImgList(HttpServletRequest request) { + UserBean sessionUserBean = (UserBean) SecurityUtils.getSubject().getPrincipal(); + RestResult> restResult = filetransferService.selectUserImage(sessionUserBean.getUserId()); + restResult.setSuccess(true); + + return restResult; + } + + /** + * 获取存储信息 + * + * @return + */ + @RequestMapping("/getstorage") + @ResponseBody + public RestResult getStorage() { + RestResult restResult = new RestResult(); + UserBean sessionUserBean = (UserBean) SecurityUtils.getSubject().getPrincipal(); + StorageBean storageBean = new StorageBean(); + if (FileController.isShareFile){ + storageBean.setUserid(2); + }else{ + storageBean.setUserid(sessionUserBean.getUserId()); + } + + StorageBean storage = filetransferService.selectStorageByUser(storageBean); + restResult.setData(storage); + restResult.setSuccess(true); + return restResult; + } + + + +} diff --git a/file-web/src/main/java/com/mac/scp/controller/HomeController.java b/file-web/src/main/java/com/mac/scp/controller/HomeController.java new file mode 100644 index 0000000..6d87597 --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/controller/HomeController.java @@ -0,0 +1,26 @@ +package com.mac.scp.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +public class HomeController { + + /** + * 登录后将重定向到这里 + * + * @return + */ + @RequestMapping("/index") + //@ResponseBody + public String index() { + return "index.html"; + } + + @RequestMapping("/403") + public String unauthorizedRole() { + System.out.println("------没有权限-------"); + return "/common/403.html"; + } + +} \ No newline at end of file diff --git a/file-web/src/main/java/com/mac/scp/controller/UserController.java b/file-web/src/main/java/com/mac/scp/controller/UserController.java new file mode 100644 index 0000000..9c303dc --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/controller/UserController.java @@ -0,0 +1,244 @@ +package com.mac.scp.controller; + +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; + +//import org.apache.shiro.authz.annotation.RequiresPermissions; +//import org.codehaus.jackson.type.TypeReference; +//import org.springframework.stereotype.Controller; +import com.mac.common.cbb.RestResult; +import com.mac.common.domain.TableData; +import com.mac.common.domain.TableQueryBean; +import com.mac.scp.api.IUserService; + +import com.mac.scp.domain.*; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.authc.IncorrectCredentialsException; +import org.apache.shiro.authc.UnknownAccountException; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import com.alibaba.fastjson.JSON; + +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.ModelAndView; + +/** + * 用户控制类 + * + * @author ma116 + */ +@RestController +@RequestMapping("/user") +public class UserController { + @Resource + IUserService userService; + + public static final int TEXT = 4; + + /** + * 当前模块 + */ + public static final String CURRENT_MODULE = "用户管理"; + + /** + * 用户注册 + * + * @return + */ + //@MyLog(operation = "用户注册", module = CURRENT_MODULE) + @RequestMapping("/userregister") + @ResponseBody + public ModelAndView userRegister() { + ModelAndView mv = new ModelAndView("/user/userRegister.html"); + return mv; + } + + @RequestMapping("/adduser") + @ResponseBody + public String addUser(UserBean userBean) { + RestResult result = userService.registerUser(userBean); + + String resultJson = JSON.toJSONString(result); + return resultJson; + } + + + + /** + * 用户登录 + * + * @param request + * @return + */ + @RequestMapping("/userlogin") + @ResponseBody + public RestResult userLogin(HttpServletRequest request, Map map) { + RestResult result = new RestResult(); + + System.out.println("HomeController.login()"); + // 登录失败从request中获取shiro处理的异常信息。 + // // shiroLoginFailure:就是shiro异常类的全类名. + String exception = (String) request.getAttribute("shiroLoginFailure"); + System.out.println("exception=" + exception); + String msg = ""; + if (exception != null) { //登录失败 + if (UnknownAccountException.class.getName().equals(exception)) { + msg = "账号不存在"; + } else if (IncorrectCredentialsException.class.getName().equals(exception)) { + msg = "密码不正确"; + } else if ("kaptchaValidateFailed".equals(exception)) { + msg = "验证码错误"; + } else { + msg = exception; + } + result.setSuccess(false); + result.setErrorMessage(msg); + } + else{ + //登录成功 + result.setSuccess(true); + } + + return result; + } + + /** + * 检查用户登录信息 + * + * @return + */ + @RequestMapping("/checkuserlogininfo") + @ResponseBody + public String checkUserLoginInfo(HttpServletRequest request) { + RestResult restResult = new RestResult(); + UserBean sessionUserBean = (UserBean) SecurityUtils.getSubject().getPrincipal(); + if (sessionUserBean != null) { + UserBean userInfo = userService.getUserInfoById(sessionUserBean.getUserId()); + restResult.setData(userInfo); + restResult.setSuccess(true); + } else { + restResult.setSuccess(false); + restResult.setErrorMessage("用户暂未登录"); + } + return JSON.toJSONString(restResult); + } + + /** + * 得到用户信息通过id + * + * @param userid + * @return + */ + @RequestMapping("/getuserinfobyid") + @ResponseBody + public String getUserInfoById(int userid) { + RestResult restResult = new RestResult(); + + UserBean userBean = userService.getUserInfoById(userid); + if (userBean == null) { + restResult.setSuccess(false); + restResult.setErrorCode("100001"); + restResult.setErrorMessage("用户不存在!"); + } else { + restResult.setSuccess(true); + restResult.setData(userBean); + } + String resultJson = JSON.toJSONString(restResult); + return resultJson; + } + + + /** + * 修改用戶信息 + * + * @param userBean + * @return + */ + @RequestMapping("/updateuserinfo") + @ResponseBody + public RestResult updateUserInfo(HttpServletRequest request, UserBean userBean) { + UserBean sessionUserBean = (UserBean) SecurityUtils.getSubject().getPrincipal(); + userBean.setUserId(sessionUserBean.getUserId()); + RestResult restResult = userService.updateUserInfo(userBean); + + + return restResult; + } + + /** + * 得到所有的用户 + * + * @return + */ + @RequestMapping("/selectalluserlist") + @ResponseBody + public String selectAllUserList(TableQueryBean tableQueryBean) { + + TableData> miniuiTableData = new TableData>(); + + String resultJson = ""; + + List userList = userService.selectUserList(tableQueryBean); + int userCount = userService.selectUserCountByCondition(tableQueryBean); + miniuiTableData.setData(userList); + miniuiTableData.setCount(userCount); + + + resultJson = JSON.toJSONString(miniuiTableData); + return resultJson; + } + + /** + * 只获取管理员用户 + * + * @return + */ + @RequestMapping("/selectadminuserlist") + @ResponseBody + public String selectAdminUserList() { + + TableData> miniuiTableData = new TableData>(); + + String resultJson = ""; + + List userList = userService.selectAdminUserList(); + + miniuiTableData.setData(userList); + + resultJson = JSON.toJSONString(miniuiTableData); + return resultJson; + } + + /** + * 得到所有的角色 + * + * @return + */ + @RequestMapping("/selectrolelist") + @ResponseBody + public TableData> selectRoleList() { + TableData> miniuiTableData = new TableData>(); + List result = userService.selectRoleList(); + miniuiTableData.setData(result); + return miniuiTableData; + } + + /** + * 得到所有的权限 + * + * @return + */ + @RequestMapping("/selectpermissionlist") + @ResponseBody + public TableData> selectPermissionList(TableQueryBean tableQueryBean) { + TableData> miniuiTableData = new TableData>(); + List result = userService.selectPermissionList(tableQueryBean); + miniuiTableData.setData(result); + return miniuiTableData; + } + +} diff --git a/file-web/src/main/java/com/mac/scp/domain/FileBean.java b/file-web/src/main/java/com/mac/scp/domain/FileBean.java new file mode 100644 index 0000000..5bfa378 --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/domain/FileBean.java @@ -0,0 +1,135 @@ +package com.mac.scp.domain; + +import javax.persistence.*; + +/** + * 相册实体类 + * + * @author ma116 + */ +@Table(name = "file", uniqueConstraints = { + @UniqueConstraint(name = "fileindex", columnNames = {"filename", "filepath", "extendname"})}) +@Entity +public class FileBean { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long fileid; + + private long albumid; + + private long essayid; + + private long userid; + + private String fileurl; + + private String filepath; + + private String uploadtime; + + private String timestampname; + + private String extendname; + + private String filename; + + private long filesize; + + private int isdir; + + public long getAlbumid() { + return albumid; + } + + public void setAlbumid(long albumid) { + this.albumid = albumid; + } + + public String getFilepath() { + return filepath; + } + + public void setFilepath(String filepath) { + this.filepath = filepath; + } + + public int getIsdir() { + return isdir; + } + + public void setIsdir(int isdir) { + this.isdir = isdir; + } + + public long getUserid() { + return userid; + } + + public void setUserid(long userid) { + this.userid = userid; + } + + public long getEssayid() { + return essayid; + } + + public void setEssayid(long essayid) { + this.essayid = essayid; + } + + public long getFileid() { + return fileid; + } + + public void setFileid(long fileid) { + this.fileid = fileid; + } + + public String getFileurl() { + return fileurl; + } + + public void setFileurl(String fileurl) { + this.fileurl = fileurl; + } + + public String getUploadtime() { + return uploadtime; + } + + public void setUploadtime(String uploadtime) { + this.uploadtime = uploadtime; + } + + public String getTimestampname() { + return timestampname; + } + + public void setTimestampname(String timestampname) { + this.timestampname = timestampname; + } + + public String getExtendname() { + return extendname; + } + + public void setExtendname(String extendname) { + this.extendname = extendname; + } + + public String getFilename() { + return filename; + } + + public void setFilename(String filename) { + this.filename = filename; + } + + public long getFilesize() { + return filesize; + } + + public void setFilesize(long filesize) { + this.filesize = filesize; + } +} diff --git a/file-web/src/main/java/com/mac/scp/domain/Permission.java b/file-web/src/main/java/com/mac/scp/domain/Permission.java new file mode 100644 index 0000000..cd839fd --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/domain/Permission.java @@ -0,0 +1,102 @@ +package com.mac.scp.domain; + +import javax.persistence.*; +import java.io.Serializable; +import java.util.List; + +@Table(name = "permission") +@Entity +public class Permission { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long permissionid;//主键. + @Column + private String name;//名称. + @Column + private String resourceType;//资源类型,[menu|button] + @Column + private String url;//资源路径. + @Column + private String permission; //权限字符串,menu例子:role:*,button例子:role:create,role:update,role:delete,role:view + @Column + private Long parentId; //父编号 + @Column + private String parentIds; //父编号列表 + @Column + private Boolean available = Boolean.FALSE; + + @Transient + private List roles; + + public long getPermissionid() { + return permissionid; + } + + public void setPermissionid(long permissionid) { + this.permissionid = permissionid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getPermission() { + return permission; + } + + public void setPermission(String permission) { + this.permission = permission; + } + + public Long getParentId() { + return parentId; + } + + public void setParentId(Long parentId) { + this.parentId = parentId; + } + + public String getParentIds() { + return parentIds; + } + + public void setParentIds(String parentIds) { + this.parentIds = parentIds; + } + + public Boolean getAvailable() { + return available; + } + + public void setAvailable(Boolean available) { + this.available = available; + } + + public List getRoles() { + return roles; + } + + public void setRoles(List roles) { + this.roles = roles; + } +} \ No newline at end of file diff --git a/file-web/src/main/java/com/mac/scp/domain/Role.java b/file-web/src/main/java/com/mac/scp/domain/Role.java new file mode 100644 index 0000000..8a138fd --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/domain/Role.java @@ -0,0 +1,79 @@ +package com.mac.scp.domain; + +import javax.persistence.*; +import java.util.List; + +@Table(name = "role") +@Entity +public class Role { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long roleid; // 编号 + + private String role; // 角色标识程序中判断使用,如"admin",这个是唯一的: + + private String description; // 角色描述,UI界面显示使用 + + private Boolean available = Boolean.FALSE; // 是否可用,如果不可用将不会添加给用户 + + @ManyToMany(fetch = FetchType.EAGER)//立即从数据库中进行加载数据 + @JoinTable(name = "role_permission", + joinColumns = {@JoinColumn(name = "roleid")}, + inverseJoinColumns = {@JoinColumn(name = "permissionid")}) + private List permissions; + +// @ManyToMany +// @JoinTable(name = "role_permission", +// joinColumns = {@JoinColumn(name="roleid")}, +// inverseJoinColumns = {@JoinColumn(name="permissionid")}) +// private List userList;// 一个角色对应多个用户 + + + public long getRoleid() { + return roleid; + } + + public void setRoleid(long roleid) { + this.roleid = roleid; + } + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Boolean getAvailable() { + return available; + } + + public void setAvailable(Boolean available) { + this.available = available; + } + + public List getPermissions() { + return permissions; + } + + public void setPermissions(List permissions) { + this.permissions = permissions; + } + +// public List getUserList() { +// return userList; +// } +// +// public void setUserList(List userList) { +// this.userList = userList; +// } +} \ No newline at end of file diff --git a/file-web/src/main/java/com/mac/scp/domain/StorageBean.java b/file-web/src/main/java/com/mac/scp/domain/StorageBean.java new file mode 100644 index 0000000..ea8b670 --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/domain/StorageBean.java @@ -0,0 +1,47 @@ +package com.mac.scp.domain; + +import javax.persistence.*; + +@Table(name = "storage") +@Entity +public class StorageBean { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long storageid; + + private long userid; + + private long storagesize; + + public StorageBean() { + + } + + public StorageBean(long userid) { + this.userid = userid; + } + + public long getStorageid() { + return storageid; + } + + public void setStorageid(long storageid) { + this.storageid = storageid; + } + + public long getUserid() { + return userid; + } + + public void setUserid(long userid) { + this.userid = userid; + } + + public long getStoragesize() { + return storagesize; + } + + public void setStoragesize(long storagesize) { + this.storagesize = storagesize; + } +} diff --git a/file-web/src/main/java/com/mac/scp/domain/TreeNode.java b/file-web/src/main/java/com/mac/scp/domain/TreeNode.java new file mode 100644 index 0000000..5a6cb8c --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/domain/TreeNode.java @@ -0,0 +1,66 @@ +package com.mac.scp.domain; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 树节点 + */ +public class TreeNode { + private long id; + private String label; + private int depth; + private String state = "closed"; + private Map attributes = new HashMap<>(); + private List children = new ArrayList<>(); + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public Map getAttributes() { + return attributes; + } + + public void setAttributes(Map attributes) { + this.attributes = attributes; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public int getDepth() { + return depth; + } + + public void setDepth(int depth) { + this.depth = depth; + } + + public String getLabel() { + return label; + } + + public void setNodeName(String nodeName) { + this.label = nodeName; + } + + public List getChildren() { + return children; + } + + public void setChildNode(List childNode) { + this.children = childNode; + } +} diff --git a/file-web/src/main/java/com/mac/scp/domain/UserBean.java b/file-web/src/main/java/com/mac/scp/domain/UserBean.java new file mode 100644 index 0000000..a257400 --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/domain/UserBean.java @@ -0,0 +1,254 @@ +package com.mac.scp.domain; + +import java.io.Serializable; +import java.util.List; + +import javax.persistence.*; +import javax.websocket.Session; + +/** + * 用户基础信息类 + * + * @author ma116 + */ +@Table(name = "user", uniqueConstraints = { + @UniqueConstraint(name = "openidIndex", columnNames = {"openid"}) +}) +@Entity +public class UserBean{ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long userId; + + private String openid; //qq登录使用 + + private String username; + + private String realname; + + private String password; + + @Transient + private String passwordAgain; + + private String telephone; + + private String sex; + + private String birthday; + + private String addrprovince; + + private String addrcity; + + private String addrarea; + + private String industry; + + private String position; + + private String intro; + + private String salt;//加密密码的盐 + //private byte state;//用户状态,0:创建未认证(比如没有激活,没有输入验证码等等)--等待验证的用户 , 1:正常状态,2:用户被锁定. + + @ManyToMany(fetch = FetchType.EAGER)//立即从数据库中进行加载数据 + @JoinTable(name = "user_role", + joinColumns = {@JoinColumn(name = "userId")}, + inverseJoinColumns = {@JoinColumn(name = "roleid")}) + private List roleList;// 一个用户具有多个角色 + /** + * 与某个客户端的连接会话,需要通过它来给客户端发送数据 + */ + @Transient + private Session session; + + /** + * 消息未读数 + */ + @Transient + private int notReadCount; + + @Transient + private List imageBeanList; + + public List getImageBeanList() { + return imageBeanList; + } + + public void setImageBeanList(List imageBeanList) { + this.imageBeanList = imageBeanList; + } + + public int getNotReadCount() { + return notReadCount; + } + + public void setNotReadCount(int notReadCount) { + this.notReadCount = notReadCount; + } + + + public long getUserId() { + return userId; + } + + public void setUserId(long userId) { + this.userId = userId; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getTelephone() { + return telephone; + } + + public void setTelephone(String telephone) { + this.telephone = telephone; + } + + public String getSex() { + return sex; + } + + public void setSex(String sex) { + this.sex = sex; + } + + public String getRealname() { + return realname; + } + + public void setRealname(String realname) { + this.realname = realname; + } + + public String getBirthday() { + return birthday; + } + + public void setBirthday(String birthday) { + this.birthday = birthday; + } + + public String getAddrcity() { + return addrcity; + } + + public void setAddrcity(String addrcity) { + this.addrcity = addrcity; + } + + public String getAddrarea() { + return addrarea; + } + + public void setAddrarea(String addrarea) { + this.addrarea = addrarea; + } + + public String getIndustry() { + return industry; + } + + public void setIndustry(String industry) { + this.industry = industry; + } + + public String getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getIntro() { + return intro; + } + + public void setIntro(String intro) { + this.intro = intro; + } + + public String getAddrprovince() { + return addrprovince; + } + + public void setAddrprovince(String addrprovince) { + this.addrprovince = addrprovince; + } + + public Session getSession() { + return session; + } + + public void setSession(Session session) { + this.session = session; + } + + public String getSalt() { + return salt; + } + + public void setSalt(String salt) { + this.salt = salt; + } + + +// public byte getState() { +// return state; +// } +// +// public void setState(byte state) { +// this.state = state; +// } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public String getPasswordAgain() { + return passwordAgain; + } + + public void setPasswordAgain(String passwordAgain) { + this.passwordAgain = passwordAgain; + } + + public String getOpenid() { + return openid; + } + + public void setOpenid(String openid) { + this.openid = openid; + } + + /** + * 密码盐. + * + * @return + */ + public String getCredentialsSalt() { + return this.username + this.salt; + } + //重新对盐重新进行了定义,用户名+salt,这样就更加不容易被破解 +} diff --git a/file-web/src/main/java/com/mac/scp/domain/UserImageBean.java b/file-web/src/main/java/com/mac/scp/domain/UserImageBean.java new file mode 100644 index 0000000..e83aa43 --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/domain/UserImageBean.java @@ -0,0 +1,66 @@ +package com.mac.scp.domain; + +import javax.persistence.*; +import java.io.Serializable; + +/** + * 用户头像实体类 + * + * @author ma116 + */ +@Table(name = "userimage") +@Entity +public class UserImageBean implements Serializable { + /** + * 序列id + */ + private static final long serialVersionUID = 1L; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long imageid; + @Column + private long userid; + @Column + private String imageurl; + @Column + private String uploadtime; + + + public String getUploadtime() { + return uploadtime; + } + + public void setUploadtime(String uploadtime) { + this.uploadtime = uploadtime; + } + + public static long getSerialVersionUID() { + return serialVersionUID; + } + + public long getImageid() { + return imageid; + } + + public void setImageid(long imageid) { + this.imageid = imageid; + } + + public long getUserid() { + return userid; + } + + public void setUserid(long userid) { + this.userid = userid; + } + + public String getImageurl() { + return imageurl; + } + + public void setImageurl(String imageurl) { + this.imageurl = imageurl; + } + + +} diff --git a/file-web/src/main/java/com/mac/scp/mapper/FileMapper.java b/file-web/src/main/java/com/mac/scp/mapper/FileMapper.java new file mode 100644 index 0000000..3f898c0 --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/mapper/FileMapper.java @@ -0,0 +1,25 @@ +package com.mac.scp.mapper; + +import com.mac.scp.domain.*; +import org.apache.ibatis.annotations.Param; + +import java.io.File; +import java.util.List; + +public interface FileMapper { + + void insertFile(FileBean fileBean); + void batchInsertFile(List fileBeanList); + void updateFile(FileBean fileBean); + FileBean selectFileById(FileBean fileBean); + List selectFilePathTreeByUserid(FileBean fileBean); + List selectFileList(FileBean fileBean); + List selectFileTreeListLikeFilePath(FileBean fileBean); + void deleteFileById(FileBean fileBean); + void deleteFileByIds(List fileidList); + List selectFileListByIds(List fileidList); + void updateFilepathByFilepath(String oldfilepath, String newfilepath); + void updateFilepathByPathAndName(String oldfilepath, String newfilepath, String filename, String extendname); + List selectFileByExtendName(@Param("filenameList") List filenameList, + @Param("userid") long userid); +} diff --git a/file-web/src/main/java/com/mac/scp/mapper/FiletransferMapper.java b/file-web/src/main/java/com/mac/scp/mapper/FiletransferMapper.java new file mode 100644 index 0000000..e0f77cb --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/mapper/FiletransferMapper.java @@ -0,0 +1,32 @@ +package com.mac.scp.mapper; + +import com.mac.scp.domain.*; +import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoProperties; + +import java.util.List; + +public interface FiletransferMapper { + + void deleteUserImageById(UserImageBean userImageBean); + + /** + * 插入用户头像 + * + * @param userImageBean + */ + void insertUserImage(UserImageBean userImageBean); + + List selectUserImage(long userId); + + List selectUserImageByUrl(String url); + + void deleteUserImageByIds(List imageidList); + + StorageBean selectStorageBean(StorageBean storageBean); + + void insertStorageBean(StorageBean storageBean); + + void updateStorageBean(StorageBean storageBean); + + StorageBean selectStorageByUser(StorageBean storageBean); +} diff --git a/file-web/src/main/java/com/mac/scp/mapper/UserMapper.java b/file-web/src/main/java/com/mac/scp/mapper/UserMapper.java new file mode 100644 index 0000000..074d42a --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/mapper/UserMapper.java @@ -0,0 +1,63 @@ +package com.mac.scp.mapper; + +import com.mac.common.domain.TableQueryBean; +import com.mac.scp.domain.*; + +import java.util.List; + +public interface UserMapper { + int insertUser(UserBean userBean); + + int insertUserRole(long userId, long roleid); + + UserBean selectUser(UserBean userBean); + + List selectAdminUserList(); + + /** + * 通過id得到用戶信息 + * + * @param userId + * @return + */ + UserBean selectUserById(long userId); + + /** + * 通過openid得到用戶信息 + * @param openid + * @return + */ + UserBean selectUserByopenid(String openid); + + /** + * 批量删除用户信息 + * + * @param userBean + */ + void deleteUserInfo(UserBean userBean); + + /** + * 修改用戶信息 + * + * @param userBean + */ + void updateUserInfo(UserBean userBean); + + UserBean selectUserByUserName(UserBean userBean); + + UserBean selectUserByUserNameAndPassword(UserBean userBean); + + List selectUserByTelephone(UserBean userBean); + + List selectAllUserList(); + + List selectUserListByCondition(TableQueryBean tableQueryBean); + + List selectRoleList(); + + List selectPermissionListByCondition(TableQueryBean tableQueryBean); + + int selectUserCountByCondition(TableQueryBean tableQueryBean); + + List getPermissionByRole(int roleid); +} diff --git a/file-web/src/main/java/com/mac/scp/service/FileService.java b/file-web/src/main/java/com/mac/scp/service/FileService.java new file mode 100644 index 0000000..dce9047 --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/service/FileService.java @@ -0,0 +1,141 @@ +package com.mac.scp.service; + +import com.mac.common.cbb.DateUtil; +import com.mac.common.operation.FileOperation; +import com.mac.common.util.PathUtil; +import com.mac.scp.api.IFileService; +import com.mac.scp.domain.*; +import com.mac.scp.mapper.FileMapper; +import org.apache.shiro.SecurityUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + + +@Service +public class FileService implements IFileService { + + @Resource + FileMapper fileMapper; + @Resource + FiletransferService filetransferService; + + @Override + public void insertFile(FileBean fileBean) { + fileMapper.insertFile(fileBean); + } + + @Override + public void batchInsertFile(List fileBeanList) { + fileMapper.batchInsertFile(fileBeanList); + } + + @Override + public void updateFile(FileBean fileBean) { + fileBean.setUploadtime(DateUtil.getCurrentTime()); + fileMapper.updateFile(fileBean); + } + + @Override + public FileBean selectFileById(FileBean fileBean) { + return fileMapper.selectFileById(fileBean); + } + + @Override + public List selectFilePathTreeByUserid(FileBean fileBean) { + return fileMapper.selectFilePathTreeByUserid(fileBean); + } + + @Override + public List selectFileList(FileBean fileBean) { + return fileMapper.selectFileList(fileBean); + } + + @Override + public List selectFileListByIds(List fileidList) { + return fileMapper.selectFileListByIds(fileidList); + } + + @Override + public List selectFileTreeListLikeFilePath(String filePath) { + FileBean fileBean = new FileBean(); + fileBean.setFilepath(filePath); + + return fileMapper.selectFileTreeListLikeFilePath(fileBean); + } + + @Override + public void deleteFile(FileBean fileBean) { + UserBean sessionUserBean = (UserBean) SecurityUtils.getSubject().getPrincipal(); + StorageBean storageBean = filetransferService.selectStorageBean(new StorageBean(sessionUserBean.getUserId())); + long deleteSize = 0; + String fileUrl = PathUtil.getStaticPath() + fileBean.getFileurl(); + if (fileBean.getIsdir() == 1) { + //1、先删除子目录 + String filePath = fileBean.getFilepath() + fileBean.getFilename() + "/"; + List fileList = selectFileTreeListLikeFilePath(filePath); + + for (int i = 0; i < fileList.size(); i++){ + FileBean file = fileList.get(i); + //1.1、删除数据库文件 + fileMapper.deleteFileById(file); + //1.2、如果是文件,需要记录文件大小 + if (file.getIsdir() != 1){ + deleteSize += file.getFilesize(); + //1.3、删除服务器文件,只删除文件,目录是虚拟的 + if (file.getFileurl() != null && file.getFileurl().indexOf("upload") != -1){ + FileOperation.deleteFile(PathUtil.getStaticPath() + file.getFileurl()); + } + } + } + //2、根目录单独删除 + fileMapper.deleteFileById(fileBean); + }else{ + fileMapper.deleteFileById(fileBean); + deleteSize = FileOperation.getFileSize(fileUrl); + //删除服务器文件 + if (fileBean.getFileurl() != null && fileBean.getFileurl().indexOf("upload") != -1){ + FileOperation.deleteFile(fileUrl); + } + } + + if (storageBean != null) { + long updateFileSize = storageBean.getStoragesize() - deleteSize; + if (updateFileSize < 0) { + updateFileSize = 0; + } + storageBean.setStoragesize(updateFileSize); + filetransferService.updateStorageBean(storageBean); + } + } + + @Override + public void deleteFileByIds(List fileidList) { + fileMapper.deleteFileByIds(fileidList); + } + + + @Override + public void updateFilepathByFilepath(String oldfilepath, String newfilepath, String filename, String extendname) { + if ("null".equals(extendname)){ + extendname = null; + } + //移动根目录 + fileMapper.updateFilepathByPathAndName(oldfilepath, newfilepath, filename, extendname); + + //移动子目录 + oldfilepath = oldfilepath + filename + "/"; + newfilepath = newfilepath + filename + "/"; + + if (extendname == null) { //为null说明是目录,则需要移动子目录 + fileMapper.updateFilepathByFilepath(oldfilepath, newfilepath); + } + + } + + @Override + public List selectFileByExtendName(List filenameList, long userid) { + return fileMapper.selectFileByExtendName(filenameList, userid); + } +} diff --git a/file-web/src/main/java/com/mac/scp/service/FiletransferService.java b/file-web/src/main/java/com/mac/scp/service/FiletransferService.java new file mode 100644 index 0000000..82e3b7f --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/service/FiletransferService.java @@ -0,0 +1,171 @@ +package com.mac.scp.service; + +import java.util.List; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; + +import com.mac.common.cbb.DateUtil; +import com.mac.common.cbb.RestResult; +import com.mac.common.cbb.Uploader; +import com.mac.common.domain.UploadFile; +import com.mac.scp.api.IFiletransferService; + +import com.mac.scp.domain.*; +import com.mac.scp.mapper.FileMapper; +import com.mac.scp.mapper.FiletransferMapper; +import org.apache.shiro.SecurityUtils; +import org.springframework.stereotype.Service; + + +@Service +public class FiletransferService implements IFiletransferService { + + @Resource + FiletransferMapper filetransferMapper; + @Resource + FileMapper fileMapper; + + + @Override + public void deleteUserImageById(UserImageBean userImageBean) { + filetransferMapper.deleteUserImageById(userImageBean); + + } + + + /** + * 添加用户头像 + */ + @Override + public RestResult insertUserImage(UserImageBean userImageBean) { + RestResult restResult = new RestResult(); + filetransferMapper.insertUserImage(userImageBean); + + restResult.setSuccess(true); + return restResult; + } + + /** + * 查找用户头像 + */ + @Override + public RestResult> selectUserImage(long userId) { + RestResult> restResult = new RestResult>(); + List result = filetransferMapper.selectUserImage(userId); + if (result == null) { + restResult.setSuccess(false); + restResult.setErrorMessage("没有头像"); + } else { + restResult.setSuccess(true); + restResult.setData(result); + } + return restResult; + } + + /** + * 上传用户头像 + */ + @Override + public RestResult uploadUserImage(HttpServletRequest request) { + RestResult restResult = new RestResult(); + UserBean sessionUserBean = (UserBean) SecurityUtils.getSubject().getPrincipal(); + UserImageBean userImageBean = new UserImageBean(); + UserBean userBean = null; + //判断用户是否登陆 + if (sessionUserBean == null) { + restResult.setErrorCode("用户未登陆"); + restResult.setSuccess(false); + } else { + Uploader uploader = null; + uploader = new Uploader(request); + List uploadFile = uploader.upload(); + + String imageurl = uploadFile.get(0).getUrl(); + userBean = sessionUserBean; + userImageBean.setUserid(userBean.getUserId()); + userImageBean.setImageurl(imageurl); + userImageBean.setUploadtime(DateUtil.getCurrentTime()); + insertUserImage(userImageBean); + restResult.setData("filetransfer/" + imageurl); + restResult.setSuccess(true); + } + + return restResult; + } + + @Override + public List selectUserImageByUrl(String url) { + List result = filetransferMapper.selectUserImageByUrl(url); + return result; + } + + + @Override + public void deleteUserImageByIds(List imageidList) { + filetransferMapper.deleteUserImageByIds(imageidList); + } + + + + +// public void insertFile(FileBean fileBean){ +// filetransferMapper.insertFile(fileBean); +// } + + @Override + public void uploadFile(HttpServletRequest request, FileBean fileBean) { + Uploader uploader = new Uploader(request); + List uploadFileList = uploader.upload(); + for (int i = 0; i < uploadFileList.size(); i++){ + UploadFile uploadFile = uploadFileList.get(i); + if (uploadFile.getSuccess() == 1){ + fileBean.setFileurl(uploadFile.getUrl()); + fileBean.setFilesize(uploadFile.getFileSize()); + fileBean.setFilename(uploadFile.getFileName()); + fileBean.setExtendname(uploadFile.getFileType()); + fileBean.setTimestampname(uploadFile.getTimeStampName()); + fileBean.setUploadtime(DateUtil.getCurrentTime()); + + fileMapper.insertFile(fileBean); + } + + + synchronized (FiletransferService.class) { + UserBean sessionUserBean = (UserBean) SecurityUtils.getSubject().getPrincipal(); + + long sessionUserId = sessionUserBean.getUserId(); + StorageBean storageBean = selectStorageBean(new StorageBean(sessionUserId)); + if (storageBean == null) { + StorageBean storage = new StorageBean(sessionUserId); + storage.setStoragesize(fileBean.getFilesize()); + insertStorageBean(storage); + } else { + storageBean.setStoragesize(storageBean.getStoragesize() + uploadFile.getFileSize()); + updateStorageBean(storageBean); + } + } + + } + } + + @Override + public StorageBean selectStorageBean(StorageBean storageBean) { + return filetransferMapper.selectStorageBean(storageBean); + } + + @Override + public void insertStorageBean(StorageBean storageBean) { + filetransferMapper.insertStorageBean(storageBean); + } + + @Override + public void updateStorageBean(StorageBean storageBean) { + filetransferMapper.updateStorageBean(storageBean); + } + + @Override + public StorageBean selectStorageByUser(StorageBean storageBean) { + return filetransferMapper.selectStorageByUser(storageBean); + } +} diff --git a/file-web/src/main/java/com/mac/scp/service/RequestListener.java b/file-web/src/main/java/com/mac/scp/service/RequestListener.java new file mode 100644 index 0000000..1a40a07 --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/service/RequestListener.java @@ -0,0 +1,24 @@ +package com.mac.scp.service; + +import javax.servlet.ServletRequestEvent; +import javax.servlet.ServletRequestListener; +import javax.servlet.annotation.WebListener; +import javax.servlet.http.HttpServletRequest; + +@WebListener +public class RequestListener implements ServletRequestListener { + + public void requestInitialized(ServletRequestEvent sre) { + //将所有request请求都携带上httpSession + ((HttpServletRequest) sre.getServletRequest()).getSession(); + + } + + public RequestListener() { + // TODO Auto-generated constructor stub + } + + public void requestDestroyed(ServletRequestEvent arg0) { + // TODO Auto-generated method stub + } +} \ No newline at end of file diff --git a/file-web/src/main/java/com/mac/scp/service/UserService.java b/file-web/src/main/java/com/mac/scp/service/UserService.java new file mode 100644 index 0000000..fd8bf82 --- /dev/null +++ b/file-web/src/main/java/com/mac/scp/service/UserService.java @@ -0,0 +1,277 @@ +package com.mac.scp.service; + +import com.mac.common.cbb.MiniuiUtil; +import com.mac.common.cbb.RestResult; +import com.mac.common.domain.TableQueryBean; +import com.mac.common.util.PasswordUtil; +import com.mac.scp.api.IUserService; + +import com.mac.scp.domain.*; +import com.mac.scp.mapper.FiletransferMapper; +import com.mac.scp.mapper.UserMapper; +import org.apache.shiro.crypto.hash.SimpleHash; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.regex.Pattern; + +@Service +public class UserService implements IUserService { + //private static final Logger log= Logger.getLogger(EssayService.class); + @Resource + UserMapper userMapper; + + @Resource + FiletransferMapper filetransferMapper; + + /** + * 用户注册 + */ + @Override + public RestResult registerUser(UserBean userBean) { + RestResult restResult = new RestResult(); + if (userBean.getTelephone() == null || "".equals(userBean.getTelephone())){ + restResult.setSuccess(false); + restResult.setErrorMessage("用户名不能为空!"); + return restResult; + } + if (userBean.getPassword() == null || "".equals(userBean.getPassword())){ + restResult.setSuccess(false); + restResult.setErrorMessage("密码不能为空!"); + return restResult; + } + if (userBean.getPasswordAgain() == null || "".equals(userBean.getPasswordAgain())){ + restResult.setSuccess(false); + restResult.setErrorMessage("确认密码不能为空!"); + return restResult; + } + if (userBean.getUsername() == null || "".equals(userBean.getUsername())){ + restResult.setSuccess(false); + restResult.setErrorMessage("用户名不能为空!"); + return restResult; + } + if (isUserNameExit(userBean)) { + restResult.setSuccess(false); + restResult.setErrorMessage("用户名已存在!"); + return restResult; + } + if (!isPhoneFormatRight(userBean.getTelephone())){ + restResult.setSuccess(false); + restResult.setErrorMessage("手机号格式不正确!"); + return restResult; + } + if (isPhoneExit(userBean)) { + restResult.setSuccess(false); + restResult.setErrorMessage("手机号已存在!"); + return restResult; + } + if (!userBean.getPassword().equals(userBean.getPasswordAgain())) { + restResult.setSuccess(false); + restResult.setErrorMessage("确认密码不一致!"); + return restResult; + } + + String salt = PasswordUtil.getSaltValue(); + String newPassword = new SimpleHash("MD5", userBean.getPassword(), salt, 1024).toHex(); + + userBean.setSalt(salt); + + userBean.setPassword(newPassword); + + int result = userMapper.insertUser(userBean); + //UserBean userInsertResult = userMapper.selectUserByUserName(userBean); + userMapper.insertUserRole(userBean.getUserId(), 2); + UserImageBean userImageBean = new UserImageBean(); + userImageBean.setImageurl(""); + userImageBean.setUserid(userBean.getUserId()); + filetransferMapper.insertUserImage(userImageBean); + if (result == 1) { + restResult.setSuccess(true); + return restResult; + } else { + restResult.setSuccess(false); + restResult.setErrorCode("100000"); + restResult.setErrorMessage("注册用户失败,请检查输入信息!"); + return restResult; + } + } + + /** + * 添加用户 + */ + @Override + public RestResult addUser(UserBean userBean) { + RestResult restResult = new RestResult(); + + String salt = PasswordUtil.getSaltValue(); + String newPassword = new SimpleHash("MD5", userBean.getPassword(), salt, 1024).toHex(); + + userBean.setSalt(salt); + + userBean.setPassword(newPassword); + + int result = userMapper.insertUser(userBean); + //UserBean userInsertResult = userMapper.selectUserByUserName(userBean); + userMapper.insertUserRole(userBean.getUserId(), 2); + UserImageBean userImageBean = new UserImageBean(); + userImageBean.setImageurl(""); + userImageBean.setUserid(userBean.getUserId()); + filetransferMapper.insertUserImage(userImageBean); + if (result == 1) { + restResult.setSuccess(true); + return restResult; + } else { + restResult.setSuccess(false); + restResult.setErrorCode("100000"); + restResult.setErrorMessage("注册用户失败,请检查输入信息!"); + return restResult; + } + } + + /** + * 检测用户名是否存在 + * + * @param userBean + */ + private Boolean isUserNameExit(UserBean userBean) { + UserBean result = userMapper.selectUserByUserName(userBean); + if (result != null) { + return true; + } else { + return false; + } + } + + /** + * 检测手机号是否存在 + * + * @param userBean + * @return + */ + private Boolean isPhoneExit(UserBean userBean) { + List resultList = userMapper.selectUserByTelephone(userBean); + if (resultList.size() > 0) { + return true; + } else { + return false; + } + } + + private Boolean isPhoneFormatRight(String phone){ + String regex = "^1\\d{10}"; + boolean isRight = Pattern.matches(regex, phone); + return isRight; + } + + /** + * 通过用户名获取用户信息 + * + * @param userName + * @return + */ + public UserBean findUserInfoByName(String userName) { + UserBean userinfo = new UserBean(); + userinfo.setUsername(userName); + return userMapper.selectUserByUserName(userinfo); + } + + /** + * 通过用户名获取用户信息 + * + * @param userName + * @return + */ + public UserBean findUserInfoByNameAndPassword(String userName, String password) { + UserBean userinfo = new UserBean(); + userinfo.setUsername(userName); + return userMapper.selectUserByUserName(userinfo); + } + + /** + * 用户登录 + */ + @Override + public UserBean loginUser(UserBean userBean) { + RestResult restResult = new RestResult(); + if (userBean.getUsername() == null && userBean.getTelephone() != null) { + userBean.setUsername(userBean.getTelephone()); + } + if (userBean.getUsername() != null && userBean.getTelephone() == null) { + userBean.setTelephone(userBean.getUsername()); + } + UserBean result = userMapper.selectUser(userBean); + + return result; + } + + @Override + public List selectAdminUserList() { + return userMapper.selectAdminUserList(); + } + + @Override + public UserBean getUserInfoById(long userId) { + UserBean userBean = userMapper.selectUserById(userId); + + return userBean; + } + + @Override + public UserBean selectUserByopenid(String openid) { + UserBean userBean = userMapper.selectUserByopenid(openid); + return userBean; + } + + + /** + * 修改用户信息 + */ + @Override + public RestResult updateUserInfo(UserBean userBean) { + RestResult restResult = new RestResult(); + userMapper.updateUserInfo(userBean); + + restResult.setSuccess(true); + return restResult; + } + + /** + * 查询所有的用户 + */ + @Override + public List selectAllUserList() { + return userMapper.selectAllUserList(); + } + + @Override + public List selectUserList(TableQueryBean tableQueryBean) { + TableQueryBean tablePageQuery = MiniuiUtil.getMiniuiTablePageQuery(tableQueryBean); + return userMapper.selectUserListByCondition(tablePageQuery); + } + + @Override + public List selectRoleList() { + //TableQueryBean tablePageQuery = MiniuiUtil.getMiniuiTablePageQuery(tableQueryBean); + return userMapper.selectRoleList(); + } + + @Override + public List selectPermissionList(TableQueryBean tableQueryBean) { + TableQueryBean tablePageQuery = MiniuiUtil.getMiniuiTablePageQuery(tableQueryBean); + return userMapper.selectPermissionListByCondition(tablePageQuery); + } + + + @Override + public int selectUserCountByCondition(TableQueryBean tableQueryBean) { + return userMapper.selectUserCountByCondition(tableQueryBean); + } + + @Override + public void deleteUserInfo(UserBean userBean) { + userMapper.deleteUserInfo(userBean); + + } + +} diff --git a/file-web/src/main/resources/application.properties b/file-web/src/main/resources/application.properties new file mode 100644 index 0000000..217ad6f --- /dev/null +++ b/file-web/src/main/resources/application.properties @@ -0,0 +1,52 @@ +server.port=8080 +#eureka.instance.hostname=localhost +#eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:8761/eureka/ +spring.application.name=web +#日志配置 +logging.file=/qiwen/log/web.log +#单个文件超过200M会压包 +logging.file.max-size=200 +#保留10条数据 +logging.file.max-history=10 +logging.level.root=info +# 控制台日志输出格式 +# -5表示从左显示5个字符宽度 +logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) %boldYellow(%thread) | %boldGreen(%logger) | %msg%n +# 文件中输出的格式 +logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss.SSS} = [%thread] = %-5level = %logger{50} - %msg%n + +#mybatis配置 +mybatis.type-aliases-package=com.mac.scp.domain +mybatis.config-locations=classpath:mybatis/mybatis-config.xml +mybatis.mapper-locations=classpath:mybatis/mapper/*.xml +#jdbc连接 +spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver +spring.datasource.url = jdbc:mysql://localhost:3306/scp?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8 +spring.datasource.username=root +spring.datasource.password=ma123456 +#数据库支持emoj表情包 +spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource +spring.datasource.dbcp2.connection-init-sqls=SET NAMES utf8mb4 +#数据库初始化 +spring.datasource.data=classpath:database/data.sql +spring.datasource.sql-script-encoding=utf-8 +spring.datasource.initialization-mode=ALWAYS +#jpa配置 +spring.jpa.properties.hibernate.hbm2ddl.auto=update +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect +spring.jpa.show-sql=true +spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl + +#静态资源指定 +spring.mvc.static-path-pattern=/** +spring.resources.static-locations=classpath:/static +#上传下载 +spring.servlet.multipart.max-file-size=2048MB +spring.servlet.multipart.max-request-size=2048MB +spring.servlet.multipart.enabled=true + +#ehcache配置 +#spring.cache.type=jcache +#spring.cache.jcache.config=classpath:/config/ehcache3.xml + +spring.main.allow-bean-definition-overriding=true diff --git a/file-web/src/main/resources/config/ehcache3.xml b/file-web/src/main/resources/config/ehcache3.xml new file mode 100644 index 0000000..dc215e8 --- /dev/null +++ b/file-web/src/main/resources/config/ehcache3.xml @@ -0,0 +1,29 @@ + + + + + org.springframework.cache.interceptor.SimpleKey + java.lang.String + + + java.lang.String + java.lang.String + + 200 + + + + 2000 + 100 + 1000 + + + + + + java.lang.String + java.lang.String + + \ No newline at end of file diff --git a/file-web/src/main/resources/database/data.sql b/file-web/src/main/resources/database/data.sql new file mode 100644 index 0000000..838aec8 --- /dev/null +++ b/file-web/src/main/resources/database/data.sql @@ -0,0 +1,15 @@ +-- 初始化文章来源 +INSERT ignore INTO essaysource (essaySourceId, essaySourceName) VALUES (1, '原创'),(2, '转载'); +-- 初始化文章分类 +delete from essaysort where essaysortid in (1, 2, 3, 4, 5, 6, 7, 8, 9); +INSERT INTO essaysort (essaysortid, essaysortName) VALUES (1,'程序人生'), (2, '前端'), (3, '数据库'), (4, 'Java'), +(5, '大数据/云计算'),(6, 'Python'),(7, '系统部署和维护'),(8, '数据结构与算法'),(9, '其他'); +-- 初始化用户 +insert ignore into user (userId, username, salt, password) value (1, 'admin', 'admin', 'df655ad8d3229f3269fad2a8bab59b6c'); +insert ignore into role (roleid, role, description) values (1, 'admin', '管理员'),(2, 'user', '普通用户'); +insert ignore into permission (permissionid, permission) values (1, 'admin'),(2, 'user'); + +delete from user_role where userid = 1 and roleid = 1; +insert into user_role (userid, roleid) value (1, 1); +delete from role_permission where roleid = 1 and permissionid = 1; +insert into role_permission (roleid, permissionid) value (1, 1); \ No newline at end of file diff --git a/file-web/src/main/resources/mybatis/mapper/FileMapper.xml b/file-web/src/main/resources/mybatis/mapper/FileMapper.xml new file mode 100644 index 0000000..1146025 --- /dev/null +++ b/file-web/src/main/resources/mybatis/mapper/FileMapper.xml @@ -0,0 +1,105 @@ + + + + + + + + INSERT ignore INTO file (essayid,albumid,userid, filename,timestampname, fileurl, + filepath, extendname, uploadtime, filesize, isdir) + VALUES (#{essayid},#{albumid},#{userid}, #{filename},#{timestampname}, + #{fileurl}, #{filepath}, #{extendname}, #{uploadtime}, + #{filesize}, #{isdir}); + + + + INSERT ignore INTO file (essayid,albumid,userid, filename,timestampname, fileurl, + filepath, extendname, uploadtime, filesize, isdir) + VALUES + + (#{file.essayid},#{file.albumid},#{file.userid}, #{file.filename},#{file.timestampname}, + #{file.fileurl}, #{file.filepath}, #{file.extendname}, #{file.uploadtime}, + #{file.filesize}, #{file.isdir}) + + + + + update file + SET filename = #{filename}, uploadtime = #{uploadtime} + where fileid = #{fileid} + + + + + UPDATE file SET filepath=REPLACE(filepath, #{param1}, #{param2}) + WHERE filepath like N'${param1}%' + + + + update file set filepath = #{param2} + where filepath = #{param1} and filename = #{param3} + + and extendname = #{param4} + + + and extendname is null + + + + + + + + + + + + + + + DELETE FROM file WHERE fileid = #{fileid} + + + + delete from file where fileid in + + #{fileid} + + + + + + + + + + + + + \ No newline at end of file diff --git a/file-web/src/main/resources/mybatis/mapper/FiletransferMapper.xml b/file-web/src/main/resources/mybatis/mapper/FiletransferMapper.xml new file mode 100644 index 0000000..46bbf27 --- /dev/null +++ b/file-web/src/main/resources/mybatis/mapper/FiletransferMapper.xml @@ -0,0 +1,54 @@ + + + + + + + + DELETE FROM userimage WHERE imageid = #{imageid} + + + + + + + + + + INSERT INTO userimage (userid, imageurl, uploadtime) + VALUES (#{userid}, #{imageurl}, #{uploadtime}); + + + + + + + + + + + + update storage + set storagesize = #{storagesize} + where userid = #{userid} and storageid = #{storageid} + + + insert into storage (storageid, userid, storagesize) + values (#{storageid}, #{userid}, #{storagesize}) + + + + \ No newline at end of file diff --git a/file-web/src/main/resources/mybatis/mapper/UserMapper.xml b/file-web/src/main/resources/mybatis/mapper/UserMapper.xml new file mode 100644 index 0000000..75c9fc4 --- /dev/null +++ b/file-web/src/main/resources/mybatis/mapper/UserMapper.xml @@ -0,0 +1,160 @@ + + + + + + + + INSERT INTO user (username, salt, PASSWORD, telephone, sex, openid) + VALUES (#{username},#{salt}, #{password}, #{telephone}, #{sex}, #{openid}); + + + + INSERT INTO user_role (userId, roleid) + VALUES (#{param1}, #{param2}); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + delete from user where userId = #{userId} + + + + update user set + username = #{username}, + realname = #{realname}, + sex = #{sex}, + birthday = #{birthday}, + addrprovince = #{addrprovince}, + addrcity = #{addrcity}, + addrarea = #{addrarea}, + industry = #{industry}, + position = #{position}, + intro = #{intro} + where userId = #{userId} + + + + + + + + + + + + \ No newline at end of file diff --git a/file-web/src/main/resources/mybatis/mybatis-config.xml b/file-web/src/main/resources/mybatis/mybatis-config.xml new file mode 100644 index 0000000..4f9ab61 --- /dev/null +++ b/file-web/src/main/resources/mybatis/mybatis-config.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/file-web/src/main/resources/script/startWeb.bat b/file-web/src/main/resources/script/startWeb.bat new file mode 100644 index 0000000..d93c539 --- /dev/null +++ b/file-web/src/main/resources/script/startWeb.bat @@ -0,0 +1,2 @@ +java -jar app/file-web/file-web-0.0.1-SNAPSHOT.jar +pause \ No newline at end of file diff --git a/file-web/src/main/resources/static/index.html b/file-web/src/main/resources/static/index.html new file mode 100644 index 0000000..442273e --- /dev/null +++ b/file-web/src/main/resources/static/index.html @@ -0,0 +1,10 @@ + + + + + + + + index + + \ No newline at end of file diff --git a/file-web/src/test/java/com/mac/scp/ScpApplicationTests.java b/file-web/src/test/java/com/mac/scp/ScpApplicationTests.java new file mode 100644 index 0000000..15ebc32 --- /dev/null +++ b/file-web/src/test/java/com/mac/scp/ScpApplicationTests.java @@ -0,0 +1,16 @@ +package com.mac.scp; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class ScpApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git a/file-web/src/test/java/com/mac/scp/config/redis/TestRedis.java b/file-web/src/test/java/com/mac/scp/config/redis/TestRedis.java new file mode 100644 index 0000000..7ea880a --- /dev/null +++ b/file-web/src/test/java/com/mac/scp/config/redis/TestRedis.java @@ -0,0 +1,42 @@ +package com.mac.scp.config.redis; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class TestRedis { + @Autowired + private StringRedisTemplate stringRedisTemplate; + @Autowired + private RedisTemplate redisTemplate; + + @Test + public void test() throws Exception { + stringRedisTemplate.opsForValue().set("aaa", "111"); + Assert.assertEquals("111", stringRedisTemplate.opsForValue().get("aaa")); + } + +// @Test +// public void testObj() throws Exception { +// User user=new User("aa@126.com", "aa", "aa123456", "aa","123"); +// ValueOperations operations=redisTemplate.opsForValue(); +// operations.set("com.neox", user); +// operations.set("com.neo.f", user,1, TimeUnit.SECONDS); +// Thread.sleep(1000); +// //redisTemplate.delete("com.neo.f"); +// boolean exists=redisTemplate.hasKey("com.neo.f"); +// if(exists){ +// System.out.println("exists is true"); +// }else{ +// System.out.println("exists is false"); +// } +// // Assert.assertEquals("aa", operations.get("com.neo.f").getUserName()); +// } +} \ No newline at end of file diff --git a/install.bat b/install.bat new file mode 100644 index 0000000..0d48d74 --- /dev/null +++ b/install.bat @@ -0,0 +1,2 @@ +mvn install -s file-common/src/main/resources/conf/settings.xml +pause \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..5a4644e --- /dev/null +++ b/pom.xml @@ -0,0 +1,125 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 2.1.4.RELEASE + + + com.qiwen + file + 1.0-SNAPSHOT + pom + + + + + com.alibaba + fastjson + 1.2.28 + + + + mysql + mysql-connector-java + runtime + + + + + org.hibernate + hibernate-core + 5.4.1.Final + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + org.springframework.boot + spring-boot-starter-aop + + + org.aspectj + aspectjrt + 1.9.3.RC1 + + + org.aspectj + aspectjweaver + 1.9.3.RC1 + + + cglib + cglib + 3.2.10 + + + org.springframework + spring-aop + 5.1.6.RELEASE + + + + + org.springframework.boot + spring-boot-starter-mail + + + com.sun.mail + javax.mail + RELEASE + + + + + + + + + + + + + + commons-io + commons-io + 2.6 + + + + org.apache.commons + commons-dbcp2 + + + + + + + + file-web + file-common + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.0.0 + + + + + \ No newline at end of file