summaryrefslogtreecommitdiff
path: root/src/main/java/com/mesasoft
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/mesasoft')
-rw-r--r--src/main/java/com/mesasoft/cn/SketchApplication.java42
-rw-r--r--src/main/java/com/mesasoft/cn/annotation/AuthInterceptor.java22
-rw-r--r--src/main/java/com/mesasoft/cn/config/SettingConfig.java100
-rw-r--r--src/main/java/com/mesasoft/cn/config/TokenConfig.java80
-rw-r--r--src/main/java/com/mesasoft/cn/config/WebMvcConfig.java63
-rw-r--r--src/main/java/com/mesasoft/cn/dao/AuthDAO.java107
-rw-r--r--src/main/java/com/mesasoft/cn/dao/CategoryDAO.java103
-rw-r--r--src/main/java/com/mesasoft/cn/dao/DownloadedDAO.java53
-rw-r--r--src/main/java/com/mesasoft/cn/dao/FileDAO.java340
-rw-r--r--src/main/java/com/mesasoft/cn/dao/UploadedDAO.java32
-rw-r--r--src/main/java/com/mesasoft/cn/dao/UserDAO.java167
-rw-r--r--src/main/java/com/mesasoft/cn/dao/sqlprovider/AuthSqlProvider.java48
-rw-r--r--src/main/java/com/mesasoft/cn/dao/sqlprovider/CommonSqlProvider.java24
-rw-r--r--src/main/java/com/mesasoft/cn/dao/sqlprovider/DownloadedSqlProvider.java48
-rw-r--r--src/main/java/com/mesasoft/cn/dao/sqlprovider/FileSqlProvider.java110
-rw-r--r--src/main/java/com/mesasoft/cn/dao/sqlprovider/UploadedSqlProvider.java47
-rw-r--r--src/main/java/com/mesasoft/cn/dao/sqlprovider/UserSqlProvider.java41
-rw-r--r--src/main/java/com/mesasoft/cn/entity/Auth.java137
-rw-r--r--src/main/java/com/mesasoft/cn/entity/Category.java63
-rw-r--r--src/main/java/com/mesasoft/cn/entity/Download.java71
-rw-r--r--src/main/java/com/mesasoft/cn/entity/File.java255
-rw-r--r--src/main/java/com/mesasoft/cn/entity/Result.java46
-rw-r--r--src/main/java/com/mesasoft/cn/entity/ResultEntity.java20
-rw-r--r--src/main/java/com/mesasoft/cn/entity/User.java196
-rw-r--r--src/main/java/com/mesasoft/cn/enums/InterceptorLevel.java29
-rw-r--r--src/main/java/com/mesasoft/cn/enums/StatusEnum.java23
-rw-r--r--src/main/java/com/mesasoft/cn/exception/BusinessException.java42
-rw-r--r--src/main/java/com/mesasoft/cn/exception/GlobalExceptionHandler.java36
-rw-r--r--src/main/java/com/mesasoft/cn/interceptor/WebInterceptor.java79
-rw-r--r--src/main/java/com/mesasoft/cn/model/AuthRecord.java153
-rw-r--r--src/main/java/com/mesasoft/cn/model/BaseAuthRecord.java66
-rw-r--r--src/main/java/com/mesasoft/cn/model/DownloadRecord.java120
-rw-r--r--src/main/java/com/mesasoft/cn/model/FileBasicRecord.java91
-rw-r--r--src/main/java/com/mesasoft/cn/model/FileRecord.java261
-rw-r--r--src/main/java/com/mesasoft/cn/model/UploadedRecord.java113
-rw-r--r--src/main/java/com/mesasoft/cn/modules/constant/ConfigConsts.java201
-rw-r--r--src/main/java/com/mesasoft/cn/modules/constant/DefaultValues.java82
-rw-r--r--src/main/java/com/mesasoft/cn/service/IAuthService.java92
-rw-r--r--src/main/java/com/mesasoft/cn/service/ICategoryService.java65
-rw-r--r--src/main/java/com/mesasoft/cn/service/ICommonService.java28
-rw-r--r--src/main/java/com/mesasoft/cn/service/IConfigService.java22
-rw-r--r--src/main/java/com/mesasoft/cn/service/IDownloadedService.java39
-rw-r--r--src/main/java/com/mesasoft/cn/service/IFileManagerService.java136
-rw-r--r--src/main/java/com/mesasoft/cn/service/IFileService.java228
-rw-r--r--src/main/java/com/mesasoft/cn/service/IUploadedService.java24
-rw-r--r--src/main/java/com/mesasoft/cn/service/IUserService.java161
-rw-r--r--src/main/java/com/mesasoft/cn/service/impl/AuthServiceImpl.java96
-rw-r--r--src/main/java/com/mesasoft/cn/service/impl/CategoryServiceImpl.java62
-rw-r--r--src/main/java/com/mesasoft/cn/service/impl/CommonServiceImpl.java59
-rw-r--r--src/main/java/com/mesasoft/cn/service/impl/ConfigServiceImpl.java33
-rw-r--r--src/main/java/com/mesasoft/cn/service/impl/DownloadedServiceImpl.java42
-rw-r--r--src/main/java/com/mesasoft/cn/service/impl/FileManagerServiceImpl.java236
-rw-r--r--src/main/java/com/mesasoft/cn/service/impl/FileServiceImpl.java383
-rw-r--r--src/main/java/com/mesasoft/cn/service/impl/UploadedServiceImpl.java30
-rw-r--r--src/main/java/com/mesasoft/cn/service/impl/UserServiceImpl.java163
-rw-r--r--src/main/java/com/mesasoft/cn/sketch/api/BrightCloud.java193
-rw-r--r--src/main/java/com/mesasoft/cn/sketch/api/ChinaZ.java336
-rw-r--r--src/main/java/com/mesasoft/cn/sketch/config/ApplicationConfig.java54
-rw-r--r--src/main/java/com/mesasoft/cn/sketch/config/MariaDbBase.java84
-rw-r--r--src/main/java/com/mesasoft/cn/sketch/config/SketchDatabaseConfig.java125
-rw-r--r--src/main/java/com/mesasoft/cn/sketch/controller/SketchDomainController.java54
-rw-r--r--src/main/java/com/mesasoft/cn/sketch/controller/SketchFileController.java93
-rw-r--r--src/main/java/com/mesasoft/cn/sketch/dao/SketchDAO.java81
-rw-r--r--src/main/java/com/mesasoft/cn/sketch/dao/sqlprovider/SketchSqlProvider.java27
-rw-r--r--src/main/java/com/mesasoft/cn/sketch/entity/DomainCategory.java340
-rw-r--r--src/main/java/com/mesasoft/cn/sketch/entity/DomainWhois.java423
-rw-r--r--src/main/java/com/mesasoft/cn/sketch/service/SketchService.java232
-rw-r--r--src/main/java/com/mesasoft/cn/util/BeanUtils.java77
-rw-r--r--src/main/java/com/mesasoft/cn/util/CommonUtils.java26
-rw-r--r--src/main/java/com/mesasoft/cn/util/ConfigUtils.java46
-rw-r--r--src/main/java/com/mesasoft/cn/util/Contants.java54
-rw-r--r--src/main/java/com/mesasoft/cn/util/ControllerUtils.java152
-rw-r--r--src/main/java/com/mesasoft/cn/util/FileUtils.java197
-rw-r--r--src/main/java/com/mesasoft/cn/util/MariaDBUtils.java80
-rw-r--r--src/main/java/com/mesasoft/cn/util/MariaDbBase.java84
-rw-r--r--src/main/java/com/mesasoft/cn/util/ServiceUtils.java59
-rw-r--r--src/main/java/com/mesasoft/cn/util/TimeUtils.java59
-rw-r--r--src/main/java/com/mesasoft/cn/util/ValidationUtils.java202
-rw-r--r--src/main/java/com/mesasoft/cn/util/Verify.java20
-rw-r--r--src/main/java/com/mesasoft/cn/web/controller/AuthController.java66
-rw-r--r--src/main/java/com/mesasoft/cn/web/controller/CategoryController.java75
-rw-r--r--src/main/java/com/mesasoft/cn/web/controller/CommonController.java94
-rw-r--r--src/main/java/com/mesasoft/cn/web/controller/ConfigController.java92
-rw-r--r--src/main/java/com/mesasoft/cn/web/controller/CustomErrorController.java42
-rw-r--r--src/main/java/com/mesasoft/cn/web/controller/DownloadedController.java41
-rw-r--r--src/main/java/com/mesasoft/cn/web/controller/FileController.java220
-rw-r--r--src/main/java/com/mesasoft/cn/web/controller/FileMangerController.java188
-rw-r--r--src/main/java/com/mesasoft/cn/web/controller/GlobalExceptionHandler.java49
-rw-r--r--src/main/java/com/mesasoft/cn/web/controller/UploadedController.java39
-rw-r--r--src/main/java/com/mesasoft/cn/web/controller/UserController.java281
-rw-r--r--src/main/java/com/mesasoft/cn/web/controller/ViewController.java63
91 files changed, 9758 insertions, 0 deletions
diff --git a/src/main/java/com/mesasoft/cn/SketchApplication.java b/src/main/java/com/mesasoft/cn/SketchApplication.java
new file mode 100644
index 0000000..44a3041
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/SketchApplication.java
@@ -0,0 +1,42 @@
+package com.mesasoft.cn;
+
+import com.spring4all.swagger.EnableSwagger2Doc;
+import com.zhazhapan.config.JsonParser;
+import com.mesasoft.cn.config.TokenConfig;
+import com.mesasoft.cn.modules.constant.ConfigConsts;
+import com.mesasoft.cn.modules.constant.DefaultValues;
+import com.zhazhapan.util.FileExecutor;
+import com.zhazhapan.util.MailSender;
+import com.zhazhapan.util.ReflectUtils;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.List;
+
+/**
+ * @author pantao
+ */
+@SpringBootApplication
+@EnableSwagger2Doc
+@MapperScan("com.mesasoft.cn.dao")
+@EnableTransactionManagement
+public class SketchApplication {
+
+ public static JsonParser settings = new JsonParser();
+
+ public static List<Class<?>> controllers;
+
+ public static Hashtable<String, Integer> tokens;
+
+ public static void main(String[] args) throws IOException, ClassNotFoundException {
+ settings.setJsonObject(FileExecutor.read(SketchApplication.class.getResourceAsStream(DefaultValues.SETTING_PATH)));
+ MailSender.config(settings.getObjectUseEval(ConfigConsts.EMAIL_CONFIG_OF_SETTINGS));
+ controllers = ReflectUtils.getClasses(DefaultValues.CONTROLLER_PACKAGE);
+ tokens = TokenConfig.loadToken();
+ SpringApplication.run(SketchApplication.class, args);
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/annotation/AuthInterceptor.java b/src/main/java/com/mesasoft/cn/annotation/AuthInterceptor.java
new file mode 100644
index 0000000..3b1a658
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/annotation/AuthInterceptor.java
@@ -0,0 +1,22 @@
+package com.mesasoft.cn.annotation;
+
+import com.mesasoft.cn.enums.InterceptorLevel;
+
+import java.lang.annotation.*;
+
+/**
+ * @author pantao
+ * @since 2018/1/25
+ */
+@Documented
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface AuthInterceptor {
+
+ /**
+ * 定义拦截级别,默认为用户级别拦截
+ *
+ * @return {@link InterceptorLevel}
+ */
+ InterceptorLevel value() default InterceptorLevel.USER;
+}
diff --git a/src/main/java/com/mesasoft/cn/config/SettingConfig.java b/src/main/java/com/mesasoft/cn/config/SettingConfig.java
new file mode 100644
index 0000000..a78197a
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/config/SettingConfig.java
@@ -0,0 +1,100 @@
+package com.mesasoft.cn.config;
+
+import com.mesasoft.cn.SketchApplication;
+import com.mesasoft.cn.modules.constant.ConfigConsts;
+import com.mesasoft.cn.util.CommonUtils;
+import com.zhazhapan.modules.constant.ValueConsts;
+import com.zhazhapan.util.Checker;
+import com.zhazhapan.util.FileExecutor;
+import com.zhazhapan.util.Formatter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Date;
+
+/**
+ * @author pantao
+ * @since 2018/1/26
+ */
+public class SettingConfig {
+
+ private static final String WINDOWS = "windows";
+
+ private static final String MAC = "mac";
+
+ private static final String LINUX = "linux";
+
+ private static Logger logger = LoggerFactory.getLogger(SettingConfig.class);
+
+ private static OsName currentOS;
+
+ static {
+ if (Checker.isWindows()) {
+ currentOS = OsName.WINDOWS;
+ } else if (Checker.isMacOS()) {
+ currentOS = OsName.MAC;
+ } else {
+ currentOS = OsName.LINUX;
+ }
+ }
+
+ public static int[] getAuth(String jsonPath) {
+ int[] auth = new int[5];
+ for (int i = 0; i < ConfigConsts.AUTH_OF_SETTINGS.length; i++) {
+ String key = jsonPath + ValueConsts.DOT_SIGN + ConfigConsts.AUTH_OF_SETTINGS[i];
+ auth[i] = SketchApplication.settings.getBooleanUseEval(key) ? 1 : 0;
+ }
+ return auth;
+ }
+
+ public static String getUploadStoragePath() {
+ String parent = getStoragePath(ConfigConsts.UPLOAD_PATH_OF_SETTING);
+ String formatWay = SketchApplication.settings.getStringUseEval(ConfigConsts.UPLOAD_FORM_OF_SETTING);
+ String childPath = ValueConsts.SEPARATOR + Formatter.datetimeToCustomString(new Date(), formatWay);
+ String path = parent + childPath;
+ if (!FileExecutor.createFolder(path)) {
+ path = ConfigConsts.DEFAULT_UPLOAD_PATH + childPath;
+ FileExecutor.createFolder(path);
+ }
+ logger.info("upload path: " + path);
+ return path;
+ }
+
+ public static String getAvatarStoragePath() {
+ String path = getStoragePath(ConfigConsts.UPLOAD_PATH_OF_SETTING) + ValueConsts.SEPARATOR + "avatar";
+ FileExecutor.createFolder(path);
+ return path;
+ }
+
+ public static String getStoragePath(String path) {
+ path += ValueConsts.DOT_SIGN;
+ if (currentOS == OsName.WINDOWS) {
+ path += WINDOWS;
+ } else if (currentOS == OsName.MAC) {
+ path += MAC;
+ } else {
+ path += LINUX;
+ }
+ return CommonUtils.checkPath(SketchApplication.settings.getStringUseEval(path));
+ }
+
+ /**
+ * 当前系统名称
+ */
+ public enum OsName {
+ /**
+ * windows系统
+ */
+ WINDOWS,
+
+ /**
+ * MacOS系统
+ */
+ MAC,
+
+ /**
+ * Linux系统
+ */
+ LINUX
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/config/TokenConfig.java b/src/main/java/com/mesasoft/cn/config/TokenConfig.java
new file mode 100644
index 0000000..7a83572
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/config/TokenConfig.java
@@ -0,0 +1,80 @@
+package com.mesasoft.cn.config;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.mesasoft.cn.SketchApplication;
+import com.mesasoft.cn.modules.constant.ConfigConsts;
+import com.zhazhapan.modules.constant.ValueConsts;
+import com.zhazhapan.util.Checker;
+import com.zhazhapan.util.FileExecutor;
+import com.zhazhapan.util.Formatter;
+import com.zhazhapan.util.RandomUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Hashtable;
+
+/**
+ * @author pantao
+ * @since 2018/1/26
+ */
+public class TokenConfig {
+
+ private static Logger logger = LoggerFactory.getLogger(TokenConfig.class);
+
+ public static String generateToken(String token, int userId) {
+ if (Checker.isNotEmpty(token)) {
+ SketchApplication.tokens.remove(token);
+ }
+ return generateToken(userId);
+ }
+
+ public static String generateToken(int userId) {
+ String token = RandomUtils.getRandomStringOnlyLetter(ValueConsts.THIRTY_TWO_INT);
+ SketchApplication.tokens.put(token, userId);
+ saveToken();
+ return token;
+ }
+
+ public static void saveToken() {
+ String tokens = Formatter.mapToJson(SketchApplication.tokens);
+ try {
+ FileExecutor.saveFile(SettingConfig.getStoragePath(ConfigConsts.TOKEN_OF_SETTINGS), tokens);
+ } catch (Exception e) {
+ logger.error("save token error: " + e.getMessage());
+ }
+ }
+
+ public static Hashtable<String, Integer> loadToken() {
+ Hashtable<String, Integer> tokens = new Hashtable<>(ValueConsts.SIXTEEN_INT);
+ try {
+ String token = FileExecutor.readFile(SettingConfig.getStoragePath(ConfigConsts.TOKEN_OF_SETTINGS));
+ JSONArray array = JSON.parseArray(token);
+ array.forEach(object -> {
+ JSONObject jsonObject = (JSONObject) object;
+ tokens.put(jsonObject.getString(ValueConsts.KEY_STRING), jsonObject.getInteger(ValueConsts
+ .VALUE_STRING));
+ });
+ } catch (Exception e) {
+ logger.error("load token error: " + e.getMessage());
+ }
+ return tokens;
+ }
+
+ public static void removeTokenByValue(int userId) {
+ if (userId > 0) {
+ String removeKey = "";
+ for (String key : SketchApplication.tokens.keySet()) {
+ if (SketchApplication.tokens.get(key) == userId) {
+ removeKey = key;
+ break;
+ }
+ }
+ if (Checker.isNotEmpty(removeKey)) {
+ SketchApplication.tokens.remove(removeKey);
+ TokenConfig.saveToken();
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/config/WebMvcConfig.java b/src/main/java/com/mesasoft/cn/config/WebMvcConfig.java
new file mode 100644
index 0000000..51380b4
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/config/WebMvcConfig.java
@@ -0,0 +1,63 @@
+package com.mesasoft.cn.config;
+
+import com.alibaba.fastjson.JSONObject;
+import com.mesasoft.cn.exception.GlobalExceptionHandler;
+import com.mesasoft.cn.interceptor.WebInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.HandlerExceptionResolver;
+import org.springframework.web.servlet.config.annotation.*;
+import org.springframework.web.servlet.view.InternalResourceViewResolver;
+
+import java.util.List;
+
+/**
+ * @author pantao
+ * @since 2018/1/22
+ */
+@Configuration
+public class WebMvcConfig implements WebMvcConfigurer {
+
+ @Override
+ public void configureViewResolvers(ViewResolverRegistry registry) {
+ InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
+ viewResolver.setPrefix("/");
+ viewResolver.setSuffix(".html");
+ registry.viewResolver(viewResolver);
+ }
+
+ @Override
+ public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
+ resolvers.add(globalExceptionHandler());
+ }
+
+ @Override
+ public void configurePathMatch(PathMatchConfigurer configurer) {
+ configurer.setUseSuffixPatternMatch(false);
+ }
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(webInterceptor());
+ }
+
+ @Override
+ public void addResourceHandlers(ResourceHandlerRegistry registry) {
+ registry.addResourceHandler("/assets/**").addResourceLocations("classpath:/assets/");
+ }
+
+ @Bean
+ public WebInterceptor webInterceptor() {
+ return new WebInterceptor();
+ }
+
+ @Bean
+ public GlobalExceptionHandler globalExceptionHandler() {
+ return new GlobalExceptionHandler();
+ }
+
+ @Bean
+ public JSONObject jsonObject() {
+ return new JSONObject();
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/dao/AuthDAO.java b/src/main/java/com/mesasoft/cn/dao/AuthDAO.java
new file mode 100644
index 0000000..2d62e69
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/dao/AuthDAO.java
@@ -0,0 +1,107 @@
+package com.mesasoft.cn.dao;
+
+import com.mesasoft.cn.dao.sqlprovider.AuthSqlProvider;
+import com.mesasoft.cn.entity.Auth;
+import com.mesasoft.cn.model.AuthRecord;
+import org.apache.ibatis.annotations.*;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * @author pantao
+ * @since 2018/1/19
+ */
+@Repository
+public interface AuthDAO {
+
+ /**
+ * 检测某个权限是否存在
+ *
+ * @param userId 用户编号
+ * @param fileId 文件编号
+ *
+ * @return {@link Auth}
+ */
+ @Select("select * from auth where user_id=#{userId} and file_id=#{fileId}")
+ Auth exists(@Param("userId") int userId, @Param("fileId") long fileId);
+
+ /**
+ * 批量删除权限记录
+ *
+ * @param ids 权限编号集
+ *
+ * @return 是否删除成功
+ */
+ @DeleteProvider(type = AuthSqlProvider.class, method = "batchDelete")
+ boolean batchDelete(@Param("ids") String ids);
+
+ /**
+ * 添加一条权限记录
+ *
+ * @param auth {@link Auth}
+ *
+ * @return 是否添加成功
+ */
+ @Insert("insert into auth(user_id,file_id,is_downloadable,is_uploadable,is_deletable,is_updatable,is_visible) " +
+ "values(#{userId},#{fileId},#{isDownloadable},#{isUploadable},#{isDeletable},#{isUpdatable},#{isVisible})")
+ boolean insertAuth(Auth auth);
+
+ /**
+ * 删除一条权限记录
+ *
+ * @param id 编号
+ */
+ @Delete("delete from auth where id=#{id}")
+ void removeAuthById(int id);
+
+ /**
+ * 删除一条权限记录
+ *
+ * @param userId 编号
+ */
+ @Delete("delete from auth where user_id=#{userId}")
+ void removeAuthByUserId(int userId);
+
+ /**
+ * 删除一条权限记录
+ *
+ * @param fileId 编号
+ *
+ * @return 是否删除成功
+ */
+ @Delete("delete from auth where file_id=#{fileId}")
+ boolean removeAuthByFileId(long fileId);
+
+ /**
+ * 更新权限记录
+ *
+ * @param id 编号
+ * @param isDownloadable 下载权限
+ * @param isUploadable 上传权限
+ * @param isVisible 可查权限
+ * @param isDeletable 删除权限
+ * @param isUpdatable 更新权限
+ *
+ * @return 是否更新成功
+ */
+ @UpdateProvider(type = AuthSqlProvider.class, method = "updateAuthById")
+ boolean updateAuthById(@Param("id") long id, @Param("isDownloadable") int isDownloadable, @Param("isUploadable")
+ int isUploadable, @Param("isDeletable") int isDeletable, @Param("isUpdatable") int isUpdatable, @Param
+ ("isVisible") int isVisible);
+
+ /**
+ * 获取权限记录
+ *
+ * @param id 编号,值小于等于0时不作为条件
+ * @param userId 用户编号,值小于等于0时不作为条件
+ * @param fileId 文件编号,值小于等于0时不作为条件
+ * @param fileName 模糊搜索文件名(当参数不为空时)
+ * @param offset 偏移
+ *
+ * @return {@link List}
+ */
+ @SelectProvider(type = AuthSqlProvider.class, method = "getAuthBy")
+ List<AuthRecord> listAuthBy(@Param("id") long id, @Param("userId") int userId, @Param("fileId") long fileId,
+ @Param("fileName") String fileName, @Param("offset") int offset);
+}
diff --git a/src/main/java/com/mesasoft/cn/dao/CategoryDAO.java b/src/main/java/com/mesasoft/cn/dao/CategoryDAO.java
new file mode 100644
index 0000000..848d6b8
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/dao/CategoryDAO.java
@@ -0,0 +1,103 @@
+package com.mesasoft.cn.dao;
+
+import com.mesasoft.cn.entity.Category;
+import org.apache.ibatis.annotations.*;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * @author pantao
+ * @since 2018/1/18
+ */
+@Repository
+public interface CategoryDAO {
+
+ /**
+ * 通过分类名获取ID
+ *
+ * @param name 分类名
+ *
+ * @return {@link Integer}
+ */
+ @Select("select id from category where name=#{name}")
+ int getIdByName(String name);
+
+ /**
+ * 添加一个分类
+ *
+ * @param name 分类名
+ *
+ * @return 是否添加成功
+ */
+ @Insert("insert into category(name) values(#{name})")
+ boolean insertCategory(String name);
+
+ /**
+ * 通过编号删除一个分类
+ *
+ * @param id 编号
+ *
+ * @return 是否删除成功
+ */
+ @Delete("delete from category where id=#{id}")
+ boolean removeCategoryById(int id);
+
+ /**
+ * 通过名称删除一个分类
+ *
+ * @param name 分类名称
+ *
+ * @return 是否删除成功
+ */
+ @Delete("delete from category where name=#{name}")
+ boolean removeCategoryByName(String name);
+
+ /**
+ * 更新一个分类名
+ *
+ * @param name 分类名
+ * @param id 分类ID
+ *
+ * @return 是否更新成功
+ */
+ @Update("update category set name=#{name} where id=#{id}")
+ boolean updateNameById(@Param("id") int id, @Param("name") String name);
+
+ /**
+ * 通过分类名更新分类名
+ *
+ * @param newName 新的分类名
+ * @param oldName 旧的分类名
+ */
+ @Update("update category set name=#{newName} where name=#{oldName}")
+ void updateNameByName(String newName, String oldName);
+
+ /**
+ * 获取所有分类
+ *
+ * @return {@link List}
+ */
+ @Select("select * from category")
+ List<Category> listCategory();
+
+ /**
+ * 通过编号获取一个分类
+ *
+ * @param id 编号
+ *
+ * @return {@link Category}
+ */
+ @Select("select * from category where id=#{id}")
+ Category getCategoryById(int id);
+
+ /**
+ * 通过名称获取一个分类
+ *
+ * @param name 名称
+ *
+ * @return {@link Category}
+ */
+ @Select("select * from category where name=#{name}")
+ Category getCategoryByName(String name);
+}
diff --git a/src/main/java/com/mesasoft/cn/dao/DownloadedDAO.java b/src/main/java/com/mesasoft/cn/dao/DownloadedDAO.java
new file mode 100644
index 0000000..263945c
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/dao/DownloadedDAO.java
@@ -0,0 +1,53 @@
+package com.mesasoft.cn.dao;
+
+import com.mesasoft.cn.dao.sqlprovider.DownloadedSqlProvider;
+import com.mesasoft.cn.model.DownloadRecord;
+import org.apache.ibatis.annotations.Delete;
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.SelectProvider;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * @author pantao
+ * @since 2018/1/18
+ */
+@Repository
+public interface DownloadedDAO {
+
+ /**
+ * 新增一条下载记录
+ *
+ * @param userId 用户编号
+ * @param fileId 文件编号
+ */
+ @Insert("insert into download(user_id,file_id) values(#{userId},#{fileId})")
+ void insertDownload(@Param("userId") int userId, @Param("fileId") long fileId);
+
+ /**
+ * 查询下载记录
+ *
+ * @param userId 用户编号,不使用用户编号作为条件时设置值小于等于0即可
+ * @param fileId 文件编号,不使用文件编号作为条件时设置值小于等于0即可
+ * @param categoryId 分类编号,不用分类编号作为条件时设置值小于等于0即可
+ * @param fileName 文件名,不使用文件名作为条件时设置值为空即可
+ * @param offset 偏移
+ *
+ * @return 下载记录
+ */
+ @SelectProvider(type = DownloadedSqlProvider.class, method = "getDownloadBy")
+ List<DownloadRecord> listDownloadedBy(@Param("userId") int userId, @Param("fileId") long fileId, @Param
+ ("fileName") String fileName, @Param("categoryId") int categoryId, @Param("offset") int offset);
+
+ /**
+ * 删除文件
+ *
+ * @param fileId 文件编号
+ *
+ * @return 是否删除成功
+ */
+ @Delete("delete from download where file_id=#{fileId}")
+ boolean removeByFileId(long fileId);
+}
diff --git a/src/main/java/com/mesasoft/cn/dao/FileDAO.java b/src/main/java/com/mesasoft/cn/dao/FileDAO.java
new file mode 100644
index 0000000..fe33c54
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/dao/FileDAO.java
@@ -0,0 +1,340 @@
+package com.mesasoft.cn.dao;
+
+import com.mesasoft.cn.dao.sqlprovider.FileSqlProvider;
+import com.mesasoft.cn.entity.File;
+import com.mesasoft.cn.model.BaseAuthRecord;
+import com.mesasoft.cn.model.FileBasicRecord;
+import com.mesasoft.cn.model.FileRecord;
+import org.apache.ibatis.annotations.*;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * @author pantao
+ * @since 2018/1/19
+ */
+@Repository
+public interface FileDAO {
+
+ /**
+ * 获取文件权限
+ *
+ * @param id 文件编号
+ *
+ * @return {@link BaseAuthRecord}
+ */
+ @Select("select is_downloadable,is_uploadable,is_deletable,is_updatable,is_visible from file where id=#{id}")
+ BaseAuthRecord getAuth(long id);
+
+ /**
+ * 通过编号获取文件
+ *
+ * @param id 编号
+ *
+ * @return {@link File}
+ */
+ @Select("select * from file where id=#{id}")
+ File getById(long id);
+
+ /**
+ * 通过ID获取本地路径
+ *
+ * @param fileId 文件编号
+ *
+ * @return {@link String}
+ */
+ @Select("select local_url from file where id=#{id}")
+ String getLocalUrlById(long fileId);
+
+ /**
+ * 通过编号删除文件
+ *
+ * @param id 编号
+ *
+ * @return 是否删除成功
+ */
+ @Delete("delete from file where id=#{id}")
+ boolean removeById(long id);
+
+ /**
+ * 通过本地路径获取文件编号
+ *
+ * @param visitUrl 本地路径
+ *
+ * @return 编号
+ */
+ @Select("select id from file where visit_url=#{visitUrl}")
+ long getIdByVisitUrl(String visitUrl);
+
+ /**
+ * 通过本地路径获取文件编号
+ *
+ * @param localUrl 本地路径
+ *
+ * @return 编号
+ */
+ @Select("select id from file where local_url=#{localUrl}")
+ long getIdByLocalUrl(String localUrl);
+
+ /**
+ * 通过访问路径获取本地文件路径
+ *
+ * @param visitUrl 访问路径
+ *
+ * @return {@link String}
+ */
+ @Select("select local_url from file where visit_url=#{visitUrl}")
+ String getLocalUrlByVisitUrl(String visitUrl);
+
+ /**
+ * 通过访问路径删除
+ *
+ * @param visitUrl 访问路径
+ *
+ * @return 是否删除成功
+ */
+ @Delete("delete from file where visit_url=#{visitUrl}")
+ boolean removeByVisitUrl(String visitUrl);
+
+ /**
+ * 通过本地路径删除
+ *
+ * @param localUrl 本地路径
+ *
+ * @return 是否删除成功
+ */
+ @Delete("delete from file where local_url=#{localUrl}")
+ boolean removeByLocalUrl(String localUrl);
+
+ /**
+ * 检查本地路径
+ *
+ * @param localUrl 本地路径
+ *
+ * @return {@link Integer}
+ */
+ @Select("select count(*) from file where local_url=#{localUrl}")
+ int checkLocalUrl(String localUrl);
+
+ /**
+ * 检查访问路径
+ *
+ * @param visitUrl 访问路径
+ *
+ * @return {@link Integer}
+ */
+ @Select("select count(*) from file where visit_url=#{visitUrl}")
+ int checkVisitUrl(String visitUrl);
+
+ /**
+ * 添加一个文件
+ *
+ * @param file {@link File}
+ *
+ * @return 是否添加成功
+ */
+ @Insert("insert into file(name,suffix,local_url,visit_url,size,description,tag,user_id,category_id," +
+ "is_downloadable,is_uploadable,is_deletable,is_updatable,is_visible) values(#{name},#{suffix}," +
+ "#{localUrl},#{visitUrl},#{size},#{description},#{tag},#{userId},#{categoryId},#{isDownloadable}," +
+ "#{isUploadable},#{isDeletable},#{isUpdatable},#{isVisible})")
+ boolean insertFile(File file);
+
+ /**
+ * 删除一个文件
+ *
+ * @param id 文件编号
+ */
+ @Delete("delete from file where id=#{id}")
+ void deleteFileById(int id);
+
+ /**
+ * 删除文件
+ *
+ * @param userId 用户编号
+ */
+ @Delete("delete from file where user_id=#{userId}")
+ void deleteFileByUserId(int userId);
+
+ /**
+ * 删除文件
+ *
+ * @param categoryId 分类编号
+ */
+ @Delete("delete from file where category_d=#{categoryId}")
+ void deleteFileByCategoryId(int categoryId);
+
+ /**
+ * 更新文件基本信息
+ *
+ * @param file 文件
+ *
+ * @return 是否更新成功
+ */
+ @Update("update file set name=#{name},suffix=#{suffix},local_url=#{localUrl},visit_url=#{visitUrl}," +
+ "description=#{description},tag=#{tag},category_id=#{categoryId},last_modify_time=current_timestamp " +
+ "where" + " id=#{id}")
+ boolean updateFileInfo(File file);
+
+ /**
+ * 更新文件权限
+ *
+ * @param id 编号
+ * @param isDownloadable 下载权限
+ * @param isUploadable 上传权限
+ * @param isVisible 可查权限
+ * @param isDeletable 删除权限
+ * @param isUpdatable 上传权限
+ *
+ * @return 是否更新成功
+ */
+ @UpdateProvider(type = FileSqlProvider.class, method = "updateAuthById")
+ boolean updateAuthById(@Param("id") long id, @Param("isDownloadable") int isDownloadable, @Param("isUploadable")
+ int isUploadable, @Param("isDeletable") int isDeletable, @Param("isUpdatable") int isUpdatable, @Param
+ ("isVisible") int isVisible);
+
+ /**
+ * 更新文件名
+ *
+ * @param id 编号
+ * @param name 文件名
+ * @param suffix 后缀名
+ */
+ @Update("update file set name=#{name},suffix=#{suffix},last_modify_time=current_timestamp where id=#{id}")
+ void updateFileNameById(@Param("id") int id, @Param("name") String name, @Param("suffix") String suffix);
+
+ /**
+ * 更新文件修改时间
+ *
+ * @param id 编号
+ */
+ @Update("update file set last_modify_time=current_timestamp where id=#{id}")
+ void updateLastModifyTimeById(int id);
+
+ /**
+ * 更新文件本地路径
+ *
+ * @param id 编号
+ * @param localUrl 本地路径
+ */
+ @Update("update file set local_url=#{localUrl} where id=#{id}")
+ void updateLocalUrlById(@Param("id") int id, @Param("localUrl") String localUrl);
+
+ /**
+ * 更新文件访问路径
+ *
+ * @param id 编号
+ * @param visitUrl 访问链接
+ */
+ @Update("update file set visit_url=#{visitUrl} where id=#{id}")
+ void updateVisitUrlById(@Param("id") int id, @Param("visitUrl") String visitUrl);
+
+ /**
+ * 更新文件描述
+ *
+ * @param id 文件编号
+ * @param description 描述
+ */
+ @Update("update file set description=#{description} where id=#{id}")
+ void updateDescriptionById(@Param("id") int id, @Param("description") String description);
+
+ /**
+ * 更新文件查看次数
+ *
+ * @param id 编号
+ */
+ @Update("update file set check_times=check_times+1 where id=#{id}")
+ void updateCheckTimesById(int id);
+
+ /**
+ * 更新文件下载次数
+ *
+ * @param id 编号
+ */
+ @Update("update file set download_times=download_times+1 where id=#{id}")
+ void updateDownloadTimesById(long id);
+
+ /**
+ * 更新文件标签
+ *
+ * @param id 编号
+ * @param tag 标签
+ */
+ @Update("update file set tag=#{tag} where id=#{id}")
+ void updateTagById(@Param("id") int id, @Param("tag") String tag);
+
+ /**
+ * 更新文件分类
+ *
+ * @param id 编号
+ * @param categoryId 分类编号
+ */
+ @Update("update file set category_id=#{categoryId} where id=#{id}")
+ void updateCategoryById(@Param("id") int id, @Param("categoryId") int categoryId);
+
+ /**
+ * 获取文件信息
+ *
+ * @param visitUrl 访问链接
+ *
+ * @return {@link File}
+ */
+ @Select("select * from file where visit_url=#{visitUrl}")
+ File getFileByVisitUrl(String visitUrl);
+
+ /**
+ * 获取所有文件
+ *
+ * @param userId 用户编号
+ * @param offset 偏移
+ * @param categoryId 分类编号
+ * @param orderBy 排序方式
+ * @param search 搜索
+ *
+ * @return {@link List}
+ */
+ @SelectProvider(type = FileSqlProvider.class, method = "getAll")
+ List<FileRecord> listAll(@Param("userId") int userId, @Param("offset") int offset, @Param("categoryId") int
+ categoryId, @Param("orderBy") String orderBy, @Param("search") String search);
+
+ /**
+ * 获取用户的上传资源
+ *
+ * @param userId 用户编号
+ * @param offset 偏移
+ * @param search 搜索
+ *
+ * @return {@link List}
+ */
+ @SelectProvider(type = FileSqlProvider.class, method = "getUserUploaded")
+ List<FileRecord> listUserUploaded(@Param("userId") int userId, @Param("offset") int offset, @Param("search")
+ String search);
+
+ /**
+ * 获取用户的下载资源
+ *
+ * @param userId 用户编号
+ * @param offset 偏移
+ * @param search 搜索
+ *
+ * @return {@link List}
+ */
+ @SelectProvider(type = FileSqlProvider.class, method = "getUserDownloaded")
+ List<FileRecord> listUserDownloaded(@Param("userId") int userId, @Param("offset") int offset, @Param("search")
+ String search);
+
+ /**
+ * 查询文件基本信息
+ *
+ * @param userId 用户编号,不使用用户编号作为条件时设置值小于等于0即可
+ * @param fileId 文件编号,不使用文件编号作为条件时设置值小于等于0即可
+ * @param categoryId 分类编号,不用分类编号作为条件时设置值小于等于0即可
+ * @param fileName 文件名,不使用文件名作为条件时设置值为空即可
+ * @param offset 偏移
+ *
+ * @return 上传记录
+ */
+ @SelectProvider(type = FileSqlProvider.class, method = "getBasicBy")
+ List<FileBasicRecord> listBasicBy(@Param("userId") int userId, @Param("fileId") long fileId, @Param("fileName")
+ String fileName, @Param("categoryId") int categoryId, @Param("offset") int offset);
+}
diff --git a/src/main/java/com/mesasoft/cn/dao/UploadedDAO.java b/src/main/java/com/mesasoft/cn/dao/UploadedDAO.java
new file mode 100644
index 0000000..8fa32d0
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/dao/UploadedDAO.java
@@ -0,0 +1,32 @@
+package com.mesasoft.cn.dao;
+
+import com.mesasoft.cn.dao.sqlprovider.UploadedSqlProvider;
+import com.mesasoft.cn.model.UploadedRecord;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.SelectProvider;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * @author pantao
+ * @since 2018/2/28
+ */
+@Repository
+public interface UploadedDAO {
+
+ /**
+ * 查询上传记录
+ *
+ * @param userId 用户编号,不使用用户编号作为条件时设置值小于等于0即可
+ * @param fileId 文件编号,不使用文件编号作为条件时设置值小于等于0即可
+ * @param categoryId 分类编号,不用分类编号作为条件时设置值小于等于0即可
+ * @param fileName 文件名,不使用文件名作为条件时设置值为空即可
+ * @param offset 偏移
+ *
+ * @return 上传记录
+ */
+ @SelectProvider(type = UploadedSqlProvider.class, method = "getDownloadBy")
+ List<UploadedRecord> listUploadedBy(@Param("userId") int userId, @Param("fileId") long fileId, @Param("fileName")
+ String fileName, @Param("categoryId") int categoryId, @Param("offset") int offset);
+}
diff --git a/src/main/java/com/mesasoft/cn/dao/UserDAO.java b/src/main/java/com/mesasoft/cn/dao/UserDAO.java
new file mode 100644
index 0000000..d2993c3
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/dao/UserDAO.java
@@ -0,0 +1,167 @@
+package com.mesasoft.cn.dao;
+
+import com.mesasoft.cn.dao.sqlprovider.UserSqlProvider;
+import com.mesasoft.cn.entity.User;
+import org.apache.ibatis.annotations.*;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * @author pantao
+ * @since 2018/1/12
+ */
+@Repository
+public interface UserDAO {
+
+ /**
+ * 更新用户权限
+ *
+ * @param id 用户编号
+ * @param permission 权限
+ *
+ * @return 是否更新成功
+ */
+ @Update("update user set permission=#{permission} where id=#{id}")
+ boolean updatePermission(@Param("id") int id, @Param("permission") int permission);
+
+ /**
+ * 用过用户名获取用户Id
+ *
+ * @param usernameOrEmail 用户名或邮箱
+ *
+ * @return 用户编号
+ */
+ @Select("select id from user where username=#{usernameOrEmail} or email=#{usernameOrEmail}")
+ int getUserId(String usernameOrEmail);
+
+ /**
+ * 通过ID更新用户基本信息
+ *
+ * @param id 编号
+ * @param avatar 头像
+ * @param realName 真实姓名
+ * @param email 邮箱
+ *
+ * @return 是否更新成功
+ */
+ @Update("update user set avatar=#{avatar},real_name=#{realName},email=#{email} where id=#{id}")
+ boolean updateBasicInfo(@Param("id") int id, @Param("avatar") String avatar, @Param("realName") String realName,
+ @Param("email") String email);
+
+ /**
+ * 通过id获取一个用户
+ *
+ * @param id 编号
+ *
+ * @return {@link User}
+ */
+ @Select("select * from user where id=#{id}")
+ User getUserById(int id);
+
+ /**
+ * 通过权限获取用户
+ *
+ * @param permission 权限
+ * @param condition 条件
+ * @param offset 偏移
+ *
+ * @return {@link List}
+ */
+ @SelectProvider(type = UserSqlProvider.class, method = "getUserBy")
+ List<User> listUserBy(@Param("permission") int permission, @Param("condition") String condition,
+ @Param("offset") int offset);
+
+ /**
+ * 用户登录
+ *
+ * @param usernameOrEmail 用户名
+ * @param password 密码
+ *
+ * @return {@link User}
+ */
+ @Select("select * from user where (username=#{usernameOrEmail} or email=#{usernameOrEmail}) and password=sha2" +
+ "(#{password},256)")
+ User login(@Param("usernameOrEmail") String usernameOrEmail, @Param("password") String password);
+
+ /**
+ * 添加一个用户
+ *
+ * @param user {@link User}
+ *
+ * @return 是否插入成功
+ */
+ @Insert("insert into user(username,real_name,email,password,is_downloadable,is_uploadable,is_deletable," +
+ "is_updatable,is_visible) values(#{username},#{realName},#{email},sha2(#{password},256)," +
+ "#{isDownloadable},#{isUploadable},#{isDeletable},#{isUpdatable},#{isVisible})")
+ boolean insertUser(User user);
+
+ /**
+ * 通过id更新用户登录时间
+ *
+ * @param id 编号
+ *
+ * @return {@link Boolean}
+ */
+ @Update("update user set last_login_time=current_timestamp where id=#{id}")
+ boolean updateUserLoginTime(int id);
+
+ /**
+ * 更新操作用户权限
+ *
+ * @param id 用户编号
+ * @param isDownloadable 下载权限
+ * @param isUploadable 上传权限
+ * @param isVisible 可查权限
+ * @param isDeletable 删除权限
+ * @param isUpdatable 更新权限
+ *
+ * @return {@link Boolean}
+ */
+ @UpdateProvider(type = UserSqlProvider.class, method = "updateAuthById")
+ boolean updateAuthById(@Param("id") int id, @Param("isDownloadable") int isDownloadable,
+ @Param("isUploadable") int isUploadable, @Param("isDeletable") int isDeletable, @Param(
+ "isUpdatable") int isUpdatable, @Param("isVisible") int isVisible);
+
+ /**
+ * 通过编号哦更新密码
+ *
+ * @param id 编号
+ * @param password 密码
+ *
+ * @return {@link Boolean}
+ */
+ @Update("update user set password=sha2(#{password},256) where id=#{id}")
+ boolean updatePasswordById(@Param("id") int id, @Param("password") String password);
+
+ /**
+ * 通过邮箱更新密码
+ *
+ * @param password 密码
+ * @param email 邮箱
+ *
+ * @return {@link Boolean}
+ */
+ @Update("update user set password=sha2(#{password},256) where email=#{email}")
+ boolean updatePasswordByEmail(@Param("password") String password, @Param("email") String email);
+
+ /**
+ * 检查用户名
+ *
+ * @param username 用户名
+ *
+ * @return {@link Integer}
+ */
+ @Select("select count(*) from user where username=#{username}")
+ int checkUsername(String username);
+
+ /**
+ * 检查邮箱
+ *
+ * @param email 邮箱
+ *
+ * @return {@link Integer}
+ */
+ @Select("select count(*) from user where email=#{email}")
+ int checkEmail(String email);
+}
diff --git a/src/main/java/com/mesasoft/cn/dao/sqlprovider/AuthSqlProvider.java b/src/main/java/com/mesasoft/cn/dao/sqlprovider/AuthSqlProvider.java
new file mode 100644
index 0000000..3c9c10f
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/dao/sqlprovider/AuthSqlProvider.java
@@ -0,0 +1,48 @@
+package com.mesasoft.cn.dao.sqlprovider;
+
+import com.mesasoft.cn.SketchApplication;
+import com.mesasoft.cn.modules.constant.ConfigConsts;
+import com.zhazhapan.util.Checker;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.jdbc.SQL;
+
+/**
+ * @author pantao
+ * @since 2018/1/19
+ */
+public class AuthSqlProvider {
+
+ public String updateAuthById() {
+ return CommonSqlProvider.updateAuthById("auth");
+ }
+
+ public String batchDelete(@Param("ids") String ids) {
+ return "delete from auth where id in " + (ids.startsWith("(") ? "" : "(") + ids + (ids.endsWith(")") ? "" :
+ ")");
+ }
+
+ public String getAuthBy(@Param("id") long id, @Param("userId") int userId, @Param("fileId") long fileId, @Param
+ ("fileName") String fileName, @Param("offset") int offset) {
+ String sql = new SQL() {{
+ SELECT("a.id,a.user_id,a.file_id,u.username,f.name file_name,f.local_url,a.is_downloadable,a" + "" + "" +
+ ".is_uploadable,a.is_deletable,a.is_updatable,a.is_visible,a.create_time");
+ FROM("auth a");
+ JOIN("user u on u.id=a.user_id");
+ JOIN("file f on f.id=a.file_id");
+ if (id > 0) {
+ WHERE("a.id=#{id}");
+ }
+ if (userId > 0) {
+ WHERE("u.id=#{userId}");
+ }
+ if (fileId > 0) {
+ WHERE("f.id=#{fileId}");
+ } else if (Checker.isNotEmpty(fileName)) {
+ WHERE("f.local_url like '%" + fileName + "%'");
+ }
+ ORDER_BY("a." + SketchApplication.settings.getStringUseEval(ConfigConsts.AUTH_ORDER_BY_OF_SETTINGS));
+ }}.toString();
+ int size = SketchApplication.settings.getIntegerUseEval(ConfigConsts.AUTH_PAGE_SIZE_OF_SETTINGS);
+ return sql + " limit " + (offset * size) + "," + size;
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/dao/sqlprovider/CommonSqlProvider.java b/src/main/java/com/mesasoft/cn/dao/sqlprovider/CommonSqlProvider.java
new file mode 100644
index 0000000..ad2d024
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/dao/sqlprovider/CommonSqlProvider.java
@@ -0,0 +1,24 @@
+package com.mesasoft.cn.dao.sqlprovider;
+
+import org.apache.ibatis.jdbc.SQL;
+
+/**
+ * @author pantao
+ * @since 2018/1/19
+ */
+public class CommonSqlProvider {
+
+ private CommonSqlProvider() {}
+
+ public static String updateAuthById(String table) {
+ return new SQL() {{
+ UPDATE(table);
+ SET("is_downloadable=#{isDownloadable}");
+ SET("is_uploadable=#{isUploadable}");
+ SET("is_deletable=#{isDeletable}");
+ SET("is_updatable=#{isUpdatable}");
+ SET("is_visible=#{isVisible}");
+ WHERE("id=#{id}");
+ }}.toString();
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/dao/sqlprovider/DownloadedSqlProvider.java b/src/main/java/com/mesasoft/cn/dao/sqlprovider/DownloadedSqlProvider.java
new file mode 100644
index 0000000..5c1745f
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/dao/sqlprovider/DownloadedSqlProvider.java
@@ -0,0 +1,48 @@
+package com.mesasoft.cn.dao.sqlprovider;
+
+import com.mesasoft.cn.SketchApplication;
+import com.mesasoft.cn.modules.constant.ConfigConsts;
+import com.zhazhapan.util.Checker;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.jdbc.SQL;
+
+/**
+ * @author pantao
+ * @since 2018/1/19
+ */
+public class DownloadedSqlProvider {
+
+ /**
+ * 生成一条下载记录表的查询语句
+ *
+ * @param userId 用户编号
+ * @param fileId 文件编号
+ *
+ * @return SQL语句
+ */
+ public String getDownloadBy(@Param("userId") int userId, @Param("fileId") long fileId, @Param("fileName") String
+ fileName, @Param("categoryId") int categoryId, @Param("offset") int offset) {
+ String sql = new SQL() {{
+ SELECT("d.id,d.user_id,d.file_id,u.username,u.email,f.name file_name,c.name category_name,f.visit_url,d"
+ + ".create_time");
+ FROM("download d");
+ JOIN("user u on d.user_id=u.id");
+ JOIN("file f on d.file_id=f.id");
+ JOIN("category c on f.category_id=c.id");
+ if (userId > 0) {
+ WHERE("d.user_id=#{userId}");
+ }
+ if (fileId > 0) {
+ WHERE("d.file_id=#{fileId}");
+ } else if (Checker.isNotEmpty(fileName)) {
+ WHERE("f.local_url like '%" + fileName + "%'");
+ }
+ if (categoryId > 0) {
+ WHERE("c.id=#{categoryId}");
+ }
+ ORDER_BY("d." + SketchApplication.settings.getStringUseEval(ConfigConsts.DOWNLOAD_ORDER_BY_OF_SETTINGS));
+ }}.toString();
+ int size = SketchApplication.settings.getIntegerUseEval(ConfigConsts.DOWNLOAD_PAGE_SIZE_OF_SETTINGS);
+ return sql + " limit " + (offset * size) + "," + size;
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/dao/sqlprovider/FileSqlProvider.java b/src/main/java/com/mesasoft/cn/dao/sqlprovider/FileSqlProvider.java
new file mode 100644
index 0000000..8a2ecdc
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/dao/sqlprovider/FileSqlProvider.java
@@ -0,0 +1,110 @@
+package com.mesasoft.cn.dao.sqlprovider;
+
+import com.mesasoft.cn.SketchApplication;
+import com.mesasoft.cn.modules.constant.ConfigConsts;
+import com.zhazhapan.modules.constant.ValueConsts;
+import com.zhazhapan.util.Checker;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.jdbc.SQL;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author pantao
+ * @since 2018/1/19
+ */
+@Component
+public class FileSqlProvider {
+
+ public String updateAuthById() {
+ return CommonSqlProvider.updateAuthById("file");
+ }
+
+ /**
+ * 生成一条文件基本信息的查询语句
+ *
+ * @param userId 用户编号
+ * @param fileId 文件编号
+ *
+ * @return SQL语句
+ */
+ public String getBasicBy(@Param("userId") int userId, @Param("fileId") long fileId, @Param("fileName") String
+ fileName, @Param("categoryId") int categoryId, @Param("offset") int offset) {
+ String sql = new SQL() {{
+ SELECT("f.id,u.username,f.local_url,c.name category_name,f.visit_url,f.download_times," + "f" + "" + "" +
+ ".create_time");
+ FROM("file f");
+ JOIN("user u on f.user_id=u.id");
+ JOIN("category c on f.category_id=c.id");
+ if (userId > 0) {
+ WHERE("f.user_id=#{userId}");
+ }
+ if (fileId > 0) {
+ WHERE("f.id=#{fileId}");
+ } else if (Checker.isNotEmpty(fileName)) {
+ WHERE("f.local_url like '%" + fileName + "%'");
+ }
+ if (categoryId > 0) {
+ WHERE("c.id=#{categoryId}");
+ }
+ ORDER_BY("f." + SketchApplication.settings.getStringUseEval(ConfigConsts.FILE_ORDER_BY_OF_SETTING));
+ }}.toString();
+ int size = SketchApplication.settings.getIntegerUseEval(ConfigConsts.FILE_PAGE_SIZE_OF_SETTING);
+ return sql + " limit " + (offset * size) + "," + size;
+ }
+
+ private String getSqlEnds(int offset, String orderBy, String search) {
+ int size = SketchApplication.settings.getIntegerUseEval(ConfigConsts.FILE_PAGE_SIZE_OF_SETTING);
+ return getSearch(search) + " order by " + (Checker.isEmpty(orderBy) ? SketchApplication.settings
+ .getStringUseEval(ConfigConsts.FILE_ORDER_BY_OF_SETTING) : orderBy) + " limit " + offset * size
+ + "," + size;
+ }
+
+ public String getAll(@Param("offset") int offset, @Param("categoryId") int categoryId, @Param("orderBy") String
+ orderBy, @Param("search") String search) {
+ return getBaseSql(ValueConsts.FALSE) + " where f.is_visible=1" + (categoryId < 1 ? "" : " and " +
+ "category_id=#{categoryId}") + " and ((select a.is_visible from auth a where a.file_id=f.id and a" +
+ ".user_id=#{userId}) is null or (a.user_id=#{userId} and a.is_visible=1))" + getSqlEnds(offset,
+ orderBy, search);
+ }
+
+ public String getUserUploaded(@Param("offset") int offset, @Param("search") String search) {
+ return getBaseSql(ValueConsts.FALSE) + " where f.is_visible=1 and (f.user_id=#{userId} or a.is_updatable=1 or" +
+ " a.is_deletable=1)" + getSqlEnds(offset,
+ ValueConsts.EMPTY_STRING, search);
+ }
+
+ public String getUserDownloaded(@Param("offset") int offset, @Param("search") String search) {
+ return getBaseSql(ValueConsts.TRUE) + " where d.user_id=#{userId}" + getSqlEnds(offset, ValueConsts
+ .EMPTY_STRING, search);
+ }
+
+ private String getSearch(String search) {
+ if (Checker.isEmpty(search)) {
+ return ValueConsts.EMPTY_STRING;
+ } else {
+ search = "'%" + search + "%'";
+ return " and (f.name like " + search + " or f.visit_url like " + search + " or f.description like " +
+ search + " or f.tag like " + search + ")";
+ }
+ }
+
+ private String getBaseSql(boolean isDownloaded) {
+ return new SQL() {{
+ SELECT("distinct f.id,f.user_id,u.username,u.avatar,f.name file_name,f.size,f.create_time,c.name " +
+ "category_name,f"
+ + ".description,f.tag,f.check_times,f.download_times,f.visit_url,f.is_uploadable,f.is_deletable,"
+ + "f.is_updatable,f.is_downloadable,f.is_visible");
+ if (isDownloaded) {
+ SELECT("d.create_time download_time");
+ }
+ FROM("file f");
+ JOIN("user u on u.id=f.user_id");
+ JOIN("category c on c.id=f.category_id");
+ if (isDownloaded) {
+ JOIN("download d on d.file_id=f.id");
+ } else {
+ JOIN("auth a on a.file_id=f.id");
+ }
+ }}.toString();
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/dao/sqlprovider/UploadedSqlProvider.java b/src/main/java/com/mesasoft/cn/dao/sqlprovider/UploadedSqlProvider.java
new file mode 100644
index 0000000..720b716
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/dao/sqlprovider/UploadedSqlProvider.java
@@ -0,0 +1,47 @@
+package com.mesasoft.cn.dao.sqlprovider;
+
+import com.mesasoft.cn.SketchApplication;
+import com.mesasoft.cn.modules.constant.ConfigConsts;
+import com.zhazhapan.util.Checker;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.jdbc.SQL;
+
+/**
+ * @author pantao
+ * @since 2018/2/28
+ */
+public class UploadedSqlProvider {
+
+ /**
+ * 生成一条上传记录表的查询语句
+ *
+ * @param userId 用户编号
+ * @param fileId 文件编号
+ *
+ * @return SQL语句
+ */
+ public String getDownloadBy(@Param("userId") int userId, @Param("fileId") long fileId, @Param("fileName") String
+ fileName, @Param("categoryId") int categoryId, @Param("offset") int offset) {
+ String sql = new SQL() {{
+ SELECT("f.id,f.user_id,u.username,u.email,f.name file_name,c.name category_name,f.local_url,f.visit_url,"
+ + "" + "" + "" + "f" + ".create_time");
+ FROM("file f");
+ JOIN("user u on f.user_id=u.id");
+ JOIN("category c on f.category_id=c.id");
+ if (userId > 0) {
+ WHERE("f.user_id=#{userId}");
+ }
+ if (fileId > 0) {
+ WHERE("f.id=#{fileId}");
+ } else if (Checker.isNotEmpty(fileName)) {
+ WHERE("f.local_url like '%" + fileName + "%'");
+ }
+ if (categoryId > 0) {
+ WHERE("c.id=#{categoryId}");
+ }
+ ORDER_BY("f." + SketchApplication.settings.getStringUseEval(ConfigConsts.FILE_ORDER_BY_OF_SETTING));
+ }}.toString();
+ int size = SketchApplication.settings.getIntegerUseEval(ConfigConsts.FILE_PAGE_SIZE_OF_SETTING);
+ return sql + " limit " + (offset * size) + "," + size;
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/dao/sqlprovider/UserSqlProvider.java b/src/main/java/com/mesasoft/cn/dao/sqlprovider/UserSqlProvider.java
new file mode 100644
index 0000000..5d36845
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/dao/sqlprovider/UserSqlProvider.java
@@ -0,0 +1,41 @@
+package com.mesasoft.cn.dao.sqlprovider;
+
+import com.mesasoft.cn.SketchApplication;
+import com.mesasoft.cn.modules.constant.ConfigConsts;
+import com.mesasoft.cn.modules.constant.DefaultValues;
+import com.zhazhapan.util.Checker;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.jdbc.SQL;
+
+/**
+ * @author pantao
+ * @since 2018/1/19
+ */
+public class UserSqlProvider {
+
+ public String updateAuthById() {
+ return CommonSqlProvider.updateAuthById("user");
+ }
+
+ public String getUserBy(@Param("permission") int permission, @Param("condition") String condition, @Param
+ ("offset") int offset) {
+ String sql = new SQL() {{
+ SELECT("*");
+ FROM("user");
+ if (permission == DefaultValues.THREE_INT) {
+ WHERE("permission<3");
+ } else if (permission == DefaultValues.TWO_INT) {
+ WHERE("permission<2");
+ } else {
+ WHERE("permission<0");
+ }
+ if (Checker.isNotEmpty(condition)) {
+ WHERE("username like '%" + condition + "%' or email like '%" + condition + "%' or real_name like '" +
+ condition + "'");
+ }
+ ORDER_BY(SketchApplication.settings.getStringUseEval(ConfigConsts.USER_ORDER_BY_OF_SETTINGS));
+ }}.toString();
+ int size = SketchApplication.settings.getIntegerUseEval(ConfigConsts.USER_PAGE_SIZE_OF_SETTINGS);
+ return sql + " limit " + (offset * size) + "," + size;
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/entity/Auth.java b/src/main/java/com/mesasoft/cn/entity/Auth.java
new file mode 100644
index 0000000..5249ad0
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/entity/Auth.java
@@ -0,0 +1,137 @@
+package com.mesasoft.cn.entity;
+
+import com.mesasoft.cn.util.BeanUtils;
+
+import java.sql.Timestamp;
+
+/**
+ * @author pantao
+ * @since 2018/1/18
+ */
+public class Auth {
+
+ private long id;
+
+ private int isUploadable;
+
+ private int isDeletable;
+
+ private int isUpdatable;
+
+ private int isDownloadable;
+
+ private int isVisible;
+
+ private int userId;
+
+ private long fileId;
+
+ private Timestamp createTime;
+
+ public Auth(int userId, long fileId) {
+ this.userId = userId;
+ this.fileId = fileId;
+ }
+
+ public Auth(long id, int isUploadable, int isDeletable, int isUpdatable, int userId, long fileId, int isVisible,
+ int isDownloadable, Timestamp createTime) {
+ this.id = id;
+ this.isUploadable = isUploadable;
+ this.isDeletable = isDeletable;
+ this.isUpdatable = isUpdatable;
+ this.isDownloadable = isDownloadable;
+ this.isVisible = isVisible;
+ this.userId = userId;
+ this.fileId = fileId;
+ this.createTime = createTime;
+ }
+
+ public void setAuth(int isDownloadable, int isUploadable, int isDeletable, int isUpdatable, int isVisible) {
+ this.isUploadable = isUploadable;
+ this.isDeletable = isDeletable;
+ this.isUpdatable = isUpdatable;
+ this.isDownloadable = isDownloadable;
+ this.isVisible = isVisible;
+ }
+
+ public void setAuth(int[] auth) {
+ setAuth(auth[0], auth[1], auth[2], auth[3], auth[4]);
+ }
+
+ @Override
+ public String toString() {
+ return BeanUtils.toPrettyJson(this);
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public int getIsUploadable() {
+ return isUploadable;
+ }
+
+ public void setIsUploadable(int isUploadable) {
+ this.isUploadable = isUploadable;
+ }
+
+ public int getIsDeletable() {
+ return isDeletable;
+ }
+
+ public void setIsDeletable(int isDeletable) {
+ this.isDeletable = isDeletable;
+ }
+
+ public int getIsUpdatable() {
+ return isUpdatable;
+ }
+
+ public void setIsUpdatable(int isUpdatable) {
+ this.isUpdatable = isUpdatable;
+ }
+
+ public int getIsDownloadable() {
+ return isDownloadable;
+ }
+
+ public void setIsDownloadable(int isDownloadable) {
+ this.isDownloadable = isDownloadable;
+ }
+
+ public int getIsVisible() {
+ return isVisible;
+ }
+
+ public void setIsVisible(int isVisible) {
+ this.isVisible = isVisible;
+ }
+
+ public int getUserId() {
+ return userId;
+ }
+
+ public void setUserId(int userId) {
+ this.userId = userId;
+ }
+
+ public long getFileId() {
+ return fileId;
+ }
+
+ public void setFileId(long fileId) {
+ this.fileId = fileId;
+ }
+
+ public Timestamp getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(Timestamp createTime) {
+ this.createTime = createTime;
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/entity/Category.java b/src/main/java/com/mesasoft/cn/entity/Category.java
new file mode 100644
index 0000000..3ea1b55
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/entity/Category.java
@@ -0,0 +1,63 @@
+package com.mesasoft.cn.entity;
+
+import com.mesasoft.cn.util.BeanUtils;
+
+import java.sql.Timestamp;
+
+/**
+ * 分类表
+ *
+ * @author pantao
+ * @since 2018/1/11
+ */
+public class Category {
+
+ private int id;
+
+ /**
+ * 分类名称
+ */
+ private String name;
+
+ private Timestamp createTime;
+
+ public Category(String name) {
+ this.name = name;
+ }
+
+ public Category(int id, String name, Timestamp createTime) {
+ this.id = id;
+ this.name = name;
+ this.createTime = createTime;
+ }
+
+ @Override
+ public String toString() {
+ return BeanUtils.toPrettyJson(this);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Timestamp getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(Timestamp createTime) {
+ this.createTime = createTime;
+ }
+
+ public int getId() {
+
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/entity/Download.java b/src/main/java/com/mesasoft/cn/entity/Download.java
new file mode 100644
index 0000000..6e13fa9
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/entity/Download.java
@@ -0,0 +1,71 @@
+package com.mesasoft.cn.entity;
+
+import com.mesasoft.cn.util.BeanUtils;
+
+import java.sql.Timestamp;
+
+/**
+ * 下载记录表
+ *
+ * @author pantao
+ * @since 2018/1/11
+ */
+public class Download {
+
+ private long id;
+
+ private Timestamp createTime;
+
+ private int userId;
+
+ private int fileId;
+
+ public Download(int userId, int fileId) {
+ this.userId = userId;
+ this.fileId = fileId;
+ }
+
+ public Download(int id, Timestamp createTime, int userId, int fileId) {
+ this.id = id;
+ this.createTime = createTime;
+ this.userId = userId;
+ this.fileId = fileId;
+ }
+
+ @Override
+ public String toString() {
+ return BeanUtils.toPrettyJson(this);
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public Timestamp getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(Timestamp createTime) {
+ this.createTime = createTime;
+ }
+
+ public int getUserId() {
+ return userId;
+ }
+
+ public void setUserId(int userId) {
+ this.userId = userId;
+ }
+
+ public int getFileId() {
+ return fileId;
+ }
+
+ public void setFileId(int fileId) {
+ this.fileId = fileId;
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/entity/File.java b/src/main/java/com/mesasoft/cn/entity/File.java
new file mode 100644
index 0000000..346373e
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/entity/File.java
@@ -0,0 +1,255 @@
+package com.mesasoft.cn.entity;
+
+import com.mesasoft.cn.util.BeanUtils;
+
+import java.sql.Timestamp;
+
+/**
+ * 文件表
+ *
+ * @author pantao
+ * @since 2018/1/11
+ */
+public class File {
+
+ private long id;
+
+ private String name;
+
+ private String suffix;
+
+ private String localUrl;
+
+ private String visitUrl;
+
+ private long size;
+
+ private Timestamp createTime;
+
+ private String description;
+
+ private int checkTimes;
+
+ private int downloadTimes;
+
+ private String tag;
+
+ private int userId;
+
+ private int categoryId;
+
+ private int isUploadable;
+
+ private int isDeletable;
+
+ private int isUpdatable;
+
+ private int isDownloadable;
+
+ private int isVisible;
+
+ private Timestamp lastModifyTime;
+
+ public File(String name, String suffix, String localUrl, String visitUrl, String description, String tag, int
+ userId, int categoryId) {
+ this.name = name;
+ this.suffix = suffix;
+ this.categoryId = categoryId;
+ this.description = description;
+ this.localUrl = localUrl;
+ this.visitUrl = visitUrl;
+ this.tag = tag;
+ this.userId = userId;
+ this.size = new java.io.File(localUrl).length();
+ }
+
+ public File(long id, String name, String suffix, String localUrl, String visitUrl, long size, Timestamp
+ createTime, String description, int checkTimes, int downloadTimes, String tag, int userId, int
+ categoryId, int isDownloadable, int isUploadable, int isVisible, int isDeletable, int isUpdatable,
+ Timestamp lastModifyTime) {
+ this.id = id;
+ this.name = name;
+ this.suffix = suffix;
+ this.localUrl = localUrl;
+ this.visitUrl = visitUrl;
+ this.size = size;
+ this.createTime = createTime;
+ this.description = description;
+ this.checkTimes = checkTimes;
+ this.downloadTimes = downloadTimes;
+ this.tag = tag;
+ this.userId = userId;
+ this.categoryId = categoryId;
+ this.isUploadable = isUploadable;
+ this.isDeletable = isDeletable;
+ this.isUpdatable = isUpdatable;
+ this.isDownloadable = isDownloadable;
+ this.isVisible = isVisible;
+ this.lastModifyTime = lastModifyTime;
+ }
+
+ public void setAuth(int isDownloadable, int isUploadable, int isDeletable, int isUpdatable, int isVisible) {
+ this.isUploadable = isUploadable;
+ this.isDeletable = isDeletable;
+ this.isUpdatable = isUpdatable;
+ this.isDownloadable = isDownloadable;
+ this.isVisible = isVisible;
+ }
+
+ public Timestamp getLastModifyTime() {
+ return lastModifyTime;
+ }
+
+ public void setLastModifyTime(Timestamp lastModifyTime) {
+ this.lastModifyTime = lastModifyTime;
+ }
+
+ @Override
+ public String toString() {
+ return BeanUtils.toPrettyJson(this);
+ }
+
+ public int getIsUploadable() {
+ return isUploadable;
+ }
+
+ public void setIsUploadable(int isUploadable) {
+ this.isUploadable = isUploadable;
+ }
+
+ public int getIsDeletable() {
+ return isDeletable;
+ }
+
+ public void setIsDeletable(int isDeletable) {
+ this.isDeletable = isDeletable;
+ }
+
+ public int getIsUpdatable() {
+ return isUpdatable;
+ }
+
+ public void setIsUpdatable(int isUpdatable) {
+ this.isUpdatable = isUpdatable;
+ }
+
+ public int getIsDownloadable() {
+ return isDownloadable;
+ }
+
+ public void setIsDownloadable(int isDownloadable) {
+ this.isDownloadable = isDownloadable;
+ }
+
+ public int getIsVisible() {
+ return isVisible;
+ }
+
+ public void setIsVisible(int isVisible) {
+ this.isVisible = isVisible;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getSuffix() {
+ return suffix;
+ }
+
+ public void setSuffix(String suffix) {
+ this.suffix = suffix;
+ }
+
+ public String getLocalUrl() {
+ return localUrl;
+ }
+
+ public void setLocalUrl(String localUrl) {
+ this.localUrl = localUrl;
+ }
+
+ public String getVisitUrl() {
+ return visitUrl;
+ }
+
+ public void setVisitUrl(String visitUrl) {
+ this.visitUrl = visitUrl;
+ }
+
+ public long getSize() {
+ return size;
+ }
+
+ public void setSize(long size) {
+ this.size = size;
+ }
+
+ public Timestamp getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(Timestamp createTime) {
+ this.createTime = createTime;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public int getCheckTimes() {
+ return checkTimes;
+ }
+
+ public void setCheckTimes(int checkTimes) {
+ this.checkTimes = checkTimes;
+ }
+
+ public int getDownloadTimes() {
+ return downloadTimes;
+ }
+
+ public void setDownloadTimes(int downloadTimes) {
+ this.downloadTimes = downloadTimes;
+ }
+
+ public String getTag() {
+ return tag;
+ }
+
+ public void setTag(String tag) {
+ this.tag = tag;
+ }
+
+ public int getUserId() {
+ return userId;
+ }
+
+ public void setUserId(int userId) {
+ this.userId = userId;
+ }
+
+ public int getCategoryId() {
+ return categoryId;
+ }
+
+ public void setCategoryId(int categoryId) {
+ this.categoryId = categoryId;
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/entity/Result.java b/src/main/java/com/mesasoft/cn/entity/Result.java
new file mode 100644
index 0000000..0cfcc22
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/entity/Result.java
@@ -0,0 +1,46 @@
+package com.mesasoft.cn.entity;
+
+import com.mesasoft.cn.enums.StatusEnum;
+
+
+/**
+ * @author zhq
+ */
+public class Result {
+
+ public static ResultEntity success() {
+ return new ResultEntity(StatusEnum.SUCCESS.getStatus(), StatusEnum.SUCCESS.getCode(), StatusEnum.SUCCESS.getMessage(), null);
+ }
+
+ public static <T> ResultEntity success(T data) {
+ return new ResultEntity(StatusEnum.SUCCESS.getStatus(), StatusEnum.SUCCESS.getCode(), StatusEnum.SUCCESS.getMessage(), data);
+ }
+
+ public static ResultEntity fail() {
+ return new ResultEntity(StatusEnum.FAIL.getStatus(), StatusEnum.FAIL.getCode(), StatusEnum.FAIL.getMessage(), null);
+ }
+
+ public static ResultEntity fail(String message) {
+ return new ResultEntity(StatusEnum.FAIL.getStatus(), StatusEnum.FAIL.getCode(), message, null);
+ }
+
+ /**
+ * @param code
+ * @param message
+ * @return ResultEntity
+ */
+ public static ResultEntity fail(String code, String message) {
+ return new ResultEntity(StatusEnum.FAIL.getStatus(), code, message, null);
+ }
+
+ /**
+ *
+ * @param status
+ * @param code
+ * @param message
+ * @return ResultEntity
+ */
+ public static ResultEntity fail(int status, String code, String message) {
+ return new ResultEntity(status, code, message, null);
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/entity/ResultEntity.java b/src/main/java/com/mesasoft/cn/entity/ResultEntity.java
new file mode 100644
index 0000000..c73e206
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/entity/ResultEntity.java
@@ -0,0 +1,20 @@
+package com.mesasoft.cn.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+@Builder
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ResultEntity<T> implements Serializable {
+
+ private int status;
+ private String code;
+ private String message;
+ private T data;
+} \ No newline at end of file
diff --git a/src/main/java/com/mesasoft/cn/entity/User.java b/src/main/java/com/mesasoft/cn/entity/User.java
new file mode 100644
index 0000000..4c91ef2
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/entity/User.java
@@ -0,0 +1,196 @@
+package com.mesasoft.cn.entity;
+
+import com.mesasoft.cn.util.BeanUtils;
+
+import java.sql.Timestamp;
+
+/**
+ * 用户表
+ *
+ * @author pantao
+ * @since 2018/1/11
+ */
+public class User {
+
+ private int id;
+
+ private String username;
+
+ private String realName;
+
+ private String email;
+
+ private String password;
+
+ private int isUploadable;
+
+ private int isDeletable;
+
+ private int isUpdatable;
+
+ private int isDownloadable;
+
+ private int isVisible;
+
+ /**
+ * 权限级别:0(禁止登录),1(正常,普通用户),2(正常,管理员),3(正常,超级管理员)
+ */
+ private int permission;
+
+ private Timestamp createTime;
+
+ private Timestamp lastLoginTime;
+
+ private String avatar;
+
+ public User(String username, String realName, String email, String password) {
+ this.username = username;
+ this.realName = realName;
+ this.email = email;
+ this.password = password;
+ }
+
+ public User(int id, String username, String realName, String email, String password, int permission, Timestamp
+ createTime, Timestamp lastLoginTime, int isDownloadable, int isUploadable, int isVisible, int
+ isDeletable, int isUpdatable, String avatar) {
+ this.id = id;
+ this.username = username;
+ this.realName = realName;
+ this.email = email;
+ this.password = password;
+ this.isUploadable = isUploadable;
+ this.isDeletable = isDeletable;
+ this.isUpdatable = isUpdatable;
+ this.isDownloadable = isDownloadable;
+ this.isVisible = isVisible;
+ this.permission = permission;
+ this.createTime = createTime;
+ this.lastLoginTime = lastLoginTime;
+ this.avatar = avatar;
+ }
+
+ public void setAuth(int isDownloadable, int isUploadable, int isDeletable, int isUpdatable, int isVisible) {
+ this.isUploadable = isUploadable;
+ this.isDeletable = isDeletable;
+ this.isUpdatable = isUpdatable;
+ this.isDownloadable = isDownloadable;
+ this.isVisible = isVisible;
+ }
+
+ @Override
+ public String toString() {
+ return BeanUtils.toPrettyJson(this);
+ }
+
+ public int getIsUploadable() {
+ return isUploadable;
+ }
+
+ public void setIsUploadable(int isUploadable) {
+ this.isUploadable = isUploadable;
+ }
+
+ public int getIsDeletable() {
+ return isDeletable;
+ }
+
+ public void setIsDeletable(int isDeletable) {
+ this.isDeletable = isDeletable;
+ }
+
+ public int getIsUpdatable() {
+ return isUpdatable;
+ }
+
+ public void setIsUpdatable(int isUpdatable) {
+ this.isUpdatable = isUpdatable;
+ }
+
+ public int getIsDownloadable() {
+ return isDownloadable;
+ }
+
+ public void setIsDownloadable(int isDownloadable) {
+ this.isDownloadable = isDownloadable;
+ }
+
+ public int getIsVisible() {
+ return isVisible;
+ }
+
+ public void setIsVisible(int isVisible) {
+ this.isVisible = isVisible;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getRealName() {
+ return realName;
+ }
+
+ public void setRealName(String realName) {
+ this.realName = realName;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public int getPermission() {
+ return permission;
+ }
+
+ public void setPermission(int permission) {
+ this.permission = permission;
+ }
+
+ public Timestamp getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(Timestamp createTime) {
+ this.createTime = createTime;
+ }
+
+ public Timestamp getLastLoginTime() {
+ return lastLoginTime;
+ }
+
+ public void setLastLoginTime(Timestamp lastLoginTime) {
+ this.lastLoginTime = lastLoginTime;
+ }
+
+ public String getAvatar() {
+ return avatar;
+ }
+
+ public void setAvatar(String avatar) {
+ this.avatar = avatar;
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/enums/InterceptorLevel.java b/src/main/java/com/mesasoft/cn/enums/InterceptorLevel.java
new file mode 100644
index 0000000..6a0d753
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/enums/InterceptorLevel.java
@@ -0,0 +1,29 @@
+package com.mesasoft.cn.enums;
+
+/**
+ * 拦截级别
+ *
+ * @author pantao
+ * @since 2018/1/25
+ */
+public enum InterceptorLevel {
+ /**
+ * 不拦截
+ */
+ NONE,
+
+ /**
+ * 用户级别拦截
+ */
+ USER,
+
+ /**
+ * 管理员级别拦截
+ */
+ ADMIN,
+
+ /**
+ * 系统用户
+ */
+ SYSTEM
+}
diff --git a/src/main/java/com/mesasoft/cn/enums/StatusEnum.java b/src/main/java/com/mesasoft/cn/enums/StatusEnum.java
new file mode 100644
index 0000000..958fbc3
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/enums/StatusEnum.java
@@ -0,0 +1,23 @@
+package com.mesasoft.cn.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @description:
+ * @author: zhq
+ * @create: 2022-03-21
+ **/
+@Getter
+@AllArgsConstructor
+public enum StatusEnum {
+
+ SUCCESS(200, "200", "success"),
+ FAIL(400, "400", "fail"),
+ NOT_FOUND(404, "404", "not found"),
+ SERROR_ERROR(500, "500", "not found");
+
+ private int status;
+ private String code;
+ private String message;
+}
diff --git a/src/main/java/com/mesasoft/cn/exception/BusinessException.java b/src/main/java/com/mesasoft/cn/exception/BusinessException.java
new file mode 100644
index 0000000..90f70b1
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/exception/BusinessException.java
@@ -0,0 +1,42 @@
+package com.mesasoft.cn.exception;
+
+import lombok.*;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class BusinessException extends RuntimeException {
+
+ /**
+ * 异常代码
+ */
+ @Builder.Default
+ private int status = 500;
+
+ @Builder.Default
+ private String code = "500";
+
+ /**
+ * 异常信息
+ */
+ private String message;
+
+ public BusinessException(String message) {
+ this.message = message;
+ }
+
+
+ public BusinessException(String message, Throwable e) {
+ super(message, e);
+ }
+
+ public BusinessException(int status, String code, String message, Throwable e) {
+ super(message, e);
+ this.status = status;
+ this.code = code;
+ }
+
+
+}
diff --git a/src/main/java/com/mesasoft/cn/exception/GlobalExceptionHandler.java b/src/main/java/com/mesasoft/cn/exception/GlobalExceptionHandler.java
new file mode 100644
index 0000000..7c21c36
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/exception/GlobalExceptionHandler.java
@@ -0,0 +1,36 @@
+package com.mesasoft.cn.exception;
+
+import com.alibaba.fastjson.support.spring.FastJsonJsonView;
+import com.zhazhapan.modules.constant.ValueConsts;
+import com.zhazhapan.util.Checker;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.servlet.HandlerExceptionResolver;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author pantao
+ * @since 2018/2/5
+ */
+public class GlobalExceptionHandler implements HandlerExceptionResolver {
+
+ @Override
+ public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
+ Exception ex) {
+ ModelAndView mv = new ModelAndView();
+ FastJsonJsonView view = new FastJsonJsonView();
+ Map<String, Object> attributes = new HashMap<>(ValueConsts.TWO_INT);
+ attributes.put("code", "502");
+ attributes.put("message", ex.getMessage());
+ String queryString = request.getQueryString();
+ attributes.put("url", request.getRequestURI() + (Checker.isEmpty(queryString) ? "" : "?" + queryString));
+ view.setAttributesMap(attributes);
+ mv.setView(view);
+ mv.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
+ return mv;
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/interceptor/WebInterceptor.java b/src/main/java/com/mesasoft/cn/interceptor/WebInterceptor.java
new file mode 100644
index 0000000..50e16f1
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/interceptor/WebInterceptor.java
@@ -0,0 +1,79 @@
+package com.mesasoft.cn.interceptor;
+
+import com.mesasoft.cn.SketchApplication;
+import com.mesasoft.cn.modules.constant.DefaultValues;
+import com.mesasoft.cn.service.impl.UserServiceImpl;
+import com.mesasoft.cn.annotation.AuthInterceptor;
+import com.mesasoft.cn.entity.User;
+import com.mesasoft.cn.enums.InterceptorLevel;
+import com.zhazhapan.modules.constant.ValueConsts;
+import com.zhazhapan.util.Checker;
+import com.zhazhapan.util.HttpUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author pantao
+ * @since 2018/1/25
+ */
+public class WebInterceptor implements HandlerInterceptor {
+
+ @Autowired
+ UserServiceImpl userService;
+
+ @Override
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws
+ Exception {
+ String url = request.getServletPath();
+ InterceptorLevel level = InterceptorLevel.NONE;
+ if (handler instanceof HandlerMethod) {
+ AuthInterceptor interceptor = ((HandlerMethod) handler).getMethodAnnotation(AuthInterceptor.class);
+ //注解到类上面的注解,无法直接获取,只能通过扫描
+ if (Checker.isNull(interceptor)) {
+ for (Class<?> type : SketchApplication.controllers) {
+ RequestMapping mapping = type.getAnnotation(RequestMapping.class);
+ if (Checker.isNotNull(mapping)) {
+ for (String path : mapping.value()) {
+ if (url.startsWith(path)) {
+ interceptor = type.getAnnotation(AuthInterceptor.class);
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+ if (Checker.isNotNull(interceptor)) {
+ level = interceptor.value();
+ }
+ }
+ User user = (User) request.getSession().getAttribute(ValueConsts.USER_STRING);
+ if (Checker.isNull(user)) {
+ //读取token,自动登录
+ Cookie cookie = HttpUtils.getCookie(ValueConsts.TOKEN_STRING, request.getCookies());
+ if (Checker.isNotNull(cookie)) {
+ user = userService.login(ValueConsts.EMPTY_STRING, ValueConsts.EMPTY_STRING, cookie.getValue(),
+ response);
+ if (Checker.isNotNull(user)) {
+ request.getSession().setAttribute(ValueConsts.USER_STRING, user);
+ }
+ }
+ }
+ if (level != InterceptorLevel.NONE) {
+ boolean isRedirect = Checker.isNull(user) || (level == InterceptorLevel.ADMIN && user.getPermission() <
+ 2) || (level == InterceptorLevel.SYSTEM && user.getPermission() < 3);
+ if (isRedirect) {
+ response.setStatus(401);
+ response.sendRedirect(DefaultValues.SIGNIN_PAGE);
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/model/AuthRecord.java b/src/main/java/com/mesasoft/cn/model/AuthRecord.java
new file mode 100644
index 0000000..c3e4e27
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/model/AuthRecord.java
@@ -0,0 +1,153 @@
+package com.mesasoft.cn.model;
+
+import com.mesasoft.cn.util.BeanUtils;
+
+import java.sql.Timestamp;
+
+/**
+ * @author pantao
+ * @since 2018/1/19
+ */
+public class AuthRecord {
+
+ private long id;
+
+ private int userId;
+
+ private long fileId;
+
+ private String username;
+
+ private String fileName;
+
+ private String localUrl;
+
+ private int isDownloadable;
+
+ private int isUploadable;
+
+ private int isDeletable;
+
+ private int isUpdatable;
+
+ private int isVisible;
+
+ private Timestamp createTime;
+
+ public AuthRecord(long id, int userId, long fileId, String username, String fileName, String localUrl, int
+ isDownloadable, int isUploadable, int isDeletable, int isUpdatable, int isVisible, Timestamp createTime) {
+ this.id = id;
+ this.userId = userId;
+ this.fileId = fileId;
+ this.username = username;
+ this.fileName = fileName;
+ this.localUrl = localUrl;
+ this.isDownloadable = isDownloadable;
+ this.isUploadable = isUploadable;
+ this.isDeletable = isDeletable;
+ this.isUpdatable = isUpdatable;
+ this.isVisible = isVisible;
+ this.createTime = createTime;
+ }
+
+ @Override
+ public String toString() {
+ return BeanUtils.toPrettyJson(this);
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public int getUserId() {
+ return userId;
+ }
+
+ public void setUserId(int userId) {
+ this.userId = userId;
+ }
+
+ public long getFileId() {
+ return fileId;
+ }
+
+ public void setFileId(long fileId) {
+ this.fileId = fileId;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public String getLocalUrl() {
+ return localUrl;
+ }
+
+ public void setLocalUrl(String localUrl) {
+ this.localUrl = localUrl;
+ }
+
+ public int getIsDownloadable() {
+ return isDownloadable;
+ }
+
+ public void setIsDownloadable(int isDownloadable) {
+ this.isDownloadable = isDownloadable;
+ }
+
+ public int getIsUploadable() {
+ return isUploadable;
+ }
+
+ public void setIsUploadable(int isUploadable) {
+ this.isUploadable = isUploadable;
+ }
+
+ public int getIsDeletable() {
+ return isDeletable;
+ }
+
+ public void setIsDeletable(int isDeletable) {
+ this.isDeletable = isDeletable;
+ }
+
+ public int getIsUpdatable() {
+ return isUpdatable;
+ }
+
+ public void setIsUpdatable(int isUpdatable) {
+ this.isUpdatable = isUpdatable;
+ }
+
+ public int getIsVisible() {
+ return isVisible;
+ }
+
+ public void setIsVisible(int isVisible) {
+ this.isVisible = isVisible;
+ }
+
+ public Timestamp getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(Timestamp createTime) {
+ this.createTime = createTime;
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/model/BaseAuthRecord.java b/src/main/java/com/mesasoft/cn/model/BaseAuthRecord.java
new file mode 100644
index 0000000..a791a7a
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/model/BaseAuthRecord.java
@@ -0,0 +1,66 @@
+package com.mesasoft.cn.model;
+
+/**
+ * @author pantao
+ * @since 2018/3/6
+ */
+public class BaseAuthRecord {
+
+ private int isDownloadable;
+
+ private int isUploadable;
+
+ private int isDeletable;
+
+ private int isUpdatable;
+
+ private int isVisible;
+
+ public BaseAuthRecord(int isDownloadable, int isUploadable, int isDeletable, int isUpdatable, int isVisible) {
+ this.isDownloadable = isDownloadable;
+ this.isUploadable = isUploadable;
+ this.isDeletable = isDeletable;
+ this.isUpdatable = isUpdatable;
+ this.isVisible = isVisible;
+ }
+
+ public int getIsDownloadable() {
+ return isDownloadable;
+ }
+
+ public void setIsDownloadable(int isDownloadable) {
+ this.isDownloadable = isDownloadable;
+ }
+
+ public int getIsUploadable() {
+ return isUploadable;
+ }
+
+ public void setIsUploadable(int isUploadable) {
+ this.isUploadable = isUploadable;
+ }
+
+ public int getIsDeletable() {
+ return isDeletable;
+ }
+
+ public void setIsDeletable(int isDeletable) {
+ this.isDeletable = isDeletable;
+ }
+
+ public int getIsUpdatable() {
+ return isUpdatable;
+ }
+
+ public void setIsUpdatable(int isUpdatable) {
+ this.isUpdatable = isUpdatable;
+ }
+
+ public int getIsVisible() {
+ return isVisible;
+ }
+
+ public void setIsVisible(int isVisible) {
+ this.isVisible = isVisible;
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/model/DownloadRecord.java b/src/main/java/com/mesasoft/cn/model/DownloadRecord.java
new file mode 100644
index 0000000..c467965
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/model/DownloadRecord.java
@@ -0,0 +1,120 @@
+package com.mesasoft.cn.model;
+
+import com.mesasoft.cn.util.BeanUtils;
+
+import java.sql.Timestamp;
+
+/**
+ * @author pantao
+ * @since 2018/1/19
+ */
+public class DownloadRecord {
+
+ private long id;
+
+ private int userId;
+
+ private long fileId;
+
+ private String username;
+
+ private String email;
+
+ private String fileName;
+
+ private String categoryName;
+
+ private String visitUrl;
+
+ private Timestamp createTime;
+
+ public DownloadRecord(long id, int userId, long fileId, String username, String email, String fileName, String
+ categoryName, String visitUrl, Timestamp createTime) {
+ this.id = id;
+ this.userId = userId;
+ this.fileId = fileId;
+ this.username = username;
+ this.email = email;
+ this.fileName = fileName;
+ this.categoryName = categoryName;
+ this.visitUrl = visitUrl;
+ this.createTime = createTime;
+ }
+
+ @Override
+ public String toString() {
+ return BeanUtils.toPrettyJson(this);
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public int getUserId() {
+ return userId;
+ }
+
+ public void setUserId(int userId) {
+ this.userId = userId;
+ }
+
+ public long getFileId() {
+ return fileId;
+ }
+
+ public void setFileId(long fileId) {
+ this.fileId = fileId;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public String getCategoryName() {
+ return categoryName;
+ }
+
+ public void setCategoryName(String categoryName) {
+ this.categoryName = categoryName;
+ }
+
+ public String getVisitUrl() {
+ return visitUrl;
+ }
+
+ public void setVisitUrl(String visitUrl) {
+ this.visitUrl = visitUrl;
+ }
+
+ public Timestamp getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(Timestamp createTime) {
+ this.createTime = createTime;
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/model/FileBasicRecord.java b/src/main/java/com/mesasoft/cn/model/FileBasicRecord.java
new file mode 100644
index 0000000..9d3b914
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/model/FileBasicRecord.java
@@ -0,0 +1,91 @@
+package com.mesasoft.cn.model;
+
+import java.sql.Timestamp;
+
+/**
+ * @author pantao
+ * @since 2018/3/1
+ */
+public class FileBasicRecord {
+
+ private long id;
+
+ private String username;
+
+ private String localUrl;
+
+ private String categoryName;
+
+ private String visitUrl;
+
+ private int downloadTimes;
+
+ private Timestamp createTime;
+
+ public FileBasicRecord(long id, String username, String localUrl, String categoryName, String visitUrl, int
+ downloadTimes, Timestamp createTime) {
+ this.id = id;
+ this.username = username;
+ this.localUrl = localUrl;
+ this.categoryName = categoryName;
+ this.visitUrl = visitUrl;
+ this.downloadTimes = downloadTimes;
+ this.createTime = createTime;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getLocalUrl() {
+ return localUrl;
+ }
+
+ public void setLocalUrl(String localUrl) {
+ this.localUrl = localUrl;
+ }
+
+ public String getCategoryName() {
+ return categoryName;
+ }
+
+ public void setCategoryName(String categoryName) {
+ this.categoryName = categoryName;
+ }
+
+ public String getVisitUrl() {
+ return visitUrl;
+ }
+
+ public void setVisitUrl(String visitUrl) {
+ this.visitUrl = visitUrl;
+ }
+
+ public int getDownloadTimes() {
+ return downloadTimes;
+ }
+
+ public void setDownloadTimes(int downloadTimes) {
+ this.downloadTimes = downloadTimes;
+ }
+
+ public Timestamp getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(Timestamp createTime) {
+ this.createTime = createTime;
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/model/FileRecord.java b/src/main/java/com/mesasoft/cn/model/FileRecord.java
new file mode 100644
index 0000000..dc6b3fa
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/model/FileRecord.java
@@ -0,0 +1,261 @@
+package com.mesasoft.cn.model;
+
+import com.mesasoft.cn.util.BeanUtils;
+
+import java.sql.Timestamp;
+
+/**
+ * @author pantao
+ * @since 2018/1/19
+ */
+public class FileRecord {
+
+ private long id;
+
+ private int userId;
+
+ private String username;
+
+ private String avatar;
+
+ private String fileName;
+
+ private long size;
+
+ private String categoryName;
+
+ private String description;
+
+ private String tag;
+
+ private int checkTimes;
+
+ private int downloadTimes;
+
+ private String visitUrl;
+
+ private int isUploadable;
+
+ private int isDeletable;
+
+ private int isUpdatable;
+
+ private int isDownloadable;
+
+ private int isVisible;
+
+ private Timestamp createTime;
+
+ private Timestamp downloadTime;
+
+ public FileRecord(long id, int userId, String username, String avatar, String fileName, long size, Timestamp
+ createTime, String categoryName, String description, String tag, int checkTimes, int downloadTimes,
+ String visitUrl, int isUploadable, int isDeletable, int isUpdatable, int isDownloadable, int
+ isVisible, Timestamp downloadTime) {
+ this.id = id;
+ this.userId = userId;
+ this.username = username;
+ this.avatar = avatar;
+ this.fileName = fileName;
+ this.size = size;
+ this.createTime = createTime;
+ this.categoryName = categoryName;
+ this.description = description;
+ this.tag = tag;
+ this.checkTimes = checkTimes;
+ this.downloadTimes = downloadTimes;
+ this.visitUrl = visitUrl;
+ this.isUploadable = isUploadable;
+ this.isDeletable = isDeletable;
+ this.isUpdatable = isUpdatable;
+ this.isDownloadable = isDownloadable;
+ this.isVisible = isVisible;
+ this.downloadTime = downloadTime;
+ }
+
+ public FileRecord(long id, int userId, String username, String avatar, String fileName, long size, Timestamp
+ createTime, String categoryName, String description, String tag, int checkTimes, int downloadTimes,
+ String visitUrl, int isUploadable, int isDeletable, int isUpdatable, int isDownloadable, int
+ isVisible) {
+ this.id = id;
+ this.userId = userId;
+ this.username = username;
+ this.avatar = avatar;
+ this.fileName = fileName;
+ this.size = size;
+ this.createTime = createTime;
+ this.categoryName = categoryName;
+ this.description = description;
+ this.tag = tag;
+ this.checkTimes = checkTimes;
+ this.downloadTimes = downloadTimes;
+ this.visitUrl = visitUrl;
+ this.isUploadable = isUploadable;
+ this.isDeletable = isDeletable;
+ this.isUpdatable = isUpdatable;
+ this.isDownloadable = isDownloadable;
+ this.isVisible = isVisible;
+ }
+
+ @Override
+ public String toString() {
+ return BeanUtils.toPrettyJson(this);
+ }
+
+ public Timestamp getDownloadTime() {
+ return downloadTime;
+ }
+
+ public void setDownloadTime(Timestamp downloadTime) {
+ this.downloadTime = downloadTime;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getAvatar() {
+ return avatar;
+ }
+
+ public void setAvatar(String avatar) {
+ this.avatar = avatar;
+ }
+
+ public Timestamp getCreateTime() {
+
+ return createTime;
+ }
+
+ public void setCreateTime(Timestamp createTime) {
+ this.createTime = createTime;
+ }
+
+ public int getUserId() {
+ return userId;
+ }
+
+ public void setUserId(int userId) {
+ this.userId = userId;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public long getSize() {
+ return size;
+ }
+
+ public void setSize(long size) {
+ this.size = size;
+ }
+
+ public String getCategoryName() {
+ return categoryName;
+ }
+
+ public void setCategoryName(String categoryName) {
+ this.categoryName = categoryName;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getTag() {
+ return tag;
+ }
+
+ public void setTag(String tag) {
+ this.tag = tag;
+ }
+
+ public int getCheckTimes() {
+ return checkTimes;
+ }
+
+ public void setCheckTimes(int checkTimes) {
+ this.checkTimes = checkTimes;
+ }
+
+ public int getDownloadTimes() {
+ return downloadTimes;
+ }
+
+ public void setDownloadTimes(int downloadTimes) {
+ this.downloadTimes = downloadTimes;
+ }
+
+ public String getVisitUrl() {
+ return visitUrl;
+ }
+
+ public void setVisitUrl(String visitUrl) {
+ this.visitUrl = visitUrl;
+ }
+
+ public int getIsUploadable() {
+ return isUploadable;
+ }
+
+ public void setIsUploadable(int isUploadable) {
+ this.isUploadable = isUploadable;
+ }
+
+ public int getIsDeletable() {
+ return isDeletable;
+ }
+
+ public void setIsDeletable(int isDeletable) {
+ this.isDeletable = isDeletable;
+ }
+
+ public int getIsUpdatable() {
+ return isUpdatable;
+ }
+
+ public void setIsUpdatable(int isUpdatable) {
+ this.isUpdatable = isUpdatable;
+ }
+
+ public int getIsDownloadable() {
+ return isDownloadable;
+ }
+
+ public void setIsDownloadable(int isDownloadable) {
+ this.isDownloadable = isDownloadable;
+ }
+
+ public int getIsVisible() {
+ return isVisible;
+ }
+
+ public void setIsVisible(int isVisible) {
+ this.isVisible = isVisible;
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/model/UploadedRecord.java b/src/main/java/com/mesasoft/cn/model/UploadedRecord.java
new file mode 100644
index 0000000..b9410da
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/model/UploadedRecord.java
@@ -0,0 +1,113 @@
+package com.mesasoft.cn.model;
+
+import java.sql.Timestamp;
+
+/**
+ * @author pantao
+ * @since 2018/2/28
+ */
+public class UploadedRecord {
+
+ private long id;
+
+ private int userId;
+
+ private String username;
+
+ private String email;
+
+ private String fileName;
+
+ private String categoryName;
+
+ private String localUrl;
+
+ private String visitUrl;
+
+ private Timestamp createTime;
+
+ public UploadedRecord(long id, int userId, String username, String email, String fileName, String categoryName,
+ String localUrl, String visitUrl, Timestamp createTime) {
+ this.id = id;
+ this.userId = userId;
+ this.username = username;
+ this.email = email;
+ this.fileName = fileName;
+ this.categoryName = categoryName;
+ this.localUrl = localUrl;
+ this.visitUrl = visitUrl;
+ this.createTime = createTime;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public int getUserId() {
+ return userId;
+ }
+
+ public void setUserId(int userId) {
+ this.userId = userId;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public String getCategoryName() {
+ return categoryName;
+ }
+
+ public void setCategoryName(String categoryName) {
+ this.categoryName = categoryName;
+ }
+
+ public String getLocalUrl() {
+ return localUrl;
+ }
+
+ public void setLocalUrl(String localUrl) {
+ this.localUrl = localUrl;
+ }
+
+ public String getVisitUrl() {
+ return visitUrl;
+ }
+
+ public void setVisitUrl(String visitUrl) {
+ this.visitUrl = visitUrl;
+ }
+
+ public Timestamp getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(Timestamp createTime) {
+ this.createTime = createTime;
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/modules/constant/ConfigConsts.java b/src/main/java/com/mesasoft/cn/modules/constant/ConfigConsts.java
new file mode 100644
index 0000000..15a563d
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/modules/constant/ConfigConsts.java
@@ -0,0 +1,201 @@
+package com.mesasoft.cn.modules.constant;
+
+/**
+ * @author pantao
+ * @since 2018/1/12
+ */
+public class ConfigConsts {
+
+ /**
+ * 认证方式
+ */
+ public static final String AUTHENTICATION_OF_SETTING = "system.authentication";
+
+ /**
+ * 最大标签长度
+ */
+ public static final String TAG_SIZE_OF_SETTING = "file.tag.maxSize";
+
+ /**
+ * 每个标签最大长度
+ */
+ public static final String TAG_LENGTH_OF_SETTING = "file.tag.maxLength";
+
+ /**
+ * 文件标签
+ */
+ public static final String TAG_REQUIRE_OF_SETTING = "file.tag.require";
+
+ /**
+ * 文件默认排序方式
+ */
+ public static final String FILE_ORDER_BY_OF_SETTING = "file.orderBy";
+
+ /**
+ * 文件分页大小
+ */
+ public static final String FILE_PAGE_SIZE_OF_SETTING = "file.pageSize";
+
+ /**
+ * 匿名用户下载权限
+ */
+ public static final String ANONYMOUS_DOWNLOADABLE_OF_SETTING = "global.anonymousUser.downloadable";
+
+ /**
+ * 匿名用户访问权限
+ */
+ public static final String ANONYMOUS_VISIBLE_OF_SETTING = "global.anonymousUser.visible";
+
+ /**
+ * 文件后缀匹配
+ */
+ public static final String FILE_SUFFIX_MATCH_OF_SETTING = "file.suffixMatch.pattern";
+
+ /**
+ * 是否覆盖文件
+ */
+ public static final String FILE_COVER_OF_SETTING = "file.coverIfExists";
+
+ /**
+ * 自定义文件上传链接
+ */
+ public static final String CUSTOM_LINK_RULE_OF_SETTING = "file.linkRule.custom";
+
+ /**
+ * 最大上传大小路径
+ */
+ public static final String FILE_MAX_SIZE_OF_SETTING = "file.maxSize";
+
+ /**
+ * 上传路径在全局中的路径
+ */
+ public static final String UPLOAD_PATH_OF_SETTING = "global.uploadPath";
+
+ /**
+ * 上传形式路径
+ */
+ public static final String UPLOAD_FORM_OF_SETTING = "global.uploadForm";
+
+ /**
+ * token的路径
+ */
+ public static final String TOKEN_OF_SETTINGS = "global.tokenPath";
+
+ /**
+ * 是否验证邮箱的路径
+ */
+ public static final String EMAIL_VERIFY_OF_SETTINGS = "user.emailVerify";
+
+ /**
+ * 用户默认权限
+ */
+ public static final String FILE_DEFAULT_AUTH_OF_SETTING = "file.defaultAuth";
+
+ /**
+ * 默认权限
+ */
+ public static final String AUTH_DEFAULT_OF_SETTING = "auth.default";
+
+ /**
+ * 用户默认权限
+ */
+ public static final String USER_DEFAULT_AUTH_OF_SETTING = "user.defaultAuth";
+
+ /**
+ * 默认权限路径
+ */
+ public static final String[] AUTH_OF_SETTINGS = {"isDownloadable", "isUploadable", "isDeletable", "isUpdatable",
+ "isVisible"};
+
+ /**
+ * 密码最短长度的路径
+ */
+ public static final String PASSWORD_MIN_LENGTH_OF_SETTINGS = "user.password.minLength";
+
+ /**
+ * 密码最长长度的路径
+ */
+ public static final String PASSWORD_MAX_LENGTH_OF_SETTINGS = "user.password.maxLength";
+
+ /**
+ * 用户名匹配模式的路径
+ */
+ public static final String USERNAME_PATTERN_OF_SETTINGS = "user.usernameMatch.pattern";
+
+ /**
+ * 邮件配置的路径
+ */
+ public static final String EMAIL_CONFIG_OF_SETTINGS = "user.emailConfig";
+
+ /**
+ * 邮件配置在用户配置中的路径
+ */
+ public static final String EMAIL_CONFIG_OF_USER = "emailConfig";
+
+ /**
+ * 配置文件中用户配置的路径
+ */
+ public static final String USER_OF_SETTINGS = "user";
+
+ /**
+ * 是否允许用户注册的路径
+ */
+ public static final String ALLOW_REGISTER_OF_SETTINGS = "global.allowRegister";
+
+ /**
+ * 配置文件中登录的路径
+ */
+ public static final String ALLOW_LOGIN_OF_SETTINGS = "global.allowLogin";
+
+ /**
+ * token在全局中的路径
+ */
+ public static final String TOKEN_PATH_OF_GLOBAL = "tokenPath";
+
+ /**
+ * 上传路径在全局配置中的路径
+ */
+ public static final String UPLOAD_PATH_OF_GLOBAL = "uploadPath";
+
+ /**
+ * 配置文件中全局配置的路径
+ */
+ public static final String GLOBAL_OF_SETTINGS = "global";
+
+ /**
+ * 配置文件中用户表的order by路径
+ */
+ public static final String USER_ORDER_BY_OF_SETTINGS = "user.orderBy";
+
+ /**
+ * 配置文件中用户表的page size路径
+ */
+ public static final String USER_PAGE_SIZE_OF_SETTINGS = "user.pageSize";
+
+ /**
+ * 配置文件中下载记录表的order by路径
+ */
+ public static final String DOWNLOAD_ORDER_BY_OF_SETTINGS = "download.orderBy";
+
+ /**
+ * 配置文件中下载表的page size路径
+ */
+ public static final String DOWNLOAD_PAGE_SIZE_OF_SETTINGS = "download.pageSize";
+
+ /**
+ * 配置文件中权限记录表的order by路径
+ */
+ public static final String AUTH_ORDER_BY_OF_SETTINGS = "auth.orderBy";
+
+ /**
+ * 配置文件中权限表的page size路径
+ */
+ public static final String AUTH_PAGE_SIZE_OF_SETTINGS = "auth.pageSize";
+
+ /**
+ * 默认上传路径,如果配置文件中的上传路径无法创建,将使用默认的上传路径
+ */
+ public static final String DEFAULT_UPLOAD_PATH = DefaultValues.STORAGE_PATH + "upload";
+
+ private ConfigConsts() {}
+}
diff --git a/src/main/java/com/mesasoft/cn/modules/constant/DefaultValues.java b/src/main/java/com/mesasoft/cn/modules/constant/DefaultValues.java
new file mode 100644
index 0000000..76de50b
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/modules/constant/DefaultValues.java
@@ -0,0 +1,82 @@
+package com.mesasoft.cn.modules.constant;
+
+import com.zhazhapan.modules.constant.ValueConsts;
+
+/**
+ * @author pantao
+ * @since 2018/1/19
+ */
+public class DefaultValues {
+
+ /**
+ * 未分类
+ */
+ public static final String UNCATEGORIZED = "未分类";
+
+ /**
+ * 404页面路径
+ */
+ public static final String NOT_FOUND_PAGE = "/404.html";
+
+ /**
+ * Controller包路径
+ */
+ public static final String CONTROLLER_PACKAGE = "com.zhazhapan.efo.web.controller";
+
+ /**
+ * 配置文件路径
+ */
+ public static final String SETTING_PATH = "/config.json";
+
+ /**
+ * 冒号
+ */
+ public static final String COLON = ":";
+
+ /**
+ * 默认存储路径
+ */
+ public static final String STORAGE_PATH = ValueConsts.USER_HOME + ValueConsts.SEPARATOR + "Desktop" + ValueConsts
+ .SEPARATOR;
+
+ /**
+ * 首页映射路径
+ */
+ public static final String INDEX_PAGE = "/index";
+
+ /**
+ * 配置映射的路径
+ */
+ public static final String CONFIG_PAGE = "/config";
+
+ /**
+ * 资源映射的路径
+ */
+ public static final String ASSETS_PAGE = "/assets";
+
+ /**
+ * 登陆注册页面映射路径
+ */
+ public static final String SIGNIN_PAGE = "/signin";
+
+ /**
+ * 管理员页面映射路径
+ */
+ public static final String ADMIN_PAGE = "/admin";
+
+ /**
+ * int型数值3
+ */
+ public static final int THREE_INT = 3;
+ /**
+ * int型数值2
+ */
+ public static final int TWO_INT = 2;
+
+ /**
+ * code字符
+ */
+ public static final String CODE_STRING = "code";
+
+ private DefaultValues() {}
+}
diff --git a/src/main/java/com/mesasoft/cn/service/IAuthService.java b/src/main/java/com/mesasoft/cn/service/IAuthService.java
new file mode 100644
index 0000000..4f1759c
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/service/IAuthService.java
@@ -0,0 +1,92 @@
+package com.mesasoft.cn.service;
+
+import com.mesasoft.cn.entity.Auth;
+import com.mesasoft.cn.model.AuthRecord;
+
+import java.util.List;
+
+/**
+ * @author pantao
+ * @since 2018/2/1
+ */
+public interface IAuthService {
+
+ /**
+ * 添加权限集
+ *
+ * @param files 文件
+ * @param users 用户
+ * @param auths 权限集
+ *
+ * @return 是否添加成功
+ */
+ boolean addAuth(String files, String users, String auths);
+
+ /**
+ * 批量删除权限记录
+ *
+ * @param ids 权限编号集
+ *
+ * @return 是否删除成功
+ */
+ boolean batchDelete(String ids);
+
+ /**
+ * 更新权限
+ *
+ * @param id 权限编号
+ * @param auths 权限
+ *
+ * @return 是否更新成功
+ */
+ boolean updateAuth(long id, String auths);
+
+ /**
+ * 获取权限表数据
+ *
+ * @param usernameOrEmail 用户名或邮箱
+ * @param fileName 文件名
+ * @param offset 偏移
+ *
+ * @return {@link List}
+ */
+ List<AuthRecord> listAuth(String usernameOrEmail, String fileName, int offset);
+
+ /**
+ * 获取一个权限
+ *
+ * @param fileId 文件编号
+ * @param userId 用户编号
+ *
+ * @return {@link AuthRecord}
+ */
+ AuthRecord getByFileIdAndUserId(long fileId, int userId);
+
+ /**
+ * 添加一个默认权限
+ *
+ * @param userId 用户编号
+ * @param fileId 文件编号
+ *
+ * @return 是否添加成功
+ */
+ boolean insertDefaultAuth(int userId, long fileId);
+
+ /**
+ * 添加一个权限
+ *
+ * @param auth {@link Auth}
+ *
+ * @return 是否添加成功
+ */
+ boolean insertAuth(Auth auth);
+
+ /**
+ * 通过文件编号删除权限
+ *
+ * @param fileId 文件编号
+ *
+ * @return 是否删除成功
+ */
+ boolean removeByFileId(long fileId);
+}
diff --git a/src/main/java/com/mesasoft/cn/service/ICategoryService.java b/src/main/java/com/mesasoft/cn/service/ICategoryService.java
new file mode 100644
index 0000000..bf85404
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/service/ICategoryService.java
@@ -0,0 +1,65 @@
+package com.mesasoft.cn.service;
+
+import com.mesasoft.cn.entity.Category;
+
+import java.util.List;
+
+/**
+ * @author pantao
+ * @since 2018/1/30
+ */
+public interface ICategoryService {
+
+ /**
+ * 添加一个分类
+ *
+ * @param name 分类名称
+ *
+ * @return 是否添加成功
+ */
+ boolean insert(String name);
+
+ /**
+ * 删除一个分类
+ *
+ * @param id 分类编号
+ *
+ * @return 是否删除成功
+ */
+ boolean remove(int id);
+
+ /**
+ * 更新分类
+ *
+ * @param id 分类编号
+ * @param name 分类名称
+ *
+ * @return 是否更新成功
+ */
+ boolean update(int id, String name);
+
+ /**
+ * 获取一个分类
+ *
+ * @param id 分类编号
+ *
+ * @return {@link Category}
+ */
+ Category getById(int id);
+
+ /**
+ * 获取所有的分类
+ *
+ * @return {@link List}
+ */
+ List<Category> list();
+
+ /**
+ * 通过分类名获取ID
+ *
+ * @param name 分类名
+ *
+ * @return {@link Integer}
+ */
+ int getIdByName(String name);
+}
diff --git a/src/main/java/com/mesasoft/cn/service/ICommonService.java b/src/main/java/com/mesasoft/cn/service/ICommonService.java
new file mode 100644
index 0000000..de5fbc4
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/service/ICommonService.java
@@ -0,0 +1,28 @@
+package com.mesasoft.cn.service;
+
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * @author pantao
+ * @since 2018/1/23
+ */
+public interface ICommonService {
+
+ /**
+ * 发送验证码
+ *
+ * @param email 邮箱
+ *
+ * @return 验证码
+ */
+ int sendVerifyCode(String email);
+
+ /**
+ * 上传头像
+ *
+ * @param multipartFile 头像文件
+ *
+ * @return 头像文件名
+ */
+ String uploadAvatar(MultipartFile multipartFile);
+}
diff --git a/src/main/java/com/mesasoft/cn/service/IConfigService.java b/src/main/java/com/mesasoft/cn/service/IConfigService.java
new file mode 100644
index 0000000..e5acfef
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/service/IConfigService.java
@@ -0,0 +1,22 @@
+package com.mesasoft.cn.service;
+
+/**
+ * @author pantao
+ * @since 2018/1/22
+ */
+public interface IConfigService {
+
+ /**
+ * 获取全局配置
+ *
+ * @return {@link String}
+ */
+ String getGlobalConfig();
+
+ /**
+ * 获取用户配置
+ *
+ * @return {@link String}
+ */
+ String getUserConfig();
+}
diff --git a/src/main/java/com/mesasoft/cn/service/IDownloadedService.java b/src/main/java/com/mesasoft/cn/service/IDownloadedService.java
new file mode 100644
index 0000000..bb47ecd
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/service/IDownloadedService.java
@@ -0,0 +1,39 @@
+package com.mesasoft.cn.service;
+
+import com.mesasoft.cn.model.DownloadRecord;
+
+import java.util.List;
+
+/**
+ * @author pantao
+ * @since 2018/2/1
+ */
+public interface IDownloadedService {
+
+ /**
+ * 添加下载记录
+ *
+ * @param userId 用户编号
+ * @param fileId 文件编号
+ */
+ void insertDownload(int userId, long fileId);
+
+ /**
+ * 通过文件编号删除下载记录
+ *
+ * @param fileId 文件编号
+ */
+ void removeByFileId(long fileId);
+
+ /**
+ * 获取所有下载记录
+ *
+ * @param user 用户名或邮箱
+ * @param category 分类名称
+ * @param file 文件名
+ * @param offset 偏移
+ *
+ * @return {@link DownloadRecord}
+ */
+ List<DownloadRecord> list(String user, String file, String category, int offset);
+}
diff --git a/src/main/java/com/mesasoft/cn/service/IFileManagerService.java b/src/main/java/com/mesasoft/cn/service/IFileManagerService.java
new file mode 100644
index 0000000..44c3a4f
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/service/IFileManagerService.java
@@ -0,0 +1,136 @@
+package com.mesasoft.cn.service;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * @author pantao
+ * @since 2018/1/29
+ */
+public interface IFileManagerService {
+
+
+ /**
+ * 下载多个文件
+ *
+ * @param response {@link HttpServletResponse}
+ * @param items 文件集
+ * @param destFile 目标文件名
+ *
+ * @throws IOException 异常
+ */
+ void multiDownload(HttpServletResponse response, String[] items, String destFile) throws IOException;
+
+ /**
+ * 上传文件(暂时还没有实现)
+ *
+ * @param destination 目标文件
+ * @param files {@link MultipartFile}
+ *
+ * @return {@link JSONObject}
+ */
+ JSONObject upload(String destination, MultipartFile... files);
+
+ /**
+ * 解压文件
+ *
+ * @param object {@link JSONObject}
+ *
+ * @return {@link JSONObject}
+ */
+ JSONObject extract(JSONObject object);
+
+ /**
+ * 压缩文件
+ *
+ * @param object {@link JSONObject}
+ *
+ * @return {@link JSONObject}
+ */
+ JSONObject compress(JSONObject object);
+
+ /**
+ * 设置文件权限
+ *
+ * @param object {@link JSONObject}
+ *
+ * @return {@link JSONObject}
+ */
+ JSONObject setPermission(JSONObject object);
+
+ /**
+ * 创建文件夹
+ *
+ * @param object {@link JSONObject}
+ *
+ * @return {@link JSONObject}
+ */
+ JSONObject createFolder(JSONObject object);
+
+ /**
+ * 获取文件内容
+ *
+ * @param object {@link JSONObject}
+ *
+ * @return 文件内容
+ */
+ String getContent(JSONObject object);
+
+ /**
+ * 编辑文件
+ *
+ * @param object {@link JSONObject}
+ *
+ * @return {@link JSONObject}
+ */
+ JSONObject edit(JSONObject object);
+
+ /**
+ * 移除文件
+ *
+ * @param object {@link JSONObject}
+ *
+ * @return {@link JSONObject}
+ */
+ JSONObject remove(JSONObject object);
+
+ /**
+ * 复制文件
+ *
+ * @param object {@link JSONObject}
+ *
+ * @return {@link JSONObject}
+ */
+ JSONObject copy(JSONObject object);
+
+ /**
+ * 移动文件
+ *
+ * @param object {@link JSONObject}
+ *
+ * @return {@link JSONObject}
+ */
+ JSONObject move(JSONObject object);
+
+ /**
+ * 重命名
+ *
+ * @param object {@link JSONObject}
+ *
+ * @return {@link JSONObject}
+ */
+ JSONObject rename(JSONObject object);
+
+ /**
+ * 列出文件
+ *
+ * @param object {@link JSONObject}
+ *
+ * @return {@link JSONObject}
+ */
+ JSONArray list(JSONObject object);
+}
diff --git a/src/main/java/com/mesasoft/cn/service/IFileService.java b/src/main/java/com/mesasoft/cn/service/IFileService.java
new file mode 100644
index 0000000..3024830
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/service/IFileService.java
@@ -0,0 +1,228 @@
+package com.mesasoft.cn.service;
+
+import com.mesasoft.cn.entity.User;
+import com.mesasoft.cn.model.BaseAuthRecord;
+import com.mesasoft.cn.model.FileBasicRecord;
+import com.mesasoft.cn.model.FileRecord;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.File;
+import java.util.List;
+
+/**
+ * @author pantao
+ * @since 2018/1/29
+ */
+public interface IFileService {
+
+ /**
+ * 更新文件权限
+ *
+ * @param id 文件编号
+ * @param auth 权限集
+ *
+ * @return 是否更新成功
+ */
+ boolean updateAuth(long id, String auth);
+
+ /**
+ * 获取文件权限
+ *
+ * @param id 文件编号
+ *
+ * @return {@link BaseAuthRecord}
+ */
+ BaseAuthRecord getAuth(long id);
+
+ /**
+ * 批量删除文件
+ *
+ * @param ids 所有文件编号
+ *
+ * @return 是否删除成功
+ */
+ boolean deleteFiles(String ids);
+
+ /**
+ * 更新文件路径
+ *
+ * @param id 文件编号
+ * @param oldLocalUrl 原本地路径
+ * @param localUrl 本地路径
+ * @param visitUrl 访问路径
+ *
+ * @return 是否更新成功
+ */
+ boolean[] updateUrl(int id, String oldLocalUrl, String localUrl, String visitUrl);
+
+ /**
+ * 更新文件信息
+ *
+ * @param id 文件编号
+ * @param user 用户对象
+ * @param name 文件名
+ * @param category 文件分类
+ * @param tag 标签
+ * @param description 文件描述
+ *
+ * @return 是否更新成功
+ */
+ boolean updateFileInfo(long id, User user, String name, String category, String tag, String description);
+
+ /**
+ * 删除文件,验证权限
+ *
+ * @param user 用户对象
+ * @param fileId 文件编号
+ *
+ * @return {@link Boolean}
+ */
+ boolean removeFile(User user, long fileId);
+
+ /**
+ * 获取用户的下载资源
+ *
+ * @param userId 用户编号
+ * @param offset 偏移
+ * @param search 搜索
+ *
+ * @return {@link List}
+ */
+ List<FileRecord> listUserDownloaded(int userId, int offset, String search);
+
+ /**
+ * 获取用户的上传资源
+ *
+ * @param userId 用户编号
+ * @param offset 偏移
+ * @param search 搜索
+ *
+ * @return {@link List}
+ */
+ List<FileRecord> listUserUploaded(int userId, int offset, String search);
+
+ /**
+ * 通过编号删除,不验证权限
+ *
+ * @param id 编号
+ *
+ * @return 是否删除成功
+ */
+ boolean removeById(long id);
+
+ /**
+ * 通过访问路径删除
+ *
+ * @param visitUrl 访问路径
+ *
+ * @return 是否删除成功
+ */
+ boolean removeByVisitUrl(String visitUrl);
+
+ /**
+ * 通过本地路径删除
+ *
+ * @param localUrl 访问路径
+ *
+ * @return 是否删除成功
+ */
+ boolean removeByLocalUrl(String localUrl);
+
+ /**
+ * 获取资源
+ *
+ * @param visitUrl 访问路径
+ * @param request {@link HttpServletRequest}
+ *
+ * @return {@link File}
+ */
+ String getResource(String visitUrl, HttpServletRequest request);
+
+ /**
+ * 通过访问路径获取本地文件路径
+ *
+ * @param visitUrl 访问路径
+ *
+ * @return {@link String}
+ */
+ String getLocalUrlByVisitUrl(String visitUrl);
+
+ /**
+ * 获取所有文件
+ *
+ * @param userId 用户编号
+ * @param offset 偏移
+ * @param categoryId 分类编号
+ * @param orderBy 排序方式
+ * @param search 搜索
+ *
+ * @return {@link List}
+ */
+ List<FileRecord> listAll(int userId, int offset, int categoryId, String orderBy, String search);
+
+ /**
+ * 上传文件
+ *
+ * @param categoryId 分类ID
+ * @param tag 标签
+ * @param description 描述
+ * @param prefix 自定义前缀
+ * @param multipartFile 文件
+ * @param user {@link User}
+ *
+ * @return 是否上传成功
+ */
+ boolean upload(int categoryId, String tag, String description, String prefix, MultipartFile multipartFile, User
+ user);
+
+ /**
+ * 分享服务器本地文件
+ *
+ * @param prefix 链接前缀
+ * @param files 文件
+ * @param user 用户对象
+ *
+ * @return 是否添加成功
+ */
+ boolean shareFiles(String prefix, String files, User user);
+
+ /**
+ * 本地路径是否存在
+ *
+ * @param localUrl 本地路径
+ *
+ * @return {@link Boolean}
+ */
+ boolean localUrlExists(String localUrl);
+
+ /**
+ * 访问路径是否存在
+ *
+ * @param visitUrl 访问路径
+ *
+ * @return {@link Boolean}
+ */
+ boolean visitUrlExists(String visitUrl);
+
+ /**
+ * 通过本地路径获取文件编号
+ *
+ * @param localUrl 本地路径
+ *
+ * @return 文件编号
+ */
+ long getFileId(String localUrl);
+
+ /**
+ * 获取所有文件基本信息
+ *
+ * @param user 用户名或邮箱
+ * @param category 分类名称
+ * @param file 文件名
+ * @param offset 偏移
+ *
+ * @return {@link List}
+ */
+ List<FileBasicRecord> listBasicAll(String user, String file, String category, int offset);
+}
diff --git a/src/main/java/com/mesasoft/cn/service/IUploadedService.java b/src/main/java/com/mesasoft/cn/service/IUploadedService.java
new file mode 100644
index 0000000..25cc002
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/service/IUploadedService.java
@@ -0,0 +1,24 @@
+package com.mesasoft.cn.service;
+
+import com.mesasoft.cn.model.UploadedRecord;
+
+import java.util.List;
+
+/**
+ * @author pantao
+ * @since 2018/2/28
+ */
+public interface IUploadedService {
+
+ /**
+ * 获取所有上传记录
+ *
+ * @param user 用户名或邮箱
+ * @param category 分类名称
+ * @param file 文件名
+ * @param offset 偏移
+ *
+ * @return {@link List}
+ */
+ List<UploadedRecord> list(String user, String file, String category, int offset);
+}
diff --git a/src/main/java/com/mesasoft/cn/service/IUserService.java b/src/main/java/com/mesasoft/cn/service/IUserService.java
new file mode 100644
index 0000000..485e65d
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/service/IUserService.java
@@ -0,0 +1,161 @@
+package com.mesasoft.cn.service;
+
+import com.mesasoft.cn.entity.User;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/**
+ * @author pantao
+ * @since 2018/1/22
+ */
+public interface IUserService {
+
+ /**
+ * 更新用户权限
+ *
+ * @param id 用户编号
+ * @param permission 权限
+ *
+ * @return 是否更新成功
+ */
+ boolean updatePermission(int id, int permission);
+
+ /**
+ * 重置用户密码
+ *
+ * @param id 用户编号
+ * @param password 密码
+ *
+ * @return 是否重置成功
+ */
+ boolean resetPassword(int id, String password);
+
+ /**
+ * 更新用户权限
+ *
+ * @param id 编号
+ * @param auths 操作文件的权限集
+ *
+ * @return 是否更新成功
+ */
+ boolean updateFileAuth(int id, String auths);
+
+ /**
+ * 获取用户
+ *
+ * @param permission 当前用户权限
+ * @param condition 筛选条件
+ * @param offset 偏移
+ *
+ * @return {@link List}
+ */
+ List<User> listUser(int permission, String condition, int offset);
+
+ /**
+ * 登录
+ *
+ * @param loginName 登录名
+ * @param password 密码
+ * @param token 自动登录
+ * @param response 响应
+ *
+ * @return {@link User}
+ */
+ User login(String loginName, String password, String token, HttpServletResponse response);
+
+ /**
+ * 注册
+ *
+ * @param username 用户名
+ * @param email 邮箱
+ * @param password 密码
+ *
+ * @return 是否插入成功
+ */
+ boolean register(String username, String email, String password);
+
+ /**
+ * 重置密码
+ *
+ * @param email 邮箱
+ * @param password 密码
+ *
+ * @return {@link Boolean}
+ */
+ boolean resetPasswordByEmail(String email, String password);
+
+ /**
+ * 检查用户名是否存在
+ *
+ * @param username 用户名
+ *
+ * @return {@link Boolean}
+ */
+ boolean usernameExists(String username);
+
+ /**
+ * 通过编号获取用户
+ *
+ * @param id 编号
+ *
+ * @return {@link User}
+ */
+ User getUserById(int id);
+
+ /**
+ * 更新用户登录时间
+ *
+ * @param user {@link User}
+ */
+ void updateUserLoginTime(User user);
+
+ /**
+ * 更新密码
+ *
+ * @param password 密码
+ * @param id 用户编号
+ *
+ * @return 是否更新成功
+ */
+ boolean updatePasswordById(String password, int id);
+
+ /**
+ * 检查密码是否合法
+ *
+ * @param password 密码
+ *
+ * @return {@link Boolean}
+ */
+ boolean checkPassword(String password);
+
+ /**
+ * 检查邮箱是否存在
+ *
+ * @param email 邮箱
+ *
+ * @return {@link Boolean}
+ */
+ boolean emailExists(String email);
+
+ /**
+ * 更新用户基本信息
+ *
+ * @param id 编号
+ * @param avatar 头像
+ * @param realName 真实姓名
+ * @param email 邮箱
+ *
+ * @return 是否更新成功
+ */
+ boolean updateBasicInfoById(int id, String avatar, String realName, String email);
+
+ /**
+ * 用过用户名获取用户Id
+ *
+ * @param usernameOrEmail 用户名或邮箱
+ *
+ * @return 用户编号
+ */
+ int getUserId(String usernameOrEmail);
+}
diff --git a/src/main/java/com/mesasoft/cn/service/impl/AuthServiceImpl.java b/src/main/java/com/mesasoft/cn/service/impl/AuthServiceImpl.java
new file mode 100644
index 0000000..d4d0e53
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/service/impl/AuthServiceImpl.java
@@ -0,0 +1,96 @@
+package com.mesasoft.cn.service.impl;
+
+import com.mesasoft.cn.dao.AuthDAO;
+import com.mesasoft.cn.util.BeanUtils;
+import com.mesasoft.cn.config.SettingConfig;
+import com.mesasoft.cn.entity.Auth;
+import com.mesasoft.cn.model.AuthRecord;
+import com.mesasoft.cn.modules.constant.ConfigConsts;
+import com.mesasoft.cn.service.IAuthService;
+import com.mesasoft.cn.util.ServiceUtils;
+import com.zhazhapan.modules.constant.ValueConsts;
+import com.zhazhapan.util.Checker;
+import com.zhazhapan.util.Formatter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author pantao
+ * @since 2018/2/1
+ */
+@Service
+public class AuthServiceImpl implements IAuthService {
+
+ private final AuthDAO authDAO;
+
+ @Autowired
+ public AuthServiceImpl(AuthDAO authDAO) {this.authDAO = authDAO;}
+
+ @Override
+ public boolean addAuth(String files, String users, String auths) {
+ if (Checker.isNotEmpty(files) && Checker.isNotEmpty(users) && Checker.isNotEmpty(auths)) {
+ String[] file = files.split(ValueConsts.COMMA_SIGN);
+ String[] user = users.split(ValueConsts.COMMA_SIGN);
+ for (String f : file) {
+ long fileId = Formatter.stringToLong(f);
+ for (String u : user) {
+ int userId = Formatter.stringToInt(u);
+ if (Checker.isNull(authDAO.exists(userId, fileId))) {
+ Auth auth = new Auth(userId, fileId);
+ auth.setAuth(BeanUtils.getAuth(auths));
+ authDAO.insertAuth(auth);
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean batchDelete(String ids) {
+ return Checker.isNotEmpty(ids) && authDAO.batchDelete(ids);
+ }
+
+ @Override
+ public boolean updateAuth(long id, String auths) {
+ int[] auth = BeanUtils.getAuth(auths);
+ return authDAO.updateAuthById(id, auth[0], auth[1], auth[2], auth[3], auth[4]);
+ }
+
+ @Override
+ public List<AuthRecord> listAuth(String usernameOrEmail, String fileName, int offset) {
+ long fileId = ServiceUtils.getFileId(fileName);
+ int userId = ServiceUtils.getUserId(usernameOrEmail);
+ return authDAO.listAuthBy(ValueConsts.ZERO_INT, userId, fileId, fileName, offset);
+ }
+
+ @Override
+ public AuthRecord getByFileIdAndUserId(long fileId, int userId) {
+ List<AuthRecord> authRecords = authDAO.listAuthBy(ValueConsts.ZERO_INT, userId, fileId, ValueConsts
+ .EMPTY_STRING, ValueConsts.ZERO_INT);
+ if (Checker.isNotEmpty(authRecords)) {
+ return authRecords.get(0);
+ }
+ return null;
+ }
+
+ @Override
+ public boolean insertDefaultAuth(int userId, long fileId) {
+ int[] defaultAuth = SettingConfig.getAuth(ConfigConsts.AUTH_DEFAULT_OF_SETTING);
+ Auth auth = new Auth(userId, fileId);
+ auth.setAuth(defaultAuth[0], defaultAuth[1], defaultAuth[2], defaultAuth[3], defaultAuth[4]);
+ return insertAuth(auth);
+ }
+
+ @Override
+ public boolean insertAuth(Auth auth) {
+ return authDAO.insertAuth(auth);
+ }
+
+ @Override
+ public boolean removeByFileId(long fileId) {
+ return authDAO.removeAuthByFileId(fileId);
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/service/impl/CategoryServiceImpl.java b/src/main/java/com/mesasoft/cn/service/impl/CategoryServiceImpl.java
new file mode 100644
index 0000000..12f9a2d
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/service/impl/CategoryServiceImpl.java
@@ -0,0 +1,62 @@
+package com.mesasoft.cn.service.impl;
+
+import com.mesasoft.cn.dao.CategoryDAO;
+import com.mesasoft.cn.entity.Category;
+import com.mesasoft.cn.modules.constant.DefaultValues;
+import com.mesasoft.cn.service.ICategoryService;
+import com.zhazhapan.util.Checker;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author pantao
+ * @since 2018/1/30
+ */
+@Service
+public class CategoryServiceImpl implements ICategoryService {
+
+ private final CategoryDAO categoryDAO;
+
+ @Autowired
+ public CategoryServiceImpl(CategoryDAO categoryDAO) {this.categoryDAO = categoryDAO;}
+
+ @Override
+ public boolean insert(String name) {
+ return Checker.isNotNull(name) && categoryDAO.insertCategory(name);
+ }
+
+ @Override
+ public boolean remove(int id) {
+ return isCategorized(id) && categoryDAO.removeCategoryById(id);
+ }
+
+ @Override
+ public boolean update(int id, String name) {
+ return Checker.isNotEmpty(name) && isCategorized(id) && categoryDAO.updateNameById(id, name);
+ }
+
+ private boolean isCategorized(int id) {
+ return !DefaultValues.UNCATEGORIZED.equals(getById(id).getName());
+ }
+
+ @Override
+ public Category getById(int id) {
+ return categoryDAO.getCategoryById(id);
+ }
+
+ @Override
+ public List<Category> list() {
+ return categoryDAO.listCategory();
+ }
+
+ @Override
+ public int getIdByName(String name) {
+ try {
+ return categoryDAO.getIdByName(name);
+ } catch (Exception e) {
+ return Integer.MAX_VALUE;
+ }
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/service/impl/CommonServiceImpl.java b/src/main/java/com/mesasoft/cn/service/impl/CommonServiceImpl.java
new file mode 100644
index 0000000..05f1d10
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/service/impl/CommonServiceImpl.java
@@ -0,0 +1,59 @@
+package com.mesasoft.cn.service.impl;
+
+import com.mesasoft.cn.modules.constant.DefaultValues;
+import com.mesasoft.cn.config.SettingConfig;
+import com.mesasoft.cn.service.ICommonService;
+import com.zhazhapan.modules.constant.ValueConsts;
+import com.zhazhapan.util.Checker;
+import com.zhazhapan.util.FileExecutor;
+import com.zhazhapan.util.MailSender;
+import com.zhazhapan.util.RandomUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @author pantao
+ * @since 2018/1/23
+ */
+@Service
+public class CommonServiceImpl implements ICommonService {
+
+ private static final String EMAIL_TITLE = "请查收您的验证码";
+ private static Logger logger = LoggerFactory.getLogger(CommonServiceImpl.class);
+
+ @Override
+ public int sendVerifyCode(String email) {
+ int code = RandomUtils.getRandomInteger(ValueConsts.VERIFY_CODE_FLOOR, ValueConsts.VERIFY_CODE_CEIL);
+ String content = "<p>您的验证码:" + code + "</p><br/><br/><p>如非本人操作,请忽略本条消息。</p>";
+ try {
+ MailSender.sendMail(email, EMAIL_TITLE, content);
+ return code;
+ } catch (Exception e) {
+ logger.error(e.getMessage());
+ return 0;
+ }
+ }
+
+ @Override
+ public String uploadAvatar(MultipartFile multipartFile) {
+ if (!multipartFile.isEmpty()) {
+ String name = RandomUtils.getRandomStringOnlyLowerCase(ValueConsts.SIXTEEN_INT) + ValueConsts.DOT_SIGN +
+ FileExecutor.getFileSuffix(multipartFile.getOriginalFilename());
+ if (Checker.isImage(name) && multipartFile.getSize() < ValueConsts.MB * DefaultValues.TWO_INT) {
+ String path = SettingConfig.getAvatarStoragePath() + ValueConsts.SEPARATOR + name;
+ try {
+ FileExecutor.writeByteArrayToFile(new File(path), multipartFile.getBytes());
+ return name;
+ } catch (IOException e) {
+ logger.error("upload avatar error: " + e.getMessage());
+ }
+ }
+ }
+ return "";
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/service/impl/ConfigServiceImpl.java b/src/main/java/com/mesasoft/cn/service/impl/ConfigServiceImpl.java
new file mode 100644
index 0000000..1de92b2
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/service/impl/ConfigServiceImpl.java
@@ -0,0 +1,33 @@
+package com.mesasoft.cn.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.mesasoft.cn.SketchApplication;
+import com.mesasoft.cn.modules.constant.ConfigConsts;
+import com.mesasoft.cn.service.IConfigService;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author pantao
+ * @since 2018/1/22
+ */
+@Service
+public class ConfigServiceImpl implements IConfigService {
+
+ @Override
+ public String getGlobalConfig() {
+ JSONObject jsonObject = (JSONObject) SketchApplication.settings.getObjectUseEval(ConfigConsts
+ .GLOBAL_OF_SETTINGS).clone();
+ jsonObject.remove(ConfigConsts.UPLOAD_PATH_OF_GLOBAL);
+ jsonObject.remove(ConfigConsts.TOKEN_PATH_OF_GLOBAL);
+ jsonObject.remove(ConfigConsts.UPLOAD_FORM_OF_SETTING);
+ return jsonObject.toString();
+ }
+
+ @Override
+ public String getUserConfig() {
+ JSONObject jsonObject = (JSONObject) SketchApplication.settings.getObjectUseEval(ConfigConsts.USER_OF_SETTINGS)
+ .clone();
+ jsonObject.remove(ConfigConsts.EMAIL_CONFIG_OF_USER);
+ return jsonObject.toString();
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/service/impl/DownloadedServiceImpl.java b/src/main/java/com/mesasoft/cn/service/impl/DownloadedServiceImpl.java
new file mode 100644
index 0000000..3c2b546
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/service/impl/DownloadedServiceImpl.java
@@ -0,0 +1,42 @@
+package com.mesasoft.cn.service.impl;
+
+import com.mesasoft.cn.dao.DownloadedDAO;
+import com.mesasoft.cn.model.DownloadRecord;
+import com.mesasoft.cn.service.IDownloadedService;
+import com.mesasoft.cn.util.ServiceUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author pantao
+ * @since 2018/2/1
+ */
+@Service
+public class DownloadedServiceImpl implements IDownloadedService {
+
+ private final DownloadedDAO downloadDAO;
+
+ @Autowired
+ public DownloadedServiceImpl(DownloadedDAO downloadDAO) {
+ this.downloadDAO = downloadDAO;
+ }
+
+ @Override
+ public void insertDownload(int userId, long fileId) {
+ downloadDAO.insertDownload(userId, fileId);
+ }
+
+ @Override
+ public void removeByFileId(long fileId) {
+ downloadDAO.removeByFileId(fileId);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<DownloadRecord> list(String user, String file, String category, int offset) {
+ return (List<DownloadRecord>) ServiceUtils.invokeFileFilter(downloadDAO, "listDownloadedBy", user, file,
+ category, offset);
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/service/impl/FileManagerServiceImpl.java b/src/main/java/com/mesasoft/cn/service/impl/FileManagerServiceImpl.java
new file mode 100644
index 0000000..0ae179b
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/service/impl/FileManagerServiceImpl.java
@@ -0,0 +1,236 @@
+package com.mesasoft.cn.service.impl;
+
+import cn.hutool.core.util.ZipUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.mesasoft.cn.modules.constant.DefaultValues;
+import com.mesasoft.cn.service.IFileManagerService;
+import com.zhazhapan.modules.constant.ValueConsts;
+import com.zhazhapan.util.Checker;
+import com.zhazhapan.util.FileExecutor;
+import com.zhazhapan.util.Formatter;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.swing.filechooser.FileSystemView;
+import java.io.File;
+import java.io.IOException;
+import java.util.Date;
+
+/**
+ * @author pantao
+ * @since 2018/1/29
+ */
+@Service
+public class FileManagerServiceImpl implements IFileManagerService {
+
+ private static Logger logger = Logger.getLogger(FileManagerServiceImpl.class);
+
+ @Override
+ public void multiDownload(HttpServletResponse response, String[] items, String destFile) throws IOException {
+ File zip = ZipUtil.zip(new File(ValueConsts.USER_DESKTOP + File.separator + destFile), ValueConsts.FALSE,
+ FileExecutor.getFiles(items));
+ if (zip.exists()) {
+ response.getOutputStream().write(FileExecutor.readFileToByteArray(zip));
+ FileExecutor.deleteFile(zip);
+ }
+ }
+
+ @Override
+ public JSONObject upload(String destination, MultipartFile... files) {
+ System.out.println(files.length);
+ if (Checker.isNotEmpty(files)) {
+ if (Checker.isWindows() && destination.length() < ValueConsts.TWO_INT) {
+ destination = "C:";
+ }
+ for (MultipartFile file : files) {
+ if (Checker.isNotNull(file) && !file.isEmpty()) {
+ try {
+ file.transferTo(new File(destination + File.separator + file.getOriginalFilename()));
+ } catch (IOException e) {
+ logger.error(e.getMessage());
+ return getBasicResponse(ValueConsts.FALSE);
+ }
+ }
+ }
+ }
+ return getBasicResponse(ValueConsts.TRUE);
+ }
+
+ @Override
+ public JSONObject extract(JSONObject object) {
+ String destination = object.getString("destination") + File.separator + object.getString("folderName");
+ String zipFile = object.getString("item");
+ return getBasicResponse(ZipUtil.unzip(zipFile, destination).exists());
+ }
+
+ @Override
+ public JSONObject compress(JSONObject object) {
+ JSONArray array = object.getJSONArray("items");
+ File[] files = new File[array.size()];
+ int i = 0;
+ for (Object file : array) {
+ files[i++] = new File(file.toString());
+ }
+ String dest = object.getString("destination");
+ String name = object.getString("compressedFilename");
+ File zip = ZipUtil.zip(new File(dest + File.separator + name), ValueConsts.FALSE, files);
+ return getBasicResponse(zip.exists());
+ }
+
+ @Override
+ public JSONObject setPermission(JSONObject object) {
+ if (Checker.isLinux()) {
+ JSONArray array = object.getJSONArray("items");
+ int code = object.getInteger("permsCode");
+ for (Object file : array) {
+ try {
+ Runtime.getRuntime().exec("chmod -R " + code + " " + file.toString());
+ } catch (IOException e) {
+ logger.error(e.getMessage());
+ return getBasicResponse(ValueConsts.FALSE);
+ }
+ }
+ }
+ return getBasicResponse(ValueConsts.TRUE);
+ }
+
+ @Override
+ public JSONObject createFolder(JSONObject object) {
+ String folder = object.getString("newPath");
+ return getBasicResponse(FileExecutor.createFolder(folder));
+ }
+
+ @Override
+ public String getContent(JSONObject object) {
+ String fileName = object.getString("item");
+ try {
+ return FileExecutor.readFile(fileName);
+ } catch (IOException e) {
+ logger.error(e.getMessage());
+ return "";
+ }
+ }
+
+ @Override
+ public JSONObject edit(JSONObject object) {
+ String file = object.getString("item");
+ String content = object.getString("content");
+ try {
+ FileExecutor.saveFile(file, content);
+ return getBasicResponse(ValueConsts.TRUE);
+ } catch (IOException e) {
+ logger.error(e.getMessage());
+ return getBasicResponse(ValueConsts.FALSE);
+ }
+ }
+
+ @Override
+ public JSONObject remove(JSONObject object) {
+ JSONArray array = object.getJSONArray("items");
+ array.forEach(file -> FileExecutor.deleteFile(file.toString()));
+ return getBasicResponse(ValueConsts.TRUE);
+ }
+
+ @Override
+ public JSONObject copy(JSONObject object) {
+ JSONArray array = object.getJSONArray("items");
+ String dest = object.getString("newPath");
+ File[] files = new File[array.size()];
+ int i = 0;
+ for (Object file : array) {
+ files[i++] = new File(file.toString());
+ }
+ try {
+ FileExecutor.copyFiles(files, dest);
+ return getBasicResponse(ValueConsts.TRUE);
+ } catch (IOException e) {
+ logger.error(e.getMessage());
+ return getBasicResponse(ValueConsts.FALSE);
+ }
+ }
+
+ @Override
+ public JSONObject move(JSONObject object) {
+ JSONArray array = object.getJSONArray("items");
+ String dest = object.getString("newPath");
+ for (Object file : array) {
+ try {
+ FileExecutor.moveToDirectory(new File(file.toString()), new File(dest), ValueConsts.TRUE);
+ } catch (IOException e) {
+ logger.error(e.getMessage());
+ return getBasicResponse(ValueConsts.FALSE);
+ }
+ }
+ return getBasicResponse(ValueConsts.TRUE);
+ }
+
+ @Override
+ public JSONObject rename(JSONObject object) {
+ String fileName = object.getString("item");
+ String newFileName = object.getString("newItemPath");
+ FileExecutor.renameTo(fileName, newFileName);
+ return getBasicResponse(ValueConsts.TRUE);
+ }
+
+ @Override
+ public JSONArray list(JSONObject object) {
+ String path = object.getString("path");
+ JSONArray array = new JSONArray();
+ File[] files = null;
+ if (Checker.isWindows()) {
+ if (Checker.isNotEmpty(path) && path.startsWith(ValueConsts.SPLASH_STRING)) {
+ path = path.substring(1);
+ }
+ if (Checker.isEmpty(path)) {
+ FileSystemView fsv = FileSystemView.getFileSystemView();
+ File[] fs = File.listRoots();
+ for (File file : fs) {
+ if (file.getTotalSpace() > 0) {
+ String displayName = fsv.getSystemDisplayName(file);
+ int len = displayName.length();
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put("name", displayName.substring(len - 3, len - 1));
+ jsonObject.put("rights", "----------");
+ jsonObject.put("size", file.getTotalSpace() - file.getFreeSpace());
+ jsonObject.put("date", Formatter.datetimeToString(new Date(file.lastModified())));
+ jsonObject.put("type", file.isDirectory() ? "dir" : "file");
+ array.add(jsonObject);
+ }
+ }
+ } else if (path.startsWith(DefaultValues.COLON, 1)) {
+ files = FileExecutor.listFile(path.endsWith(DefaultValues.COLON) ? path + File.separator : path);
+ } else {
+ logger.error("path error");
+ }
+ } else {
+ files = FileExecutor.listFile(Checker.isEmpty(path) ? "/" : (path.startsWith("/") ? path : "/" + path));
+ }
+ if (Checker.isNotNull(files)) {
+ for (File file : files) {
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put("name", file.getName());
+ jsonObject.put("rights", "----------");
+ jsonObject.put("size", file.length());
+ jsonObject.put("date", Formatter.datetimeToString(new Date(file.lastModified())));
+ jsonObject.put("type", file.isDirectory() ? "dir" : "file");
+ array.add(jsonObject);
+ }
+ }
+ return array;
+ }
+
+ private JSONObject getBasicResponse(boolean isSuccess) {
+ JSONObject jsonObject = new JSONObject();
+ if (isSuccess) {
+ jsonObject.put("success", true);
+ jsonObject.put("error", null);
+ } else {
+ jsonObject.put("success", null);
+ jsonObject.put("error", "服务器异常");
+ }
+ return jsonObject;
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/service/impl/FileServiceImpl.java b/src/main/java/com/mesasoft/cn/service/impl/FileServiceImpl.java
new file mode 100644
index 0000000..2c6e6e9
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/service/impl/FileServiceImpl.java
@@ -0,0 +1,383 @@
+package com.mesasoft.cn.service.impl;
+
+import com.mesasoft.cn.SketchApplication;
+import com.mesasoft.cn.dao.DownloadedDAO;
+import com.mesasoft.cn.dao.FileDAO;
+import com.mesasoft.cn.util.BeanUtils;
+import com.mesasoft.cn.config.SettingConfig;
+import com.mesasoft.cn.entity.Category;
+import com.mesasoft.cn.entity.File;
+import com.mesasoft.cn.entity.User;
+import com.mesasoft.cn.model.AuthRecord;
+import com.mesasoft.cn.model.BaseAuthRecord;
+import com.mesasoft.cn.model.FileBasicRecord;
+import com.mesasoft.cn.model.FileRecord;
+import com.mesasoft.cn.modules.constant.ConfigConsts;
+import com.mesasoft.cn.modules.constant.DefaultValues;
+import com.mesasoft.cn.service.IAuthService;
+import com.mesasoft.cn.service.ICategoryService;
+import com.mesasoft.cn.service.IFileService;
+import com.mesasoft.cn.util.ServiceUtils;
+import com.zhazhapan.modules.constant.ValueConsts;
+import com.zhazhapan.util.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Date;
+import java.util.List;
+import java.util.regex.Pattern;
+
+/**
+ * @author pantao
+ * @since 2018/1/29
+ */
+@Service
+public class FileServiceImpl implements IFileService {
+
+ private final static Logger logger = LoggerFactory.getLogger(FileServiceImpl.class);
+
+ private static final String FILE_SUFFIX = "{fileSuffix}";
+
+ private static final String RANDOM_ID = "{randomId}";
+
+ private static final String YEAR = "{year}";
+
+ private static final String MONTH = "{month}";
+
+ private static final String DAY = "{day}";
+
+ private static final String AUTHOR = "{author}";
+
+ private static final String FILE_NAME = "{fileName}";
+
+ private static final String CATEGORY_NAME = "{categoryName}";
+
+ private final FileDAO fileDAO;
+
+ private final ICategoryService categoryService;
+
+ private final IAuthService authService;
+
+ private final DownloadedDAO downloadDAO;
+
+ @Autowired
+ public FileServiceImpl(FileDAO fileDAO, ICategoryService categoryService, IAuthService authService,
+ DownloadedDAO downloadDAO) {
+ this.fileDAO = fileDAO;
+ this.categoryService = categoryService;
+ this.authService = authService;
+ this.downloadDAO = downloadDAO;
+ }
+
+ @Override
+ public boolean updateAuth(long id, String auth) {
+ int[] au = BeanUtils.getAuth(auth);
+ return fileDAO.updateAuthById(id, au[0], au[1], au[2], au[3], au[4]);
+ }
+
+ @Override
+ public BaseAuthRecord getAuth(long id) {
+ return fileDAO.getAuth(id);
+ }
+
+ @Override
+ @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor =
+ Exception.class)
+ public boolean deleteFiles(String ids) {
+ if (Checker.isNotEmpty(ids)) {
+ String[] id = ids.split(ValueConsts.COMMA_SIGN);
+ for (String s : id) {
+ long fileId = Formatter.stringToLong(s);
+ String localUrl = fileDAO.getLocalUrlById(fileId);
+ FileExecutor.deleteFile(localUrl);
+ removeById(fileId);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor =
+ Exception.class)
+ public boolean[] updateUrl(int id, String oldLocalUrl, String localUrl, String visitUrl) {
+ boolean[] b = new boolean[]{false, false};
+ boolean canUpdateLocalUrl = Checker.isExists(oldLocalUrl) && Checker.isNotEmpty(localUrl) && Checker
+ .isNotExists(localUrl) && !localUrlExists(localUrl);
+ if (canUpdateLocalUrl) {
+ FileExecutor.renameTo(oldLocalUrl, localUrl);
+ fileDAO.updateLocalUrlById(id, localUrl);
+ b[0] = true;
+ }
+ if (Checker.isNotEmpty(visitUrl) && !visitUrlExists(visitUrl)) {
+ fileDAO.updateVisitUrlById(id, visitUrl);
+ b[1] = true;
+ }
+ return b;
+ }
+
+ @Override
+ @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor =
+ Exception.class)
+ public boolean updateFileInfo(long id, User user, String name, String category, String tag, String description) {
+ File file = fileDAO.getById(id);
+ if (Checker.isNotNull(file) && file.getIsUpdatable() == 1) {
+ AuthRecord authRecord = authService.getByFileIdAndUserId(id, user.getId());
+ String suffix = FileExecutor.getFileSuffix(name);
+ boolean canUpdate = (Checker.isNull(authRecord) ? user.getIsUpdatable() == 1 :
+ authRecord.getIsUpdatable() == 1) && Checker.isNotEmpty(name) && Pattern.compile(SketchApplication.settings.getStringUseEval(ConfigConsts.FILE_SUFFIX_MATCH_OF_SETTING)).matcher(suffix).matches();
+ if (canUpdate) {
+ String localUrl = file.getLocalUrl();
+ java.io.File newFile = new java.io.File(localUrl);
+ String visitUrl = file.getVisitUrl();
+ String newLocalUrl = localUrl.substring(0, localUrl.lastIndexOf(ValueConsts.SEPARATOR) + 1) + name;
+ String newVisitUrl = visitUrl.substring(0, visitUrl.lastIndexOf(ValueConsts.SPLASH_STRING) + 1) + name;
+ file.setName(name);
+ file.setSuffix(suffix);
+ file.setLocalUrl(newLocalUrl);
+ file.setVisitUrl(newVisitUrl);
+ file.setCategoryId(categoryService.getIdByName(category));
+ file.setTag(tag);
+ file.setDescription(description);
+ boolean isValid = (localUrl.endsWith(ValueConsts.SEPARATOR + name) || (!Checker.isExists(newLocalUrl)
+ && !localUrlExists(newLocalUrl) && !visitUrlExists(newVisitUrl)));
+ if (isValid && fileDAO.updateFileInfo(file)) {
+ return newFile.renameTo(new java.io.File(newLocalUrl));
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean removeFile(User user, long fileId) {
+ File file = fileDAO.getById(fileId);
+ boolean isDeleted = false;
+ if (Checker.isNotNull(file) && file.getIsDeletable() == 1) {
+ AuthRecord authRecord = authService.getByFileIdAndUserId(fileId, user.getId());
+ String localUrl = fileDAO.getLocalUrlById(fileId);
+ isDeleted = (Checker.isNull(authRecord) ? user.getIsDeletable() == 1 : authRecord.getIsDeletable() == 1)
+ && removeById(fileId);
+ if (isDeleted) {
+ FileExecutor.deleteFile(localUrl);
+ }
+ }
+ return isDeleted;
+ }
+
+ @Override
+ public List<FileRecord> listUserDownloaded(int userId, int offset, String search) {
+ return fileDAO.listUserDownloaded(userId, offset, search);
+ }
+
+ @Override
+ public List<FileRecord> listUserUploaded(int userId, int offset, String search) {
+ return fileDAO.listUserUploaded(userId, offset, search);
+ }
+
+ @Override
+ @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor =
+ Exception.class)
+ public boolean removeById(long id) {
+ downloadDAO.removeByFileId(id);
+ authService.removeByFileId(id);
+ return fileDAO.removeById(id);
+ }
+
+ @Override
+ public boolean removeByVisitUrl(String visitUrl) {
+ long fileId = fileDAO.getIdByVisitUrl(visitUrl);
+ return removeById(fileId);
+ }
+
+ @Override
+ public boolean removeByLocalUrl(String localUrl) {
+ long fileId = fileDAO.getIdByLocalUrl(localUrl);
+ return removeById(fileId);
+ }
+
+ @Override
+ public String getResource(String visitUrl, HttpServletRequest request) {
+ logger.info("visit url: " + visitUrl);
+ boolean downloadable = SketchApplication.settings.getBooleanUseEval(ConfigConsts
+ .ANONYMOUS_DOWNLOADABLE_OF_SETTING);
+ User user = (User) request.getSession().getAttribute(ValueConsts.USER_STRING);
+ File file = fileDAO.getFileByVisitUrl(visitUrl);
+ AuthRecord authRecord = null;
+ if (Checker.isNotNull(file)) {
+ authRecord = authService.getByFileIdAndUserId(file.getId(), Checker.isNull(user) ? 0 : user.getId());
+ }
+ boolean canDownload = Checker.isNotNull(file) && file.getIsDownloadable() == 1 && (downloadable || (Checker
+ .isNull(authRecord) ? (Checker.isNotNull(user) && user.getIsDownloadable() == 1) : authRecord
+ .getIsDownloadable() == 1));
+ if (canDownload) {
+ fileDAO.updateDownloadTimesById(file.getId());
+ if (Checker.isNotNull(user)) {
+ downloadDAO.insertDownload(user.getId(), file.getId());
+ }
+ return file.getLocalUrl();
+ }
+ return "";
+ }
+
+ @Override
+ public String getLocalUrlByVisitUrl(String visitUrl) {
+ return fileDAO.getLocalUrlByVisitUrl(Checker.checkNull(visitUrl));
+ }
+
+ @Override
+ public List<FileRecord> listAll(int userId, int offset, int categoryId, String orderBy, String search) {
+ return fileDAO.listAll(userId, offset, categoryId, orderBy, search);
+ }
+
+ @Override
+ @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor =
+ Exception.class)
+ public boolean upload(int categoryId, String tag, String description, String prefix, MultipartFile multipartFile,
+ User user) {
+ if (user.getIsUploadable() == 1) {
+ String name = multipartFile.getOriginalFilename();
+ String suffix = FileExecutor.getFileSuffix(name);
+ String localUrl = SettingConfig.getUploadStoragePath() + ValueConsts.SEPARATOR + name;
+ Category category = categoryService.getById(categoryId);
+ long maxSize = Formatter.sizeToLong(SketchApplication.settings.getStringUseEval(ConfigConsts
+ .FILE_MAX_SIZE_OF_SETTING));
+ long size = multipartFile.getSize();
+ boolean fileExists = localUrlExists(localUrl);
+ //检测标签是否合法
+ if (SketchApplication.settings.getBooleanUseEval(ConfigConsts.TAG_REQUIRE_OF_SETTING)) {
+ String[] tags = Checker.checkNull(tag).split(ValueConsts.SPACE);
+ if (tags.length <= SketchApplication.settings.getIntegerUseEval(ConfigConsts.TAG_SIZE_OF_SETTING)) {
+ int maxLength = SketchApplication.settings.getIntegerUseEval(ConfigConsts.TAG_LENGTH_OF_SETTING);
+ for (String t : tags) {
+ if (t.length() > maxLength) {
+ return false;
+ }
+ }
+ } else {
+ return false;
+ }
+ }
+ //是否可以上传
+ boolean canUpload = !multipartFile.isEmpty() && size <= maxSize && Pattern.compile(SketchApplication
+ .settings.getStringUseEval(ConfigConsts.FILE_SUFFIX_MATCH_OF_SETTING)).matcher(suffix).matches()
+ && (Checker.isNotExists(localUrl) || !fileExists || SketchApplication.settings.getBooleanUseEval
+ (ConfigConsts.FILE_COVER_OF_SETTING));
+ logger.info("is empty [" + multipartFile.isEmpty() + "], file size [" + size + "], max file size [" +
+ maxSize + "]");
+ if (canUpload) {
+ String visitUrl = getRegularVisitUrl(Checker.isNotEmpty(prefix) && user.getPermission() > 1 ? prefix
+ : SketchApplication.settings.getStringUseEval(ConfigConsts.CUSTOM_LINK_RULE_OF_SETTING), user,
+ name, suffix, category);
+ if (fileExists) {
+ removeByLocalUrl(localUrl);
+ }
+ if (visitUrlExists(visitUrl)) {
+ removeByVisitUrl(visitUrl);
+ }
+ try {
+ multipartFile.transferTo(new java.io.File(localUrl));
+ logger.info("local url of upload file: " + localUrl);
+ File file = new File(name, suffix, localUrl, visitUrl, WebUtils.scriptFilter(description),
+ WebUtils.scriptFilter(tag), user.getId(), categoryId);
+ int[] auth = SettingConfig.getAuth(ConfigConsts.FILE_DEFAULT_AUTH_OF_SETTING);
+ file.setAuth(auth[0], auth[1], auth[2], auth[3], auth[4]);
+ boolean isSuccess = fileDAO.insertFile(file);
+ if (isSuccess) {
+ long fileId = fileDAO.getIdByLocalUrl(localUrl);
+ if (fileId > 0) {
+ authService.insertDefaultAuth(user.getId(), fileId);
+ }
+ } else {
+ FileExecutor.deleteFile(localUrl);
+ }
+ return isSuccess;
+ } catch (Exception e) {
+ FileExecutor.deleteFile(localUrl);
+ logger.error("save file error: " + e.getMessage());
+ }
+ }
+ }
+ return false;
+ }
+
+ private String getRegularVisitUrl(String customUrl, User user, String fileName, String suffix, Category category) {
+ Date date = new Date();
+ suffix = suffix.startsWith(".") ? "" : "." + suffix;
+ if (Checker.isNotEmpty(customUrl)) {
+ try {
+ customUrl = URLDecoder.decode(customUrl, "utf-8");
+ } catch (UnsupportedEncodingException e) {
+ logger.error(e.getMessage());
+ }
+ }
+ if (!customUrl.contains(FILE_NAME) && !customUrl.contains(RANDOM_ID)) {
+ customUrl += (customUrl.endsWith("/") ? "" : "/") + fileName;
+ }
+ customUrl = customUrl.replace(YEAR, DateUtils.getYear(date)).replace(MONTH, DateUtils.getMonth(date)).replace
+ (DAY, DateUtils.getDay(date)).replace(AUTHOR, user.getUsername()).replace(FILE_NAME, fileName)
+ .replace(CATEGORY_NAME, Checker.checkNull(Checker.isNull(category) ? "uncategorized" : category
+ .getName())).replace(RANDOM_ID, String.valueOf(RandomUtils.getRandomInteger(ValueConsts
+ .NINE_INT))).replace(FILE_SUFFIX, suffix);
+ return "/file" + (customUrl.startsWith("/") ? "" : "/") + customUrl;
+ }
+
+ @Override
+ @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor =
+ Exception.class)
+ public boolean shareFiles(String prefix, String files, User user) {
+ if (Checker.isNotEmpty(files)) {
+ String[] paths = files.split(ValueConsts.COMMA_SIGN);
+ for (String path : paths) {
+ java.io.File f = new java.io.File(path);
+ String name = f.getName();
+ String suffix = FileExecutor.getFileSuffix(name);
+ String visitUrl = getRegularVisitUrl(prefix, user, name, suffix, null);
+ if (f.exists() && f.isFile() && !localUrlExists(path) && !visitUrlExists(visitUrl)) {
+ File file = new File(name, suffix, path, visitUrl, ValueConsts.EMPTY_STRING,
+ ValueConsts.EMPTY_STRING, user.getId(),
+ categoryService.getIdByName(DefaultValues.UNCATEGORIZED));
+ file.setAuth(ValueConsts.ONE_INT, ValueConsts.ZERO_INT, ValueConsts.ZERO_INT,
+ ValueConsts.ZERO_INT, ValueConsts.ONE_INT);
+ fileDAO.insertFile(file);
+ }
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean localUrlExists(String localUrl) {
+ return fileDAO.checkLocalUrl(localUrl) > 0;
+ }
+
+ @Override
+ public boolean visitUrlExists(String visitUrl) {
+ return fileDAO.checkVisitUrl(visitUrl) > 0;
+ }
+
+ @Override
+ public long getFileId(String localUrl) {
+ try {
+ return fileDAO.getIdByLocalUrl(localUrl);
+ } catch (Exception e) {
+ return 0;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<FileBasicRecord> listBasicAll(String user, String file, String category, int offset) {
+ return (List<FileBasicRecord>) ServiceUtils.invokeFileFilter(fileDAO, "listBasicBy", user, file, category,
+ offset);
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/service/impl/UploadedServiceImpl.java b/src/main/java/com/mesasoft/cn/service/impl/UploadedServiceImpl.java
new file mode 100644
index 0000000..a02afff
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/service/impl/UploadedServiceImpl.java
@@ -0,0 +1,30 @@
+package com.mesasoft.cn.service.impl;
+
+import com.mesasoft.cn.dao.UploadedDAO;
+import com.mesasoft.cn.model.UploadedRecord;
+import com.mesasoft.cn.service.IUploadedService;
+import com.mesasoft.cn.util.ServiceUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author pantao
+ * @since 2018/2/28
+ */
+@Service
+public class UploadedServiceImpl implements IUploadedService {
+
+ private final UploadedDAO uploadedDAO;
+
+ @Autowired
+ public UploadedServiceImpl(UploadedDAO uploadedDAO) {this.uploadedDAO = uploadedDAO;}
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<UploadedRecord> list(String user, String file, String category, int offset) {
+ return (List<UploadedRecord>) ServiceUtils.invokeFileFilter(uploadedDAO, "listUploadedBy", user, file,
+ category, offset);
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/service/impl/UserServiceImpl.java b/src/main/java/com/mesasoft/cn/service/impl/UserServiceImpl.java
new file mode 100644
index 0000000..8974f95
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/service/impl/UserServiceImpl.java
@@ -0,0 +1,163 @@
+package com.mesasoft.cn.service.impl;
+
+import com.mesasoft.cn.SketchApplication;
+import com.mesasoft.cn.dao.UserDAO;
+import com.mesasoft.cn.util.BeanUtils;
+import com.mesasoft.cn.config.SettingConfig;
+import com.mesasoft.cn.config.TokenConfig;
+import com.mesasoft.cn.entity.User;
+import com.mesasoft.cn.modules.constant.ConfigConsts;
+import com.mesasoft.cn.service.IUserService;
+import com.zhazhapan.modules.constant.ValueConsts;
+import com.zhazhapan.util.Checker;
+import com.zhazhapan.util.DateUtils;
+import com.zhazhapan.util.MailSender;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+import java.util.regex.Pattern;
+
+/**
+ * @author pantao
+ * @since 2018/1/22
+ */
+@Service
+public class UserServiceImpl implements IUserService {
+
+ private final UserDAO userDAO;
+
+ private Logger logger = Logger.getLogger(UserServiceImpl.class);
+
+ @Autowired
+ public UserServiceImpl(UserDAO userDAO) {this.userDAO = userDAO;}
+
+ @Override
+ public boolean updatePermission(int id, int permission) {
+ return userDAO.updatePermission(id, permission > 2 ? 2 : permission);
+ }
+
+ @Override
+ public boolean resetPassword(int id, String password) {
+ boolean result = Checker.isNotEmpty(password) && userDAO.updatePasswordById(id, password);
+ if (result) {
+ TokenConfig.removeTokenByValue(id);
+ try {
+ MailSender.sendMail(getUserById(id).getEmail(), "密码重置通知", "您的密码已被管理员重置为:" + password);
+ } catch (Exception e) {
+ logger.error(e.getMessage());
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public boolean updateFileAuth(int id, String auths) {
+ int[] auth = BeanUtils.getAuth(auths);
+ return userDAO.updateAuthById(id, auth[0], auth[1], auth[2], auth[3], auth[4]);
+ }
+
+ @Override
+ public List<User> listUser(int permission, String condition, int offset) {
+ return userDAO.listUserBy(permission, condition, offset);
+ }
+
+ @Override
+ public User login(String loginName, String password, String token, HttpServletResponse response) {
+ boolean allowLogin = SketchApplication.settings.getBooleanUseEval(ConfigConsts.ALLOW_LOGIN_OF_SETTINGS);
+ User user = null;
+ if (allowLogin) {
+ if (Checker.isNotEmpty(token) && SketchApplication.tokens.containsKey(token)) {
+ user = userDAO.getUserById(SketchApplication.tokens.get(token));
+ if (Checker.isNotNull(response)) {
+ Cookie cookie = new Cookie(ValueConsts.TOKEN_STRING, TokenConfig.generateToken(token, user.getId
+ ()));
+ cookie.setMaxAge(30 * 24 * 60 * 60);
+ response.addCookie(cookie);
+ }
+ }
+ if (Checker.isNull(user) && Checker.isNotEmpty(loginName) && Checker.isNotEmpty(password)) {
+ user = userDAO.login(loginName, password);
+ if (Checker.isNotNull(user)) {
+ TokenConfig.removeTokenByValue(user.getId());
+ }
+ }
+ updateUserLoginTime(user);
+ }
+ return user;
+ }
+
+ @Override
+ public boolean register(String username, String email, String password) {
+ boolean allowRegister = SketchApplication.settings.getBooleanUseEval(ConfigConsts.ALLOW_REGISTER_OF_SETTINGS);
+ if (allowRegister) {
+ boolean isValid = Checker.isEmail(email) && checkPassword(password) && Pattern.compile(SketchApplication.settings
+ .getStringUseEval(ConfigConsts.USERNAME_PATTERN_OF_SETTINGS)).matcher(username).matches();
+ if (isValid) {
+ User user = new User(username, ValueConsts.EMPTY_STRING, email, password);
+ int[] auth = SettingConfig.getAuth(ConfigConsts.USER_DEFAULT_AUTH_OF_SETTING);
+ user.setAuth(auth[0], auth[1], auth[2], auth[3], auth[4]);
+ return userDAO.insertUser(user);
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean resetPasswordByEmail(String email, String password) {
+ return Checker.isEmail(email) && checkPassword(password) && userDAO.updatePasswordByEmail(password, email);
+ }
+
+ @Override
+ public boolean checkPassword(String password) {
+ int min = SketchApplication.settings.getIntegerUseEval(ConfigConsts.PASSWORD_MIN_LENGTH_OF_SETTINGS);
+ int max = SketchApplication.settings.getIntegerUseEval(ConfigConsts.PASSWORD_MAX_LENGTH_OF_SETTINGS);
+ return Checker.isLimited(password, min, max);
+ }
+
+ @Override
+ public boolean emailExists(String email) {
+ return Checker.isEmail(email) && userDAO.checkEmail(email) > 0;
+ }
+
+ @Override
+ public boolean updateBasicInfoById(int id, String avatar, String realName, String email) {
+ return Checker.isEmail(email) && userDAO.updateBasicInfo(id, Checker.checkNull(avatar), Checker.checkNull
+ (realName), email);
+ }
+
+ @Override
+ public int getUserId(String usernameOrEmail) {
+ try {
+ return userDAO.getUserId(Checker.checkNull(usernameOrEmail));
+ } catch (Exception e) {
+ return Integer.MAX_VALUE;
+ }
+ }
+
+ @Override
+ public boolean usernameExists(String username) {
+ return Checker.isNotEmpty(username) && userDAO.checkUsername(username) > 0;
+ }
+
+ @Override
+ public User getUserById(int id) {
+ return userDAO.getUserById(id);
+ }
+
+ @Override
+ public void updateUserLoginTime(User user) {
+ if (Checker.isNotNull(user)) {
+ user.setLastLoginTime(DateUtils.getCurrentTimestamp());
+ userDAO.updateUserLoginTime(user.getId());
+ }
+ }
+
+ @Override
+ public boolean updatePasswordById(String password, int id) {
+ return checkPassword(password) && userDAO.updatePasswordById(id, password);
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/sketch/api/BrightCloud.java b/src/main/java/com/mesasoft/cn/sketch/api/BrightCloud.java
new file mode 100644
index 0000000..3a51220
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/sketch/api/BrightCloud.java
@@ -0,0 +1,193 @@
+package com.mesasoft.cn.sketch.api;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.mesasoft.cn.sketch.config.ApplicationConfig;
+import com.mesasoft.cn.sketch.entity.DomainCategory;
+import com.mesasoft.cn.util.FileUtils;
+import com.mesasoft.cn.util.ValidationUtils;
+import org.apache.log4j.Logger;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+
+/**
+ * @author yjy
+ * @version 1.0
+ * @date 2021/2/22 2:37 下午
+ */
+
+public class BrightCloud {
+ private static final Logger LOG = Logger.getLogger(BrightCloud.class);
+
+ private final Integer maxObjectNum = ApplicationConfig.API_BC_MAXIMUM_QUERYNUM;
+ private final HashMap<Integer, List<String>> catId2Info = new HashMap<>();
+ private HttpURLConnection con;
+
+ public List<DomainCategory> getQueryFiles(List<String> domains){
+ JSONObject queryResults = getQueryResults(domains);
+ return responseSparse(queryResults);
+ }
+
+ // 获取json格式查询结果
+ public JSONObject getQueryResults(List<String> domains) {
+ if (domains.size()> ApplicationConfig.API_BC_MAXIMUM_QUERYNUM){
+ LOG.warn("Too many domains in a http post request, the number of fqdn/url should be no more than "
+ + ApplicationConfig.API_BC_MAXIMUM_QUERYNUM + "!");
+ }
+ JSONObject jsonRes = new JSONObject();
+ try {
+ URL url = new URL(ApplicationConfig.API_BC_URL);
+ con = (HttpURLConnection) url.openConnection();
+ con.setRequestMethod(ApplicationConfig.API_BC_METHOD);
+ con.setDoOutput(true);
+ con.setDoInput(true);
+
+ con.setRequestProperty("Content-Type", "application/json");
+
+ JSONObject param = new JSONObject();
+ param.put("oemid", ApplicationConfig.API_BC_OEMID);
+ param.put("deviceid", ApplicationConfig.API_BC_DEVICEID);
+ param.put("uid", ApplicationConfig.API_BC_UID);
+
+ param.put("queries", Collections.singletonList(ApplicationConfig.API_BC_QUERYTYPE));
+ param.put("a1cat", ApplicationConfig.API_BC_ISA1CAT);
+ param.put("reputation", ApplicationConfig.API_BC_ISREPU);
+ param.put("xml", ApplicationConfig.API_BC_ISXML); // json or xml格式
+
+ param.put("urls", domains);
+
+ //建立实际的连接
+ con.connect();
+ OutputStreamWriter writer = new OutputStreamWriter(this.con.getOutputStream(), StandardCharsets.UTF_8);
+ writer.write(param.toString());
+ writer.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ try {
+ // 获取服务端响应,通过输入流来读取URL的响应
+ InputStream is = con.getInputStream();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
+ StringBuilder sbf = new StringBuilder();
+ String strRead = null;
+ while ((strRead = reader.readLine()) != null) {
+ sbf.append(strRead);
+ sbf.append("\r\n");
+ }
+ reader.close();
+
+ jsonRes = JSONObject.parseObject(sbf.toString());
+ con.disconnect();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return jsonRes;
+ }
+
+ // json响应内容解析
+ public List<DomainCategory> responseSparse(JSONObject records){
+ List<DomainCategory> domainFiles = new ArrayList<>();
+ Boolean querySucess = records.get("status").equals(200);
+
+ if (!querySucess) {
+ System.out.print(records);
+ LOG.error("Wrong query. Query type: " + records.get("type"));
+ } else {
+ JSONArray array = records.getJSONArray("results");
+ for (int i = 0; i < array.size(); i++) {
+ JSONObject jo = array.getJSONObject(i);
+
+ // json处理
+ JSONObject queries = jo.getJSONObject("queries");
+ JSONObject getInfo = queries.getJSONObject(ApplicationConfig.API_BC_QUERYTYPE);
+
+ JSONObject cat = getInfo.getJSONArray("cats").getJSONObject(0);
+ Integer catId = cat.getInteger("catid");
+ String fqdn = jo.getString("url");
+ domainFiles.add(new DomainCategory(
+ fqdn,
+ "brightcloud",
+ querySucess,
+ ValidationUtils.getMatchPattern(fqdn),
+ getInfo.getInteger("reputation"),
+ getRepLevel(getInfo.getInteger("reputation")),
+ catId,
+ getCatInfo(catId).get(0),
+ getCatInfo(catId).get(1),
+ cat.getInteger("conf"),
+ getInfo.getBoolean("a1cat")));
+ }
+ }
+ return domainFiles;
+ }
+
+ private String getRepLevel(Integer repScore){
+ String level = null; //用str存放数据
+ if (repScore > 80){ level="Trustworthy";}
+ else if (repScore > 60){ level="Low Risk";}
+ else if (repScore > 40){ level="Moderate Risk";}
+ else if (repScore > 20){ level="Suspicious";}
+ else if (repScore > 0){ level="High Risk";}
+ return level;
+ }
+
+ // 获取类别id对应信息
+ public void geneCatInfo(){
+ if (catId2Info.size()==0){
+ JSONObject jsonObject;
+// String filePath = Objects.requireNonNull(BrightCloud.class.getClassLoader()
+// .getResource(ApplicationConfig.API_BC_CATEINFO_FILE)).getFile();
+ String filePath =ApplicationConfig.API_BC_CATEINFO_FILE;
+ String s = FileUtils.readJsonFile(filePath);
+ jsonObject = JSON.parseObject(s);
+
+ if (!(jsonObject==null)){
+ JSONObject tmp = (JSONObject) jsonObject.getJSONArray("results").get(0);
+ JSONArray catInfoArray = tmp.getJSONObject("queries").getJSONObject("getcatlist").getJSONArray("cats");
+
+ for (int i = 0; i < catInfoArray.size(); i++){
+ JSONObject keyObject = catInfoArray.getJSONObject(i);
+ List<String> value = new ArrayList<>(Arrays.asList(
+ keyObject.getString("catname"),
+ keyObject.getString("catgroup")));
+ catId2Info.put(i+1, value);
+ }
+ }
+ }
+ }
+
+ public List<String> getCatInfo(Integer catId){
+ List<String> info = Arrays.asList("", "");
+
+ if (0 < catId && catId <= 83) {
+ if (catId2Info.size()==0){
+ geneCatInfo();
+ }
+
+ info = catId2Info.get(catId);
+
+ if (info == null){
+ LOG.error("Failed at geneCatInfo function");
+ System.out.print("Failed at geneCatInfo function");
+ }
+ }
+
+ return info;
+ }
+
+ public Integer getMaxObjectNum() {
+ return maxObjectNum;
+ }
+
+ public static void main(String[] args) {
+ JSONObject queryResults = new BrightCloud().getQueryResults(Arrays.asList("baidu.com"));
+ new BrightCloud().responseSparse(queryResults);
+ }
+}
+
diff --git a/src/main/java/com/mesasoft/cn/sketch/api/ChinaZ.java b/src/main/java/com/mesasoft/cn/sketch/api/ChinaZ.java
new file mode 100644
index 0000000..1c75093
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/sketch/api/ChinaZ.java
@@ -0,0 +1,336 @@
+package com.mesasoft.cn.sketch.api;
+/*
+ * @Description:
+ * @Author: chenxu
+ * @Date: 2021-12-27 13:59:29
+ * @LastEditTime: 2021-12-29 17:05:45
+ * @LastEditors: chenxu
+ */
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.mesasoft.cn.sketch.config.ApplicationConfig;
+import com.mesasoft.cn.sketch.entity.DomainWhois;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.log4j.Logger;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.sql.Date;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+public class ChinaZ {
+ private static final Logger LOG = Logger.getLogger(ChinaZ.class);
+ private final String apiKey = ApplicationConfig.API_CHINAZ_KEY;
+
+ public List<DomainWhois> getQueryFiles(List<String> objectList) {
+ List<JSONObject> queryResults = getQueryResults(objectList);
+ return responseSparse(queryResults);
+ }
+
+ /**
+ * @Description: 站长之家单查询
+ * @Param : 域名
+ * @Return: 查询结果
+ */
+ public JSONObject getQueryResult(String domain){
+ String urlString = ApplicationConfig.API_CHINAZ_URL_SINGLE;
+ Map<String, String> params = new LinkedHashMap<String,String>();
+ params.put("key", apiKey);
+ params.put("domain", domain);
+ return whoisInfoResolve(doPost(urlString, params),domain);
+ }
+
+ /**
+ * @Description: 站长之家多域名查询
+ * @Param : 域名
+ * @Return: 查询结果
+ */
+ public List<JSONObject> getQueryResults(List<String> domainList){
+ String urlString = ApplicationConfig.API_CHINAZ_URL_SINGLE;
+ List<JSONObject> whoisInfoList = new ArrayList<>();
+ for (String s : domainList) {
+ Map<String, String> params = new LinkedHashMap<String, String>();
+ params.put("key", apiKey);
+ params.put("domain", s);
+ JSONObject r = doPost(urlString, params);
+ whoisInfoList.add(whoisInfoResolve(r, s));
+ }
+ return whoisInfoList;
+ }
+
+ public List<DomainWhois> responseSparse(List<JSONObject> records){
+ List<DomainWhois> whoisFiles = new ArrayList<>();
+
+ for(JSONObject record: records) {
+ Boolean querySucess = record.getBoolean("isSuccess");
+ if (!querySucess) {
+ LOG.error("Failed query. Query response: " + record);
+ break;
+ }
+
+ String fqdn = record.getString("domain_name");
+ String domainName = record.getString("domain_host");
+ Integer matchPattern = fqdn.equals(domainName)? 1 : 2 ;
+ String source = "chinaz";
+
+ // json处理
+ Date creatDate = null;
+ Date expiraDate = null;
+ java.util.Date tmpDate = record.getDate("domain_whois_create_time");
+ if(tmpDate!=null){
+ creatDate = new Date(tmpDate.getTime());
+ }
+ tmpDate = record.getDate("domain_whois_expiration_time");
+ if(tmpDate!=null){
+ expiraDate = new Date(tmpDate.getTime());
+ }
+ whoisFiles.add(new DomainWhois(
+ fqdn,
+ source,
+ matchPattern,
+ record.getBoolean("isSuccess"),
+ record.getString("domain_host"),
+ null,
+ creatDate,
+ expiraDate,
+ record.getString("domain_whois_email"),
+ record.getString("domain_whois_name_servers"),
+ record.getString("domain_whois_registrar"),
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ record.getString("domain_whois_phone")
+ ));
+ }
+ return whoisFiles;
+ }
+ /**
+ * @Description: 解析并重构JSON串
+ * @Param : 查询得到的“单个”JSON串
+ * @Return: 返回重构的JSON串
+ */
+ public JSONObject whoisInfoResolve(JSONObject jsonRes,String queryDomain){
+ JSONObject whoisInfo = new JSONObject(true);
+ JSONObject res = jsonRes.getJSONObject("Result");
+ if(jsonRes.get("StateCode").equals(1)){
+ whoisInfo.put("isSuccess", jsonRes.get("StateCode"));
+ whoisInfo.put("domain_name",queryDomain);
+ whoisInfo.put("domain_host", res.get("Host"));
+ whoisInfo.put("domain_whois_create_time", res.get("CreationDate"));
+ whoisInfo.put("domain_whois_expiration_time", res.get("ExpirationDate"));
+ whoisInfo.put("domain_whois_registrar", res.get("Registrar"));
+ whoisInfo.put("whois_registrar_name", res.get("ContactPerson"));
+ whoisInfo.put("domain_whois_email", res.get("Email"));
+ whoisInfo.put("domain_whois_phone", res.get("Phone"));
+ whoisInfo.put("domain_whois_name_servers", res.get("DnsServer"));
+ whoisInfo.put("domain_whois_status", res.get("DomainStatus"));
+ }else{
+ whoisInfo.put("isSuccess", jsonRes.get("StateCode"));
+ }
+ return whoisInfo;
+ }
+
+ /**
+ * @Description: 构造批量查询需要的URL
+ * @Param : 待查询域名
+ * @Return: 拼接好的URL
+ */
+ public List<String> queryStringBuilder(List<String> domainList){
+ //将域名每50个划分一组
+ int CHINAZ_REQUEST_LIMIT = 50 ;
+ int domainListSize = domainList.size();
+ int toIndex = CHINAZ_REQUEST_LIMIT;
+ Map domainListMap = new HashMap();
+ int keyToken = 0;
+ for(int i = 0;i<domainList.size();i+=CHINAZ_REQUEST_LIMIT){
+ if(i+CHINAZ_REQUEST_LIMIT>domainListSize){ //作用为toIndex最后没有50条数据则剩余几条newList中就装几条
+ toIndex=domainListSize-i;
+ }
+ List<String> newList = domainList.subList(i,i+toIndex);
+ domainListMap.put("keyName"+keyToken, newList);
+ keyToken++;
+ }
+ //将批量查询的域名,构造成CHINAZ的格式
+ List<String> domainListString = new ArrayList<>();
+ Iterator iter = domainListMap.entrySet().iterator();
+ while (iter.hasNext()) {
+ Map.Entry entry = (Map.Entry) iter.next();
+ Object key = entry.getKey();
+ Object val = entry.getValue();
+ String urlString = "";
+ urlString = String.valueOf(val);
+ urlString = urlString.replace(", ","|");
+ urlString =urlString.replace("[","").replace("]","");
+ domainListString.add(urlString);
+ }
+ return domainListString;
+ }
+
+ /**
+ * @Description: 站长之家批量查询-批量提交查询请求,并获得提取任务ID
+ * @Param : 域名集合(不能超过50个)
+ * @Return: 查询结果
+ */
+ public String batchRequest_step1(String domainsString){
+ String TaskID = "";
+ String urlString = ApplicationConfig.API_CHINAZ_URL_BATCH;
+
+ Map<String, String> params = new LinkedHashMap<String,String>();
+ if (!Objects.equals(domainsString, "overflow")){
+ params.put("domains",domainsString);
+ params.put("key", apiKey);
+ JSONObject r = doPost(urlString, params);
+ TaskID = r.get("TaskID").toString();
+ return TaskID;
+ }else{
+ return TaskID;
+ }
+
+ }
+
+ /**
+ * @Description: 站长之家查询-根据提取任务ID查询数据是否采集完成,如果完成则得到Json格式结果
+ * @Param : 任务ID
+ * @Return: 查询结果
+ */
+ public JSONObject batchRequest_step2(String TaskID){
+ String urlString = ApplicationConfig.API_CHINAZ_URL_BATCH;
+
+ Map<String, String> params = new LinkedHashMap<String,String>();
+ params.put("taskid",TaskID);
+ JSONObject requestTotal = null;
+ requestTotal = doPost(urlString, params);
+ return requestTotal;
+ }
+
+ /**
+ * @Description: 完成如下内容:1)将domain拼接成50个一组;2)调用step_1的API上传数据;3)调用step_2的API获取数据;4)格式整理,输出数据
+ * @Param : 域名列表
+ * @Return: whois记录列表
+ */
+ public List<String> batchRequestController(List<String> domainList){
+
+ List<String> result = new ArrayList<>();
+ if (domainList.size()> 5000){
+ System.out.println("Too many urls in a http post request!");
+ }
+ List<String> domainListString = new ArrayList<>();
+ List<String> TaskID = new ArrayList<>();
+
+
+ // Queue<String> queue = new LinkedList<String>();
+ domainListString = queryStringBuilder(domainList);
+ //循环发送请求,收集每个请求的TaskID
+ for (String domainParam : domainListString) {
+ TaskID.add(batchRequest_step1(domainParam));
+ }
+
+ for (String s : TaskID) {
+ int flag = 0;
+ //查询接口数据,如果API仍在查询中,则等待10秒继续访问
+ while (flag == 0) {
+ JSONObject data = batchRequest_step2(s);
+ if (data.get("StateCode").equals(0)) {
+ long timeToSleep = 10L;
+ TimeUnit time = TimeUnit.SECONDS;
+ try {
+ time.sleep(timeToSleep);
+ } catch (InterruptedException e) {
+ System.out.println("Interrupted " + "while Sleeping");
+ }
+ } else {
+ flag = 1;
+
+ JSONObject json_result = data.getJSONObject("Result");
+
+ JSONArray json_data = json_result.getJSONArray("Data");
+ // //对Data内部的数据进行遍历
+ for (int j = 0; j < json_data.size(); j++) {
+ String queryDomain = (String) json_data.getJSONObject(j).get("Domain");
+ result.add(whoisInfoResolve(json_data.getJSONObject(j), queryDomain).toJSONString());
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * @Description: POST调用API数据
+ * @Param : 请求对URL,POST请求体需要添加的 k-v 数据
+ * @Return: API JSON数据
+ */
+ public JSONObject doPost(String url, Map params){
+ JSONObject jsonRes = null;
+ try {
+ // 定义HttpClient
+ CloseableHttpClient client = HttpClients.createDefault();
+ // 实例化HTTP方法
+ HttpPost request = new HttpPost();
+ request.setURI(new URI(url));
+
+ //设置参数
+ List<NameValuePair> nvps = new ArrayList<NameValuePair>();
+ for (Object o : params.keySet()) {
+ String name = (String) o;
+ String value = String.valueOf(params.get(name));
+ nvps.add(new BasicNameValuePair(name, value));
+
+ //System.out.println(name +"-"+value);
+ }
+ request.setEntity(new UrlEncodedFormEntity(nvps));
+ //发送请求
+ HttpResponse httpResponse = client.execute(request);
+ // 获取响应输入流
+ InputStream inStream = httpResponse.getEntity().getContent();
+ //对放回数据进行处理
+ BufferedReader reader = new BufferedReader(new InputStreamReader(inStream , StandardCharsets.UTF_8));
+ StringBuilder strber = new StringBuilder();
+ StringBuilder sbf = new StringBuilder();
+ String strRead = null;
+ while ((strRead = reader.readLine()) != null) {
+ sbf.append(strRead);
+ sbf.append("\r\n");
+ }
+ // 关闭输入流
+ inStream.close();
+ jsonRes = JSONObject.parseObject(sbf.toString());
+ }catch (Exception e) {
+ System.out.println("请求接口异常");
+ }
+ return jsonRes;
+ }
+
+
+ public static void main(String[] args){
+ ChinaZ t = new ChinaZ();
+
+ //单查询测试
+// System.out.println(t.singleRequest("aaa.baidu.com"));
+
+ //批量查询测试
+ List<String> domainList = new ArrayList<>();
+ domainList.add("www.baidu.com");
+// domainList.add("aaa.qq.com");
+// domainList.add("doc.mesalab.com");
+
+// System.out.println(t.batchRequestController(domainList));
+ System.out.println(t.getQueryResults(domainList));
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/sketch/config/ApplicationConfig.java b/src/main/java/com/mesasoft/cn/sketch/config/ApplicationConfig.java
new file mode 100644
index 0000000..099205e
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/sketch/config/ApplicationConfig.java
@@ -0,0 +1,54 @@
+package com.mesasoft.cn.sketch.config;
+
+
+import com.mesasoft.cn.util.ConfigUtils;
+
+public class ApplicationConfig {
+ public static final String QUERY_OUTPUT_DIR = ConfigUtils.getStringProperty("query.output.dir");
+
+ public static final String QUERY_TYPES_DOMAIN = ConfigUtils.getStringProperty("query.types.domain");
+ public static final String QUERY_TYPES_IP = ConfigUtils.getStringProperty("query.types.ip");
+
+ public static final Integer UPDATE_EXPIRED_DAY = ConfigUtils.getIntProperty("update.expired.day"); // 更新任务中过期时间长度(天数)
+
+ public static final Integer QUERY_READIN_BATCH = ConfigUtils.getIntProperty("query.readin.batch");
+ public static final Integer QUERY_LOG_FILE_LINE_INTERVAL = ConfigUtils.getIntProperty("query.log.file.line.interval"); // 文件查询时,打印log的读取行数间隔
+
+ // api参数
+ // brightcloud
+ public static final String API_BC_OEMID = ConfigUtils.getStringProperty("bc.oemid");
+ public static final String API_BC_DEVICEID = ConfigUtils.getStringProperty("bc.deviceid");
+ public static final String API_BC_UID = ConfigUtils.getStringProperty("bc.uid");
+ public static final String API_BC_URL = ConfigUtils.getStringProperty("bc.url");
+ public static final String API_BC_METHOD = ConfigUtils.getStringProperty("bc.method");
+
+ public static final String API_BC_ISA1CAT = ConfigUtils.getStringProperty("bc.isa1cat");
+ public static final String API_BC_ISREPU = ConfigUtils.getStringProperty("bc.isReputation");
+ public static final String API_BC_ISXML = ConfigUtils.getStringProperty("bc.isxml");
+
+
+ public static final Integer API_BC_MAXIMUM_QUERYNUM = ConfigUtils.getIntProperty("bc.maximum.query.num"); // brightcloud单次查询条数上线
+ public static final String API_BC_QUERYTYPE = ConfigUtils.getStringProperty("bc.queryType");
+
+ public static final String API_BC_USE_REPORT_FILE = ConfigUtils.getStringProperty("bc.usereport.filepath"); // brightcloud使用报告导出文件目录
+ public static final String API_BC_CATEINFO_FILE = ConfigUtils.getStringProperty("bc.cateinfo.filepath"); // brightcloud使用报告导出文件目录
+
+
+ // chinaz
+ public static final String API_CHINAZ_URL_SINGLE = ConfigUtils.getStringProperty("chinaz.url.single");
+ public static final String API_CHINAZ_URL_BATCH = ConfigUtils.getStringProperty("chinaz.url.batch");
+ public static final String API_CHINAZ_KEY = ConfigUtils.getStringProperty("chinaz.key");
+ public static final Integer API_CHINAZ_MAXIMUM_QUERYNUM = ConfigUtils.getIntProperty("chinaz.maximum.query.num");
+ public static final String API_CHINAZ_USE_REPORT_FILE = ConfigUtils.getStringProperty("chinaz.usereport.filepath");
+
+ // Mariadb
+ public static final String DATABASE = ConfigUtils.getStringProperty("database");
+ public static final String DOMAIN_CATE_TABLENAME = ConfigUtils.getStringProperty("tablename.domain.category");
+ public static final String DOMAIN_WHOIS_TABLENAME = ConfigUtils.getStringProperty("tablename.domain.whois");
+ public static final String DNS_SERVER_TABLENAME = ConfigUtils.getStringProperty("tablename.dns.server");
+ public static final Integer DB_QUERY_BATCH_SIZE = ConfigUtils.getIntProperty("db.query.batch.size");
+
+ // 其他
+ public static final String TLD_FILE = ConfigUtils.getStringProperty("tld.file"); // 顶级域名公开列表文件
+
+}
diff --git a/src/main/java/com/mesasoft/cn/sketch/config/MariaDbBase.java b/src/main/java/com/mesasoft/cn/sketch/config/MariaDbBase.java
new file mode 100644
index 0000000..ba617ce
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/sketch/config/MariaDbBase.java
@@ -0,0 +1,84 @@
+package com.mesasoft.cn.sketch.config;
+
+import com.mesasoft.cn.util.TimeUtils;
+import org.apache.log4j.Logger;
+
+import java.sql.*;
+import java.util.Date;
+import java.util.Properties;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: joy
+ * Date: 2021/12/28
+ * Time: 2:56 PM
+ * Description: No Description
+ */
+public class MariaDbBase {
+
+ private static final Logger LOG = Logger.getLogger(MariaDbBase.class);
+ private static final Properties props = new Properties();
+
+ private final Statement statement;
+
+ public MariaDbBase(Connection conn, Statement stat) {
+ statement = stat;
+ }
+
+ /**
+ * 执行写入sql
+ */
+ public void writeSqlExecute(String sql){
+ try {
+ statement.executeUpdate(sql);
+ } catch (SQLIntegrityConstraintViolationException e){
+ LOG.error("Duplicated entry for key 'PRIMARY'");
+ } catch (SQLException exception) {
+ LOG.error("Sql : " + sql);
+ exception.printStackTrace();
+ }
+ }
+
+ /**
+ * 执行查询sql
+ */
+ public ResultSet querySqlExecute(String sql){
+ ResultSet set = null;
+ try {
+ set = statement.executeQuery(sql);
+ } catch (SQLException exception) {
+ exception.printStackTrace();
+ }
+ return set;
+ }
+
+
+ /**
+ * 获得指定表格、按指定时间字段的过期记录
+ * @param tableName 库表名称
+ * @param timeColumnName 时间列名
+ * @return 查询结果
+ */
+ public ResultSet getExpiredRecord(String tableName, String timeColumnName){
+ Date lastUpdateTime = new Timestamp(getExpiredTime(ApplicationConfig.UPDATE_EXPIRED_DAY).getTime());
+
+ String resSql = "SELECT *"
+ + " FROM " + ApplicationConfig.DATABASE + "." + tableName
+ + " WHERE " + timeColumnName + " < '" + lastUpdateTime + '\'';
+
+ LOG.debug("Update task: expired query sql" + resSql);
+
+ return querySqlExecute(resSql);
+ }
+
+ /**
+ * TODO: getUnlabeledRecord() 考虑多个来源的情况
+ */
+
+ /**
+ * 获得过期时间, 当前时间的expiredRangeDays天之前的日期为过期日期
+ */
+ public static Date getExpiredTime(int expiredRangeDays){
+ return new Timestamp(TimeUtils.getStartOfDay(-expiredRangeDays).getTime());
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/sketch/config/SketchDatabaseConfig.java b/src/main/java/com/mesasoft/cn/sketch/config/SketchDatabaseConfig.java
new file mode 100644
index 0000000..dc69bbd
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/sketch/config/SketchDatabaseConfig.java
@@ -0,0 +1,125 @@
+//package com.zhazhapan.efo.sketch.config;
+//
+//import com.alibaba.druid.pool.DruidDataSource;
+//import lombok.Data;
+//import org.apache.ibatis.session.SqlSessionFactory;
+//import org.mybatis.spring.SqlSessionFactoryBean;
+//import org.mybatis.spring.annotation.MapperScan;
+//import org.springframework.beans.factory.annotation.Qualifier;
+//import org.springframework.beans.factory.annotation.Value;
+//import org.springframework.boot.context.properties.ConfigurationProperties;
+//import org.springframework.context.annotation.Bean;
+//import org.springframework.context.annotation.Configuration;
+//import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+//import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+//
+//import javax.sql.DataSource;
+//import java.sql.SQLException;
+//
+///**
+// * @ProjectName
+// * @Description: 后台数据源配置类
+// */
+//@Data
+//@Configuration
+//@ConfigurationProperties(prefix = "sketch.datasource.druid")
+//@MapperScan(basePackages = SketchDatabaseConfig.PACKAGE, sqlSessionFactoryRef = "sketchSqlSessionFactory")
+//public class SketchDatabaseConfig {
+// /**
+// * dao层的包路径
+// */
+// static final String PACKAGE = "com.mao.mysqlhive.demomh.mapper.sketch";
+//
+// /**
+// * mapper文件的相对路径
+// */
+// private static final String MAPPER_LOCATION = "classpath:mappers/sketch/*Mapper.xml";
+//
+// @Value("${sketch.datasource.druid.filters}")
+// private String filters;
+// @Value("${sketch.datasource.druid.driverClassName}")
+// private String url;
+// @Value("${sketch.datasource.druid.url}")
+// private String username;
+// @Value("${sketch.datasource.druid.username}")
+// private String password;
+// @Value("${sketch.datasource.druid.password}")
+// private String driverClassName;
+// @Value("${sketch.datasource.druid.initialSize}")
+// private int initialSize;
+// @Value("${sketch.datasource.druid.minIdle}")
+// private int minIdle;
+// @Value("${sketch.datasource.druid.maxActive}")
+// private int maxActive;
+// @Value("${sketch.datasource.druid.maxWait}")
+// private long maxWait;
+// @Value("${sketch.datasource.druid.timeBetweenEvictionRunsMillis}")
+// private long timeBetweenEvictionRunsMillis;
+// @Value("${sketch.datasource.druid.minEvictableIdleTimeMillis}")
+// private long minEvictableIdleTimeMillis;
+// @Value("${sketch.datasource.druid.validationQuery}")
+// private String validationQuery;
+// @Value("${sketch.datasource.druid.testWhileIdle}")
+// private boolean testWhileIdle;
+// @Value("${sketch.datasource.druid.testOnBorrow}")
+// private boolean testOnBorrow;
+// @Value("${sketch.datasource.druid.testOnReturn}")
+// private boolean testOnReturn;
+// @Value("${sketch.datasource.druid.poolPreparedStatements}")
+// private boolean poolPreparedStatements;
+// @Value("${sketch.datasource.druid.maxPoolPreparedStatementPerConnectionSize}")
+// private int maxPoolPreparedStatementPerConnectionSize;
+//
+//
+// @Bean(name = "sketchDataSource")
+// public DataSource sketchDataSource() throws SQLException {
+// DruidDataSource druid = new DruidDataSource();
+// // 监控统计拦截的filters
+// druid.setFilters(filters);
+//
+// // 配置基本属性
+// druid.setDriverClassName(driverClassName);
+// druid.setUsername(username);
+// druid.setPassword(password);
+// druid.setUrl(url);
+//
+// //初始化时建立物理连接的个数
+// druid.setInitialSize(initialSize);
+// //最大连接池数量
+// druid.setMaxActive(maxActive);
+// //最小连接池数量
+// druid.setMinIdle(minIdle);
+// //获取连接时最大等待时间,单位毫秒。
+// druid.setMaxWait(maxWait);
+// //间隔多久进行一次检测,检测需要关闭的空闲连接
+// druid.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
+// //一个连接在池中最小生存的时间
+// druid.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
+// //用来检测连接是否有效的sql
+// druid.setValidationQuery(validationQuery);
+// //建议配置为true,不影响性能,并且保证安全性。
+// druid.setTestWhileIdle(testWhileIdle);
+// //申请连接时执行validationQuery检测连接是否有效
+// druid.setTestOnBorrow(testOnBorrow);
+// druid.setTestOnReturn(testOnReturn);
+// //是否缓存preparedStatement,也就是PSCache,oracle设为true,mysql设为false。分库分表较多推荐设置为false
+// druid.setPoolPreparedStatements(poolPreparedStatements);
+// // 打开PSCache时,指定每个连接上PSCache的大小
+// druid.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
+// return druid;
+// }
+//
+// @Bean(name = "sketchTransactionManager")
+// public DataSourceTransactionManager sketchTransactionManager() throws SQLException {
+// return new DataSourceTransactionManager(sketchDataSource());
+// }
+//
+// @Bean(name = "sketchSqlSessionFactory")
+// public SqlSessionFactory sketchSqlSessionFactory(@Qualifier("sketchDataSource") DataSource sketchDataSource) throws Exception {
+// final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
+// sessionFactory.setDataSource(sketchDataSource);
+// sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(SketchDatabaseConfig.MAPPER_LOCATION));
+//
+// return sessionFactory.getObject();
+// }
+//}
diff --git a/src/main/java/com/mesasoft/cn/sketch/controller/SketchDomainController.java b/src/main/java/com/mesasoft/cn/sketch/controller/SketchDomainController.java
new file mode 100644
index 0000000..736a5be
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/sketch/controller/SketchDomainController.java
@@ -0,0 +1,54 @@
+package com.mesasoft.cn.sketch.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.mesasoft.cn.annotation.AuthInterceptor;
+import com.mesasoft.cn.enums.InterceptorLevel;
+import com.mesasoft.cn.service.IFileManagerService;
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * @description:
+ * @author: zhq
+ * @create: 2022-03-10
+ **/
+@RestController
+@RequestMapping("/sketch/domain")
+@Api(value = "/sketch/domain", description = "文件相关操作")
+@Slf4j
+public class SketchDomainController {
+
+ private final IFileManagerService fileManagerService;
+ private final HttpServletRequest request;
+ private JSONObject jsonObject;
+
+ @Value("${sketch.path.admin}")
+ private String pathAdmin;
+ @Value("${sketch.path.user}")
+ private String pathUser;
+
+ @Autowired
+ public SketchDomainController(HttpServletRequest request, IFileManagerService fileManagerService, JSONObject jsonObject) {
+ this.fileManagerService = fileManagerService;
+ this.jsonObject = jsonObject;
+ this.request = request;
+ }
+
+ @AuthInterceptor(InterceptorLevel.USER)
+ @RequestMapping(value = "/list", method = RequestMethod.GET)
+ public String list(String searchPath) {
+
+ log.info("search path :", searchPath);
+
+
+ return jsonObject.toJSONString();
+ }
+
+}
diff --git a/src/main/java/com/mesasoft/cn/sketch/controller/SketchFileController.java b/src/main/java/com/mesasoft/cn/sketch/controller/SketchFileController.java
new file mode 100644
index 0000000..b9c9ba1
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/sketch/controller/SketchFileController.java
@@ -0,0 +1,93 @@
+package com.mesasoft.cn.sketch.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.mesasoft.cn.annotation.AuthInterceptor;
+import com.mesasoft.cn.entity.User;
+import com.mesasoft.cn.enums.InterceptorLevel;
+import com.mesasoft.cn.service.IFileManagerService;
+import com.mesasoft.cn.util.ControllerUtils;
+import com.zhazhapan.modules.constant.ValueConsts;
+import com.zhazhapan.util.ArrayUtils;
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * @description:
+ * @author: zhq
+ * @create: 2022-03-10
+ **/
+@RestController
+@RequestMapping("/sketch")
+@Api(value = "/sketch", description = "文件相关操作")
+@Slf4j
+public class SketchFileController {
+
+ private final IFileManagerService fileManagerService;
+ private final HttpServletRequest request;
+ private JSONObject jsonObject;
+
+ @Value("${sketch.path.admin}")
+ private String pathAdmin;
+ @Value("${sketch.path.user}")
+ private String pathUser;
+
+ @Autowired
+ public SketchFileController(HttpServletRequest request, IFileManagerService fileManagerService, JSONObject jsonObject) {
+ this.fileManagerService = fileManagerService;
+ this.jsonObject = jsonObject;
+ this.request = request;
+ }
+
+ @AuthInterceptor(InterceptorLevel.USER)
+ @RequestMapping(value = "/list", method = RequestMethod.GET)
+ public String list(String searchPath) {
+
+ log.info("search path :", searchPath);
+
+ User user = (User) request.getSession().getAttribute(ValueConsts.USER_STRING);
+ JSONObject json = new JSONObject();
+ String rootPath = "";
+ if ("system".equals(user.getUsername())) {
+ rootPath = pathAdmin;
+ } else {
+ rootPath = pathUser;
+ }
+ searchPath = searchPath.replace("\\\\", "");
+ searchPath = searchPath.replace("//", "");
+ if (StringUtils.isNotBlank(searchPath) && !rootPath.contains(searchPath)) {
+ json.fluentPut("path", searchPath);
+ } else {
+ json.fluentPut("path", rootPath);
+ }
+ //返回结果
+ jsonObject.put("path", json.getString("path"));
+ jsonObject.put("result", fileManagerService.list(json));
+ return jsonObject.toJSONString();
+ }
+
+ @RequestMapping(value = "/upload", method = RequestMethod.POST)
+ public String upload(String destination, MultipartHttpServletRequest request) {
+ Map<String, MultipartFile> fileMap = request.getFileMap();
+ MultipartFile[] files = ArrayUtils.mapToArray(fileMap, MultipartFile.class);
+ jsonObject.put("result", fileManagerService.upload(destination, files));
+ return jsonObject.toJSONString();
+ }
+
+ @RequestMapping(value = "/download", method = RequestMethod.GET)
+ public void download(HttpServletRequest request, HttpServletResponse response, String path) throws IOException, ClassNotFoundException {
+ ControllerUtils.loadResource2(response, path, ValueConsts.TRUE);
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/sketch/dao/SketchDAO.java b/src/main/java/com/mesasoft/cn/sketch/dao/SketchDAO.java
new file mode 100644
index 0000000..0473403
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/sketch/dao/SketchDAO.java
@@ -0,0 +1,81 @@
+package com.mesasoft.cn.sketch.dao;
+
+import com.mesasoft.cn.sketch.dao.sqlprovider.SketchSqlProvider;
+import com.mesasoft.cn.sketch.entity.DomainCategory;
+import com.mesasoft.cn.dao.sqlprovider.UserSqlProvider;
+import org.apache.ibatis.annotations.*;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface SketchDAO {
+
+ /**
+ * 通过域名查询
+ */
+ @Select("select * from domain_category_reputation where fqdn=#{fqdn}")
+ DomainCategory getDomainCategoryByFqdn(String usernameOrEmail);
+
+ /**
+ * 获取列表
+ *
+ * @return {@link List}
+ */
+ @SelectProvider(type = SketchSqlProvider.class, method = "getDomainCategoryListBy")
+ List<DomainCategory> getDomainCategoryList(@Param("condition") String condition, @Param("offset") int offset);
+
+
+ /**
+ * 添加一个用户
+ *
+ * @param domainCategory {@link DomainCategory}
+ * @return 是否插入成功
+ */
+ @Insert("insert into domain_category_reputation(username,real_name,email,password,is_downloadable,is_uploadable,is_deletable," +
+ "is_updatable,is_visible) values(#{username},#{realName},#{email},sha2(#{password},256)," +
+ "#{isDownloadable},#{isUploadable},#{isDeletable},#{isUpdatable},#{isVisible})")
+ boolean insertDomainCategory(DomainCategory domainCategory);
+
+ /**
+ * 通过ID更新用户基本信息
+ *
+ * @param id 编号
+ * @param avatar 头像
+ * @param realName 真实姓名
+ * @param email 邮箱
+ * @return 是否更新成功
+ */
+ @Update("update user set avatar=#{avatar},real_name=#{realName},email=#{email} where id=#{id}")
+ boolean updateBasicInfo(@Param("id") int id, @Param("avatar") String avatar, @Param("realName") String realName,
+ @Param("email") String email);
+
+
+
+ /**
+ * 通过id更新用户登录时间
+ *
+ * @param id 编号
+ * @return {@link Boolean}
+ */
+ @Update("update user set last_login_time=current_timestamp where id=#{id}")
+ boolean updateUserLoginTime(int id);
+
+ /**
+ * 更新操作用户权限
+ *
+ * @param id 用户编号
+ * @param isDownloadable 下载权限
+ * @param isUploadable 上传权限
+ * @param isVisible 可查权限
+ * @param isDeletable 删除权限
+ * @param isUpdatable 更新权限
+ * @return {@link Boolean}
+ */
+ @UpdateProvider(type = UserSqlProvider.class, method = "updateAuthById")
+ boolean updateAuthById(@Param("id") int id, @Param("isDownloadable") int isDownloadable,
+ @Param("isUploadable") int isUploadable, @Param("isDeletable") int isDeletable, @Param(
+ "isUpdatable") int isUpdatable, @Param("isVisible") int isVisible);
+
+
+}
diff --git a/src/main/java/com/mesasoft/cn/sketch/dao/sqlprovider/SketchSqlProvider.java b/src/main/java/com/mesasoft/cn/sketch/dao/sqlprovider/SketchSqlProvider.java
new file mode 100644
index 0000000..53e24a2
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/sketch/dao/sqlprovider/SketchSqlProvider.java
@@ -0,0 +1,27 @@
+package com.mesasoft.cn.sketch.dao.sqlprovider;
+
+import com.mesasoft.cn.SketchApplication;
+import com.mesasoft.cn.modules.constant.ConfigConsts;
+import com.zhazhapan.util.Checker;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.jdbc.SQL;
+
+/**
+ * @author pantao
+ * @since 2018/1/19
+ */
+public class SketchSqlProvider {
+
+ public String getDomainCategoryListBy(@Param("condition") String condition, @Param("offset") int offset) {
+ String sql = new SQL() {{
+ SELECT("*");
+ FROM("domain_category_reputation");
+ if (Checker.isNotEmpty(condition)) {
+ WHERE("fqdn like '%" + condition + "'");
+ }
+ ORDER_BY(SketchApplication.settings.getStringUseEval(ConfigConsts.USER_ORDER_BY_OF_SETTINGS));
+ }}.toString();
+ int size = SketchApplication.settings.getIntegerUseEval(ConfigConsts.USER_PAGE_SIZE_OF_SETTINGS);
+ return sql + " limit " + (offset * size) + "," + size;
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/sketch/entity/DomainCategory.java b/src/main/java/com/mesasoft/cn/sketch/entity/DomainCategory.java
new file mode 100644
index 0000000..dbcfdc1
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/sketch/entity/DomainCategory.java
@@ -0,0 +1,340 @@
+package com.mesasoft.cn.sketch.entity;
+
+import com.alibaba.fastjson.JSONObject;
+import com.mesasoft.cn.util.ConfigUtils;
+import com.mesasoft.cn.sketch.config.ApplicationConfig;
+import com.mesasoft.cn.util.MariaDbBase;
+import com.mesasoft.cn.util.ValidationUtils;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: joy
+ * Date: 2021/12/29
+ * Time: 9:27 AM
+ * Description: No Description
+ */
+public class DomainCategory {
+ private static final String dataBase = ApplicationConfig.DATABASE;
+ private static final String tableName = ApplicationConfig.DOMAIN_CATE_TABLENAME;
+
+ private String fqdn;
+ private String source;
+ private Boolean query_success;
+ private Integer match_pattern;
+ private Integer reputation_score;
+ private String reputation_level;
+ private Integer category_id;
+ private String category_name;
+ private String category_group;
+ private Integer category_conf;
+ private Boolean is_a1_cat;
+ private Integer status_code = 0;
+ private String submit_user ="''";
+
+
+ // category schema
+ public DomainCategory(String fqdn,
+ String source,
+ Boolean query_success,
+ Integer match_pattern,
+ Integer reputation_score,
+ String reputationLevel,
+ Integer categoryId,
+ String categoryName,
+ String categoryGroup,
+ Integer categoryConf,
+ Boolean isA1Cat, Integer statusCode, String submitUser) {
+
+ this.fqdn = fqdn;
+ this.source = source; // 默认应为为brightcloud
+ this.query_success = query_success;
+
+ // 没有设置match_pattern,则二级域名为右匹配,其余为全匹配
+ if (match_pattern == null) {
+ this.match_pattern = ValidationUtils.getMatchPattern(fqdn);
+ } else {
+ this.match_pattern = match_pattern;
+ }
+
+ this.reputation_score = reputation_score;
+ this.reputation_level = ConfigUtils.getEffectiveString(reputationLevel);
+ this.category_id = categoryId;
+ this.category_name = ConfigUtils.getEffectiveString(categoryName);
+ this.category_group = ConfigUtils.getEffectiveString(categoryGroup);
+ this.category_conf = categoryConf;
+ this.is_a1_cat = isA1Cat;
+ this.status_code = statusCode;
+ this.submit_user = submitUser;
+
+ }
+ public DomainCategory(String fqdn,
+ String source,
+ Boolean query_success,
+ Integer match_pattern,
+ Integer reputation_score,
+ String reputationLevel,
+ Integer categoryId,
+ String categoryName,
+ String categoryGroup,
+ Integer categoryConf,
+ Boolean isA1Cat) {
+
+ this.fqdn = fqdn;
+ this.source = source; // 默认应为为brightcloud
+ this.query_success = query_success;
+
+ // 没有设置match_pattern,则二级域名为右匹配,其余为全匹配
+ if (match_pattern == null) {
+ this.match_pattern = ValidationUtils.getMatchPattern(fqdn);
+ } else {
+ this.match_pattern = match_pattern;
+ }
+
+ this.reputation_score = reputation_score;
+ this.reputation_level = ConfigUtils.getEffectiveString(reputationLevel);
+ this.category_id = categoryId;
+ this.category_name = ConfigUtils.getEffectiveString(categoryName);
+ this.category_group = ConfigUtils.getEffectiveString(categoryGroup);
+ this.category_conf = categoryConf;
+ this.is_a1_cat = isA1Cat;
+
+ }
+ public static void insertRecords(List<DomainCategory> categoryFiles, MariaDbBase mariaDbBase) {
+ for (DomainCategory categoryFile : categoryFiles) {
+ // 生成sql
+ String resSql = "INSERT INTO " + dataBase + "." + tableName + ' ' +
+ " (" + categoryFile.getKeys() + ") values" +
+ '(' + categoryFile.getValues() + ')';
+ resSql = resSql.replace("'null'", "null");
+
+ mariaDbBase.writeSqlExecute(resSql);
+ }
+ }
+
+ public void updateRecords(List<DomainCategory> categoryFiles, MariaDbBase mariaDbBase) {
+ for (DomainCategory categoryFile : categoryFiles) {
+
+ String resSql = "UPDATE " + dataBase + "." +
+ tableName + ' ' +
+ "SET " + categoryFile.getKeyValues() +
+ ", update_time = current_time() " +
+ " WHERE fqdn = '" + categoryFile.getFqdn() + '\'';
+ resSql = resSql.replace("'null'", "null");
+
+ mariaDbBase.writeSqlExecute(resSql);
+ }
+ }
+
+ public static List<DomainCategory> getDbRecord(List<String> fqdns, MariaDbBase mariaDbBase, String source) throws SQLException {
+ String queryFqdns = fqdns.stream().map(s -> "'" + s + "'").collect(Collectors.joining(","));
+ String sql = "SELECT * FROM " + dataBase + "." +
+ tableName + ' ' +
+ " WHERE fqdn in (" + queryFqdns + ") and source = '" + source + "'";
+
+ return rs2schema(mariaDbBase.querySqlExecute(sql));
+ }
+
+ public static List<DomainCategory> rs2schema(ResultSet rs) throws SQLException {
+ List<DomainCategory> schemaFiles = new ArrayList<>();
+ while (rs.next()) {
+ schemaFiles.add(
+ new DomainCategory(
+ rs.getString("fqdn"),
+ rs.getString("source"),
+ rs.getBoolean("query_success"),
+ rs.getInt("match_pattern"),
+ rs.getInt("reputation_score"),
+ rs.getString("reputation_level"),
+ rs.getInt("category_id"),
+ rs.getString("category_name"),
+ rs.getString("category_group"),
+ rs.getInt("category_conf"),
+ rs.getBoolean("is_a1_cat"),
+ rs.getInt("status_code"),
+ rs.getString("submit_user")
+
+ ));
+ }
+ return schemaFiles;
+ }
+
+ public static JSONObject schema2json(DomainCategory schema) throws SQLException {
+ JSONObject jsonObject = new JSONObject(true);
+ jsonObject.put("fqdn", schema.getFqdn());
+ jsonObject.put("source", schema.getSource());
+ jsonObject.put("query_success", schema.getQuery_success());
+ jsonObject.put("match_pattern", schema.getMatch_pattern());
+ jsonObject.put("reputation_score", schema.getReputation_score());
+ jsonObject.put("reputation_level", schema.getReputation_level());
+ jsonObject.put("category_id", schema.getCategory_id());
+ jsonObject.put("category_group", schema.getCategory_group());
+ jsonObject.put("category_name", schema.getCategory_name());
+ jsonObject.put("category_conf", schema.getCategory_conf());
+ jsonObject.put("is_a1_cat", schema.getIs_a1_cat());
+ jsonObject.put("status_code", schema.getStatus_code());
+ jsonObject.put("submit_user", schema.getSubmit_user());
+
+ return jsonObject;
+ }
+
+ public String getValues() {
+ String resString = "'" + fqdn + '\'' +
+ ", '" + source + '\'' +
+ ", " + query_success +
+ ", " + match_pattern +
+ ", " + reputation_score +
+ ", '" + reputation_level + '\'' +
+ ", " + category_id +
+ ", '" + category_name + '\'' +
+ ", '" + category_group + '\'' +
+ ", " + category_conf +
+ ", " + status_code +
+ ", " + submit_user +
+ ", " + is_a1_cat;
+
+ return resString.replace("'null'", "null");
+ }
+
+ public String getKeys() {
+ String resString;
+ resString = "fqdn" +
+ ", source" +
+ ", query_success" +
+ ", match_pattern" +
+ ", reputation_score" +
+ ", reputation_level" +
+ ", category_id" +
+ ", category_name" +
+ ", category_group" +
+ ", category_conf" +
+ ", status_code" +
+ ", submit_user" +
+ ", is_a1_cat";
+ return resString;
+ }
+
+ public String getKeyValues() {
+ String resString = "source='" + source + '\'' +
+ ", query_success=" + query_success +
+ ", match_pattern=" + match_pattern +
+ ", reputation_score=" + reputation_score +
+ ", reputation_level='" + reputation_level + '\'' +
+ ", category_id=" + category_id +
+ ", category_name='" + category_name + '\'' +
+ ", category_group='" + category_group + '\'' +
+ ", category_conf=" + category_conf +
+ ", is_a1_cat=" + is_a1_cat;
+
+ return resString.replace("'null'", "null");
+ }
+
+ public String getFqdn() {
+ return fqdn;
+ }
+
+ public void setFqdn(String fqdn) {
+ this.fqdn = fqdn;
+ }
+
+ public String getSource() {
+ return source;
+ }
+
+ public void setSource(String source) {
+ this.source = source;
+ }
+
+ public Boolean getQuery_success() {
+ return query_success;
+ }
+
+ public void setQuery_success(Boolean query_success) {
+ this.query_success = query_success;
+ }
+
+ public Integer getMatch_pattern() {
+ return match_pattern;
+ }
+
+ public void setMatch_pattern(Integer match_pattern) {
+ this.match_pattern = match_pattern;
+ }
+
+ public Integer getReputation_score() {
+ return reputation_score;
+ }
+
+ public void setReputation_score(Integer reputation_score) {
+ this.reputation_score = reputation_score;
+ }
+
+ public String getReputation_level() {
+ return reputation_level;
+ }
+
+ public void setReputation_level(String reputation_level) {
+ this.reputation_level = reputation_level;
+ }
+
+ public Integer getCategory_id() {
+ return category_id;
+ }
+
+ public void setCategory_id(Integer category_id) {
+ this.category_id = category_id;
+ }
+
+ public String getCategory_name() {
+ return category_name;
+ }
+
+ public void setCategory_name(String category_name) {
+ this.category_name = category_name;
+ }
+
+ public String getCategory_group() {
+ return category_group;
+ }
+
+ public void setCategory_group(String category_group) {
+ this.category_group = category_group;
+ }
+
+ public Integer getCategory_conf() {
+ return category_conf;
+ }
+
+ public void setCategory_conf(Integer category_conf) {
+ this.category_conf = category_conf;
+ }
+
+ public Boolean getIs_a1_cat() {
+ return is_a1_cat;
+ }
+
+ public void setIs_a1_cat(Boolean is_a1_cat) {
+ this.is_a1_cat = is_a1_cat;
+ }
+
+ public Integer getStatus_code() {
+ return status_code;
+ }
+
+ public void setStatus_code(Integer status_code) {
+ this.status_code = status_code;
+ }
+
+ public String getSubmit_user() {
+ return submit_user;
+ }
+
+ public void setSubmit_user(String submit_user) {
+ this.submit_user = submit_user;
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/sketch/entity/DomainWhois.java b/src/main/java/com/mesasoft/cn/sketch/entity/DomainWhois.java
new file mode 100644
index 0000000..55679a8
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/sketch/entity/DomainWhois.java
@@ -0,0 +1,423 @@
+package com.mesasoft.cn.sketch.entity;
+
+import com.alibaba.fastjson.JSONObject;
+import com.mesasoft.cn.sketch.config.ApplicationConfig;
+import com.mesasoft.cn.util.ConfigUtils;
+import com.mesasoft.cn.util.MariaDbBase;
+import com.mesasoft.cn.util.ValidationUtils;
+
+import java.sql.Date;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: joy
+ * Date: 2021/12/29
+ * Time: 9:27 AM
+ * Description: No Description
+ */
+public class DomainWhois {
+ private static final String dataBase = ApplicationConfig.DATABASE;
+ private static final String tableName = ApplicationConfig.DOMAIN_WHOIS_TABLENAME;
+
+ private String fqdn;
+ private String source;
+ private Boolean query_success;
+ private Integer match_pattern;
+ private String whois_domain;
+ private Timestamp whois_update_date;
+ private Timestamp whois_create_date;
+ private Timestamp whois_expire_date;
+ private String whois_email;
+ private String whois_ns;
+ private String whois_registrar_name;
+ private String whois_registrant_org;
+ private String whois_registrant_name;
+ private String whois_registrant_street;
+ private String whois_registrant_city;
+ private String whois_registrant_state;
+ private String whois_registrant_postcode;
+ private String whois_registrant_country;
+ private String whois_registrant_phone;
+
+
+ // category schema
+ public DomainWhois(String fqdn,
+ String source,
+ Integer match_pattern,
+ Boolean query_success,
+ String whoisDomain,
+ Date whoisUpdateDate,
+ Date whoisCreateDate,
+ Date whoisExpireDate,
+ String whoisEmail,
+ String whoisNs,
+ String whoisRegistrarName,
+ String whoisRegistrantOrg,
+ String whoisRegistrantName,
+ String whoisRegistrantStreet,
+ String whoisRegistrantCity,
+ String whoisRegistrantState,
+ String whoisRegistrantPostcode,
+ String whoisRegistrantCountry,
+ String whoisRegistrantPhone
+ ) {
+
+ this.fqdn = fqdn;
+ this.source = source;
+
+ // 没有设置match_pattern,则二级域名为右匹配,其余为全匹配
+ if (match_pattern == null) {
+ this.match_pattern = ValidationUtils.getMatchPattern(fqdn);
+ } else {
+ this.match_pattern = match_pattern;
+ }
+
+ this.query_success = query_success;
+ this.whois_domain = ConfigUtils.getEffectiveString(whoisDomain);
+ this.whois_update_date = whoisUpdateDate == null ? null : new Timestamp(whoisUpdateDate.getTime());
+ this.whois_create_date = whoisCreateDate == null ? null : new Timestamp(whoisCreateDate.getTime());
+ this.whois_expire_date = whoisExpireDate == null ? null : new Timestamp(whoisExpireDate.getTime());
+ this.whois_email = ConfigUtils.getEffectiveString(whoisEmail);
+ this.whois_ns = ConfigUtils.getEffectiveString(whoisNs);
+ this.whois_registrar_name = ConfigUtils.getEffectiveString(whoisRegistrarName);
+ this.whois_registrant_org = ConfigUtils.getEffectiveString(whoisRegistrantOrg);
+ this.whois_registrant_name = ConfigUtils.getEffectiveString(whoisRegistrantName);
+ this.whois_registrant_street = ConfigUtils.getEffectiveString(whoisRegistrantStreet);
+ this.whois_registrant_city = ConfigUtils.getEffectiveString(whoisRegistrantCity);
+ this.whois_registrant_state = ConfigUtils.getEffectiveString(whoisRegistrantState);
+ this.whois_registrant_postcode = ConfigUtils.getEffectiveString(whoisRegistrantPostcode);
+ this.whois_registrant_country = ConfigUtils.getEffectiveString(whoisRegistrantCountry);
+ this.whois_registrant_phone = ConfigUtils.getEffectiveString(whoisRegistrantPhone);
+ }
+
+ public static void insertRecords(List<DomainWhois> whoisFiles, MariaDbBase mariaDbBase) {
+ for (DomainWhois whoisFile : whoisFiles) {
+ // 生成sql
+ String resSql = "INSERT INTO " + dataBase + "." + tableName + ' ' +
+ " (" + whoisFile.getKeys() + ") values" +
+ '(' + whoisFile.getValues() + ')';
+ resSql = resSql.replace("'null'", "null");
+
+ mariaDbBase.writeSqlExecute(resSql);
+ }
+ }
+
+ public static String insertSql(List<DomainWhois> whoisFiles) {
+ DomainWhois whoisFile = whoisFiles.get(0);
+ // 生成sql
+ String resSql = "INSERT INTO " + dataBase + "." + tableName + ' ' +
+ " (" + whoisFile.getKeys() + ") values" +
+ '(' + whoisFile.getValues() + ')';
+ resSql = resSql.replace("'null'", "null");
+
+ return resSql;
+ }
+
+ public static void updateRecords(List<DomainWhois> categoryFiles, MariaDbBase mariaDbBase) {
+ for (DomainWhois categoryFile : categoryFiles) {
+
+ String resSql = "UPDATE " + dataBase + "." +
+ tableName + ' ' +
+ "SET " + categoryFile.getKeyValues() +
+ ", update_time = current_time() " +
+ " WHERE fqdn = '" + categoryFile.getFqdn() + '\'';
+ resSql = resSql.replace("'null'", "null");
+
+ mariaDbBase.writeSqlExecute(resSql);
+ }
+ }
+
+ public static List<DomainWhois> getDbRecord(List<String> fqdns, MariaDbBase mariaDbBase, String source) throws SQLException {
+ String queryFqdns = fqdns.stream().map(s -> "'" + s + "'").collect(Collectors.joining(","));
+ String sql = "SELECT * FROM " + dataBase + "." +
+ tableName + ' ' +
+ " WHERE fqdn in (" + queryFqdns + ") ";
+
+ return rs2schema(mariaDbBase.querySqlExecute(sql));
+ }
+
+ public String getValues() {
+ String resString = "'" + fqdn + '\'' +
+ ", '" + source + '\'' +
+ ", " + query_success +
+ ", " + match_pattern +
+ ", '" + whois_domain + '\'' +
+ ", '" + whois_update_date + '\'' +
+ ", '" + whois_create_date + '\'' +
+ ", '" + whois_expire_date + '\'' +
+ ", '" + whois_email + '\'' +
+ ", '" + whois_ns + '\'' +
+ ", '" + whois_registrar_name + '\'' +
+ ", '" + whois_registrant_org + '\'' +
+ ", '" + whois_registrant_name + '\'' +
+ ", '" + whois_registrant_street + '\'' +
+ ", '" + whois_registrant_city + '\'' +
+ ", '" + whois_registrant_state + '\'' +
+ ", '" + whois_registrant_postcode + '\'' +
+ ", '" + whois_registrant_country + '\'' +
+ ", '" + whois_registrant_phone + '\'';
+
+ return resString.replace("'null'", "null");
+ }
+
+ public static List<DomainWhois> rs2schema(ResultSet rs) throws SQLException {
+ List<DomainWhois> schemaFiles = new ArrayList<>();
+ while (rs.next()) {
+ schemaFiles.add(
+ new DomainWhois(
+ rs.getString("fqdn"),
+ rs.getString("source"),
+ rs.getInt("match_pattern"),
+ rs.getBoolean("query_success"),
+ rs.getString("whois_domain"),
+ (Date) rs.getDate("whois_update_date"),
+ (Date) rs.getDate("whois_create_date"),
+ (Date) rs.getDate("whois_expire_date"),
+ rs.getString("whois_email"),
+ rs.getString("whois_ns"),
+ rs.getString("whois_registrar_name"),
+ rs.getString("whois_registrant_org"),
+ rs.getString("whois_registrant_name"),
+ rs.getString("whois_registrant_street"),
+ rs.getString("whois_registrant_city"),
+ rs.getString("whois_registrant_state"),
+ rs.getString("whois_registrant_postcode"),
+ rs.getString("whois_registrant_country"),
+ rs.getString("whois_registrant_phone")
+ ));
+ }
+ return schemaFiles;
+ }
+
+ public static JSONObject schema2json(DomainWhois schema) throws SQLException {
+ JSONObject jsonObject = new JSONObject(true);
+ jsonObject.put("fqdn", schema.getFqdn());
+ jsonObject.put("source", schema.getSource());
+ jsonObject.put("match_pattern", schema.getMatch_pattern());
+ jsonObject.put("query_success", schema.getQuery_success());
+ jsonObject.put("whois_domain", schema.getWhois_domain());
+ jsonObject.put("whois_update_date", schema.getWhois_update_date());
+ jsonObject.put("whois_create_date", schema.getWhois_create_date());
+ jsonObject.put("whois_expire_date", schema.getWhois_expire_date());
+ jsonObject.put("whois_email", schema.getWhois_email());
+ jsonObject.put("whois_ns", schema.getWhois_ns());
+ jsonObject.put("whois_registrar_name", schema.getWhois_registrar_name());
+ jsonObject.put("whois_registrant_org", schema.getWhois_registrant_org());
+ jsonObject.put("whois_registrant_name", schema.getWhois_registrant_name());
+ jsonObject.put("whois_registrant_street", schema.getWhois_registrant_street());
+ jsonObject.put("whois_registrant_city", schema.getWhois_registrant_city());
+ jsonObject.put("whois_registrant_state", schema.getWhois_registrant_state());
+ jsonObject.put("whois_registrant_postcode", schema.getWhois_registrant_postcode());
+ jsonObject.put("whois_registrant_country", schema.getWhois_registrant_country());
+ jsonObject.put("whois_registrant_phone", schema.getWhois_registrant_phone());
+
+ return jsonObject;
+ }
+
+ public String getKeys() {
+ String resString;
+ resString = "fqdn" +
+ ", source" +
+ ", query_success" +
+ ", match_pattern" +
+ ", whois_domain" +
+ ", whois_update_date" +
+ ", whois_create_date" +
+ ", whois_expire_date" +
+ ", whois_email" +
+ ", whois_ns" +
+ ", whois_registrar_name" +
+ ", whois_registrant_org" +
+ ", whois_registrant_name" +
+ ", whois_registrant_street" +
+ ", whois_registrant_city" +
+ ", whois_registrant_state" +
+ ", whois_registrant_postcode" +
+ ", whois_registrant_country" +
+ ", whois_registrant_phone";
+ return resString;
+ }
+
+ public String getKeyValues() {
+ String resString = "query_success=" + query_success +
+ ", source='" + source + '\'' +
+ ", match_pattern=" + match_pattern +
+ ", whois_domain='" + whois_domain + '\'' +
+ ", whois_update_date='" + whois_update_date + '\'' +
+ ", whois_create_date='" + whois_create_date + '\'' +
+ ", whois_expire_date='" + whois_expire_date + '\'' +
+ ", whois_email='" + whois_email + '\'' +
+ ", whois_ns='" + whois_ns + '\'' +
+ ", whois_registrar_name='" + whois_registrar_name + '\'' +
+ ", whois_registrant_org='" + whois_registrant_org + '\'' +
+ ", whois_registrant_name='" + whois_registrant_name + '\'' +
+ ", whois_registrant_street='" + whois_registrant_street + '\'' +
+ ", whois_registrant_city='" + whois_registrant_city + '\'' +
+ ", whois_registrant_state='" + whois_registrant_state + '\'' +
+ ", whois_registrant_postcode='" + whois_registrant_postcode + '\'' +
+ ", whois_registrant_country='" + whois_registrant_country + '\'' +
+ ", whois_registrant_phone='" + whois_registrant_phone + '\'';
+
+ return resString.replace("'null'", "null");
+ }
+
+
+ public String getSource() {
+ return source;
+ }
+
+ public void setSource(String source) {
+ this.source = source;
+ }
+
+ public String getFqdn() {
+ return fqdn;
+ }
+
+ public void setFqdn(String fqdn) {
+ this.fqdn = fqdn;
+ }
+
+ public Boolean getQuery_success() {
+ return query_success;
+ }
+
+ public void setQuery_success(Boolean query_success) {
+ this.query_success = query_success;
+ }
+
+ public Integer getMatch_pattern() {
+ return match_pattern;
+ }
+
+ public void setMatch_pattern(Integer match_pattern) {
+ this.match_pattern = match_pattern;
+ }
+
+ public String getWhois_domain() {
+ return whois_domain;
+ }
+
+ public void setWhois_domain(String whois_domain) {
+ this.whois_domain = whois_domain;
+ }
+
+ public Timestamp getWhois_update_date() {
+ return whois_update_date;
+ }
+
+ public void setWhois_update_date(Timestamp whois_update_date) {
+ this.whois_update_date = whois_update_date;
+ }
+
+ public Timestamp getWhois_create_date() {
+ return whois_create_date;
+ }
+
+ public void setWhois_create_date(Timestamp whois_create_date) {
+ this.whois_create_date = whois_create_date;
+ }
+
+ public Timestamp getWhois_expire_date() {
+ return whois_expire_date;
+ }
+
+ public void setWhois_expire_date(Timestamp whois_expire_date) {
+ this.whois_expire_date = whois_expire_date;
+ }
+
+ public String getWhois_email() {
+ return whois_email;
+ }
+
+ public void setWhois_email(String whois_email) {
+ this.whois_email = whois_email;
+ }
+
+ public String getWhois_ns() {
+ return whois_ns;
+ }
+
+ public void setWhois_ns(String whois_ns) {
+ this.whois_ns = whois_ns;
+ }
+
+ public String getWhois_registrar_name() {
+ return whois_registrar_name;
+ }
+
+ public void setWhois_registrar_name(String whois_registrar_name) {
+ this.whois_registrar_name = whois_registrar_name;
+ }
+
+ public String getWhois_registrant_org() {
+ return whois_registrant_org;
+ }
+
+ public void setWhois_registrant_org(String whois_registrant_org) {
+ this.whois_registrant_org = whois_registrant_org;
+ }
+
+ public String getWhois_registrant_name() {
+ return whois_registrant_name;
+ }
+
+ public void setWhois_registrant_name(String whois_registrant_name) {
+ this.whois_registrant_name = whois_registrant_name;
+ }
+
+ public String getWhois_registrant_street() {
+ return whois_registrant_street;
+ }
+
+ public void setWhois_registrant_street(String whois_registrant_street) {
+ this.whois_registrant_street = whois_registrant_street;
+ }
+
+ public String getWhois_registrant_city() {
+ return whois_registrant_city;
+ }
+
+ public void setWhois_registrant_city(String whois_registrant_city) {
+ this.whois_registrant_city = whois_registrant_city;
+ }
+
+ public String getWhois_registrant_state() {
+ return whois_registrant_state;
+ }
+
+ public void setWhois_registrant_state(String whois_registrant_state) {
+ this.whois_registrant_state = whois_registrant_state;
+ }
+
+ public String getWhois_registrant_postcode() {
+ return whois_registrant_postcode;
+ }
+
+ public void setWhois_registrant_postcode(String whois_registrant_postcode) {
+ this.whois_registrant_postcode = whois_registrant_postcode;
+ }
+
+ public String getWhois_registrant_country() {
+ return whois_registrant_country;
+ }
+
+ public void setWhois_registrant_country(String whois_registrant_country) {
+ this.whois_registrant_country = whois_registrant_country;
+ }
+
+ public String getWhois_registrant_phone() {
+ return whois_registrant_phone;
+ }
+
+ public void setWhois_registrant_phone(String whois_registrant_phone) {
+ this.whois_registrant_phone = whois_registrant_phone;
+ }
+}
+
diff --git a/src/main/java/com/mesasoft/cn/sketch/service/SketchService.java b/src/main/java/com/mesasoft/cn/sketch/service/SketchService.java
new file mode 100644
index 0000000..bb15d13
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/sketch/service/SketchService.java
@@ -0,0 +1,232 @@
+/*
+package com.zhazhapan.efo.sketch.service;
+
+import cn.ac.iie.api.ChinaZ;
+import cn.ac.iie.dao.MariaDbBase;
+import cn.ac.iie.util.MariaDBUtils;
+import cn.ac.iie.util.ValidationUtils;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.google.common.collect.Lists;
+import com.zhazhapan.efo.sketch.api.BrightCloud;
+import com.zhazhapan.efo.sketch.api.ChinaZ;
+import com.zhazhapan.efo.sketch.config.ApplicationConfig;
+import com.zhazhapan.efo.sketch.entity.DomainCategory;
+import com.zhazhapan.efo.sketch.entity.DomainWhois;
+import com.zhazhapan.efo.util.FileUtils;
+import org.apache.log4j.Logger;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.nio.charset.StandardCharsets;
+import java.sql.Connection;
+import java.sql.Date;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+*/
+/**
+ * Created with IntelliJ IDEA.
+ * User: joy
+ * Date: 2021/12/31
+ * Time: 11:28 AM
+ * Description: No Description
+ *//*
+
+public class SketchService {
+ private static final Logger LOG = Logger.getLogger(SketchService.class);
+ private static final int MAX_DB_BATCH_SIZE = ApplicationConfig.DB_QUERY_BATCH_SIZE;
+
+ private List<String> queryObjects;
+ private String curQueryType;
+
+ private MariaDbBase mariaDB;
+
+ long queryNum;
+ long dbResultNum;
+ long apiResultNum;
+ long failedQueryNum;
+
+ public JSONArray getQueryResults(String objectType, String queryType, List<String> queryObjects, String username, Boolean isLocal) throws SQLException, IOException {
+ queryNum = 0;
+ dbResultNum = 0;
+ apiResultNum = 0;
+ failedQueryNum = 0;
+
+ this.queryObjects = queryObjects;
+ this.curQueryType = queryType;
+ JSONArray json = null;
+
+ Connection mariaConn = MariaDBUtils.getConnection();
+ Statement mariaStat = mariaConn.createStatement();
+ mariaDB = new MariaDbBase(mariaConn, mariaStat);
+
+ //去重
+ queryObjects = queryObjects.stream().distinct().collect(Collectors.toList());
+
+ // 校验
+ queryObjects = ValidationUtils.getChecked(queryObjects, objectType);
+ this.queryNum = queryObjects.size();
+
+ // 执行查询
+ if (queryType.equals("domain_category")) {
+ json = getDomainCategory(queryObjects, username, isLocal);
+ } else if (queryType.equals("domain_whois")) {
+ json = getDomainWhois(queryObjects, isLocal);
+ } else {
+ // TODO: get dns server info
+ LOG.error("Wrong query type: " + queryType);
+ }
+
+ LOG.info("Query Statistic - number of query objects: " + queryNum
+ + "\nresults from local db: " + dbResultNum
+ + " results from external api: " + apiResultNum);
+ MariaDBUtils.close(mariaStat, mariaConn);
+ return json;
+ }
+
+ public JSONArray getDomainCategory(List<String> domains, String username, boolean isLocal) throws SQLException, IOException {
+
+ JSONArray results = new JSONArray();
+
+ // 查询本地数据库
+ ArrayList<String> objectsFromDB = new ArrayList<>();
+ List<List<String>> partitions = Lists.partition(queryObjects, MAX_DB_BATCH_SIZE);
+ for (List<String> partition : partitions) { // 批量查询
+ List<DomainCategory> dbRecords = DomainCategory.getDbRecord(partition, mariaDB, "brightcloud");
+ for (DomainCategory record : dbRecords) {
+ objectsFromDB.add(record.getFqdn()); // 保存查询记录
+ JSONObject jsonObject = DomainCategory.schema2json(record);
+ results.add(jsonObject); // 保存查询结果
+ }
+ }
+ dbResultNum = results.size();
+
+ // 调用api
+ List<DomainCategory> bcResults = new ArrayList<>();
+ List<String> objectsFromApi = new ArrayList<>(queryObjects);
+ objectsFromApi.removeAll(objectsFromDB);
+ if (!isLocal && objectsFromApi.size() > 0) {
+ BrightCloud brightCloud = new BrightCloud();
+
+ List<List<String>> apiPartitions = Lists.partition(objectsFromApi, ApplicationConfig.API_BC_MAXIMUM_QUERYNUM);
+ for (List<String> partition : apiPartitions) { // 批量查询
+ List<DomainCategory> recordsFromBcApi = brightCloud.responseSparse(brightCloud.getQueryResults(partition));
+ for (DomainCategory record : recordsFromBcApi) {
+ if (record.getQuery_success().equals(true)) { //查询成功的结果
+ record.setSubmit_user(username);
+ bcResults.add(record);
+ if (bcResults.size() > MAX_DB_BATCH_SIZE) { //超过一定量时写入数据库
+ DomainCategory.insertRecords(bcResults, mariaDB);
+ bcResults.clear();
+ }
+ results.add(DomainCategory.schema2json(record));
+ } else { // 查询失败的结果
+ failedQueryNum += 1;
+ }
+ }
+ }
+ }
+ apiResultNum = results.size() - dbResultNum - failedQueryNum;
+ DomainCategory.insertRecords(bcResults, mariaDB);
+
+ if (apiResultNum > 0) { // 记录api调用次数
+ OutputStream bcQueryLogStream = new FileOutputStream(ApplicationConfig.API_BC_USE_REPORT_FILE, true);
+ OutputStreamWriter bcQueryLogWriter = new OutputStreamWriter(bcQueryLogStream, StandardCharsets.UTF_8);
+ Date d = new Date(System.currentTimeMillis());
+ bcQueryLogWriter.write(d + "," + "List Query," + "-" + "," + curQueryType + "," + apiResultNum + "\n");
+ FileUtils.writerClose(bcQueryLogWriter, bcQueryLogStream);
+ }
+
+ return results;
+ }
+
+ public JSONArray getDomainWhois(List<String> domains, boolean isLocal) throws SQLException, IOException {
+
+ JSONArray results = new JSONArray();
+
+ // 查询本地数据库
+ ArrayList<String> objectsFromDB = new ArrayList<>();
+ List<List<String>> partitions = Lists.partition(queryObjects, MAX_DB_BATCH_SIZE);
+ for (List<String> partition : partitions) { // 批量查询
+ List<DomainWhois> dbRecords =
+ DomainWhois.getDbRecord(partition, mariaDB, "chinaz");
+ for (DomainWhois record : dbRecords) {
+ objectsFromDB.add(record.getFqdn()); // 保存查询记录
+ JSONObject jsonObject = DomainWhois.schema2json(record);
+ results.add(jsonObject); // 保存查询结果
+ }
+ }
+ dbResultNum = results.size();
+
+ // 调用api
+ List<DomainWhois> chinazResults = new ArrayList<>();
+ if (!isLocal) {
+ ChinaZ chinaz = new ChinaZ();
+
+ List<String> objectsFromApi = new ArrayList<>(queryObjects);
+ objectsFromApi.removeAll(objectsFromDB); // 需要调用api查询的部分对象
+
+ List<List<String>> apiPartitions = Lists.partition(objectsFromApi, ApplicationConfig.API_CHINAZ_MAXIMUM_QUERYNUM);
+ for (List<String> partition : apiPartitions) { // 批量查询
+ List<DomainWhois> recordsFromApi = chinaz.responseSparse(chinaz.getQueryResults(partition));
+ for (DomainWhois record : recordsFromApi) {
+ if (record.getQuery_success().equals(true)) { // 查询成功的结果
+ chinazResults.add(record);
+ if (chinazResults.size() > MAX_DB_BATCH_SIZE) { // 超过一定量时写入数据库
+ DomainWhois.insertRecords(chinazResults, mariaDB);
+ chinazResults.clear();
+ }
+ results.add(DomainWhois.schema2json(record));
+ } else { // 查询失败的结果
+ failedQueryNum += 1;
+ }
+ }
+ }
+ }
+
+ DomainWhois.insertRecords(chinazResults, mariaDB);
+ apiResultNum = results.size() - dbResultNum - failedQueryNum;
+ // todo 不直接写入,维护变量,导出一次
+ if (apiResultNum > 0) { // 记录api调用次数
+ OutputStream bcQueryLogStream = new FileOutputStream(ApplicationConfig.API_CHINAZ_USE_REPORT_FILE, true);
+ OutputStreamWriter bcQueryLogWriter = new OutputStreamWriter(bcQueryLogStream, StandardCharsets.UTF_8);
+ Date d = new Date(System.currentTimeMillis());
+ bcQueryLogWriter.write(d + "," + "List Query," + "-" + "," + curQueryType + "," + apiResultNum + "\n");
+ FileUtils.writerClose(bcQueryLogWriter, bcQueryLogStream);
+ }
+
+
+ return results;
+ }
+
+
+ public static void main(String[] args) throws Exception {
+// String objectType = args[0];
+// String queryType = args[1];
+// List<String> queryObjects = Arrays.asList(args[2].split(","));
+// String username = args[4];
+// boolean isLocal = true;
+// if (args.length >= 3) {
+// isLocal = Boolean.parseBoolean(args[3]);
+// }
+
+// System.out.println(new SketchService().getQueryResults(objectType, queryType, queryObjects, username, isLocal).toString());
+
+ JSONArray queryResults = new SketchService().getQueryResults("domain",
+ "domain_category",
+ Arrays.asList("baidu.com", "cctv.com"), "", true);
+ System.err.println(queryResults.toJSONString());
+ String json = "{\"namespace\":\"log.session\",\"type\":\"record\",\"name\":\"session\",\"fields\":[{\"name\":\"common_log_id\",\"type\":\"long\"},{\"name\":\"common_service\",\"type\":\"long\"},{\"name\":\"common_recv_time\",\"type\":\"long\"},{\"name\":\"common_direction\",\"type\":\"long\"},{\"name\":\"common_l4_protocol\",\"type\":\"string\"},{\"name\":\"common_address_type\",\"type\":\"long\"},{\"name\":\"common_schema_type\",\"type\":\"string\"},{\"name\":\"common_policy_id\",\"type\":\"long\"},{\"name\":\"common_user_tags\",\"type\":\"string\"},{\"name\":\"common_action\",\"type\":\"long\"},{\"name\":\"common_sub_action\",\"type\":\"string\"},{\"name\":\"common_user_region\",\"type\":\"string\"},{\"name\":\"common_client_ip\",\"type\":\"string\"},{\"name\":\"common_client_port\",\"type\":\"long\"},{\"name\":\"common_internal_ip\",\"type\":\"string\"},{\"name\":\"common_entrance_id\",\"type\":\"long\"},{\"name\":\"common_device_id\",\"type\":\"string\"},{\"name\":\"common_egress_link_id\",\"type\":\"long\"},{\"name\":\"common_ingress_link_id\",\"type\":\"long\"},{\"name\":\"common_isp\",\"type\":\"string\"},{\"name\":\"common_device_tag\",\"type\":\"string\"},{\"name\":\"common_data_center\",\"type\":\"string\"},{\"name\":\"common_encapsulation\",\"type\":\"long\"},{\"name\":\"common_tunnels\",\"type\":\"string\"},{\"name\":\"common_sled_ip\",\"type\":\"string\"},{\"name\":\"common_device_group\",\"type\":\"string\"},{\"name\":\"common_app_behavior\",\"type\":\"string\"},{\"name\":\"common_client_location\",\"type\":\"string\"},{\"name\":\"common_client_asn\",\"type\":\"string\"},{\"name\":\"common_subscriber_id\",\"type\":\"string\"},{\"name\":\"common_imei\",\"type\":\"string\"},{\"name\":\"common_imsi\",\"type\":\"string\"},{\"name\":\"common_phone_number\",\"type\":\"string\"},{\"name\":\"common_server_ip\",\"type\":\"string\"},{\"name\":\"common_server_port\",\"type\":\"long\"},{\"name\":\"common_external_ip\",\"type\":\"string\"},{\"name\":\"common_server_location\",\"type\":\"string\"},{\"name\":\"common_server_asn\",\"type\":\"string\"},{\"name\":\"common_protocol_label\",\"type\":\"string\"},{\"name\":\"common_service_category\",\"type\":{\"type\":\"array\",\"items\":\"long\"}},{\"name\":\"common_app_label\",\"type\":\"string\"},{\"name\":\"common_app_id\",\"type\":\"string\"},{\"name\":\"common_userdefine_app_name\",\"type\":\"string\"},{\"name\":\"common_app_surrogate_id\",\"type\":\"string\"},{\"name\":\"common_l7_protocol\",\"type\":\"string\"},{\"name\":\"common_sessions\",\"type\":\"long\"},{\"name\":\"common_c2s_pkt_num\",\"type\":\"long\"},{\"name\":\"common_s2c_pkt_num\",\"type\":\"long\"},{\"name\":\"common_c2s_pkt_diff\",\"type\":\"long\"},{\"name\":\"common_s2c_pkt_diff\",\"type\":\"long\"},{\"name\":\"common_c2s_byte_diff\",\"type\":\"long\"},{\"name\":\"common_s2c_byte_diff\",\"type\":\"long\"},{\"name\":\"common_c2s_byte_num\",\"type\":\"long\"},{\"name\":\"common_s2c_byte_num\",\"type\":\"long\"},{\"name\":\"common_start_time\",\"type\":\"long\"},{\"name\":\"common_end_time\",\"type\":\"long\"},{\"name\":\"common_establish_latency_ms\",\"type\":\"long\"},{\"name\":\"common_con_duration_ms\",\"type\":\"long\"},{\"name\":\"common_stream_dir\",\"type\":\"long\"},{\"name\":\"common_address_list\",\"type\":\"string\"},{\"name\":\"common_has_dup_traffic\",\"type\":\"long\"},{\"name\":\"common_stream_error\",\"type\":\"string\"},{\"name\":\"common_stream_trace_id\",\"type\":\"long\"},{\"name\":\"common_link_info_c2s\",\"type\":\"string\"},{\"name\":\"common_link_info_s2c\",\"type\":\"string\"},{\"name\":\"common_packet_capture_file\",\"type\":\"string\"},{\"name\":\"common_c2s_ipfrag_num\",\"type\":\"long\"},{\"name\":\"common_s2c_ipfrag_num\",\"type\":\"long\"},{\"name\":\"common_c2s_tcp_lostlen\",\"type\":\"long\"},{\"name\":\"common_s2c_tcp_lostlen\",\"type\":\"long\"},{\"name\":\"common_c2s_tcp_unorder_num\",\"type\":\"long\"},{\"name\":\"common_s2c_tcp_unorder_num\",\"type\":\"long\"},{\"name\":\"common_c2s_pkt_retrans\",\"type\":\"long\"},{\"name\":\"common_s2c_pkt_retrans\",\"type\":\"long\"},{\"name\":\"common_c2s_byte_retrans\",\"type\":\"long\"},{\"name\":\"common_s2c_byte_retrans\",\"type\":\"long\"},{\"name\":\"common_tcp_client_isn\",\"type\":\"long\"},{\"name\":\"common_tcp_server_isn\",\"type\":\"long\"},{\"name\":\"common_mirrored_pkts\",\"type\":\"long\"},{\"name\":\"common_mirrored_bytes\",\"type\":\"long\"},{\"name\":\"common_first_ttl\",\"type\":\"long\"},{\"name\":\"common_processing_time\",\"type\":\"long\"},{\"name\":\"http_url\",\"type\":\"string\"},{\"name\":\"http_host\",\"type\":\"string\"},{\"name\":\"http_domain\",\"type\":\"string\"},{\"name\":\"http_request_line\",\"type\":\"string\"},{\"name\":\"http_response_line\",\"type\":\"string\"},{\"name\":\"http_request_header\",\"type\":\"string\"},{\"name\":\"http_response_header\",\"type\":\"string\"},{\"name\":\"http_request_content\",\"type\":\"string\"},{\"name\":\"http_response_content\",\"type\":\"string\"},{\"name\":\"http_request_body\",\"type\":\"string\"},{\"name\":\"http_response_body\",\"type\":\"string\"},{\"name\":\"http_request_body_key\",\"type\":\"string\"},{\"name\":\"http_response_body_key\",\"type\":\"string\"},{\"name\":\"http_proxy_flag\",\"type\":\"long\"},{\"name\":\"http_sequence\",\"type\":\"long\"},{\"name\":\"http_snapshot\",\"type\":\"string\"},{\"name\":\"http_cookie\",\"type\":\"string\"},{\"name\":\"http_referer\",\"type\":\"string\"},{\"name\":\"http_user_agent\",\"type\":\"string\"},{\"name\":\"http_request_content_length\",\"type\":\"string\"},{\"name\":\"http_request_content_type\",\"type\":\"string\"},{\"name\":\"http_response_content_length\",\"type\":\"string\"},{\"name\":\"http_response_content_type\",\"type\":\"string\"},{\"name\":\"http_content_length\",\"type\":\"string\"},{\"name\":\"http_content_type\",\"type\":\"string\"},{\"name\":\"http_set_cookie\",\"type\":\"string\"},{\"name\":\"http_version\",\"type\":\"string\"},{\"name\":\"http_response_latency_ms\",\"type\":\"long\"},{\"name\":\"http_session_duration_ms\",\"type\":\"long\"},{\"name\":\"http_action_file_size\",\"type\":\"long\"},{\"name\":\"mail_protocol_type\",\"type\":\"string\"},{\"name\":\"mail_account\",\"type\":\"string\"},{\"name\":\"mail_to_cmd\",\"type\":\"string\"},{\"name\":\"mail_from_cmd\",\"type\":\"string\"},{\"name\":\"mail_from\",\"type\":\"string\"},{\"name\":\"mail_to\",\"type\":\"string\"},{\"name\":\"mail_cc\",\"type\":\"string\"},{\"name\":\"mail_bcc\",\"type\":\"string\"},{\"name\":\"mail_subject\",\"type\":\"string\"},{\"name\":\"mail_subject_charset\",\"type\":\"string\"},{\"name\":\"mail_content\",\"type\":\"string\"},{\"name\":\"mail_content_charset\",\"type\":\"string\"},{\"name\":\"mail_attachment_name\",\"type\":\"string\"},{\"name\":\"mail_attachment_name_charset\",\"type\":\"string\"},{\"name\":\"mail_attachment_content\",\"type\":\"string\"},{\"name\":\"mail_eml_file\",\"type\":\"string\"},{\"name\":\"mail_snapshot\",\"type\":\"string\"},{\"name\":\"dns_message_id\",\"type\":\"long\"},{\"name\":\"dns_qr\",\"type\":\"long\"},{\"name\":\"dns_opcode\",\"type\":\"long\"},{\"name\":\"dns_aa\",\"type\":\"long\"},{\"name\":\"dns_tc\",\"type\":\"long\"},{\"name\":\"dns_rd\",\"type\":\"long\"},{\"name\":\"dns_ra\",\"type\":\"long\"},{\"name\":\"dns_rcode\",\"type\":\"long\"},{\"name\":\"dns_qdcount\",\"type\":\"long\"},{\"name\":\"dns_ancount\",\"type\":\"long\"},{\"name\":\"dns_nscount\",\"type\":\"long\"},{\"name\":\"dns_arcount\",\"type\":\"long\"},{\"name\":\"dns_qname\",\"type\":\"string\"},{\"name\":\"dns_qtype\",\"type\":\"long\"},{\"name\":\"dns_qclass\",\"type\":\"long\"},{\"name\":\"dns_cname\",\"type\":\"string\"},{\"name\":\"dns_sub\",\"type\":\"long\"},{\"name\":\"dns_rr\",\"type\":\"string\"},{\"name\":\"ssl_version\",\"type\":\"string\"},{\"name\":\"ssl_sni\",\"type\":\"string\"},{\"name\":\"ssl_san\",\"type\":\"string\"},{\"name\":\"ssl_cn\",\"type\":\"string\"},{\"name\":\"ssl_pinningst\",\"type\":\"long\"},{\"name\":\"ssl_intercept_state\",\"type\":\"long\"},{\"name\":\"ssl_passthrough_reason\",\"type\":\"string\"},{\"name\":\"ssl_server_side_latency\",\"type\":\"long\"},{\"name\":\"ssl_client_side_latency\",\"type\":\"long\"},{\"name\":\"ssl_server_side_version\",\"type\":\"string\"},{\"name\":\"ssl_client_side_version\",\"type\":\"string\"},{\"name\":\"ssl_cert_verify\",\"type\":\"long\"},{\"name\":\"ssl_error\",\"type\":\"string\"},{\"name\":\"ssl_con_latency_ms\",\"type\":\"long\"},{\"name\":\"ssl_ja3_fingerprint\",\"type\":\"string\"},{\"name\":\"ssl_ja3_hash\",\"type\":\"string\"},{\"name\":\"ssl_cert_issuer\",\"type\":\"string\"},{\"name\":\"ssl_cert_subject\",\"type\":\"string\"},{\"name\":\"quic_version\",\"type\":\"string\"},{\"name\":\"quic_sni\",\"type\":\"string\"},{\"name\":\"quic_user_agent\",\"type\":\"string\"},{\"name\":\"ftp_account\",\"type\":\"string\"},{\"name\":\"ftp_url\",\"type\":\"string\"},{\"name\":\"ftp_content\",\"type\":\"string\"},{\"name\":\"ftp_link_type\",\"type\":\"string\"},{\"name\":\"bgp_type\",\"type\":\"long\"},{\"name\":\"bgp_as_num\",\"type\":\"string\"},{\"name\":\"bgp_route\",\"type\":\"string\"},{\"name\":\"voip_calling_account\",\"type\":\"string\"},{\"name\":\"voip_called_account\",\"type\":\"string\"},{\"name\":\"voip_calling_number\",\"type\":\"string\"},{\"name\":\"voip_called_number\",\"type\":\"string\"},{\"name\":\"sip_call_id\",\"type\":\"string\"},{\"name\":\"sip_originator_description\",\"type\":\"string\"},{\"name\":\"sip_responder_description\",\"type\":\"string\"},{\"name\":\"sip_user_agent\",\"type\":\"string\"},{\"name\":\"sip_server\",\"type\":\"string\"},{\"name\":\"sip_originator_sdp_connect_ip\",\"type\":\"string\"},{\"name\":\"sip_originator_sdp_media_port\",\"type\":\"long\"},{\"name\":\"sip_originator_sdp_media_type\",\"type\":\"string\"},{\"name\":\"sip_originator_sdp_content\",\"type\":\"string\"},{\"name\":\"sip_responder_sdp_connect_ip\",\"type\":\"string\"},{\"name\":\"sip_responder_sdp_media_port\",\"type\":\"long\"},{\"name\":\"sip_responder_sdp_media_type\",\"type\":\"string\"},{\"name\":\"sip_responder_sdp_content\",\"type\":\"string\"},{\"name\":\"sip_duration_s\",\"type\":\"long\"},{\"name\":\"sip_bye\",\"type\":\"string\"},{\"name\":\"rtp_payload_type_c2s\",\"type\":\"long\"},{\"name\":\"rtp_payload_type_s2c\",\"type\":\"long\"},{\"name\":\"rtp_pcap_path\",\"type\":\"string\"},{\"name\":\"rtp_originator_dir\",\"type\":\"long\"},{\"name\":\"ssh_version\",\"type\":\"string\"},{\"name\":\"ssh_auth_success\",\"type\":\"string\"},{\"name\":\"ssh_client_version\",\"type\":\"string\"},{\"name\":\"ssh_server_version\",\"type\":\"string\"},{\"name\":\"ssh_cipher_alg\",\"type\":\"string\"},{\"name\":\"ssh_mac_alg\",\"type\":\"string\"},{\"name\":\"ssh_compression_alg\",\"type\":\"string\"},{\"name\":\"ssh_kex_alg\",\"type\":\"string\"},{\"name\":\"ssh_host_key_alg\",\"type\":\"string\"},{\"name\":\"ssh_host_key\",\"type\":\"string\"},{\"name\":\"ssh_hassh\",\"type\":\"string\"},{\"name\":\"stratum_cryptocurrency\",\"type\":\"string\"},{\"name\":\"stratum_mining_pools\",\"type\":\"string\"},{\"name\":\"stratum_mining_program\",\"type\":\"string\"},{\"name\":\"streaming_media_url\",\"type\":\"string\"},{\"name\":\"streaming_media_protocol\",\"type\":\"string\"},{\"name\":\"app_extra_info\",\"type\":\"string\"}]}";
+ Object parse = JSONObject.parse(json);
+
+ System.err.println(parse);
+ }
+}
+*/
diff --git a/src/main/java/com/mesasoft/cn/util/BeanUtils.java b/src/main/java/com/mesasoft/cn/util/BeanUtils.java
new file mode 100644
index 0000000..152c490
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/util/BeanUtils.java
@@ -0,0 +1,77 @@
+package com.mesasoft.cn.util;
+
+import com.alibaba.fastjson.JSONObject;
+import com.zhazhapan.modules.constant.ValueConsts;
+import com.zhazhapan.util.Checker;
+import com.zhazhapan.util.Formatter;
+import com.zhazhapan.util.enums.FieldModifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * @author pantao
+ * @since 2018/1/18
+ */
+public class BeanUtils {
+
+ private static final String ERROR_JSON = "{\"error\":\"internal error, please try again later\"}";
+
+ private static Logger logger = LoggerFactory.getLogger(BeanUtils.class);
+
+ private BeanUtils() {}
+
+ /**
+ * 将权限字符串装换成权限数组
+ *
+ * @param auth 权限字符串
+ *
+ * @return 权限数组
+ */
+ public static int[] getAuth(String auth) {
+ int[] a = new int[5];
+ if (Checker.isNotEmpty(auth)) {
+ String[] u = auth.split(ValueConsts.COMMA_SIGN);
+ int len = Math.min(a.length, u.length);
+ for (int i = 0; i < len; i++) {
+ a[i] = Formatter.stringToInt(u[i]);
+ }
+ }
+ return a;
+ }
+
+ /**
+ * 将Bean转换成JSON
+ *
+ * @param object Bean对象
+ *
+ * @return {@link String}
+ */
+ public static String toPrettyJson(Object object) {
+ String result;
+ try {
+ result = com.zhazhapan.util.BeanUtils.toPrettyJson(object, FieldModifier.PRIVATE);
+ } catch (IllegalAccessException e) {
+ result = Formatter.formatJson(ERROR_JSON);
+ logger.error(e.getMessage());
+ }
+ return result;
+ }
+
+ /**
+ * 将类属性装换成JSON(只能转换有get方法的)
+ *
+ * @param object 转换的对象
+ *
+ * @return {@link JSONObject}
+ */
+ public static JSONObject beanToJson(Object object) {
+ try {
+ return com.zhazhapan.util.BeanUtils.beanToJson(object);
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ logger.error(e.getMessage());
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/util/CommonUtils.java b/src/main/java/com/mesasoft/cn/util/CommonUtils.java
new file mode 100644
index 0000000..eebb49b
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/util/CommonUtils.java
@@ -0,0 +1,26 @@
+package com.mesasoft.cn.util;
+
+import com.mesasoft.cn.modules.constant.DefaultValues;
+import com.zhazhapan.modules.constant.ValueConsts;
+
+/**
+ * @author pantao
+ * @since 2018/1/29
+ */
+public class CommonUtils {
+
+ private CommonUtils() {}
+
+ /**
+ * 将相对路径转换成绝对路径
+ *
+ * @param path 文件路径
+ *
+ * @return {@link String}
+ */
+ public static String checkPath(String path) {
+ String prefix = DefaultValues.COLON + ValueConsts.SEPARATOR;
+ return path.startsWith(ValueConsts.SEPARATOR) || path.startsWith(prefix, ValueConsts.ONE_INT) ? path :
+ DefaultValues.STORAGE_PATH + path;
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/util/ConfigUtils.java b/src/main/java/com/mesasoft/cn/util/ConfigUtils.java
new file mode 100644
index 0000000..8aedad0
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/util/ConfigUtils.java
@@ -0,0 +1,46 @@
+package com.mesasoft.cn.util;
+
+
+import org.apache.log4j.Logger;
+
+import java.util.Properties;
+
+public class ConfigUtils {
+ private static final Logger LOG = Logger.getLogger(ConfigUtils.class);
+ private static Properties propCommon = new Properties();
+
+ public static String getStringProperty(String key) {
+ return propCommon.getProperty(key);
+ }
+
+ public static Integer getIntProperty(String key) {
+ return Integer.parseInt(propCommon.getProperty(key));
+ }
+
+ public static Long getLongProperty(String key) {
+ return Long.parseLong(propCommon.getProperty(key));
+ }
+
+ public static Boolean getBooleanProperty(String key) {
+ return "true".equals(propCommon.getProperty(key).toLowerCase().trim());
+ }
+
+ public static String getEffectiveString(String s) {
+ if (!(s == null)) {
+ return s.length() == 0 ? null : s;
+ } else {
+ return null;
+ }
+ }
+
+ static {
+ try {
+ propCommon.load(ConfigUtils.class.getClassLoader().getResourceAsStream("sketch.properties"));
+
+ } catch (Exception e) {
+ propCommon = null;
+ LOG.error("配置加载失败");
+ }
+ }
+
+}
diff --git a/src/main/java/com/mesasoft/cn/util/Contants.java b/src/main/java/com/mesasoft/cn/util/Contants.java
new file mode 100644
index 0000000..2989133
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/util/Contants.java
@@ -0,0 +1,54 @@
+package com.mesasoft.cn.util;
+
+import com.google.common.collect.ImmutableMap;
+
+import java.util.Map;
+
+/**
+ * @description,
+ * @author, zhq
+ * @create, 2022-03-18
+ **/
+public class Contants {
+
+ public static final Map<String, String> CONTENT_TYPES = ImmutableMap.<String, String>builder()
+ .put("doc", "application/msword")
+ .put("bin", "application/octet-stream")
+ .put("exe", "application/octet-stream")
+ .put("so", "application/octet-stream")
+ .put("dll", "application/octet-stream")
+ .put("pdf", "application/pdf")
+ .put("ai", "application/postscript")
+ .put("xls", "application/vnd.ms-excel")
+ .put("ppt", "application/vnd.ms-powerpoint")
+ .put("dir", "application/x-director")
+ .put("js", "application/x-javascript")
+ .put("swf", "application/x-shockwave-flash")
+ .put("xhtml", "application/xhtml+xml")
+ .put("xht", "application/xhtml+xml")
+ .put("zip", "application/zip")
+ .put("mid", "audio/midi")
+ .put("midi", "audio/midi")
+ .put("mp3", "audio/mpeg")
+ .put("rm", "audio/x-pn-realaudio")
+ .put("rpm", "audio/x-pn-realaudio-plugin")
+ .put("wav", "audio/x-wav")
+ .put("bmp", "image/bmp")
+ .put("gif", "image/gif")
+ .put("jpeg", "image/jpeg")
+ .put("jpg", "image/jpeg")
+ .put("png", "image/png")
+ .put("css", "text/css")
+ .put("html", "text/html")
+ .put("htm", "text/html")
+ .put("txt", "text/plain")
+ .put("xsl", "text/xml")
+ .put("xml", "text/xml")
+ .put("mpeg", "video/mpeg")
+ .put("mpg", "video/mpeg")
+ .put("avi", "video/x-msvideo")
+ .put("movie", "video/x-sgi-movie")
+ .put(".csv", "text/csv"
+ ).build();
+
+}
diff --git a/src/main/java/com/mesasoft/cn/util/ControllerUtils.java b/src/main/java/com/mesasoft/cn/util/ControllerUtils.java
new file mode 100644
index 0000000..e551434
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/util/ControllerUtils.java
@@ -0,0 +1,152 @@
+package com.mesasoft.cn.util;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.text.UnicodeUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.mesasoft.cn.modules.constant.DefaultValues;
+import com.zhazhapan.util.Checker;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.activation.MimetypesFileTypeMap;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+
+/**
+ * @author pantao
+ * @since 2018/1/30
+ */
+public class ControllerUtils {
+
+ private ControllerUtils() {
+ }
+
+ /**
+ * 获取一个简单的响应状态
+ *
+ * @param isSuccess 是否操作成功
+ * @return 响应JSON字符串
+ */
+ public static String getResponse(boolean isSuccess) {
+ JSONObject jsonObject = new JSONObject();
+ if (isSuccess) {
+ jsonObject.put("status", "success");
+ } else {
+ jsonObject.put("status", "error");
+ }
+ return jsonObject.toString();
+ }
+
+ /**
+ * 加载本地资源
+ *
+ * @param response 返回的Response
+ * @param path 资源路径
+ * @param download 直接下载
+ */
+ public static void loadResource2(HttpServletResponse response, String path, boolean download) throws IOException {
+ if (Checker.isNotEmpty(path)) {
+ File file = new File(path);
+ if (download) {
+ response.setContentType(getContentType(file)+";charset=UTF-8");
+ setResponseFileName2(response, file.getName());
+ }
+ FileInputStream in = new FileInputStream(file);
+ ServletOutputStream os = response.getOutputStream();
+ byte[] b;
+ while (in.available() > 0) {
+ b = in.available() > 1024 ? new byte[1024] : new byte[in.available()];
+ in.read(b, 0, b.length);
+ os.write(b, 0, b.length);
+ }
+ in.close();
+ os.flush();
+ os.close();
+ } else {
+ response.sendRedirect(DefaultValues.NOT_FOUND_PAGE);
+ }
+ }
+ public static void loadResource(HttpServletResponse response, String path, boolean download) throws IOException {
+ if (Checker.isNotEmpty(path)) {
+ File file = new File(path);
+ if (download) {
+ response.setContentType(getContentType(file));
+ setResponseFileName( response, file.getName());
+ response.setCharacterEncoding("UTF-8");
+ }
+ FileInputStream in = new FileInputStream(file);
+ ServletOutputStream os = response.getOutputStream();
+ byte[] b;
+ while (in.available() > 0) {
+ b = in.available() > 1024 ? new byte[1024] : new byte[in.available()];
+ in.read(b, 0, b.length);
+ os.write(b, 0, b.length);
+ }
+ in.close();
+ os.flush();
+ os.close();
+ } else {
+ response.sendRedirect(DefaultValues.NOT_FOUND_PAGE);
+ }
+ }
+ public static String getContentType(File file) {
+ String defContentType = "application/octet-stream";
+ String fileName = file.getName();
+ String fileTyle=fileName.substring(fileName.lastIndexOf(".")+1,fileName.length());
+ if (StringUtils.isNotBlank(fileTyle)) {
+ String type2 = Contants.CONTENT_TYPES.get(fileTyle);
+ if (StringUtils.isNotBlank(type2)) {
+ return type2;
+ }
+ } else {
+ String type1 = new MimetypesFileTypeMap().getContentType(file);
+ if (StringUtils.isNotBlank(type1)) {
+ return type1;
+ }
+ }
+ return defContentType;
+ }
+
+ /**
+ * 设置响应头的文件名
+ *
+ * @param response {@link HttpServletResponse}
+ * @param fileName 文件名
+ */
+ public static void setResponseFileName2(HttpServletResponse response, String fileName) {
+ response.setHeader("Content-Disposition", "attachment;filename=" + UnicodeUtil.toUnicode(fileName));
+ }
+ public static void setResponseFileName( HttpServletResponse response, String fileName) throws
+ UnsupportedEncodingException {
+ response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("UTF-8"),
+ "ISO-8859-1"));
+ }
+
+ public static void loadFile(HttpServletRequest request, HttpServletResponse response,String filePath,boolean download) throws IOException {
+ request.setCharacterEncoding("utf-8");
+ // 文件存储路径
+ // 从请求中获取文件名
+ File file=new File(filePath);
+ String fileName=file.getName();
+ // 创建输出流对象
+ ServletOutputStream outputStream = response.getOutputStream();
+ //以字节数组的形式读取文件
+ byte[] bytes = FileUtil.readBytes(filePath);
+ // 设置返回内容格式
+ response.setContentType("application/octet-stream;charset=UTF-8");
+ // 把文件名按UTF-8取出并按ISO8859-1编码,保证弹出窗口中的文件名中文不乱码
+ // 中文不要太多,最多支持17个中文,因为header有150个字节限制。
+ response.setHeader("filename", UnicodeUtil.toUnicode(fileName));
+ // 这一步一定要在读取文件之后进行,否则文件名会乱码,找不到文件
+ fileName = new String(fileName.getBytes("UTF-8"),"ISO-8859-1");
+ // 设置下载弹窗的文件名和格式(文件名要包括名字和文件格式)
+ response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
+ // 返回数据到输出流对象中
+ outputStream.write(bytes);
+ // 关闭流对象
+ IoUtil.close(outputStream);
+
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/util/FileUtils.java b/src/main/java/com/mesasoft/cn/util/FileUtils.java
new file mode 100644
index 0000000..773843d
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/util/FileUtils.java
@@ -0,0 +1,197 @@
+package com.mesasoft.cn.util;
+
+import org.apache.log4j.Logger;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author yjy
+ * @version 1.0
+ * @date 2021/2/25 6:11 下午
+ */
+public class FileUtils {
+ private static final Logger LOG = Logger.getLogger(FileUtils.class);
+
+ public static List<String> readTxtFileIntoStringArrList(String filePath)
+ {
+ List<String> list = new ArrayList<>();
+ try
+ {
+ String encoding = "GBK";
+ File file = new File(filePath);
+ if (file.isFile() && file.exists())
+ { // 判断文件是否存在
+ InputStreamReader read = new InputStreamReader(
+ new FileInputStream(file), encoding);
+ BufferedReader bufferedReader = new BufferedReader(read);
+ String lineTxt = null;
+
+ while ((lineTxt = bufferedReader.readLine()) != null)
+ {
+ if (!lineTxt.equals("")) {
+ list.add(lineTxt.trim());
+ }
+ }
+ bufferedReader.close();
+ read.close();
+ }
+ else
+ {
+ System.out.println("Can not find file: " + filePath);
+ }
+ }
+ catch (Exception e)
+ {
+ System.out.println("Error occurred in Function 'readTxtFileIntoStringArrList'");
+ e.printStackTrace();
+ }
+
+ return list;
+ }
+
+ public static List<String> getBatchLineReadIn(BufferedReader bufferedReader, int batchSize){
+ List<String> list = new ArrayList<>();
+ String lineTxt;
+ try{
+ while ((lineTxt = bufferedReader.readLine()) != null && list.size()<batchSize)
+ {
+ if (!lineTxt.equals("")) {
+ list.add(lineTxt.trim());
+ }
+ }
+ } catch (IOException e){
+ e.printStackTrace();
+ }
+ return list;
+ }
+
+ public static void createFile(File filePath, String fileName){
+ try {
+ File file = new File(filePath.toString() + "/" + fileName);
+
+ if (!filePath.exists()){
+ filePath.mkdirs();
+ }
+
+ boolean isCreate = file.createNewFile();
+ if (isCreate){
+ LOG.info("File " + fileName + " is created.");
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ public static void createFile(File file){
+ try {
+ boolean isCreate = file.createNewFile();
+ if (isCreate){
+ LOG.info("File " + file + " is created.");
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+
+ public static String readJsonFile(String fileName) {
+ String jsonStr = "";
+ try {
+ File jsonFile = new File(fileName);
+ FileReader fileReader = new FileReader(jsonFile);
+
+ Reader reader = new InputStreamReader(new FileInputStream(jsonFile), "utf-8");
+ int ch = 0;
+ StringBuffer sb = new StringBuffer();
+ while ((ch = reader.read()) != -1) {
+ sb.append((char) ch);
+ }
+
+ fileReader.close();
+ reader.close();
+ jsonStr = sb.toString();
+ return jsonStr;
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public static String getFileName(File file){
+ String[] tmp = file.toString().split("/");
+ String fileName = tmp[tmp.length-1];
+ return fileName;
+ }
+
+
+ public static void writerClose(OutputStreamWriter outWriter, OutputStream outStream) throws IOException {
+ assert outWriter != null;
+ outWriter.close();
+ outStream.close();
+ }
+
+ public static void readerClose(BufferedReader bufferedReader, InputStreamReader inputStreamReader) throws IOException {
+ assert inputStreamReader != null;
+ bufferedReader.close();
+ inputStreamReader.close();
+ }
+
+ //执行cmd命令,获取返回结果
+ public static String execCMD(String command) {
+ StringBuilder sb =new StringBuilder();
+ try {
+ Process process=Runtime.getRuntime().exec(command);
+ BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(process.getInputStream()));
+ String line;
+ while((line=bufferedReader.readLine())!=null)
+ {
+ sb.append(line+"\n");
+ }
+ } catch (Exception e) {
+ return e.toString();
+ }
+ return sb.toString();
+ }
+
+ public static Long getFileLineNum(File file){
+ Long num = 0L;
+ if (!file.exists()){
+ LOG.error("File not exist: " + file.toString());
+ } else {
+ String res = FileUtils.execCMD("wc -l " + file.toString());
+ num = Long.parseLong(res.trim().split(" ")[0]);
+ }
+ return num;
+ }
+
+ public static int getMaxLength(String filePath) {
+ int lengthDomain = 0;
+ try {
+ String encoding = "UTF-8";
+ File file = new File(filePath);
+ if (file.isFile() && file.exists()) {
+ InputStreamReader read = new InputStreamReader(
+ new FileInputStream(file), encoding);
+ BufferedReader bufferedReader = new BufferedReader(read);
+ String lineTxt = null;
+ while ((lineTxt = bufferedReader.readLine()) != null) {
+ String[] split = lineTxt.split("\\.");
+ if (split.length > lengthDomain) {
+ lengthDomain = split.length;
+ }
+ }
+ read.close();
+ } else {
+ LOG.error("FilePath is wrong--->{" + filePath + "}<---");
+ }
+ } catch (Exception e) {
+ LOG.error("Get filePathData error--->{" + e + "}<---");
+ e.printStackTrace();
+ }
+ return lengthDomain;
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/util/MariaDBUtils.java b/src/main/java/com/mesasoft/cn/util/MariaDBUtils.java
new file mode 100644
index 0000000..a86b363
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/util/MariaDBUtils.java
@@ -0,0 +1,80 @@
+package com.mesasoft.cn.util;
+
+import com.alibaba.druid.pool.DruidDataSourceFactory;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Properties;
+
+/**
+ * Druid连接池的工具类
+ */
+public class MariaDBUtils {
+ private static DataSource ds ;
+
+ static{
+ try {
+ Properties pro = new Properties();
+// pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
+ ds = DruidDataSourceFactory.createDataSource(pro);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 获取连接
+ */
+ public static Connection getConnection() throws SQLException {
+ return ds.getConnection();
+ }
+
+ /**
+ * 释放资源
+ */
+ public static void close(Statement stmt,Connection conn){
+
+ close(null,stmt,conn);
+ }
+
+
+ public static void close(ResultSet rs , Statement stmt, Connection conn){
+
+
+ if(rs != null){
+ try {
+ rs.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ if(stmt != null){
+ try {
+ stmt.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ if(conn != null){
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * 获取连接池方法
+ */
+ public static DataSource getDataSource(){
+ return ds;
+ }
+
+} \ No newline at end of file
diff --git a/src/main/java/com/mesasoft/cn/util/MariaDbBase.java b/src/main/java/com/mesasoft/cn/util/MariaDbBase.java
new file mode 100644
index 0000000..777ec44
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/util/MariaDbBase.java
@@ -0,0 +1,84 @@
+package com.mesasoft.cn.util;
+
+import com.mesasoft.cn.sketch.config.ApplicationConfig;
+import org.apache.log4j.Logger;
+
+import java.sql.*;
+import java.util.Date;
+import java.util.Properties;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: joy
+ * Date: 2021/12/28
+ * Time: 2:56 PM
+ * Description: No Description
+ */
+public class MariaDbBase {
+
+ private static final Logger LOG = Logger.getLogger(MariaDbBase.class);
+ private static final Properties props = new Properties();
+
+ private final Statement statement;
+
+ public MariaDbBase(Connection conn, Statement stat) {
+ statement = stat;
+ }
+
+ /**
+ * 执行写入sql
+ */
+ public void writeSqlExecute(String sql){
+ try {
+ statement.executeUpdate(sql);
+ } catch (SQLIntegrityConstraintViolationException e){
+ LOG.error("Duplicated entry for key 'PRIMARY'");
+ } catch (SQLException exception) {
+ LOG.error("Sql : " + sql);
+ exception.printStackTrace();
+ }
+ }
+
+ /**
+ * 执行查询sql
+ */
+ public ResultSet querySqlExecute(String sql){
+ ResultSet set = null;
+ try {
+ set = statement.executeQuery(sql);
+ } catch (SQLException exception) {
+ exception.printStackTrace();
+ }
+ return set;
+ }
+
+
+ /**
+ * 获得指定表格、按指定时间字段的过期记录
+ * @param tableName 库表名称
+ * @param timeColumnName 时间列名
+ * @return 查询结果
+ */
+ public ResultSet getExpiredRecord(String tableName, String timeColumnName){
+ Date lastUpdateTime = new Timestamp(getExpiredTime(ApplicationConfig.UPDATE_EXPIRED_DAY).getTime());
+
+ String resSql = "SELECT *"
+ + " FROM " + ApplicationConfig.DATABASE + "." + tableName
+ + " WHERE " + timeColumnName + " < '" + lastUpdateTime + '\'';
+
+ LOG.debug("Update task: expired query sql" + resSql);
+
+ return querySqlExecute(resSql);
+ }
+
+ /**
+ * TODO: getUnlabeledRecord() 考虑多个来源的情况
+ */
+
+ /**
+ * 获得过期时间, 当前时间的expiredRangeDays天之前的日期为过期日期
+ */
+ public static Date getExpiredTime(int expiredRangeDays){
+ return new Timestamp(TimeUtils.getStartOfDay(-expiredRangeDays).getTime());
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/util/ServiceUtils.java b/src/main/java/com/mesasoft/cn/util/ServiceUtils.java
new file mode 100644
index 0000000..2e3b542
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/util/ServiceUtils.java
@@ -0,0 +1,59 @@
+package com.mesasoft.cn.util;
+
+import com.mesasoft.cn.service.ICategoryService;
+import com.mesasoft.cn.service.IFileService;
+import com.mesasoft.cn.service.IUserService;
+import com.zhazhapan.modules.constant.ValueConsts;
+import com.zhazhapan.util.Checker;
+import com.zhazhapan.util.ReflectUtils;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * @author pantao
+ * @since 2018/2/28
+ */
+@Component
+public class ServiceUtils {
+
+ private static IUserService userService;
+
+ private static IFileService fileService;
+
+ private static ICategoryService categoryService;
+
+ private static Logger logger = Logger.getLogger(ServiceUtils.class);
+
+ @Autowired
+ public ServiceUtils(IUserService userService, IFileService fileService, ICategoryService categoryService) {
+ ServiceUtils.userService = userService;
+ ServiceUtils.fileService = fileService;
+ ServiceUtils.categoryService = categoryService;
+ }
+
+ public static int getUserId(String usernameOrEmail) {
+ return Checker.isEmpty(usernameOrEmail) ? ValueConsts.ZERO_INT : userService.getUserId(usernameOrEmail);
+ }
+
+ public static long getFileId(String fileName) {
+ return Checker.isEmpty(fileName) ? ValueConsts.ZERO_INT : fileService.getFileId(fileName);
+ }
+
+ public static int getCategoryId(String categoryName) {
+ return Checker.isEmpty(categoryName) ? ValueConsts.ZERO_INT : categoryService.getIdByName(categoryName);
+ }
+
+ public static Object invokeFileFilter(Object object, String methodName, String user, String file, String
+ category, int offset) {
+ try {
+ return ReflectUtils.invokeMethodUseBasicType(object, methodName, new Object[]{getUserId(user), getFileId
+ (file), file, getCategoryId(category), offset});
+ } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
+ logger.error(e.getMessage());
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/util/TimeUtils.java b/src/main/java/com/mesasoft/cn/util/TimeUtils.java
new file mode 100644
index 0000000..5e128dd
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/util/TimeUtils.java
@@ -0,0 +1,59 @@
+package com.mesasoft.cn.util;
+
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ * @author yjy
+ * @version 1.0
+ * @date 2021/2/25 11:26 上午
+ */
+public class TimeUtils {
+ public static final Long HOUR_TO_MILLISECONDS = 3600000L;
+ public static final Long DAY_TO_MILLSEDONDS = 86400000L;
+ public static final Integer SECOND_TO_MILLSEDONDS = 1000;
+
+
+ /**
+ * 获得当前时间小时的起始(0分钟)时间
+ */
+ public static Date getStartOfHour() {
+ return getStartOfHour(0);
+ }
+ public static Date getStartOfHour(Integer offset) {
+ Calendar ca = Calendar.getInstance();
+ ca.add(Calendar.HOUR, offset);
+ ca.set(Calendar.MINUTE, 0);
+ ca.set(Calendar.SECOND, 0);
+ ca.set(Calendar.MILLISECOND, 0);
+ return ca.getTime();
+ }
+
+ /**
+ * 获得当前日期的起始(0时)时间
+ */
+ public static Date getStartOfDay() {
+ return getStartOfDay(0);
+ }
+ public static Date getStartOfDay(Integer bias) {
+ Calendar ca = Calendar.getInstance();
+ ca.add(Calendar.DATE, bias);
+ ca.set(Calendar.HOUR, -12);
+ ca.set(Calendar.MINUTE, 0);
+ ca.set(Calendar.SECOND, 0);
+ ca.set(Calendar.MILLISECOND, 0);
+ return ca.getTime();
+ }
+
+ public static Date getStartOfMonth() {
+ Calendar ca = Calendar.getInstance();
+ ca.set(Calendar.DATE, 1);
+ ca.set(Calendar.HOUR, -12);
+ ca.set(Calendar.MINUTE, 0);
+ ca.set(Calendar.SECOND, 0);
+ ca.set(Calendar.MILLISECOND, 0);
+ return ca.getTime();
+ }
+
+}
+
diff --git a/src/main/java/com/mesasoft/cn/util/ValidationUtils.java b/src/main/java/com/mesasoft/cn/util/ValidationUtils.java
new file mode 100644
index 0000000..013008e
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/util/ValidationUtils.java
@@ -0,0 +1,202 @@
+package com.mesasoft.cn.util;
+
+import com.mesasoft.cn.sketch.api.BrightCloud;
+import com.mesasoft.cn.sketch.config.ApplicationConfig;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.log4j.Logger;
+import sun.net.util.IPAddressUtil;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ValidationUtils {
+ private static final Logger LOG = Logger.getLogger(ValidationUtils.class);
+
+ /**
+ * 获取二级域名
+ **/
+ public static String getSecDomain(String fqdnOrUrl){
+ String filePath = Objects.requireNonNull(BrightCloud.class.getClassLoader()
+ .getResource(ApplicationConfig.TLD_FILE)).getFile();
+ HashMap<String, HashMap<String, String>> maps = readTopDomainFile(filePath);
+ try {
+ String[] split = fqdnOrUrl.split("\\.");
+ String secDomain = null;
+ for (int i = split.length - 1; i >= 0; i--) {
+ int maps_index = split.length - (i + 1);
+ HashMap<String, String> innerMap = maps.get("map_id_" + maps_index);
+ HashMap<String, String> fullTop = maps.get("full");
+ if (!(innerMap.containsKey(split[i]))) {
+ String strSec = "";
+ for (int j = i; j < split.length; j++) {
+ strSec += (split[j] + ".");
+ }
+ secDomain = strSec.substring(0, strSec.length() - 1);
+ if (fullTop.containsKey(getTopFromSecDomain(secDomain))) {
+ break;
+ } else {
+ while (!fullTop.containsKey(getTopFromSecDomain(secDomain)) && getTopFromSecDomain(secDomain).contains(".")) {
+ secDomain = getTopFromSecDomain(secDomain);
+ }
+ break;
+ }
+ }
+ }
+ // 右匹配为顶级域名
+ if (secDomain == null){
+ secDomain = fqdnOrUrl;
+ }
+ return secDomain;
+ } catch (Exception e) {
+ LOG.error("urlDomain:" + fqdnOrUrl);
+ e.printStackTrace();
+ return "---no---return---";
+ }
+ }
+
+ public static List<String> getSecDomain(List<String> fqdnOrUrls) {
+ HashMap<String, HashMap<String, String>> maps = readTopDomainFile(ApplicationConfig.TLD_FILE);
+ List<String> secDomainList = new ArrayList<>();
+ for (String oriDomain : fqdnOrUrls) {
+ String secDomain = getSecDomain(oriDomain);
+ if (StringUtils.isNotBlank(secDomain) && !("---no---return---".equals(secDomain))) {
+ secDomainList.add(secDomain);
+ } else {
+ System.out.println(oriDomain);
+ }
+ }
+ return secDomainList;
+ }
+
+ public static String getTopFromSecDomain(String secDomain) {
+ String quFirstDian = secDomain;
+ if (secDomain.contains(".")) {
+ quFirstDian = secDomain.substring(secDomain.indexOf(".")).substring(1);
+ }
+ return quFirstDian;
+ }
+
+ public static HashMap<String, HashMap<String, String>> readTopDomainFile(String filePath) {
+ HashMap<String, HashMap<String, String>> maps = makeHashMap(filePath);
+ try {
+ String encoding = "UTF-8";
+ File file = new File(filePath);
+ if (file.isFile() && file.exists()) {
+ InputStreamReader read = new InputStreamReader(
+ new FileInputStream(file), encoding);
+ BufferedReader bufferedReader = new BufferedReader(read);
+ String lineTxt = null;
+ while ((lineTxt = bufferedReader.readLine()) != null) {
+ HashMap<String, String> fullTop = maps.get("full");
+ fullTop.put(lineTxt, lineTxt);
+ maps.put("full", fullTop);
+ String[] split = lineTxt.split("\\.");
+ for (int i = split.length - 1; i >= 0; i--) {
+ int maps_index = split.length - (i + 1);
+ HashMap<String, String> innerMap = maps.get("map_id_" + maps_index);
+ innerMap.put(split[i], split[i]);
+ maps.put("map_id_" + maps_index, innerMap);
+ }
+ }
+ read.close();
+ } else {
+ LOG.error("TopDomainUtils>=>readTopDomainFile filePath is wrong--->{" + filePath + "}<---");
+ }
+ } catch (Exception e) {
+ LOG.error("TopDomainUtils>=>readTopDomainFile get filePathData error--->{" + e + "}<---");
+ e.printStackTrace();
+ }
+ return maps;
+ }
+
+ public static HashMap<String, HashMap<String, String>> makeHashMap(String filePath) {
+ int maxLength = FileUtils.getMaxLength(filePath);
+ HashMap<String, HashMap<String, String>> maps = new HashMap<String, HashMap<String, String>>();
+ for (int i = 0; i < maxLength; i++) {
+ maps.put("map_id_" + i, new HashMap<String, String>());
+ }
+ maps.put("full", new HashMap<String, String>());
+ return maps;
+ }
+
+ public static List<String> getChecked(List<String> objectList, String type){
+ if (type.equals("ip")){
+ return getCheckedIps(objectList);
+ }
+ if (type.equals("domain")){
+ return getCheckedFqdns(objectList);
+ }
+ LOG.error("Wrong type to be checked: " + type);
+ return objectList;
+ }
+
+ public static List<String> getCheckedFqdns(List<String> fqdns){
+ List<String> res = new ArrayList<>();
+ for (String fqdn:fqdns){
+ //去端口号
+ fqdn = fqdn.split(":")[0];
+ // 去重 & 校验
+ if (isValidDomain(fqdn) && !res.contains(fqdn)){
+ res.add(fqdn.toLowerCase());
+ } else {
+ LOG.debug("Bad or duplicated fqdn:" + fqdn);
+ }
+ }
+ return res;
+ }
+
+ public static List<String> getCheckedIps(List<String> ipList){
+ List<String> res = new ArrayList<>();
+ for (String ip:ipList){
+ //去端口号
+ ip = ip.split(":")[0];
+ // 去重 & 校验
+ if (isValidIp(ip) && !res.contains(ip)){
+ res.add(ip.toLowerCase());
+ } else {
+ LOG.debug("Bad or duplicated fqdn:" + ip);
+ }
+ }
+ return res;
+ }
+
+ public static boolean isValidIp(String ip){
+ boolean iPv4LiteralAddress = IPAddressUtil.isIPv4LiteralAddress(ip);
+ boolean iPv6LiteralAddress = IPAddressUtil.isIPv6LiteralAddress(ip);
+ return iPv4LiteralAddress || iPv6LiteralAddress;
+ }
+
+ private static boolean isValidDomain(String str)
+ {
+ String regex = "^((?!-)[A-Za-z0-9-_]"
+ + "{1,63}(?<!-)\\.)"
+ + "+[A-Za-z]{2,6}";
+ Pattern p = Pattern.compile(regex);
+
+ if (str == null) {
+ return false;
+ }
+ Matcher m = p.matcher(str);
+ return m.matches();
+ }
+
+ public static Integer getMatchPattern(String fqdn){
+ int match_pattern = 2;
+ if (fqdn.equals(getSecDomain(fqdn))){
+ match_pattern = 1; // 二级域名-右匹配
+ }
+ return match_pattern;
+ }
+
+
+
+
+}
diff --git a/src/main/java/com/mesasoft/cn/util/Verify.java b/src/main/java/com/mesasoft/cn/util/Verify.java
new file mode 100644
index 0000000..8e63ea3
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/util/Verify.java
@@ -0,0 +1,20 @@
+package com.mesasoft.cn.util;
+
+import java.util.regex.Pattern;
+
+public class Verify {
+
+
+ private static final String DOMAIN_NAME_PATTERN = "^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,6}$";
+
+ private static Pattern pDomainName = Pattern.compile(DOMAIN_NAME_PATTERN);
+
+ public static boolean domainValid(String domainName) {
+ return pDomainName.matcher(domainName).find();
+ }
+
+ public static void main(String[] args) {
+ boolean b = domainValid("192.168.44.12");
+ System.err.println(b);
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/web/controller/AuthController.java b/src/main/java/com/mesasoft/cn/web/controller/AuthController.java
new file mode 100644
index 0000000..24a4a0b
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/web/controller/AuthController.java
@@ -0,0 +1,66 @@
+package com.mesasoft.cn.web.controller;
+
+import com.mesasoft.cn.annotation.AuthInterceptor;
+import com.mesasoft.cn.enums.InterceptorLevel;
+import com.mesasoft.cn.service.IAuthService;
+import com.mesasoft.cn.util.ControllerUtils;
+import com.zhazhapan.util.Formatter;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author pantao
+ * @since 2018/3/8
+ */
+@RestController
+@RequestMapping("/auth")
+@Api(value = "/auth", description = "权限表相关操作")
+public class AuthController {
+
+ private final IAuthService authService;
+
+ @Autowired
+ public AuthController(IAuthService authService) {this.authService = authService;}
+
+ @ApiOperation(value = "添加权限记录", notes = "设置指定用户对指定文件的权限")
+ @ApiImplicitParams({@ApiImplicitParam(name = "files", value = "文件", example = "file1,file2,file3", required = true),
+ @ApiImplicitParam(name = "users", value = "用户", example = "user1,user2,user3", required = true),
+ @ApiImplicitParam(name = "auths", value = "权限", example = "1,1,1,1", required = true)})
+ @AuthInterceptor(InterceptorLevel.ADMIN)
+ @RequestMapping(value = "", method = RequestMethod.POST)
+ public String add(String files, String users, String auths) {
+ System.out.println("files: " + files + " users: " + users + " auths: " + auths);
+ return ControllerUtils.getResponse(authService.addAuth(files, users, auths));
+ }
+
+ @ApiOperation(value = "获取权限记录")
+ @ApiImplicitParams({@ApiImplicitParam(name = "user", value = "用户", required = true), @ApiImplicitParam(name =
+ "file", value = "文件", required = true), @ApiImplicitParam(name = "offset", value = "偏移量", required = true)})
+ @AuthInterceptor(InterceptorLevel.ADMIN)
+ @RequestMapping(value = "/all", method = RequestMethod.GET)
+ public String getAuth(String user, String file, int offset) {
+ return Formatter.listToJson(authService.listAuth(user, file, offset));
+ }
+
+ @ApiOperation(value = "更新权限记录")
+ @ApiImplicitParams({@ApiImplicitParam(name = "auth", value = "权限值", required = true)})
+ @AuthInterceptor(InterceptorLevel.ADMIN)
+ @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
+ public String updateAuth(@PathVariable("id") long id, String auth) {
+ return ControllerUtils.getResponse(authService.updateAuth(id, auth));
+ }
+
+ @ApiOperation(value = "批量删除权限记录")
+ @AuthInterceptor(InterceptorLevel.ADMIN)
+ @RequestMapping(value = "/batch/{ids}", method = RequestMethod.DELETE)
+ public String batchDelete(@PathVariable("ids") String ids) {
+ return ControllerUtils.getResponse(authService.batchDelete(ids));
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/web/controller/CategoryController.java b/src/main/java/com/mesasoft/cn/web/controller/CategoryController.java
new file mode 100644
index 0000000..41bf74e
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/web/controller/CategoryController.java
@@ -0,0 +1,75 @@
+package com.mesasoft.cn.web.controller;
+
+import com.mesasoft.cn.annotation.AuthInterceptor;
+import com.mesasoft.cn.entity.Category;
+import com.mesasoft.cn.enums.InterceptorLevel;
+import com.mesasoft.cn.service.ICategoryService;
+import com.mesasoft.cn.util.ControllerUtils;
+import com.zhazhapan.modules.constant.ValueConsts;
+import com.zhazhapan.util.Checker;
+import com.zhazhapan.util.Formatter;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author pantao
+ * @since 2018/1/30
+ */
+@RestController
+@RequestMapping("/category")
+@Api(value = "/category", description = "文件分类相关操作")
+public class CategoryController {
+
+ private final ICategoryService categoryService;
+
+ @Autowired
+ public CategoryController(ICategoryService categoryService) {this.categoryService = categoryService;}
+
+ @ApiOperation(value = "新增一个分类")
+ @AuthInterceptor(InterceptorLevel.ADMIN)
+ @RequestMapping(value = "/{name}", method = RequestMethod.POST)
+ public String add(@PathVariable("name") String name) {
+ return ControllerUtils.getResponse(categoryService.insert(name));
+ }
+
+ @ApiOperation(value = "更新分类名称")
+ @ApiImplicitParam(name = "name", value = "新的名称", required = true)
+ @AuthInterceptor(InterceptorLevel.ADMIN)
+ @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
+ public String update(@PathVariable("id") int id, String name) {
+ boolean isSuccess = Checker.isNotEmpty(name) && categoryService.update(id, name);
+ return ControllerUtils.getResponse(isSuccess);
+ }
+
+ @ApiOperation(value = "删除一个分类")
+ @AuthInterceptor(InterceptorLevel.ADMIN)
+ @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
+ public String remove(@PathVariable("id") int id) {
+ return ControllerUtils.getResponse(categoryService.remove(id));
+ }
+
+ @ApiOperation(value = "获取一个分类")
+ @AuthInterceptor(InterceptorLevel.NONE)
+ @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+ public String getById(@PathVariable("id") int id) {
+ Category category = categoryService.getById(id);
+ if (Checker.isNull(category)) {
+ return ControllerUtils.getResponse(ValueConsts.FALSE);
+ } else {
+ return category.toString();
+ }
+ }
+
+ @ApiOperation(value = "获取所有分类")
+ @AuthInterceptor(InterceptorLevel.NONE)
+ @RequestMapping(value = "/all", method = RequestMethod.GET)
+ public String getAll() {
+ return Formatter.listToJson(categoryService.list());
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/web/controller/CommonController.java b/src/main/java/com/mesasoft/cn/web/controller/CommonController.java
new file mode 100644
index 0000000..493de1b
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/web/controller/CommonController.java
@@ -0,0 +1,94 @@
+package com.mesasoft.cn.web.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.mesasoft.cn.modules.constant.DefaultValues;
+import com.mesasoft.cn.annotation.AuthInterceptor;
+import com.mesasoft.cn.config.SettingConfig;
+import com.mesasoft.cn.enums.InterceptorLevel;
+import com.mesasoft.cn.service.ICommonService;
+import com.mesasoft.cn.util.ControllerUtils;
+import com.zhazhapan.modules.constant.ValueConsts;
+import com.zhazhapan.util.Checker;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * @author pantao
+ * @since 2018/1/23
+ */
+@RestController
+@RequestMapping("/common")
+@Api(value = "/common", description = "公共接口")
+public class CommonController {
+
+ private static Logger logger = LoggerFactory.getLogger(ConfigController.class);
+
+ private final ICommonService commonService;
+
+ private final HttpServletRequest request;
+
+ private final JSONObject jsonObject;
+
+ @Autowired
+ public CommonController(ICommonService commonService, HttpServletRequest request, JSONObject jsonObject) {
+ this.commonService = commonService;
+ this.request = request;
+ this.jsonObject = jsonObject;
+ }
+
+ @ApiOperation(value = "获取头像资源")
+ @AuthInterceptor(InterceptorLevel.NONE)
+ @RequestMapping(value = "/avatar/{name}", method = RequestMethod.GET)
+ public void getAvatar(HttpServletResponse response, @PathVariable("name") String name) throws IOException {
+ String path = SettingConfig.getAvatarStoragePath() + ValueConsts.SEPARATOR + name;
+ ControllerUtils.loadResource(response, path, ValueConsts.FALSE);
+ }
+
+ @ApiOperation(value = "上传头像")
+ @ApiImplicitParam(name = "multipartFile", value = "头像", required = true)
+ @AuthInterceptor(InterceptorLevel.USER)
+ @RequestMapping(value = "/avatar", method = RequestMethod.POST)
+ public String avatarUpload(@RequestParam("file") MultipartFile multipartFile) {
+ String name = commonService.uploadAvatar(multipartFile);
+ if (Checker.isEmpty(name)) {
+ jsonObject.put("error", "文件格式不合法");
+ } else {
+ jsonObject.put("success", "/common/avatar/" + name);
+ }
+ return jsonObject.toString();
+ }
+
+ @ApiOperation(value = "发送验证码")
+ @AuthInterceptor(InterceptorLevel.NONE)
+ @RequestMapping(value = "/{email}/code", method = RequestMethod.POST)
+ public String sendVerifyCode(@PathVariable("email") String email) {
+ int code = commonService.sendVerifyCode(email);
+ if (code > 0) {
+ request.getSession().setAttribute(DefaultValues.CODE_STRING, code);
+ logger.info("verify code: " + code);
+ jsonObject.put("status", "success");
+ } else {
+ jsonObject.put("status", "error");
+ }
+ return jsonObject.toString();
+ }
+
+ @ApiOperation(value = "验证验证码是否正确")
+ @AuthInterceptor(InterceptorLevel.NONE)
+ @RequestMapping(value = "/{code}/verification", method = RequestMethod.PUT)
+ public String verifyCode(@PathVariable("code") String code) {
+ boolean isSuccess = Checker.checkNull(code).equals(String.valueOf(request.getSession().getAttribute
+ (DefaultValues.CODE_STRING)));
+ return ControllerUtils.getResponse(isSuccess);
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/web/controller/ConfigController.java b/src/main/java/com/mesasoft/cn/web/controller/ConfigController.java
new file mode 100644
index 0000000..e13bf35
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/web/controller/ConfigController.java
@@ -0,0 +1,92 @@
+package com.mesasoft.cn.web.controller;
+
+import com.mesasoft.cn.SketchApplication;
+import com.mesasoft.cn.modules.constant.DefaultValues;
+import com.mesasoft.cn.annotation.AuthInterceptor;
+import com.mesasoft.cn.entity.User;
+import com.mesasoft.cn.enums.InterceptorLevel;
+import com.mesasoft.cn.service.IConfigService;
+import com.zhazhapan.modules.constant.ValueConsts;
+import com.zhazhapan.util.FileExecutor;
+import com.zhazhapan.util.NetUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+
+/**
+ * @author pantao
+ * @since 2018/1/22
+ */
+@RestController
+@RequestMapping("/config")
+@Api(value = "/config", description = "配置文件的相关操作")
+public class ConfigController {
+
+ private static Logger logger = Logger.getLogger(ConfigController.class);
+
+ private final IConfigService configService;
+
+ private final HttpServletRequest request;
+
+ @Autowired
+ public ConfigController(IConfigService configService, HttpServletRequest request) {
+ this.configService = configService;
+ this.request = request;
+ }
+
+ @ApiOperation(value = "更新配置文件")
+ @ApiImplicitParam(name = "config", value = "配置文件内容", required = true)
+ @AuthInterceptor(InterceptorLevel.ADMIN)
+ @RequestMapping(value = "", method = RequestMethod.PUT)
+ public String updateConfig(String config) {
+ User user = (User) request.getSession().getAttribute(ValueConsts.USER_STRING);
+ if (user.getPermission() > ValueConsts.TWO_INT) {
+ SketchApplication.settings.setJsonObject(config);
+ //打包成jar之后无法修改config.json文件
+ try {
+ FileExecutor.saveFile(NetUtils.urlToString(SketchApplication.class.getResource(DefaultValues
+ .SETTING_PATH)), SketchApplication.settings.toString());
+ } catch (IOException e) {
+ logger.error(e.getMessage());
+ return "{\"message\":\"internal error, cannot save\"}";
+ }
+ return "{\"message\":\"saved successfully\"}";
+ } else {
+ return "{\"message\":\"permission denied\"}";
+ }
+ }
+
+ @ApiOperation(value = "获取配置文件内容")
+ @AuthInterceptor(InterceptorLevel.ADMIN)
+ @RequestMapping(value = "/all", method = RequestMethod.GET)
+ public String getAll() {
+ User user = (User) request.getSession().getAttribute(ValueConsts.USER_STRING);
+ if (user.getPermission() > ValueConsts.TWO_INT) {
+ return SketchApplication.settings.toString();
+ } else {
+ return "{\"message\":\"permission denied\"}";
+ }
+ }
+
+ @ApiOperation(value = "获取配置文件中的全局相关配置内容")
+ @AuthInterceptor(InterceptorLevel.NONE)
+ @RequestMapping(value = "/global", method = RequestMethod.GET)
+ public String getGlobalConfig() {
+ return configService.getGlobalConfig();
+ }
+
+ @ApiOperation(value = "获取配置文件中的用户相关配置内容")
+ @AuthInterceptor(InterceptorLevel.NONE)
+ @RequestMapping(value = "/user", method = RequestMethod.GET)
+ public String getUserConfig() {
+ return configService.getUserConfig();
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/web/controller/CustomErrorController.java b/src/main/java/com/mesasoft/cn/web/controller/CustomErrorController.java
new file mode 100644
index 0000000..bc22a1d
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/web/controller/CustomErrorController.java
@@ -0,0 +1,42 @@
+package com.mesasoft.cn.web.controller;
+
+import com.mesasoft.cn.annotation.AuthInterceptor;
+import com.mesasoft.cn.enums.InterceptorLevel;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.boot.web.servlet.error.ErrorController;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import springfox.documentation.annotations.ApiIgnore;
+
+/**
+ * @author pantao
+ * @since 2018/1/22
+ */
+@Controller
+@Api(description = "错误页面映射")
+public class CustomErrorController implements ErrorController {
+
+ @ApiOperation(value = "异常页面")
+ @AuthInterceptor(InterceptorLevel.NONE)
+ @RequestMapping("/exception")
+ public String handleError() {
+ return "error";
+ }
+
+ @ApiOperation(value = "404、错误页面")
+ @AuthInterceptor(InterceptorLevel.NONE)
+ @RequestMapping("/error")
+ @ResponseStatus(HttpStatus.NOT_FOUND)
+ public String handleNotFound() {
+ return "/404";
+ }
+
+ @ApiIgnore
+ @Override
+ public String getErrorPath() {
+ return "/error";
+ }
+} \ No newline at end of file
diff --git a/src/main/java/com/mesasoft/cn/web/controller/DownloadedController.java b/src/main/java/com/mesasoft/cn/web/controller/DownloadedController.java
new file mode 100644
index 0000000..324aeaa
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/web/controller/DownloadedController.java
@@ -0,0 +1,41 @@
+package com.mesasoft.cn.web.controller;
+
+import com.mesasoft.cn.annotation.AuthInterceptor;
+import com.mesasoft.cn.enums.InterceptorLevel;
+import com.mesasoft.cn.service.IDownloadedService;
+import com.zhazhapan.util.Formatter;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author pantao
+ * @since 2018/2/9
+ */
+@RestController
+@RequestMapping(value = "/downloaded")
+@Api(value = "/downloaded", description = "下载记录相关操作")
+public class DownloadedController {
+
+ private final IDownloadedService downloadService;
+
+ @Autowired
+ public DownloadedController(IDownloadedService downloadService) {
+ this.downloadService = downloadService;
+ }
+
+ @ApiOperation(value = "获取文件下载记录")
+ @ApiImplicitParams({@ApiImplicitParam(name = "user", value = "指定用户(默认所有用户)"), @ApiImplicitParam(name =
+ "指定文件(默认所有文件)"), @ApiImplicitParam(name = "category", value = "指定分类(默认所有分类)"), @ApiImplicitParam(name =
+ "offset", value = "偏移量", required = true)})
+ @AuthInterceptor(InterceptorLevel.ADMIN)
+ @RequestMapping(value = "all", method = RequestMethod.GET)
+ public String getAll(String user, String file, String category, int offset) {
+ return Formatter.listToJson(downloadService.list(user, file, category, offset));
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/web/controller/FileController.java b/src/main/java/com/mesasoft/cn/web/controller/FileController.java
new file mode 100644
index 0000000..6ae6d57
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/web/controller/FileController.java
@@ -0,0 +1,220 @@
+package com.mesasoft.cn.web.controller;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.mesasoft.cn.SketchApplication;
+import com.mesasoft.cn.modules.constant.ConfigConsts;
+import com.mesasoft.cn.util.BeanUtils;
+import com.mesasoft.cn.annotation.AuthInterceptor;
+import com.mesasoft.cn.entity.User;
+import com.mesasoft.cn.enums.InterceptorLevel;
+import com.mesasoft.cn.service.IFileService;
+import com.mesasoft.cn.util.ControllerUtils;
+import com.zhazhapan.modules.constant.ValueConsts;
+import com.zhazhapan.util.Checker;
+import com.zhazhapan.util.FileExecutor;
+import com.zhazhapan.util.Formatter;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @author pantao
+ * @since 2018/1/29
+ */
+@RestController
+@RequestMapping("/file")
+@Api(value = "/file", description = "文件相关操作")
+public class FileController {
+
+ private final IFileService fileService;
+
+ private final HttpServletRequest request;
+
+ private final JSONObject jsonObject;
+
+ @Autowired
+ public FileController(IFileService fileService, HttpServletRequest request, JSONObject jsonObject) {
+ this.fileService = fileService;
+ this.request = request;
+ this.jsonObject = jsonObject;
+ }
+
+ @ApiOperation(value = "获取我的下载记录")
+ @ApiImplicitParams({@ApiImplicitParam(name = "offset", value = "偏移量", required = true), @ApiImplicitParam(name =
+ "search", value = "记录匹配(允许为空)")})
+ @AuthInterceptor(InterceptorLevel.USER)
+ @RequestMapping(value = "/user/downloaded", method = RequestMethod.GET)
+ public String getUserDownloaded(int offset, String search) {
+ User user = (User) request.getSession().getAttribute(ValueConsts.USER_STRING);
+ return Formatter.listToJson(fileService.listUserDownloaded(user.getId(), offset, search));
+ }
+
+ @ApiOperation(value = "获取我的上传记录")
+ @ApiImplicitParams({@ApiImplicitParam(name = "offset", value = "偏移量", required = true), @ApiImplicitParam(name =
+ "search", value = "记录匹配(允许为空)")})
+ @AuthInterceptor(InterceptorLevel.USER)
+ @RequestMapping(value = "/user/uploaded", method = RequestMethod.GET)
+ public String getUserUploaded(int offset, String search) {
+ User user = (User) request.getSession().getAttribute(ValueConsts.USER_STRING);
+ return Formatter.listToJson(fileService.listUserUploaded(user.getId(), offset, search));
+ }
+
+ @ApiOperation(value = "文件上传")
+ @ApiImplicitParams({@ApiImplicitParam(name = "categoryId", value = "分类ID", required = true), @ApiImplicitParam
+ (name = "tag", value = "文件标签"), @ApiImplicitParam(name = "description", value = "文件描述"),
+ @ApiImplicitParam(name = "prefix", value = "文件前缀(仅适用于管理员上传文件,普通用户无效)")})
+ @AuthInterceptor(InterceptorLevel.USER)
+ @RequestMapping(value = "", method = RequestMethod.POST)
+ public String upload(int categoryId, String tag, String description, String prefix, @RequestParam("file")
+ MultipartFile multipartFile) {
+ User user = (User) request.getSession().getAttribute(ValueConsts.USER_STRING);
+ return ControllerUtils.getResponse(fileService.upload(categoryId, tag, description, prefix, multipartFile,
+ user));
+ }
+
+ @ApiOperation(value = "获取文件记录")
+ @ApiImplicitParams({@ApiImplicitParam(name = "offset", value = "偏移量", required = true), @ApiImplicitParam(name =
+ "categoryId", value = "分类ID", required = true), @ApiImplicitParam(name = "orderBy", value = "排序方式",
+ required = true, example = "id desc"), @ApiImplicitParam(name = "search", value = "记录匹配(允许为空)")})
+ @AuthInterceptor(InterceptorLevel.NONE)
+ @RequestMapping(value = "/all", method = RequestMethod.GET)
+ public String getAll(int offset, int categoryId, String orderBy, String search) {
+ User user = (User) request.getSession().getAttribute(ValueConsts.USER_STRING);
+ boolean canGet = SketchApplication.settings.getBooleanUseEval(ConfigConsts.ANONYMOUS_VISIBLE_OF_SETTING) ||
+ (Checker.isNotNull(user) && user.getIsVisible() == 1);
+ if (canGet) {
+ int userId = Checker.isNull(user) ? 0 : user.getId();
+ return Formatter.listToJson(fileService.listAll(userId, offset, categoryId, orderBy, search));
+ } else {
+ jsonObject.put("error", "权限被限制,无法获取资源,请联系管理员");
+ return jsonObject.toString();
+ }
+ }
+
+ @ApiOperation(value = "删除指定文件")
+ @AuthInterceptor(InterceptorLevel.USER)
+ @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
+ public String removeFile(@PathVariable("id") long id) {
+ User user = (User) request.getSession().getAttribute(ValueConsts.USER_STRING);
+ jsonObject.put("status", "error");
+ if (Checker.isNull(user)) {
+ jsonObject.put("message", "请先登录");
+ } else if (id < 1) {
+ jsonObject.put("message", "格式不合法");
+ } else if (fileService.removeFile(user, id)) {
+ jsonObject.put("status", "success");
+ } else {
+ jsonObject.put("message", "删除失败,权限不够,请联系管理员");
+ }
+ return jsonObject.toString();
+ }
+
+ @ApiOperation(value = "更新文件属性")
+ @ApiImplicitParams({@ApiImplicitParam(name = "name", value = "文件名", required = true), @ApiImplicitParam(name =
+ "category", value = "分类名称", required = true), @ApiImplicitParam(name = "tag", value = "文件标签", required =
+ true), @ApiImplicitParam(name = "description", value = "文件描述", required = true)})
+ @AuthInterceptor(InterceptorLevel.USER)
+ @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
+ public String updateFileInfo(@PathVariable("id") long id, String name, String category, String tag, String
+ description) {
+ User user = (User) request.getSession().getAttribute(ValueConsts.USER_STRING);
+ jsonObject.put("status", "error");
+ if (fileService.updateFileInfo(id, user, name, category, tag, description)) {
+ jsonObject.put("status", "success");
+ } else {
+ jsonObject.put("message", "格式不正确或权限不够,更新失败,请联系管理员");
+ }
+ return jsonObject.toString();
+ }
+
+ @ApiOperation(value = "获取所有文件的基本信息")
+ @ApiImplicitParams({@ApiImplicitParam(name = "user", value = "指定用户(默认所有用户)"), @ApiImplicitParam(name = "file",
+ value = "指定文件(默认所有文件)"), @ApiImplicitParam(name = "category", value = "指定分类(默认所有分类)"), @ApiImplicitParam
+ (name = "offset", value = "偏移量", required = true)})
+ @AuthInterceptor(InterceptorLevel.ADMIN)
+ @RequestMapping(value = "/basic/all", method = RequestMethod.GET)
+ public String getBasicAll(String user, String file, String category, int offset) {
+ return Formatter.listToJson(fileService.listBasicAll(user, file, category, offset));
+ }
+
+ @ApiOperation(value = "通过文件路径获取服务器端的文件")
+ @ApiImplicitParam(name = "path", value = "文件路径(默认根目录)")
+ @AuthInterceptor(InterceptorLevel.ADMIN)
+ @RequestMapping(value = "/server", method = RequestMethod.GET)
+ public String getServerFilesByPath(String path) {
+ File[] files = FileExecutor.listFile(Checker.isEmpty(path) ? (Checker.isWindows() ? "C:\\" : "/") : path);
+ JSONArray array = new JSONArray();
+ if (Checker.isNotNull(files)) {
+ for (File file : files) {
+ array.add(BeanUtils.beanToJson(file));
+ }
+ }
+ return array.toJSONString();
+ }
+
+ @ApiOperation("分享服务器端文件")
+ @ApiImplicitParams({@ApiImplicitParam(name = "prefix", value = "自定义前缀(可空)"), @ApiImplicitParam(name = "files",
+ value = "文件", required = true, example = "file1,file2,file3")})
+ @AuthInterceptor(InterceptorLevel.ADMIN)
+ @RequestMapping(value = "/server/share", method = RequestMethod.POST)
+ public String shareFile(String prefix, String files) {
+ User user = (User) request.getSession().getAttribute(ValueConsts.USER_STRING);
+ return ControllerUtils.getResponse(fileService.shareFiles(Checker.checkNull(prefix), files, user));
+ }
+
+ @ApiOperation(value = "更新文件路径(包括本地路径,访问路径,如果新的本地路径和访问路径均为空,这什么也不会做)")
+ @ApiImplicitParams({@ApiImplicitParam(name = "oldLocalUrl", value = "文件本地路径", required = true), @ApiImplicitParam
+ (name = "localUrl", value = "新的本地路径(可空)"), @ApiImplicitParam(name = "visitUrl", value = "新的访问路径(可空)")})
+ @AuthInterceptor(InterceptorLevel.ADMIN)
+ @RequestMapping(value = "/{id}/url", method = RequestMethod.PUT)
+ public String uploadFileUrl(@PathVariable("id") int id, String oldLocalUrl, String localUrl, String visitUrl) {
+ boolean[] b = fileService.updateUrl(id, oldLocalUrl, localUrl, visitUrl);
+ String responseJson = "{status:{localUrl:" + b[0] + ",visitUrl:" + b[1] + "}}";
+ return Formatter.formatJson(responseJson);
+ }
+
+ @ApiOperation(value = "批量删除文件")
+ @AuthInterceptor(InterceptorLevel.ADMIN)
+ @RequestMapping(value = "/batch/{ids}", method = RequestMethod.DELETE)
+ public String deleteFiles(@PathVariable("ids") String ids) {
+ return ControllerUtils.getResponse(fileService.deleteFiles(ids));
+ }
+
+ @ApiOperation(value = "获取指定文件的权限记录")
+ @AuthInterceptor(InterceptorLevel.ADMIN)
+ @RequestMapping(value = "/{id}/auth", method = RequestMethod.GET)
+ public String getAuth(@PathVariable("id") long id) {
+ return BeanUtils.toPrettyJson(fileService.getAuth(id));
+ }
+
+ @ApiOperation(value = "更新指定文件的权限")
+ @ApiImplicitParam(name = "auth", value = "权限", required = true, example = "1,1,1,1")
+ @AuthInterceptor(InterceptorLevel.ADMIN)
+ @RequestMapping(value = "/{id}/auth", method = RequestMethod.PUT)
+ public String updateAuth(@PathVariable("id") long id, String auth) {
+ return ControllerUtils.getResponse(fileService.updateAuth(id, auth));
+ }
+
+ /**
+ * 资源下载
+ *
+ * @param response {@link HttpServletResponse}
+ */
+ @ApiOperation(value = "通过访问路径获取文件资源")
+ @AuthInterceptor(InterceptorLevel.NONE)
+ @RequestMapping(value = "/**", method = RequestMethod.GET)
+ public void getResource(HttpServletResponse response) throws IOException {
+ ControllerUtils.loadResource(response, fileService.getResource(request.getServletPath(), request),
+ ValueConsts.FALSE);
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/web/controller/FileMangerController.java b/src/main/java/com/mesasoft/cn/web/controller/FileMangerController.java
new file mode 100644
index 0000000..ca7dbff
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/web/controller/FileMangerController.java
@@ -0,0 +1,188 @@
+package com.mesasoft.cn.web.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.mesasoft.cn.annotation.AuthInterceptor;
+import com.mesasoft.cn.enums.InterceptorLevel;
+import com.mesasoft.cn.service.IFileManagerService;
+import com.mesasoft.cn.util.ControllerUtils;
+import com.zhazhapan.modules.constant.ValueConsts;
+import com.zhazhapan.util.ArrayUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * <a href="https://github.com/joni2back/angular-filemanager/blob/master/API.md">see api doc</a>
+ *
+ * @author pantao
+ * @since 2018/1/29
+ */
+@ApiIgnore
+@RestController
+@RequestMapping("/filemanager")
+@AuthInterceptor(InterceptorLevel.SYSTEM)
+public class FileMangerController {
+
+ private final IFileManagerService fileManagerService;
+
+ private final JSONObject jsonObject;
+
+ @Autowired
+ public FileMangerController(IFileManagerService fileManagerService, JSONObject jsonObject) {
+ this.fileManagerService = fileManagerService;
+ this.jsonObject = jsonObject;
+ }
+
+ @AuthInterceptor(InterceptorLevel.SYSTEM)
+ @RequestMapping(value = "/multidownload", method = RequestMethod.GET)
+ public void multiDownload(HttpServletResponse response, String[] items, String toFilename) throws IOException {
+ ControllerUtils.setResponseFileName(response, toFilename);
+ fileManagerService.multiDownload(response, items, toFilename);
+ }
+
+ @AuthInterceptor(InterceptorLevel.SYSTEM)
+ @RequestMapping(value = "/download", method = RequestMethod.GET)
+ public void download(HttpServletResponse response, String path) throws IOException {
+ ControllerUtils.loadResource(response, path, ValueConsts.TRUE);
+ }
+ public static String getEncoding(String str) {
+ String encode = "GB2312";
+ String finecode = "";
+ try {
+ if (str.equals(new String(str.getBytes(encode), encode))) {
+ finecode = encode;
+ }
+ } catch (Exception exception) {
+ }
+ encode = "ISO-8859-1";
+ try {
+ if (str.equals(new String(str.getBytes(encode), encode))) {
+ finecode = encode;
+ }
+ } catch (Exception exception1) {
+ }
+ encode = "GBK";
+ try {
+ if (str.equals(new String(str.getBytes(encode), encode))) {
+ finecode = encode;
+ }
+ } catch (Exception exception1) {
+ }
+ encode = "UTF-8";
+ try {
+ if (str.equals(new String(str.getBytes(encode), encode))) {
+ finecode = encode;
+ }
+ } catch (Exception exception2) {
+ }
+ encode = "GBK";
+ try {
+ if (str.equals(new String(str.getBytes(encode), encode))) {
+ finecode = encode;
+ }
+ } catch (Exception exception3) {
+ }
+ return finecode;
+ }
+ /**
+ * 暂时没有找到更好的解决方案
+ *
+ * @param destination 目的
+ *
+ * @return 响应结果
+ */
+ @AuthInterceptor(InterceptorLevel.SYSTEM)
+ @RequestMapping(value = "/upload", method = RequestMethod.POST)
+ public String upload(String destination, MultipartHttpServletRequest request) {
+ Map<String, MultipartFile> fileMap = request.getFileMap();
+ MultipartFile[] files = ArrayUtils.mapToArray(fileMap, MultipartFile.class);
+ jsonObject.put("result", fileManagerService.upload(destination, files));
+ return jsonObject.toJSONString();
+ }
+
+ @AuthInterceptor(InterceptorLevel.SYSTEM)
+ @RequestMapping(value = "/extract", method = RequestMethod.POST)
+ public String extract(@RequestBody JSONObject json) {
+ jsonObject.put("result", fileManagerService.extract(json));
+ return jsonObject.toJSONString();
+ }
+
+ @AuthInterceptor(InterceptorLevel.SYSTEM)
+ @RequestMapping(value = "/compress", method = RequestMethod.POST)
+ public String compress(@RequestBody JSONObject json) {
+ jsonObject.put("result", fileManagerService.compress(json));
+ return jsonObject.toJSONString();
+ }
+
+ @AuthInterceptor(InterceptorLevel.SYSTEM)
+ @RequestMapping(value = "/permission", method = RequestMethod.POST)
+ public String setPermission(@RequestBody JSONObject json) {
+ jsonObject.put("result", fileManagerService.setPermission(json));
+ return jsonObject.toJSONString();
+ }
+
+ @AuthInterceptor(InterceptorLevel.SYSTEM)
+ @RequestMapping(value = "/folder", method = RequestMethod.POST)
+ public String createFolder(@RequestBody JSONObject json) {
+ jsonObject.put("result", fileManagerService.createFolder(json));
+ return jsonObject.toJSONString();
+ }
+
+ @AuthInterceptor(InterceptorLevel.SYSTEM)
+ @RequestMapping(value = "/content", method = RequestMethod.POST)
+ public String getContent(@RequestBody JSONObject json) {
+ jsonObject.put("result", fileManagerService.getContent(json));
+ return jsonObject.toJSONString();
+ }
+
+ @AuthInterceptor(InterceptorLevel.SYSTEM)
+ @RequestMapping(value = "/edit", method = RequestMethod.POST)
+ public String edit(@RequestBody JSONObject json) {
+ jsonObject.put("result", fileManagerService.edit(json));
+ return jsonObject.toJSONString();
+ }
+
+ @AuthInterceptor(InterceptorLevel.SYSTEM)
+ @RequestMapping(value = "/remove", method = RequestMethod.POST)
+ public String remove(@RequestBody JSONObject json) {
+ jsonObject.put("result", fileManagerService.remove(json));
+ return jsonObject.toJSONString();
+ }
+
+ @AuthInterceptor(InterceptorLevel.SYSTEM)
+ @RequestMapping(value = "/copy", method = RequestMethod.POST)
+ public String copy(@RequestBody JSONObject json) {
+ jsonObject.put("result", fileManagerService.copy(json));
+ return jsonObject.toJSONString();
+ }
+
+ @AuthInterceptor(InterceptorLevel.SYSTEM)
+ @RequestMapping(value = "/move", method = RequestMethod.POST)
+ public String move(@RequestBody JSONObject json) {
+ jsonObject.put("result", fileManagerService.move(json));
+ return jsonObject.toJSONString();
+ }
+
+ @AuthInterceptor(InterceptorLevel.SYSTEM)
+ @RequestMapping(value = "/rename", method = RequestMethod.POST)
+ public String rename(@RequestBody JSONObject json) {
+ jsonObject.put("result", fileManagerService.rename(json));
+ return jsonObject.toJSONString();
+ }
+
+ @AuthInterceptor(InterceptorLevel.SYSTEM)
+ @RequestMapping(value = "/list", method = RequestMethod.POST)
+ public String list(@RequestBody JSONObject json) {
+ jsonObject.put("result", fileManagerService.list(json));
+ return jsonObject.toJSONString();
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/web/controller/GlobalExceptionHandler.java b/src/main/java/com/mesasoft/cn/web/controller/GlobalExceptionHandler.java
new file mode 100644
index 0000000..e096243
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/web/controller/GlobalExceptionHandler.java
@@ -0,0 +1,49 @@
+package com.mesasoft.cn.web.controller;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.log.Log;
+import cn.hutool.log.LogFactory;
+import com.mesasoft.cn.entity.Result;
+import com.mesasoft.cn.entity.ResultEntity;
+import com.mesasoft.cn.enums.StatusEnum;
+import com.mesasoft.cn.exception.BusinessException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.context.request.async.AsyncRequestTimeoutException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@RestControllerAdvice
+public class GlobalExceptionHandler {
+ private static final Log log = LogFactory.get();
+
+
+ @ExceptionHandler(AsyncRequestTimeoutException.class) //捕获特定异常
+ public void handleAsyncRequestTimeoutException(AsyncRequestTimeoutException e, HttpServletRequest request) {
+ log.info("Handle Async Request Timeout Exception");
+ }
+
+
+ @ExceptionHandler(Exception.class)
+ public ResultEntity handleException(Exception e, HttpServletRequest request, HttpServletResponse response) {
+ response.setStatus(StatusEnum.FAIL.getStatus());
+ String message = e.getMessage() + (e.getCause() != null ? e.getCause().getMessage() : "");
+ log.error("message:{}, stackTrace:{}", message, getStackTrace(e));
+ return Result.fail(e.getMessage());
+ }
+
+ @ExceptionHandler({BusinessException.class})
+ public ResultEntity handleBusinessException(BusinessException e, HttpServletRequest request, HttpServletResponse response) {
+ response.setStatus(e.getStatus());
+ String message = (e.getMessage() != null ? e.getMessage() : e.getMessage()) + " " + (e.getCause() != null ? e.getCause().getMessage() : "");
+ log.error("message:{}.stackTrace:{}", message, getStackTrace(e));
+ return Result.fail(e.getStatus(), e.getCode(), message);
+ }
+
+ private String getStackTrace(Exception e) {
+ return ObjectUtil.isNotNull(e.getStackTrace()) ? e.getStackTrace()[0].toString() : "";
+ }
+
+
+}
diff --git a/src/main/java/com/mesasoft/cn/web/controller/UploadedController.java b/src/main/java/com/mesasoft/cn/web/controller/UploadedController.java
new file mode 100644
index 0000000..a99827f
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/web/controller/UploadedController.java
@@ -0,0 +1,39 @@
+package com.mesasoft.cn.web.controller;
+
+import com.mesasoft.cn.annotation.AuthInterceptor;
+import com.mesasoft.cn.enums.InterceptorLevel;
+import com.mesasoft.cn.service.IUploadedService;
+import com.zhazhapan.util.Formatter;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author pantao
+ * @since 2018/2/28
+ */
+@RestController
+@RequestMapping(value = "/uploaded")
+@Api(value = "/uploaded", description = "上传记录相关操作")
+public class UploadedController {
+
+ private final IUploadedService uploadedService;
+
+ @Autowired
+ public UploadedController(IUploadedService uploadedService) {this.uploadedService = uploadedService;}
+
+ @ApiOperation(value = "获取文件上传记录")
+ @ApiImplicitParams({@ApiImplicitParam(name = "user", value = "指定用户(默认所有用户)"), @ApiImplicitParam(name =
+ "指定文件(默认所有文件)"), @ApiImplicitParam(name = "category", value = "指定分类(默认所有分类)"), @ApiImplicitParam(name =
+ "offset", value = "偏移量", required = true)})
+ @AuthInterceptor(InterceptorLevel.ADMIN)
+ @RequestMapping(value = "all", method = RequestMethod.GET)
+ public String getAll(String user, String file, String category, int offset) {
+ return Formatter.listToJson(uploadedService.list(user, file, category, offset));
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/web/controller/UserController.java b/src/main/java/com/mesasoft/cn/web/controller/UserController.java
new file mode 100644
index 0000000..a76aad9
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/web/controller/UserController.java
@@ -0,0 +1,281 @@
+package com.mesasoft.cn.web.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.mesasoft.cn.SketchApplication;
+import com.mesasoft.cn.modules.constant.ConfigConsts;
+import com.mesasoft.cn.modules.constant.DefaultValues;
+import com.mesasoft.cn.annotation.AuthInterceptor;
+import com.mesasoft.cn.config.TokenConfig;
+import com.mesasoft.cn.entity.Result;
+import com.mesasoft.cn.entity.ResultEntity;
+import com.mesasoft.cn.entity.User;
+import com.mesasoft.cn.enums.InterceptorLevel;
+import com.mesasoft.cn.service.IUserService;
+import com.mesasoft.cn.util.ControllerUtils;
+import com.zhazhapan.modules.constant.ValueConsts;
+import com.zhazhapan.util.Checker;
+import com.zhazhapan.util.Formatter;
+import com.zhazhapan.util.encryption.JavaEncrypt;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.UnsupportedEncodingException;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * @author pantao
+ * @since 2018/1/22
+ */
+@RestController
+@RequestMapping("/user")
+@Api(value = "/user", description = "用户相关操作")
+public class UserController {
+
+ private final IUserService userService;
+
+ private final HttpServletRequest request;
+
+ private final JSONObject jsonObject;
+
+ @Autowired
+ public UserController(IUserService userService, HttpServletRequest request, JSONObject jsonObject) {
+ this.userService = userService;
+ this.request = request;
+ this.jsonObject = jsonObject;
+ }
+
+ @ApiOperation(value = "更新用户权限(注:不是文件权限)")
+ @AuthInterceptor(InterceptorLevel.ADMIN)
+ @RequestMapping(value = "/{id}/{permission}", method = RequestMethod.PUT)
+ public String updatePermission(@PathVariable("id") int id, @PathVariable("permission") int permission) {
+ User user = (User) request.getSession().getAttribute(ValueConsts.USER_STRING);
+ if (user.getPermission() < ValueConsts.THREE_INT && permission > 1) {
+ jsonObject.put("message", "权限不够,设置失败");
+ } else if (userService.updatePermission(id, permission)) {
+ jsonObject.put("message", "更新成功");
+ } else {
+ jsonObject.put("message", "更新失败,请稍后重新尝试");
+ }
+ return jsonObject.toJSONString();
+ }
+
+ @ApiOperation("重置用户密码(管理员接口)")
+ @AuthInterceptor(InterceptorLevel.ADMIN)
+ @RequestMapping(value = "/reset/{id}/{password}", method = RequestMethod.PUT)
+ public String resetPassword(@PathVariable("id") int id, @PathVariable("password") String password) {
+ return ControllerUtils.getResponse(userService.resetPassword(id, password));
+ }
+
+ @ApiOperation(value = "更新用户的默认文件权限")
+ @ApiImplicitParam(name = "auth", value = "权限", example = "1,1,1,1", required = true)
+ @AuthInterceptor(InterceptorLevel.ADMIN)
+ @RequestMapping(value = "/{id}/auth", method = RequestMethod.PUT)
+ public String updateFileAuth(@PathVariable("id") int id, String auth) {
+ return ControllerUtils.getResponse(userService.updateFileAuth(id, auth));
+ }
+
+ @ApiOperation(value = "获取所有用户")
+ @ApiImplicitParams({@ApiImplicitParam(name = "user", value = "指定用户(默认所有用户)"), @ApiImplicitParam(name = "offset",
+ value = "偏移量", required = true)})
+ @AuthInterceptor(InterceptorLevel.ADMIN)
+ @RequestMapping(value = "/all", method = RequestMethod.GET)
+ public String getUser(String user, int offset) {
+ User u = (User) request.getSession().getAttribute(ValueConsts.USER_STRING);
+ return Formatter.listToJson(userService.listUser(u.getPermission(), user, offset));
+ }
+
+ @ApiOperation(value = "更新我的基本信息")
+ @ApiImplicitParams({@ApiImplicitParam(name = "avatar", value = "头像(可空)"), @ApiImplicitParam(name = "realName",
+ value = "真实姓名(可空)"), @ApiImplicitParam(name = "email", value = "邮箱(可空)"), @ApiImplicitParam(name =
+ "code", value = "验证码(可空)")})
+ @AuthInterceptor(InterceptorLevel.USER)
+ @RequestMapping(value = "/info", method = RequestMethod.PUT)
+ public String updateBasicInfo(String avatar, String realName, String email, String code) {
+ User user = (User) request.getSession().getAttribute(ValueConsts.USER_STRING);
+ jsonObject.put("message", "保存成功");
+ boolean emilVerify = SketchApplication.settings.getBooleanUseEval(ConfigConsts.EMAIL_VERIFY_OF_SETTINGS);
+ if (Checker.isNotEmpty(email) && !email.equals(user.getEmail())) {
+ if (!emilVerify || isCodeValidate(code)) {
+ if (userService.emailExists(email)) {
+ jsonObject.put("message", "邮箱更新失败,该邮箱已经存在");
+ } else {
+ user.setEmail(email);
+ }
+ } else {
+ jsonObject.put("message", "邮箱更新失败,验证码校验失败");
+ }
+ }
+ if (userService.updateBasicInfoById(user.getId(), avatar, realName, user.getEmail())) {
+ user.setAvatar(avatar);
+ user.setRealName(realName);
+ jsonObject.put("status", "success");
+ } else {
+ jsonObject.put("message", "服务器发生错误,请稍后重新尝试");
+ }
+ jsonObject.put("email", user.getEmail());
+ return jsonObject.toString();
+ }
+
+ @ApiOperation(value = "更新我的密码")
+ @ApiImplicitParams({@ApiImplicitParam(name = "oldPassword", value = "原密码", required = true), @ApiImplicitParam
+ (name = "newPassword", value = "新密码", required = true)})
+ @AuthInterceptor(InterceptorLevel.USER)
+ @RequestMapping(value = "/password", method = RequestMethod.PUT)
+ public String updatePassword(String oldPassword, String newPassword) {
+ User user = (User) request.getSession().getAttribute(ValueConsts.USER_STRING);
+ jsonObject.put("status", "error");
+ try {
+ if (user.getPassword().equals(JavaEncrypt.sha256(oldPassword))) {
+ if (userService.updatePasswordById(newPassword, user.getId())) {
+ jsonObject.put("status", "success");
+ TokenConfig.removeTokenByValue(user.getId());
+ } else {
+ jsonObject.put("message", "新密码格式不正确");
+ }
+ } else {
+ jsonObject.put("message", "原密码不正确");
+ }
+ } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
+ jsonObject.put("message", "服务器内部错误,请稍后重新尝试");
+ }
+ return jsonObject.toString();
+ }
+
+ @ApiOperation(value = "获取我的基本信息")
+ @AuthInterceptor(InterceptorLevel.USER)
+ @RequestMapping(value = "/info", method = RequestMethod.GET)
+ public String getInfo() {
+ User user = (User) request.getSession().getAttribute(ValueConsts.USER_STRING);
+ JSONObject object = JSON.parseObject(user.toString());
+ object.remove(ValueConsts.ID_STRING);
+ object.remove(ValueConsts.PASSWORD_STRING);
+ return object.toString();
+ }
+
+ @ApiOperation(value = "登录(用户名密码和token必须有一个输入)")
+ @ApiImplicitParams({@ApiImplicitParam(name = "username", value = "用户名"), @ApiImplicitParam(name
+ = "password", value = "密码"), @ApiImplicitParam(name = "auto", value = "是否自动登录", dataType = "Boolean"),
+ @ApiImplicitParam(name = "token", value = "用于自动登录")})
+ @AuthInterceptor(InterceptorLevel.NONE)
+ @RequestMapping(value = "/login", method = RequestMethod.PUT)
+ public String login(String username, String password, boolean auto, String token) {
+ //使用密码登录
+ User user = userService.login(username, password, ValueConsts.NULL_STRING, ValueConsts.NULL_RESPONSE);
+ if (Checker.isNull(user) || user.getPermission() < 1) {
+ jsonObject.put("status", "failed");
+ } else {
+ request.getSession().setAttribute(ValueConsts.USER_STRING, user);
+ jsonObject.put("status", "success");
+ if (auto) {
+ jsonObject.put("token", TokenConfig.generateToken(token, user.getId()));
+ } else {
+ jsonObject.put("token", "");
+ TokenConfig.removeTokenByValue(user.getId());
+ }
+ }
+ return jsonObject.toString();
+ }
+
+ @ApiOperation(value = "用户注册(当不需要验证邮箱时,邮箱和验证码可空)")
+ @ApiImplicitParams({@ApiImplicitParam(name = "username", value = "用户名", required = true), @ApiImplicitParam(name
+ = "email", value = "邮箱"), @ApiImplicitParam(name = "password", value = "密码", required = true),
+ @ApiImplicitParam(name = "code", value = "验证码")})
+ @AuthInterceptor(InterceptorLevel.NONE)
+ @RequestMapping(value = "/register", method = RequestMethod.POST)
+ public String register(String username, String email, String password, String code) {
+ boolean emilVerify = SketchApplication.settings.getBooleanUseEval(ConfigConsts.EMAIL_VERIFY_OF_SETTINGS);
+ jsonObject.put("status", "error");
+ if (!emilVerify || isCodeValidate(code)) {
+ if (userService.usernameExists(username)) {
+ jsonObject.put("message", "用户名已经存在");
+ } else if (userService.emailExists(email)) {
+ jsonObject.put("message", "该邮箱已经被注册啦");
+ } else if (userService.register(username, email, password)) {
+ jsonObject.put("status", "success");
+ } else {
+ jsonObject.put("message", "数据格式不合法");
+ }
+ } else {
+ jsonObject.put("message", "验证码校验失败");
+ }
+ return jsonObject.toString();
+ }
+
+ @ApiOperation(value = "重置我的密码")
+ @ApiImplicitParams({@ApiImplicitParam(name = "email", value = "邮箱", required = true), @ApiImplicitParam(name =
+ "code", value = "验证码", required = true), @ApiImplicitParam(name = "password", value = "密码", required =
+ true)})
+ @AuthInterceptor(InterceptorLevel.NONE)
+ @RequestMapping(value = "/password/reset", method = RequestMethod.PUT)
+ public String resetPassword(String email, String code, String password) {
+ jsonObject.put("status", "error");
+ if (isCodeValidate(code)) {
+ if (userService.resetPasswordByEmail(email, password)) {
+ jsonObject.put("status", "success");
+ } else {
+ jsonObject.put("message", "格式不合法");
+ }
+ } else {
+ jsonObject.put("message", "验证码校验失败");
+ }
+ return jsonObject.toString();
+ }
+
+ @ApiOperation(value = "检测用户名是否已经注册")
+ @ApiImplicitParam(name = "username", value = "用户名", required = true)
+ @AuthInterceptor(InterceptorLevel.NONE)
+ @RequestMapping(value = "/username/exists", method = RequestMethod.GET)
+ public String usernameExists(String username) {
+ jsonObject.put("exists", userService.usernameExists(username));
+ return jsonObject.toString();
+ }
+
+ @ApiOperation(value = "检测邮箱是否已经注册")
+ @ApiImplicitParam(name = "email", value = "邮箱", required = true)
+ @AuthInterceptor(InterceptorLevel.NONE)
+ @RequestMapping(value = "/email/exists", method = RequestMethod.GET)
+ public String emailExists(String email) {
+ jsonObject.put("exists", userService.emailExists(email));
+ return jsonObject.toString();
+ }
+
+ private boolean isCodeValidate(String code) {
+ return Checker.checkNull(code).equals(String.valueOf(request.getSession().getAttribute(DefaultValues
+ .CODE_STRING)));
+ }
+
+
+ @ApiOperation(value = "登录(用户名密码和token必须有一个输入)")
+ @ApiImplicitParams({@ApiImplicitParam(name = "username", value = "用户名"), @ApiImplicitParam(name
+ = "password", value = "密码"), @ApiImplicitParam(name = "auto", value = "是否自动登录", dataType = "Boolean"),
+ @ApiImplicitParam(name = "token", value = "用于自动登录")})
+ @AuthInterceptor(InterceptorLevel.NONE)
+ @RequestMapping(value = "/login2", method = RequestMethod.PUT)
+ public ResultEntity login2(String username, String password, boolean auto, String token) {
+
+ JSONObject resultObject = null;
+ //使用密码登录
+ User user = userService.login(username, password, ValueConsts.NULL_STRING, ValueConsts.NULL_RESPONSE);
+ if (Checker.isNull(user) || user.getPermission() < 1) {
+ return Result.fail();
+ } else {
+ request.getSession().setAttribute(ValueConsts.USER_STRING, user);
+ if (auto) {
+ resultObject.put("token", TokenConfig.generateToken(token, user.getId()));
+ } else {
+ resultObject.put("token", "");
+ TokenConfig.removeTokenByValue(user.getId());
+ }
+ }
+ return Result.success(resultObject);
+ }
+}
diff --git a/src/main/java/com/mesasoft/cn/web/controller/ViewController.java b/src/main/java/com/mesasoft/cn/web/controller/ViewController.java
new file mode 100644
index 0000000..33ad670
--- /dev/null
+++ b/src/main/java/com/mesasoft/cn/web/controller/ViewController.java
@@ -0,0 +1,63 @@
+package com.mesasoft.cn.web.controller;
+
+import com.mesasoft.cn.annotation.AuthInterceptor;
+import com.mesasoft.cn.enums.InterceptorLevel;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import springfox.documentation.annotations.ApiIgnore;
+
+/**
+ * @author pantao
+ * @since 2018/1/25
+ */
+@Controller
+@Api(description = "视图页面映射")
+public class ViewController {
+
+ @ApiOperation(value = "远程文件管理页面")
+ @AuthInterceptor(InterceptorLevel.SYSTEM)
+ @RequestMapping(value = "/filemanager", method = RequestMethod.GET)
+ public String fileManager() {
+ return "/filemanager";
+ }
+
+ @ApiOperation(value = "上传页面")
+ @AuthInterceptor
+ @RequestMapping(value = "/upload", method = RequestMethod.GET)
+ public String upload() {
+ return "/upload";
+ }
+
+ @ApiOperation(value = "首页")
+ @AuthInterceptor(InterceptorLevel.NONE)
+ @RequestMapping(value = "/index", method = RequestMethod.GET)
+ public String index() {
+ return "/index";
+ }
+
+ @ApiOperation(value = "登录、注册、忘记密码页面")
+ @AuthInterceptor(InterceptorLevel.NONE)
+ @RequestMapping(value = "/signin", method = RequestMethod.GET)
+ public String signin() {
+ return "/signin";
+ }
+
+ @ApiOperation(value = "管理员页面")
+ @AuthInterceptor(InterceptorLevel.ADMIN)
+ @RequestMapping(value = "/admin", method = RequestMethod.GET)
+ public String admin() {
+ return "/admin";
+ }
+
+ @ApiIgnore
+ @AuthInterceptor(InterceptorLevel.NONE)
+ @RequestMapping(value = "/test", method = RequestMethod.GET)
+ @ResponseBody
+ public String test() {
+ return "<b>test</b>";
+ }
+}