diff options
Diffstat (limited to 'src/main/java/com')
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>"; + } +} |
