diff --git a/neuray-pm-base-server/base-code-generator/pom.xml b/neuray-pm-base-server/base-code-generator/pom.xml index c6eec651accf4dcf40c20411bbdfa444dd0f76a0..4cd16e3866bef2fe2e34ec71d1832c1ac83e02f7 100644 --- a/neuray-pm-base-server/base-code-generator/pom.xml +++ b/neuray-pm-base-server/base-code-generator/pom.xml @@ -34,10 +34,11 @@ org.springframework.boot spring-boot-starter-web + - org.mybatis.spring.boot - mybatis-spring-boot-starter - ${mybatis.spring.boot.version} + tk.mybatis + mapper-spring-boot-starter + 1.1.2 com.github.pagehelper diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/BaseCodeGeneratorBoostrap.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/BaseCodeGeneratorBoostrap.java index 0b96e88f5ed7863b3ae5067122608e0bc824b866..5a0c6c246022213d5ba76973179badd482f64d7f 100644 --- a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/BaseCodeGeneratorBoostrap.java +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/BaseCodeGeneratorBoostrap.java @@ -1,6 +1,7 @@ package com.gitee.neuray.security.generator; import com.gitee.neuray.security.auth.client.EnableAceAuthClient; +import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @@ -15,6 +16,7 @@ import org.springframework.cloud.openfeign.EnableFeignClients; @EnableDiscoveryClient @EnableAceAuthClient @EnableFeignClients({"com.gitee.neuray.security.auth.client.feign"}) +@MapperScan({"com.gitee.neuray.security.generator"}) public class BaseCodeGeneratorBoostrap { public static void main(String[] args) { SpringApplication.run(BaseCodeGeneratorBoostrap.class, args); diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/config/DbConfig.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/config/DbConfig.java index f611b17cfe6b745b8f9bd6852644374a9a8f78fa..bde3ee9893df224954d0993a989e59ea2203d4b2 100644 --- a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/config/DbConfig.java +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/config/DbConfig.java @@ -1,7 +1,7 @@ package com.gitee.neuray.security.generator.config; import com.gitee.neuray.security.common.exception.BaseException; -import com.gitee.neuray.security.generator.dao.*; +import com.gitee.neuray.security.generator.productionmd.dao.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/configmd/biz/TConfigInfoBiz.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/configmd/biz/TConfigInfoBiz.java new file mode 100644 index 0000000000000000000000000000000000000000..dc0b08b7449b5a62f248a19d1e57e7c7cd4b21f9 --- /dev/null +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/configmd/biz/TConfigInfoBiz.java @@ -0,0 +1,20 @@ +package com.gitee.neuray.security.generator.configmd.biz; + +import org.springframework.stereotype.Service; +import java.util.Map; +import org.springframework.transaction.annotation.Transactional; +import tk.mybatis.mapper.common.Mapper; +import com.gitee.neuray.security.common.biz.BaseBiz; + +import com.gitee.neuray.security.generator.configmd.mapper.TConfigInfoMapper; +import com.gitee.neuray.security.generator.configmd.entity.TConfigInfoEntity; + + +@Service +@Transactional(rollbackFor = Exception.class) +public class TConfigInfoBiz extends BaseBiz { + @Override + protected String getPageName() { + return "TConfigInfo"+"Biz"; + } +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/configmd/controller/TConfigInfoController.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/configmd/controller/TConfigInfoController.java new file mode 100644 index 0000000000000000000000000000000000000000..ac56393ae3aa34cf94ae1412b65100dada45c9ec --- /dev/null +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/configmd/controller/TConfigInfoController.java @@ -0,0 +1,23 @@ +package com.gitee.neuray.security.generator.configmd.controller; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.gitee.neuray.security.common.rest.BaseController; + +import com.gitee.neuray.security.generator.configmd.entity.TConfigInfoEntity; +import com.gitee.neuray.security.generator.configmd.biz.TConfigInfoBiz; + + + +/** + * 代码生成器-配置信息 + * + * @author zhhongyu + * @email ${email} + * @date 2020-01-08 16:36:16 + */ +@RestController +@RequestMapping("configmd") +public class TConfigInfoController extends BaseController{ + +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/configmd/entity/TConfigInfoEntity.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/configmd/entity/TConfigInfoEntity.java new file mode 100644 index 0000000000000000000000000000000000000000..b007d5a4f97fcfceb6d62916abdd58c4be6da77b --- /dev/null +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/configmd/entity/TConfigInfoEntity.java @@ -0,0 +1,53 @@ +package com.gitee.neuray.security.generator.configmd.entity; + +import com.gitee.neuray.security.common.entity.BaseEntity; +import lombok.Data; + +import javax.persistence.Column; +import javax.persistence.Table; + +import java.util.Date; + +/** + * 代码生成器-配置信息 + * + * @author zhhongyu + * @email ${email} + * @date 2020-01-08 16:36:16 + */ +@Data +@Table(name = "T_CONFIG_INFO") +public class TConfigInfoEntity extends BaseEntity { + + /** + * 项目ID + */ + @Column(name = "PROJECT_ID") + private String projectId; + /** + * 配置名称 + */ + @Column(name = "C_NAME") + private String cName; + /** + * java路径 + */ + @Column(name = "JAVA_PATH") + private String javaPath; + /** + * vue路径 + */ + @Column(name = "VUE_PATH") + private String vuePath; + /** + * 模块名称 + */ + @Column(name = "MODULE") + private String module; + /** + * 有效标志 0 无效 1有效;默认有效 + */ + @Column(name = "FLAG") + private String flag; + +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/configmd/mapper/TConfigInfoMapper.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/configmd/mapper/TConfigInfoMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..14599f22942e52c5023f3cf2603667bfd64b34e2 --- /dev/null +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/configmd/mapper/TConfigInfoMapper.java @@ -0,0 +1,15 @@ +package com.gitee.neuray.security.generator.configmd.mapper; + +import com.gitee.neuray.security.generator.configmd.entity.TConfigInfoEntity; +import tk.mybatis.mapper.common.Mapper; + +/** + * 代码生成器-配置信息 + * + * @author zhhongyu + * @email ${email} + * @date 2020-01-08 16:36:16 + */ +public interface TConfigInfoMapper extends Mapper { + +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/databasemd/biz/TDatabaseInfoBiz.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/databasemd/biz/TDatabaseInfoBiz.java new file mode 100644 index 0000000000000000000000000000000000000000..7afcd85ff731a02b0dc6f11eb0e235d846784d0a --- /dev/null +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/databasemd/biz/TDatabaseInfoBiz.java @@ -0,0 +1,20 @@ +package com.gitee.neuray.security.generator.databasemd.biz; + +import org.springframework.stereotype.Service; +import java.util.Map; +import org.springframework.transaction.annotation.Transactional; +import tk.mybatis.mapper.common.Mapper; +import com.gitee.neuray.security.common.biz.BaseBiz; + +import com.gitee.neuray.security.generator.databasemd.mapper.TDatabaseInfoMapper; +import com.gitee.neuray.security.generator.databasemd.entity.TDatabaseInfoEntity; + + +@Service +@Transactional(rollbackFor = Exception.class) +public class TDatabaseInfoBiz extends BaseBiz { + @Override + protected String getPageName() { + return "TDatabaseInfo"+"Biz"; + } +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/databasemd/controller/TDatabaseInfoController.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/databasemd/controller/TDatabaseInfoController.java new file mode 100644 index 0000000000000000000000000000000000000000..a9c1ad02c6b7c3158387d28e48aed628f245488c --- /dev/null +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/databasemd/controller/TDatabaseInfoController.java @@ -0,0 +1,23 @@ +package com.gitee.neuray.security.generator.databasemd.controller; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.gitee.neuray.security.common.rest.BaseController; + +import com.gitee.neuray.security.generator.databasemd.entity.TDatabaseInfoEntity; +import com.gitee.neuray.security.generator.databasemd.biz.TDatabaseInfoBiz; + + + +/** + * 代码生成器-数据库信息 + * + * @author zhhongyu + * @email ${email} + * @date 2020-01-08 16:40:58 + */ +@RestController +@RequestMapping("databasemd") +public class TDatabaseInfoController extends BaseController{ + +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/databasemd/entity/TDatabaseInfoEntity.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/databasemd/entity/TDatabaseInfoEntity.java new file mode 100644 index 0000000000000000000000000000000000000000..f898600181c6455e9e58990a4b90e4e5387ed4b6 --- /dev/null +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/databasemd/entity/TDatabaseInfoEntity.java @@ -0,0 +1,58 @@ +package com.gitee.neuray.security.generator.databasemd.entity; + +import com.gitee.neuray.security.common.entity.BaseEntity; +import lombok.Data; + +import javax.persistence.Column; +import javax.persistence.Table; + +import java.util.Date; + +/** + * 代码生成器-数据库信息 + * + * @author zhhongyu + * @email ${email} + * @date 2020-01-08 16:40:58 + */ +@Data +@Table(name = "T_DATABASE_INFO") +public class TDatabaseInfoEntity extends BaseEntity { + /** + * 项目ID + */ + @Column(name = "PROJECT_ID") + private String projectId; + /** + * 数据库名称 + */ + @Column(name = "DB_NAME") + private String dbName; + /** + * 数据库类型 + */ + @Column(name = "DB_TYPE") + private String dbType; + /** + * 数据库URL + */ + @Column(name = "DB_URL") + private String dbUrl; + /** + * 数据库密码 + */ + @Column(name = "PASSWORD") + private String password; + /** + * 数据库用户名 + */ + @Column(name = "USER_NAME") + private String userName; + /** + * 有效标志 0 无效 1有效;默认有效 + */ + @Column(name = "FLAG") + private String flag; + + +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/databasemd/mapper/TDatabaseInfoMapper.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/databasemd/mapper/TDatabaseInfoMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..59828a94df51d868f8a98586a09271d4de619c90 --- /dev/null +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/databasemd/mapper/TDatabaseInfoMapper.java @@ -0,0 +1,15 @@ +package com.gitee.neuray.security.generator.databasemd.mapper; + +import com.gitee.neuray.security.generator.databasemd.entity.TDatabaseInfoEntity; +import tk.mybatis.mapper.common.Mapper; + +/** + * 代码生成器-数据库信息 + * + * @author zhhongyu + * @email ${email} + * @date 2020-01-08 16:40:58 + */ +public interface TDatabaseInfoMapper extends Mapper { + +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/controller/SysGeneratorController.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/controller/SysGeneratorController.java similarity index 90% rename from neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/controller/SysGeneratorController.java rename to neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/controller/SysGeneratorController.java index b3a8b728b273b6bfe684a1fc2c17e6c8260c4be4..4a8ad2dd247061b216e144d57e7210172582afb2 100644 --- a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/controller/SysGeneratorController.java +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/controller/SysGeneratorController.java @@ -1,6 +1,6 @@ -package com.gitee.neuray.security.generator.controller; +package com.gitee.neuray.security.generator.productionmd.controller; -import com.gitee.neuray.security.generator.service.SysGeneratorService; +import com.gitee.neuray.security.generator.productionmd.service.SysGeneratorService; import com.gitee.neuray.security.generator.utils.PageUtils; import com.gitee.neuray.security.generator.utils.Query; import com.gitee.neuray.security.generator.utils.R; diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/dao/GeneratorDao.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/dao/GeneratorDao.java similarity index 81% rename from neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/dao/GeneratorDao.java rename to neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/dao/GeneratorDao.java index c17f34c0afd12bb688f86720d6ac93b8e68d3052..627e366cf410519e94f875834928a067ac6e52d7 100644 --- a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/dao/GeneratorDao.java +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/dao/GeneratorDao.java @@ -1,4 +1,4 @@ -package com.gitee.neuray.security.generator.dao; +package com.gitee.neuray.security.generator.productionmd.dao; import java.util.List; import java.util.Map; @@ -12,4 +12,4 @@ public interface GeneratorDao { Map queryTable(String tableName); List> queryColumns(String tableName); -} \ No newline at end of file +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/dao/MySQLGeneratorDao.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/dao/MySQLGeneratorDao.java similarity index 69% rename from neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/dao/MySQLGeneratorDao.java rename to neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/dao/MySQLGeneratorDao.java index 0ca7e0fb922417194530aedfaf01b2801a626335..c0dacbdd011c7096287271fd5b1460bde4f453c2 100644 --- a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/dao/MySQLGeneratorDao.java +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/dao/MySQLGeneratorDao.java @@ -1,4 +1,4 @@ -package com.gitee.neuray.security.generator.dao; +package com.gitee.neuray.security.generator.productionmd.dao; import org.apache.ibatis.annotations.Mapper; @@ -8,6 +8,6 @@ import org.apache.ibatis.annotations.Mapper; */ @Mapper public interface MySQLGeneratorDao extends GeneratorDao { - -} \ No newline at end of file + +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/dao/OracleGeneratorDao.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/dao/OracleGeneratorDao.java similarity index 70% rename from neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/dao/OracleGeneratorDao.java rename to neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/dao/OracleGeneratorDao.java index 7324ee059bb6dcf747cbf20d34a1359dc8419fe9..ddec4676cb8a99fd8d142c96ea510b4eea5615d2 100644 --- a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/dao/OracleGeneratorDao.java +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/dao/OracleGeneratorDao.java @@ -1,4 +1,4 @@ -package com.gitee.neuray.security.generator.dao; +package com.gitee.neuray.security.generator.productionmd.dao; import org.apache.ibatis.annotations.Mapper; @@ -9,4 +9,4 @@ import org.apache.ibatis.annotations.Mapper; @Mapper public interface OracleGeneratorDao extends GeneratorDao { -} \ No newline at end of file +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/dao/PostgreSQLGeneratorDao.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/dao/PostgreSQLGeneratorDao.java similarity index 71% rename from neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/dao/PostgreSQLGeneratorDao.java rename to neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/dao/PostgreSQLGeneratorDao.java index 13544bebf4eaf6e0682ca9df17dac7db99464158..3db5932c35a5ae85d8ca1bbffd00719ab995c493 100644 --- a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/dao/PostgreSQLGeneratorDao.java +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/dao/PostgreSQLGeneratorDao.java @@ -1,4 +1,4 @@ -package com.gitee.neuray.security.generator.dao; +package com.gitee.neuray.security.generator.productionmd.dao; import org.apache.ibatis.annotations.Mapper; @@ -9,4 +9,4 @@ import org.apache.ibatis.annotations.Mapper; @Mapper public interface PostgreSQLGeneratorDao extends GeneratorDao { -} \ No newline at end of file +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/dao/SQLServerGeneratorDao.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/dao/SQLServerGeneratorDao.java similarity index 71% rename from neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/dao/SQLServerGeneratorDao.java rename to neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/dao/SQLServerGeneratorDao.java index 5a0b07345d2d34eb9f4c0c602747a337065c20af..00882e7fb9e0b9283c3824742ae247733aec18ea 100644 --- a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/dao/SQLServerGeneratorDao.java +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/dao/SQLServerGeneratorDao.java @@ -1,4 +1,4 @@ -package com.gitee.neuray.security.generator.dao; +package com.gitee.neuray.security.generator.productionmd.dao; import org.apache.ibatis.annotations.Mapper; @@ -9,4 +9,4 @@ import org.apache.ibatis.annotations.Mapper; @Mapper public interface SQLServerGeneratorDao extends GeneratorDao { -} \ No newline at end of file +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/entity/ColumnEntity.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/entity/ColumnEntity.java similarity index 96% rename from neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/entity/ColumnEntity.java rename to neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/entity/ColumnEntity.java index efc7e8985ea5ae184bfb6663e75c6957aef3c29b..77dca35a2b4fe03476d37e4e172420a9030ec4cf 100644 --- a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/entity/ColumnEntity.java +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/entity/ColumnEntity.java @@ -1,4 +1,4 @@ -package com.gitee.neuray.security.generator.entity; +package com.gitee.neuray.security.generator.productionmd.entity; /** * 列的属性 diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/entity/TableEntity.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/entity/TableEntity.java similarity index 94% rename from neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/entity/TableEntity.java rename to neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/entity/TableEntity.java index 00db965bb6e9765e9c3dbd41721cbf94bdc0392a..5eee53a6720029ae12e102947381b6ac2eac4c24 100644 --- a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/entity/TableEntity.java +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/entity/TableEntity.java @@ -1,4 +1,4 @@ -package com.gitee.neuray.security.generator.entity; +package com.gitee.neuray.security.generator.productionmd.entity; import java.util.List; @@ -15,7 +15,7 @@ public class TableEntity { private ColumnEntity pk; //表的列名(不包含主键) private List columns; - + //类名(第一个字母大写),如:sys_user => SysUser private String className; //类名(第一个字母小写),如:sys_user => sysUser @@ -68,4 +68,4 @@ public class TableEntity { public void setClassname(String classname) { this.classname = classname; } -} \ No newline at end of file +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/service/SysGeneratorService.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/service/SysGeneratorService.java similarity index 62% rename from neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/service/SysGeneratorService.java rename to neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/service/SysGeneratorService.java index 65d47f1ac91e22cce964ed7cc34f1b505937b3d9..774ed327c93836234387638122eadab2b325f793 100644 --- a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/service/SysGeneratorService.java +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/productionmd/service/SysGeneratorService.java @@ -1,6 +1,8 @@ -package com.gitee.neuray.security.generator.service; +package com.gitee.neuray.security.generator.productionmd.service; -import com.gitee.neuray.security.generator.dao.GeneratorDao; +import com.gitee.neuray.security.common.entity.BaseEntity; +import com.gitee.neuray.security.common.util.ReflectionUtils; +import com.gitee.neuray.security.generator.productionmd.dao.GeneratorDao; import com.gitee.neuray.security.generator.utils.GenUtils; import com.gitee.neuray.security.generator.utils.PageUtils; import com.gitee.neuray.security.generator.utils.Query; @@ -10,14 +12,19 @@ import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import javax.persistence.Column; import java.io.ByteArrayOutputStream; +import java.lang.reflect.Field; +import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; import java.util.zip.ZipOutputStream; /** * 代码生成器 - * + * @author zhhongyu */ @Service public class SysGeneratorService { @@ -48,10 +55,21 @@ public class SysGeneratorService { Map table = queryTable(tableName); //查询列信息 List> columns = queryColumns(tableName); + Field[] declaredFields = BaseEntity.class.getDeclaredFields(); + List baseEntityDeclares = new ArrayList<>(); + for(Field field : declaredFields){ + Column declaredAnnotation = field.getDeclaredAnnotation(Column.class); + String name = declaredAnnotation.name(); + baseEntityDeclares.add(name); + } + columns = columns.stream().filter(map -> { + String columnName = map.get("columnName"); + return !baseEntityDeclares.parallelStream().anyMatch(baseColumn -> Objects.equals(columnName,baseColumn)); + }).collect(Collectors.toList()); //生成代码 GenUtils.generatorCode(table, columns, zip); } IOUtils.closeQuietly(zip); return outputStream.toByteArray(); } -} \ No newline at end of file +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/projectmd/biz/TProjectInfoBiz.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/projectmd/biz/TProjectInfoBiz.java new file mode 100644 index 0000000000000000000000000000000000000000..c4b60573a1c5027c8c659cac4d61b466323b49e6 --- /dev/null +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/projectmd/biz/TProjectInfoBiz.java @@ -0,0 +1,18 @@ +package com.gitee.neuray.security.generator.projectmd.biz; + +import com.gitee.neuray.security.generator.projectmd.entity.TProjectInfoEntity; +import com.gitee.neuray.security.generator.projectmd.mapper.TProjectInfoMapper; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.gitee.neuray.security.common.biz.BaseBiz; + + + +@Service +@Transactional(rollbackFor = Exception.class) +public class TProjectInfoBiz extends BaseBiz { + @Override + protected String getPageName() { + return "TProjectInfo"+"Biz"; + } +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/projectmd/controller/TProjectInfoController.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/projectmd/controller/TProjectInfoController.java new file mode 100644 index 0000000000000000000000000000000000000000..55c66c81908aeb5dc87fac696388b1c349806fa1 --- /dev/null +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/projectmd/controller/TProjectInfoController.java @@ -0,0 +1,23 @@ +package com.gitee.neuray.security.generator.projectmd.controller; + +import com.gitee.neuray.security.generator.projectmd.biz.TProjectInfoBiz; +import com.gitee.neuray.security.generator.projectmd.entity.TProjectInfoEntity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.gitee.neuray.security.common.rest.BaseController; + + + + +/** + * 代码生成器-项目表 + * + * @author ddboy + * @email ${email} + * @date 2020-01-08 10:06:19 + */ +@RestController +@RequestMapping("project") +public class TProjectInfoController extends BaseController{ + +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/projectmd/entity/TProjectInfoEntity.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/projectmd/entity/TProjectInfoEntity.java new file mode 100644 index 0000000000000000000000000000000000000000..63a579fdf6bae996c0a0686d9714eb54792cec74 --- /dev/null +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/projectmd/entity/TProjectInfoEntity.java @@ -0,0 +1,30 @@ +package com.gitee.neuray.security.generator.projectmd.entity; + +import com.gitee.neuray.security.common.entity.BaseEntity; +import lombok.Data; + +import javax.persistence.Column; +import javax.persistence.Table; + +/** + * 代码生成器-项目表 + * + * @author ddboy + * @email ${email} + * @date 2020-01-08 10:06:19 + */ +@Data +@Table(name = "T_PROJECT_INFO") +public class TProjectInfoEntity extends BaseEntity { + /** + * 项目名称 + */ + @Column(name = "PROJECT_NAME") + private String projectName; + /** + * 有效标志 0 无效 1有效;默认有效 + */ + @Column(name = "FLAG") + private String flag; + +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/projectmd/mapper/TProjectInfoMapper.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/projectmd/mapper/TProjectInfoMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..f5566021601f133756b575927bcec9ad5016ed28 --- /dev/null +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/projectmd/mapper/TProjectInfoMapper.java @@ -0,0 +1,15 @@ +package com.gitee.neuray.security.generator.projectmd.mapper; + +import com.gitee.neuray.security.generator.projectmd.entity.TProjectInfoEntity; +import tk.mybatis.mapper.common.Mapper; + +/** + * 代码生成器-项目表 + * + * @author ddboy + * @email ${email} + * @date 2020-01-08 10:06:19 + */ +public interface TProjectInfoMapper extends Mapper { + +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/userprojectmd/biz/TProjectUserBiz.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/userprojectmd/biz/TProjectUserBiz.java new file mode 100644 index 0000000000000000000000000000000000000000..9051463f55c82f8f05db14498afc9ee8a8a21cb7 --- /dev/null +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/userprojectmd/biz/TProjectUserBiz.java @@ -0,0 +1,20 @@ +package com.gitee.neuray.security.generator.userprojectmd.biz; + +import org.springframework.stereotype.Service; +import java.util.Map; +import org.springframework.transaction.annotation.Transactional; +import tk.mybatis.mapper.common.Mapper; +import com.gitee.neuray.security.common.biz.BaseBiz; + +import com.gitee.neuray.security.generator.userprojectmd.mapper.TProjectUserMapper; +import com.gitee.neuray.security.generator.userprojectmd.entity.TProjectUserEntity; + + +@Service +@Transactional(rollbackFor = Exception.class) +public class TProjectUserBiz extends BaseBiz { + @Override + protected String getPageName() { + return "TProjectUser"+"Biz"; + } +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/userprojectmd/controller/TProjectUserController.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/userprojectmd/controller/TProjectUserController.java new file mode 100644 index 0000000000000000000000000000000000000000..285481bf3f964c13b13fea6749a6f8bc3427fc9f --- /dev/null +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/userprojectmd/controller/TProjectUserController.java @@ -0,0 +1,23 @@ +package com.gitee.neuray.security.generator.userprojectmd.controller; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.gitee.neuray.security.common.rest.BaseController; + +import com.gitee.neuray.security.generator.userprojectmd.entity.TProjectUserEntity; +import com.gitee.neuray.security.generator.userprojectmd.biz.TProjectUserBiz; + + + +/** + * 代码生成器-项目人员表 + * + * @author zhhongyu + * @email ${email} + * @date 2020-01-08 16:47:24 + */ +@RestController +@RequestMapping("userprojectmd") +public class TProjectUserController extends BaseController{ + +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/userprojectmd/entity/TProjectUserEntity.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/userprojectmd/entity/TProjectUserEntity.java new file mode 100644 index 0000000000000000000000000000000000000000..97ad98e5664424362771ffc722e4e38d9ceaab4e --- /dev/null +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/userprojectmd/entity/TProjectUserEntity.java @@ -0,0 +1,33 @@ +package com.gitee.neuray.security.generator.userprojectmd.entity; + +import com.gitee.neuray.security.common.entity.BaseEntity; +import lombok.Data; + +import javax.persistence.Column; +import javax.persistence.Table; + +import java.util.Date; + +/** + * 代码生成器-项目人员表 + * + * @author zhhongyu + * @email ${email} + * @date 2020-01-08 16:47:24 + */ +@Data +@Table(name = "T_PROJECT_USER") +public class TProjectUserEntity extends BaseEntity { + /** + * 项目id + */ + @Column(name="PROJECT_ID") + private String projectId; + + /** + * 人员ID + */ + @Column(name = "USER_ID") + private String userId; + +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/userprojectmd/mapper/TProjectUserMapper.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/userprojectmd/mapper/TProjectUserMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..3b3801af0e066c4a506fd014d0965d9c1dca4ffb --- /dev/null +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/userprojectmd/mapper/TProjectUserMapper.java @@ -0,0 +1,15 @@ +package com.gitee.neuray.security.generator.userprojectmd.mapper; + +import com.gitee.neuray.security.generator.userprojectmd.entity.TProjectUserEntity; +import tk.mybatis.mapper.common.Mapper; + +/** + * 代码生成器-项目人员表 + * + * @author zhhongyu + * @email ${email} + * @date 2020-01-08 16:47:24 + */ +public interface TProjectUserMapper extends Mapper { + +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/utils/GenUtils.java b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/utils/GenUtils.java index 83d39206ded595e4119e0b15224d940030499154..683eb0fb95093007c5010e4993367f4197d8aaf9 100644 --- a/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/utils/GenUtils.java +++ b/neuray-pm-base-server/base-code-generator/src/main/java/com/gitee/neuray/security/generator/utils/GenUtils.java @@ -1,8 +1,8 @@ package com.gitee.neuray.security.generator.utils; import com.gitee.neuray.security.common.exception.BaseException; -import com.gitee.neuray.security.generator.entity.ColumnEntity; -import com.gitee.neuray.security.generator.entity.TableEntity; +import com.gitee.neuray.security.generator.productionmd.entity.ColumnEntity; +import com.gitee.neuray.security.generator.productionmd.entity.TableEntity; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; @@ -38,7 +38,7 @@ public class GenUtils { templates.add("template/menu.sql.vm"); return templates; } - + /** * 生成代码 */ @@ -55,7 +55,7 @@ public class GenUtils { String className = tableToJava(tableEntity.getTableName(), config.getString("tablePrefix")); tableEntity.setClassName(className); tableEntity.setClassname(StringUtils.uncapitalize(className)); - + //列信息 List columsList = new ArrayList<>(); for(Map column : columns){ @@ -64,12 +64,12 @@ public class GenUtils { columnEntity.setDataType(column.get("dataType")); columnEntity.setComments(column.get("columnComment")); columnEntity.setExtra(column.get("extra")); - + //列名转换成Java属性名 String attrName = columnToJava(columnEntity.getColumnName()); columnEntity.setAttrName(attrName); columnEntity.setAttrname(StringUtils.uncapitalize(attrName)); - + //列的数据类型,转换成Java类型 String attrType = config.getString(columnEntity.getDataType(), "unknowType"); columnEntity.setAttrType(attrType); @@ -80,24 +80,24 @@ public class GenUtils { if("PRI".equalsIgnoreCase(column.get("columnKey")) && tableEntity.getPk() == null){ tableEntity.setPk(columnEntity); } - + columsList.add(columnEntity); } tableEntity.setColumns(columsList); - + //没主键,则第一个字段为主键 if(tableEntity.getPk() == null){ tableEntity.setPk(tableEntity.getColumns().get(0)); } - + //设置velocity资源加载器 - Properties prop = new Properties(); - prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); + Properties prop = new Properties(); + prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); Velocity.init(prop); String mainPath = config.getString("mainPath" ); mainPath = StringUtils.isBlank(mainPath) ? "io.renren" : mainPath; - + //封装模板数据 Map map = new HashMap<>(); map.put("tableName", tableEntity.getTableName()); @@ -115,7 +115,7 @@ public class GenUtils { map.put("email", config.getString("email")); map.put("datetime", DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN)); VelocityContext context = new VelocityContext(map); - + //获取模板列表 List templates = getTemplates(); for(String template : templates){ @@ -123,7 +123,7 @@ public class GenUtils { StringWriter sw = new StringWriter(); Template tpl = Velocity.getTemplate(template, "UTF-8"); tpl.merge(context, sw); - + try { //添加到zip zip.putNextEntry(new ZipEntry(getFileName(template, tableEntity.getClassName(), config.getString("package"), config.getString("moduleName")))); @@ -135,15 +135,15 @@ public class GenUtils { } } } - - + + /** * 列名转换成Java属性名 */ public static String columnToJava(String columnName) { return WordUtils.capitalizeFully(columnName, new char[]{'_'}).replace("_", ""); } - + /** * 表名转换成Java类名 */ @@ -153,7 +153,7 @@ public class GenUtils { } return columnToJava(tableName); } - + /** * 获取配置信息 */ @@ -207,4 +207,4 @@ public class GenUtils { return null; } -} \ No newline at end of file +} diff --git a/neuray-pm-base-server/base-code-generator/src/main/resources/generator.properties b/neuray-pm-base-server/base-code-generator/src/main/resources/generator.properties index 6c2cd86747bfc65d489d1aa479d05bec8ea34021..e717318448d02d8be4fa6d73714e33e77c927965 100644 --- a/neuray-pm-base-server/base-code-generator/src/main/resources/generator.properties +++ b/neuray-pm-base-server/base-code-generator/src/main/resources/generator.properties @@ -1,7 +1,7 @@ #代码生成器,配置信息 #包名 -package=com.gitee.neuray.security.admin -moduleName=user +package=com.gitee.neuray.security.generator +moduleName=userprojectmd #作者 author=zhhongyu #表前缀(类名不会包含表前缀) @@ -57,4 +57,4 @@ TIMESTAMP(6)=Date int8=Long int4=Integer int2=Integer -numeric=BigDecimal \ No newline at end of file +numeric=BigDecimal diff --git a/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/configmd/TConfigInfoMapper.xml b/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/configmd/TConfigInfoMapper.xml new file mode 100644 index 0000000000000000000000000000000000000000..ca6794ff07c91625c763b2d2a704ea107845d813 --- /dev/null +++ b/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/configmd/TConfigInfoMapper.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/databasemd/TDatabaseInfoMapper.xml b/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/databasemd/TDatabaseInfoMapper.xml new file mode 100644 index 0000000000000000000000000000000000000000..243565c211316e4b519f26c0e9fe0b74a98e5e68 --- /dev/null +++ b/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/databasemd/TDatabaseInfoMapper.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/MySQLGeneratorDao.xml b/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/productionmd/MySQLGeneratorDao.xml similarity index 91% rename from neuray-pm-base-server/base-code-generator/src/main/resources/mapper/MySQLGeneratorDao.xml rename to neuray-pm-base-server/base-code-generator/src/main/resources/mapper/productionmd/MySQLGeneratorDao.xml index cc17c22d1fddcda91efdb62c7e33bbb43477ff7b..e8ca8821dff9c3d529ef62e188cc063b844c7f2e 100644 --- a/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/MySQLGeneratorDao.xml +++ b/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/productionmd/MySQLGeneratorDao.xml @@ -1,7 +1,7 @@ - + select table_name tableName, engine, table_comment tableComment, create_time createTime from information_schema.tables where table_schema = (select database()) @@ -20,4 +20,4 @@ select column_name columnName, data_type dataType, column_comment columnComment, column_key columnKey, extra from information_schema.columns where table_name = #{tableName} and table_schema = (select database()) order by ordinal_position - \ No newline at end of file + diff --git a/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/OracleGeneratorDao.xml b/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/productionmd/OracleGeneratorDao.xml similarity index 96% rename from neuray-pm-base-server/base-code-generator/src/main/resources/mapper/OracleGeneratorDao.xml rename to neuray-pm-base-server/base-code-generator/src/main/resources/mapper/productionmd/OracleGeneratorDao.xml index 27877bcf4c4bc105aa8b15eec66c7a60c3407211..0b368354e1794a56ec3a01c7b380c03931e1db04 100644 --- a/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/OracleGeneratorDao.xml +++ b/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/productionmd/OracleGeneratorDao.xml @@ -1,7 +1,7 @@ - + @@ -60,4 +60,4 @@ order by temp.column_id - \ No newline at end of file + diff --git a/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/PostgreSQLGeneratorDao.xml b/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/productionmd/PostgreSQLGeneratorDao.xml similarity index 94% rename from neuray-pm-base-server/base-code-generator/src/main/resources/mapper/PostgreSQLGeneratorDao.xml rename to neuray-pm-base-server/base-code-generator/src/main/resources/mapper/productionmd/PostgreSQLGeneratorDao.xml index 87c171387175394d8ab6f6e7a3754e6bf385c8d9..d7fef288d6b85903166f5994f5487e40198a7b02 100644 --- a/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/PostgreSQLGeneratorDao.xml +++ b/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/productionmd/PostgreSQLGeneratorDao.xml @@ -1,7 +1,7 @@ - + @@ -34,4 +34,4 @@ left join pg_constraint t3 on t2.attnum = t3.conkey[1] and t2.attrelid = t3.conrelid where t1.relname = #{tableName} and t2.attrelid = t1.oid and t2.attnum>0 - \ No newline at end of file + diff --git a/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/SQLServerGeneratorDao.xml b/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/productionmd/SQLServerGeneratorDao.xml similarity index 95% rename from neuray-pm-base-server/base-code-generator/src/main/resources/mapper/SQLServerGeneratorDao.xml rename to neuray-pm-base-server/base-code-generator/src/main/resources/mapper/productionmd/SQLServerGeneratorDao.xml index 07507c2e473750c056aa67cc328c1862cdb8b04e..ba6d993e22a6dc37e763dee3f933b386c2aeedd2 100644 --- a/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/SQLServerGeneratorDao.xml +++ b/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/productionmd/SQLServerGeneratorDao.xml @@ -1,7 +1,7 @@ - + select * from ( @@ -87,4 +87,4 @@ a.NAME = #{tableName} and sys.types.NAME != 'sysname' - \ No newline at end of file + diff --git a/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/projectmd/TProjectInfoMapper.xml b/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/projectmd/TProjectInfoMapper.xml new file mode 100644 index 0000000000000000000000000000000000000000..182c581183a3dabcb95e01c6cff845873d9d3d7e --- /dev/null +++ b/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/projectmd/TProjectInfoMapper.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/userprojectmd/TProjectUserMapper.xml b/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/userprojectmd/TProjectUserMapper.xml new file mode 100644 index 0000000000000000000000000000000000000000..404825062eadbc06b0b42a08cb33db5a64f7a8bc --- /dev/null +++ b/neuray-pm-base-server/base-code-generator/src/main/resources/mapper/userprojectmd/TProjectUserMapper.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/neuray-pm-base-server/base-code-generator/src/main/resources/template/Entity.java.vm b/neuray-pm-base-server/base-code-generator/src/main/resources/template/Entity.java.vm index e4218e388aa7367d856fb8db9ee2262e1fe04d0e..ad8671a0991b957a0521b3811126bc9c70df0fe0 100644 --- a/neuray-pm-base-server/base-code-generator/src/main/resources/template/Entity.java.vm +++ b/neuray-pm-base-server/base-code-generator/src/main/resources/template/Entity.java.vm @@ -23,14 +23,17 @@ import java.util.Date; public class ${className}Entity extends BaseEntity { #foreach ($column in $columns) - /** - * $column.comments - */ + ## #if($column.columnName == $pk.columnName) ## @Column(name = "$column.columnName") ## #end -@Column(name = "$column.columnName") -private $column.attrType $column.attrname; + #if($column.columnName != $pk.columnName) + /** + * $column.comments + */ + @Column(name = "$column.columnName") + private $column.attrType $column.attrname; + #end #end } diff --git a/neuray-pm-base-server/base-dfsfile-client/pom.xml b/neuray-pm-base-server/base-dfsfile-client/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..d0763b8eb111139c460c2398797c17b3e605d105 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/pom.xml @@ -0,0 +1,100 @@ + + + + neuray-pm-base-server + com.gitee.neuray.security + 1.0-SNAPSHOT + + 4.0.0 + + base-dfsfile-client + + UTF-8 + UTF-8 + 1.8 + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + + + org.springframework.cloud + spring-cloud-starter-netflix-eureka-client + + + com.gitee.neuray.security + neuray-pm-common + 1.0-SNAPSHOT + + + com.github.tobato + fastdfs-client + 1.26.2 + + + + com.oracle + ojdbc6 + 11.2.0.3 + + + + tk.mybatis + mapper-spring-boot-starter + 1.1.2 + + + + com.github.pagehelper + pagehelper-spring-boot-starter + 1.2.3 + + + com.github.wxiaoqi + ace-cache + 0.0.2 + + + log4j + log4j + 1.2.17 + + + org.springframework.cloud + spring-cloud-starter-netflix-hystrix + 2.0.0.M7 + + + com.gitee.neuray.security + auth-client + 1.0-SNAPSHOT + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/BasedfsClientBootStrap.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/BasedfsClientBootStrap.java new file mode 100644 index 0000000000000000000000000000000000000000..5d0088a0808d7d922ea8012409098f04554240c9 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/BasedfsClientBootStrap.java @@ -0,0 +1,38 @@ +package com.gitee.neuray.security.file; + +import com.ace.cache.EnableAceCache; +import com.gitee.neuray.security.auth.client.EnableAceAuthClient; +import com.github.tobato.fastdfs.FdfsClientConfig; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.netflix.hystrix.EnableHystrix; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.context.annotation.EnableMBeanExport; +import org.springframework.context.annotation.Import; +import org.springframework.jmx.support.RegistrationPolicy; + +/** + * FastdfsClient客户端 + * @author zhhongyu + */ +@EnableAceAuthClient +@EnableHystrix +@EnableAceCache +@SpringBootApplication +@EnableDiscoveryClient +@Import(FdfsClientConfig.class) +@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING) +@MapperScan({"com.gitee.neuray.security.file.dao","com.gitee.neuray.security.file.mapper"}) +@EnableAspectJAutoProxy(exposeProxy=true) +@EnableFeignClients({"com.gitee.neuray.security.auth.client.feign"}) +@ServletComponentScan +public class BasedfsClientBootStrap { + + public static void main(String[] args) { + SpringApplication.run(BasedfsClientBootStrap.class, args); + } +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/biz/FileInfoBiz.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/biz/FileInfoBiz.java new file mode 100644 index 0000000000000000000000000000000000000000..7430a7f134ff314ecf08a5650fa5d73a251daeca --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/biz/FileInfoBiz.java @@ -0,0 +1,542 @@ +package com.gitee.neuray.security.file.biz; + +import com.ace.cache.annotation.Cache; +import com.ace.cache.api.impl.CacheRedis; +import com.alibaba.fastjson.JSON; +import com.gitee.neuray.security.common.biz.BaseBiz; +import com.gitee.neuray.security.common.exception.BaseException; +import com.gitee.neuray.security.common.msg.TableResultResponse; +import com.gitee.neuray.security.common.util.EntityUtils; +import com.gitee.neuray.security.common.util.Query; +import com.gitee.neuray.security.common.util.UUIDUtils; +import com.gitee.neuray.security.common.vo.FileInfoVO; +import com.gitee.neuray.security.file.contants.FileContants; +import com.gitee.neuray.security.file.entity.FileInfoEntity; +import com.gitee.neuray.security.file.entity.FileServerPathEntity; +import com.gitee.neuray.security.file.mapper.FileInfoMapper; +import com.gitee.neuray.security.file.mapper.FileServerPathMapper; +import com.gitee.neuray.security.file.util.*; +import com.gitee.neuray.security.file.vo.JwtInfoVO; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.aop.framework.AopContext; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; +import org.springframework.web.multipart.MultipartFile; +import tk.mybatis.mapper.entity.Example; + +import javax.servlet.http.HttpServletResponse; +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 文件基础数据业务处理层 + * + * @author zhhongyu + * @since 2019-07-29 + */ +@Slf4j +@Service +@Transactional(rollbackFor = Exception.class) +public class FileInfoBiz extends BaseBiz { + @Autowired + private FastDFSClientWrapper dfsClient; + @Autowired + private FileServerPathBiz fileServerPathBiz; + @Autowired + private AppendFileUtils appendFileUtils; + @Autowired + private CacheRedis cacheRedis; + + @Autowired + private FileServerPathMapper fileServerPathMapper; + + + @Override + protected String getPageName() { + return null; + } + + /** + * 上传非加密文件业务处理 + * + * @param file + * @return + * @throws Exception + */ + public FileInfoVO uploadFile(MultipartFile file) throws Exception { + String md5Key = MD5Util.MD5(file.getBytes()); + String fileServerPathId = ""; + //先从缓存中获取文件 + fileServerPathId = ((FileInfoBiz) AopContext.currentProxy()).uploadFileCache(md5Key, null); + FileInfoEntity fileInforEntity = new FileInfoEntity(); + FileServerPathEntity fileServerPathEntity = new FileServerPathEntity(); + String fullPath = ""; + //如果缓存中没有该文件 + if (StringUtils.isEmpty(fileServerPathId)) { + String path = dfsClient.uploadFile(file); + fullPath = path; + fileServerPathEntity.setPath(path); + fileServerPathEntity.setFileEncrype(FileContants.NO_SENSITIVE_TYPE); + this.fileToEntity(file, fileInforEntity, fileServerPathEntity); + this.insertEntityAce(fileInforEntity, fileServerPathEntity, md5Key); + } + //如果缓存中有该文件,则进行插入数据库表到文件基本信息表,然后直接返回成功上传到服务器 + // 从而实现秒传效果 + if (!StringUtils.isEmpty(fileServerPathId)) { + this.fileToEntity(file, fileInforEntity, null); + fileInforEntity.setFilePathId(fileServerPathId); + mapper.insertSelective(fileInforEntity); + fullPath = fileServerPathBiz.selectById(fileServerPathId).getPath(); + } + FileInfoVO fileInforVO = this.transferEntityToVo(fileInforEntity); + fileInforVO.setFullPath(fullPath); + return fileInforVO; + } + + /** + * 上传默认头像 + * + * @param file + * @return + * @throws Exception + */ + public FileInfoVO uploadDefaultAvator(MultipartFile file) throws Exception { + FileInfoVO fileInfoVO = this.uploadFile(file); + //使用扩展字段arrt1,标识为是否是默认头像文件,1为是,0或者为null为否 + FileInfoEntity fileInfoEntity = new FileInfoEntity(); + fileInfoEntity.setId(fileInfoVO.getFileId()); + fileInfoEntity.setAttr1("1"); + mapper.updateByPrimaryKeySelective(fileInfoEntity); + return fileInfoVO; + } + + /** + * 分页获取默认头像 + * + * @param query + * @return + */ + public TableResultResponse defaultAvatorPageList(Query query) { + Example example = new Example(FileInfoEntity.class); + if (query.entrySet().size() > 0) { + Example.Criteria criteria = example.createCriteria(); + for (Map.Entry entry : query.entrySet()) { + criteria.andLike(entry.getKey(), "%" + entry.getValue().toString() + "%"); + } + criteria.andEqualTo("attr1", "1"); + } + example.setOrderByClause("CRT_TIME DESC"); + Page result = PageHelper.startPage(query.getPageNo(), query.getPageSize()); + List list = mapper.selectByExample(example); + return new TableResultResponse(result.getPageSize(), result.getPageNum(), result.getPages(), result.getTotal(), list); + } + + /** + * 上传加密文件 + * + * @param file 文件 + * @param sensitiveType 加密类型(1为base64加密,2为位移加密法,3为文件流加密) + * @return + * @throws Exception + */ + public FileInfoVO uploadSensitiveFile(MultipartFile file, String sensitiveType) throws Exception { + String md5Key = MD5Util.MD5(file.getBytes()); + String fileServerPathId = ""; + //先从缓存中获取文件 + fileServerPathId = ((FileInfoBiz) AopContext.currentProxy()).uploadFileCache(md5Key, null); + FileInfoEntity fileInforEntity = new FileInfoEntity(); + FileServerPathEntity fileServerPathEntity = new FileServerPathEntity(); + //如果缓存中没有该文件 + if (StringUtils.isEmpty(fileServerPathId)) { + String path = ""; + //采用文件流加密 + if (FileContants.SENSITIVE_BASE64_TYPE.equals(sensitiveType)) { + path = dfsClient.uploadbase64SensitiveFile(file); + fileServerPathEntity.setFileEncrype(FileContants.SENSITIVE_BASE64_TYPE); + } + //采用文件流加密 + if (FileContants.SENSITIVE_CIPHER_TYPE.equals(sensitiveType)) { + path = dfsClient.uploadCipherSensitiveFile(file); + fileServerPathEntity.setFileEncrype(FileContants.SENSITIVE_CIPHER_TYPE); + } + //采用位移加密 + if (FileContants.SENSITIVE_BYTEMOVE_TYPE.equals(sensitiveType)) { + path = dfsClient.uploadByteMoveSensitiveFile(file); + fileServerPathEntity.setFileEncrype(FileContants.SENSITIVE_BYTEMOVE_TYPE); + } + fileServerPathEntity.setPath(path); + this.fileToEntity(file, fileInforEntity, fileServerPathEntity); + this.insertEntityAce(fileInforEntity, fileServerPathEntity, md5Key); + } + //如果缓存中有该文件,则进行插入数据库表到文件基本信息表,然后直接返回成功上传到服务器 + // 从而实现秒传效果 + if (!StringUtils.isEmpty(fileServerPathId)) { + this.fileToEntity(file, fileInforEntity, null); + fileInforEntity.setFilePathId(fileServerPathId); + mapper.insertSelective(fileInforEntity); + } + FileInfoVO fileInforVO = this.transferEntityToVo(fileInforEntity); + return fileInforVO; + } + + /** + * 上传加密文件(文件分块上传) + * + * @param file 文件 + * @param md5key 整个文件的唯一性标识 + * @param currentNo 当前块 + * @param totalSize 总块数 + * @param fileInfo 文件基本信息 + * @param jwtInfoVO jwttoken解析用户结果实体类 + * @return 最后一块时,返回文件上传基本信息值 + * @throws Exception + */ + public FileInfoVO uploadAppendSensitiveFile(MultipartFile file, String md5key, + String currentNo, String totalSize, + FileInfoEntity fileInfo, + JwtInfoVO jwtInfoVO) throws Exception { + if (Integer.parseInt(currentNo) > Integer.parseInt(totalSize)) { + throw new BaseException("当前块数不能大于总块数..."); + } + //先从redies中获取相同文件,进行秒传实现 + if (!StringUtils.isEmpty(md5key)) { + String fileServerPathId = cacheRedis.get("files:" + md5key); + //秒传实现如果有id,则进行保存数据操作,直接响应给客户端 + if (!StringUtils.isEmpty(fileServerPathId)) { + fileInfo.setFilePathId(fileServerPathId); + mapper.insertSelective(fileInfo); + FileInfoVO fileInforVO = this.transferEntityToVo(fileInfo); + //方便前端实现秒传进度条 + fileInforVO.setTotalSize(totalSize); + fileInforVO.setIsSuccessNo(totalSize); + return fileInforVO; + } + } + FileInfoVO fileInforVO = null; + Map fileCard = appendFileUtils.uploadCipherSensitiveFile(file, md5key, jwtInfoVO.getCrtUser(), currentNo, totalSize); + String path = (String) fileCard.get("path"); + String isSuccessNo = (String) fileCard.get("isSuccessNo"); + //最后一块时进行数据库保存操作 + if (currentNo.equals(totalSize)) { + FileServerPathEntity fileServerPathEntity = this.generFileServerPathEntity(jwtInfoVO); + fileServerPathEntity.setPath(path); + fileServerPathEntity.setFileEncrype(FileContants.SENSITIVE_CIPHER_TYPE); + try { + fileServerPathMapper.insertSelective(fileServerPathEntity); + fileInfo.setFilePathId(fileServerPathEntity.getId()); + mapper.insertSelective(fileInfo); + //缓存整个文件唯一性编码到redies,做秒传功能 + if (!StringUtils.isEmpty(md5key)) { + String appendPersonKey = FileContants.REDIS_KEY_CON_APPEND_FILE + + jwtInfoVO.getCrtUser() + + FileContants.REDIS_KEY_CON_APPEND_FILE; + cacheRedis.remove(FileContants.REDIS_KEY_APPEND_FILE + appendPersonKey + md5key); + cacheRedis.remove(FileContants.REDIS_KEY_PRE_APPEND_FILE + appendPersonKey + md5key); + cacheRedis.set("files:" + md5key, fileServerPathEntity.getId(), 525600); + } + fileInforVO = this.transferEntityToVo(fileInfo); + //将最后一次的参数也返回给调用方,下一块为总块数,成功块数为总块数 + fileInforVO.setNextNo(totalSize); + fileInforVO.setTotalSize(totalSize); + fileInforVO.setIsSuccessNo(totalSize); + return fileInforVO; + } catch (Exception e) { + //如果数据存入数据库失败,回滚fast服务的文件 + log.error(CommonUtil.getExceptionMessage(e)); + dfsClient.deleteFile(path); + throw e; + } + } + fileInforVO = new FileInfoVO(); + fileInforVO.setFullPath(path); + fileInforVO.setIsSuccessNo(isSuccessNo); + //设置要传的下一块 + fileInforVO.setNextNo(String.valueOf(Integer.parseInt(isSuccessNo) + 1)); + fileInforVO.setTotalSize(totalSize); + return fileInforVO; + } + + /** + * 删除文件业务处理 + * + * @param fileId 文件id + */ + public void deleteFile(String fileId) { + if (StringUtils.isEmpty(fileId)) { + throw new BaseException("fileId is null..."); + } + FileInfoEntity fileInfoEntity = new FileInfoEntity(); + fileInfoEntity.setId(fileId); + fileInfoEntity = mapper.selectByPrimaryKey(fileInfoEntity); + if (fileInfoEntity == null) { + throw new BaseException("没有改文件..."); + } + //保留文件历史,只是将数据库中文件信息设置为无效状态 + fileInfoEntity.setStatus(FileContants.INVALID_FILE); + mapper.updateByPrimaryKeySelective(fileInfoEntity); + } + + /** + * 文件下载业务处理 + * + * @param fileId + * @param sensitiveType + * @return + */ + public Map downLoadFile(String fileId, String sensitiveType) throws IOException { + if (StringUtils.isEmpty(fileId)) { + throw new BaseException("fileId is null ... "); + } + FileInfoEntity fileInfoEntity = new FileInfoEntity(); + fileInfoEntity.setId(fileId); + fileInfoEntity = mapper.selectByPrimaryKey(fileInfoEntity); + if (fileInfoEntity == null) { + throw new BaseException("没有该文件..."); + } + if (StringUtils.isEmpty(fileInfoEntity.getFilePathId())) { + throw new BaseException("该文件没有对应的服务器路径..."); + } + FileServerPathEntity fileServerPathEntity = fileServerPathBiz.selectById(fileInfoEntity.getFilePathId()); + if (fileServerPathEntity == null || StringUtils.isEmpty(fileServerPathEntity.getPath())) { + throw new BaseException("文件没有存在在服务器中..."); + } + String path = fileServerPathEntity.getPath(); + //文件名称 + String fileName = fileInfoEntity.getFileName(); + //文件后缀 + String fileExt = fileInfoEntity.getFileExt(); + if (StringUtils.isEmpty(fileName)) { + fileName = FileContants.DOWNLOAD_FILE_NAME; + } + if (StringUtils.isEmpty(fileExt)) { + fileExt = FileContants.DOWNLOAD_FILE_EXT; + } + fileName = fileName + FileContants.FILE_REGIX_VALUE + fileExt; + byte[] fileIO = null; + //非涉密文件下载 + if (FileContants.NO_SENSITIVE_TYPE.equals(sensitiveType)) { + fileIO = dfsClient.download(path); + } + if (FileContants.SENSITIVE_BASE64_TYPE.equals(sensitiveType)) { + fileIO = dfsClient.downloadBase64SensitiveFile(path); + } + if (FileContants.SENSITIVE_CIPHER_TYPE.equals(sensitiveType)) { + fileIO = dfsClient.downloadCipherSensitiveFile(path); + } + if (FileContants.SENSITIVE_BYTEMOVE_TYPE.equals(sensitiveType)) { + fileIO = dfsClient.downloadByteMoveSensitiveFile(path); + } + Map result = new HashMap(); + result.put("fileName", fileName); + result.put("fileByte", fileIO); + return result; + } + + /** + * 获取图片,并响应给客户端 + * + * @param fileId + * @param response + * @param sensitiveType + * @throws IOException + */ + public void getImg(String fileId, HttpServletResponse response, String sensitiveType) throws IOException { + if (StringUtils.isEmpty(fileId)) { + throw new BaseException("fileId is null ... "); + } + OutputStream outputStream = null; + try { + //读取路径下面的文件 + FileInfoEntity fileInfoEntity = new FileInfoEntity(); + fileInfoEntity.setId(fileId); + fileInfoEntity = mapper.selectByPrimaryKey(fileInfoEntity); + if (fileInfoEntity == null) { + throw new BaseException("查询不到该文件 ... "); + } + if (StringUtils.isEmpty(fileInfoEntity.getFilePathId())) { + throw new BaseException("该文件没有存储文件路径 ... "); + } + FileServerPathEntity fileServerPathEntity = fileServerPathBiz.selectById(fileInfoEntity.getFilePathId()); + if (fileServerPathEntity == null || StringUtils.isEmpty(fileServerPathEntity.getPath())) { + throw new BaseException("文件没有在文件服务中 ... "); + } + String path = fileServerPathEntity.getPath(); + byte[] data = null; + if (FileContants.NO_SENSITIVE_TYPE.equals(sensitiveType)) { + data = dfsClient.download(path); + } + if (FileContants.SENSITIVE_BASE64_TYPE.equals(sensitiveType)) { + data = dfsClient.downloadBase64SensitiveFile(path); + } + if (FileContants.SENSITIVE_BYTEMOVE_TYPE.equals(sensitiveType)) { + data = dfsClient.downloadByteMoveSensitiveFile(path); + } + if (FileContants.SENSITIVE_CIPHER_TYPE.equals(sensitiveType)) { + data = dfsClient.downloadCipherSensitiveFile(path); + } + //获取文件后缀名格式 + String ext = ((fileInfoEntity.getFileExt() == null) ? "" : fileInfoEntity.getFileExt()); + //判断图片格式,设置相应的输出文件格式 + if ("jpg".equals(ext) || "JPG".equals(ext)) { + response.setContentType("image/jpeg"); + } + if ("png".equals(ext) || "PNG".equals(ext)) { + response.setContentType("image/png"); + } + outputStream = new BufferedOutputStream(response.getOutputStream()); + outputStream.write(data); + outputStream.flush(); + } catch (Exception e) { + log.error(CommonUtil.getExceptionMessage(e)); + } finally { + //关流 + if (outputStream != null) { + outputStream.close(); + } + } + } + + public TableResultResponse page(Query query) { + Example example = new Example(FileInfoEntity.class); + if (query.entrySet().size() > 0) { + Example.Criteria criteria = example.createCriteria(); + for (Map.Entry entry : query.entrySet()) { + criteria.andLike(entry.getKey(), "%" + entry.getValue().toString() + "%"); + } + } + example.setOrderByClause("CRT_TIME DESC"); + Page result = PageHelper.startPage(query.getPageNo(), query.getPageSize()); + List list = mapper.selectByExample(example); + List voList = new ArrayList<>(); + list.stream().forEach((FileInfoEntity file) -> { + String path = ""; + String type = "0"; + if (!StringUtils.isEmpty(file.getFilePathId())) { + FileServerPathEntity fileServerPathEntity = fileServerPathBiz.selectById(file.getFilePathId()); + path = fileServerPathEntity.getPath(); + type = fileServerPathEntity.getFileEncrype(); + } + com.gitee.neuray.security.file.vo.FileInfoVO fileVo = new com.gitee.neuray.security.file.vo.FileInfoVO(); + BeanUtils.copyProperties(file, fileVo); + fileVo.setPath(path); + fileVo.setSensitiveType(type); + voList.add(fileVo); + }); + return new TableResultResponse(result.getPageSize(), result.getPageNum(), result.getPages(), result.getTotal(), voList); + } + + private String insertEntityAce(FileInfoEntity fileInforEntity, FileServerPathEntity fileServerPathEntity, + String md5Key) throws Exception { + //首先插入文件服务路径表中记录 + fileServerPathBiz.insertSelective(fileServerPathEntity); + fileInforEntity.setFilePathId(fileServerPathEntity.getId()); + //todo:欠一个redis和数据库事务一致性,这个方法可能不需要 + mapper.insertSelective(fileInforEntity); + //插入成功将唯一性的md5编码key缓存到缓存中 + String fileServerPathId = null; + try { + fileServerPathId = ((FileInfoBiz) AopContext.currentProxy()).uploadFileCache(md5Key, JSON.toJSONString(fileServerPathEntity.getId())); + } catch (Exception e) { + log.error(CommonUtil.getExceptionMessage(e)); + dfsClient.deleteFile(fileServerPathEntity.getPath()); + throw e; + } + return fileServerPathId; + } + + /** + * 将file文件转为数据库实体(path字段需要单独赋值) + * + * @param file 文件 + * @param fileInforEntity 文件基本信息实体类 + * @param fileServerPathEntity 上传文件到服务器路径实体类 + * @return + * @throws Exception + */ + private void fileToEntity(MultipartFile file, FileInfoEntity fileInforEntity, + FileServerPathEntity fileServerPathEntity) throws Exception { + if (file == null) { + throw new BaseException("上传文件不能为空..."); + } + if (fileInforEntity != null) { + String fileName = file.getOriginalFilename(); + String suffix = ""; + String fileExt = ""; + String regixValue = FileContants.FILE_REGIX_VALUE; + if (fileName.indexOf(regixValue) != -1) { + suffix = fileName.substring(fileName.lastIndexOf(regixValue)); + fileName = fileName.substring(0, fileName.lastIndexOf(regixValue)); + } + if (!"".equals(suffix) && !regixValue.equals(suffix)) { + fileExt = suffix.substring(suffix.indexOf(regixValue) + 1); + } + fileInforEntity.setFileExt(fileExt); + fileInforEntity.setFileName(fileName); + String fileType = ""; + FileTypeEnum fileTypeEnum = FileTypeEnum.getEnumByValue(fileExt); + fileType = fileTypeEnum.getType(); + fileInforEntity.setFileType(fileType.toLowerCase()); + fileInforEntity.setFileSize(Double.valueOf(file.getSize())); + fileInforEntity.setStatus(FileContants.EFECTIVE_FILE); + EntityUtils.setCreatAndUpdatInfo(fileInforEntity); + } + if (fileServerPathEntity != null) { + fileServerPathEntity.setStatus(FileContants.EFECTIVE_FILE); + EntityUtils.setCreatAndUpdatInfo(fileServerPathEntity); + } + return; + } + + /** + * 生成FileServerPathEntity私有方法 + * + * @param jwtInfoVO + * @return + */ + private FileServerPathEntity generFileServerPathEntity(JwtInfoVO jwtInfoVO) { + FileServerPathEntity fileServerPathEntity = new FileServerPathEntity(); + if (jwtInfoVO != null) { + BeanUtils.copyProperties(jwtInfoVO, fileServerPathEntity); + } + fileServerPathEntity.setId(UUIDUtils.generateShortUuid()); + fileServerPathEntity.setStatus(FileContants.EFECTIVE_FILE); + return fileServerPathEntity; + } + + private FileInfoVO transferEntityToVo(FileInfoEntity fileInfoEntity) { + FileInfoVO fileInfoVO = new FileInfoVO(); + BeanUtils.copyProperties(fileInfoEntity, fileInfoVO); + fileInfoVO.setFileId(fileInfoEntity.getId()); + return fileInfoVO; + } + + /** + * 文件存放redies中,时间为一年 + * + * @param base64FileName + * @param fileId + * @return + * @throws Exception + */ + @Cache(key = "files{1}", result = String.class, expire = 525600) + public String uploadFileCache(String base64FileName, String fileId) throws Exception { + return fileId; + } + + + public static void main(String[] args) { + System.out.println(JSON.toJSONString("654sdf")); + String s = JSON.parseObject("\"654sdf\"", String.class); + System.out.println(s); + } +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/biz/FileServerPathBiz.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/biz/FileServerPathBiz.java new file mode 100644 index 0000000000000000000000000000000000000000..5647efd199a8a13184d9c44347484e25437dc7be --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/biz/FileServerPathBiz.java @@ -0,0 +1,23 @@ +package com.gitee.neuray.security.file.biz; + +import com.gitee.neuray.security.common.biz.BaseBiz; +import com.gitee.neuray.security.file.entity.FileServerPathEntity; +import com.gitee.neuray.security.file.mapper.FileServerPathMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * fast服务文件路径基础数据业务处理层 + * @author zhhongyu + * @since 2019-08-01 + */ +@Slf4j +@Service +@Transactional(rollbackFor = Exception.class) +public class FileServerPathBiz extends BaseBiz { + @Override + protected String getPageName() { + return null; + } +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/config/FileHeaderFilter.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/config/FileHeaderFilter.java new file mode 100644 index 0000000000000000000000000000000000000000..d3df6522570e7c494b72502c9f30631de9bfc51e --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/config/FileHeaderFilter.java @@ -0,0 +1,59 @@ +package com.gitee.neuray.security.file.config; + +import com.gitee.neuray.security.auth.common.util.jwt.IJWTInfo; +import com.gitee.neuray.security.common.util.ClientUtil; +import com.gitee.neuray.security.common.util.ExceptionCommonUtil; +import com.gitee.neuray.security.file.jwt.FileJwtInfo; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.StringUtils; + +import javax.servlet.*; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; + +/** + * @author: zhhongyu + * @description: 文件服务定义请求头过滤器 + * @since: Create in 15:37 2019/12/2 + */ +@Slf4j +@WebFilter(filterName = "fileHeaderFilter", urlPatterns = "/fdfs/file/*") +public class FileHeaderFilter implements Filter { + @Autowired + private FileJwtInfo fileJwtInfo; + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + log.info("FileHeaderFilter init...."); + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + HttpServletRequest req = (HttpServletRequest) request; + HeaderMapRequestWrapper requestWrapper = new HeaderMapRequestWrapper(req); + try { + IJWTInfo infoFromToken = fileJwtInfo.getJwtInfo(req); + if(infoFromToken != null){ + requestWrapper.addHeader("userId",infoFromToken.getUniqueName()); + requestWrapper.addHeader("userName",infoFromToken.getName()); + String host = StringUtils.isEmpty(req.getHeader("clientIp")) ? + req.getHeader("clientIp") : ClientUtil.getClientIp(req); + requestWrapper.addHeader("userHost",host); + requestWrapper.addHeader("userSecretLevel",infoFromToken.getSecretLevel()); + chain.doFilter(requestWrapper, response); + return; + } + } catch (Exception e) { + log.error(ExceptionCommonUtil.getExceptionMessage(e)); + } + // Goes to default servlet. + chain.doFilter(request, response); + } + + @Override + public void destroy() { + log.info("sysUserRequestFilter destroy..."); + } +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/config/HeaderMapRequestWrapper.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/config/HeaderMapRequestWrapper.java new file mode 100644 index 0000000000000000000000000000000000000000..8fa05b2310d66d36194bac6e3de55bcbf5d917c5 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/config/HeaderMapRequestWrapper.java @@ -0,0 +1,59 @@ +package com.gitee.neuray.security.file.config; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.util.*; + +public class HeaderMapRequestWrapper extends HttpServletRequestWrapper { + /** + * construct a wrapper for this request + * + * @param request + */ + public HeaderMapRequestWrapper(HttpServletRequest request) { + super(request); + } + + private Map headerMap = new HashMap(); + + /** + * add a header with given name and value + * + * @param name + * @param value + */ + public void addHeader(String name, String value) { + headerMap.put(name, value); + } + + @Override + public String getHeader(String name) { + String headerValue = super.getHeader(name); + if (headerMap.containsKey(name)) { + headerValue = headerMap.get(name); + } + return headerValue; + } + + /** + * get the Header names + */ + @Override + public Enumeration getHeaderNames() { + List names = Collections.list(super.getHeaderNames()); + for (String name : headerMap.keySet()) { + names.add(name); + } + return Collections.enumeration(names); + } + + @Override + public Enumeration getHeaders(String name) { + List values = Collections.list(super.getHeaders(name)); + if (headerMap.containsKey(name)) { + values.add(headerMap.get(name)); + } + return Collections.enumeration(values); + } + +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/config/WebConfiguration.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/config/WebConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..b233e8d117ccbbf067aa9bbeb05b7e77f0284132 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/config/WebConfiguration.java @@ -0,0 +1,47 @@ +package com.gitee.neuray.security.file.config; + +import com.gitee.neuray.security.auth.client.interceptor.UserAuthRestInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.util.ArrayList; +import java.util.Collections; + +/** + * @author: zhhongyu + * @description: + * @since: Create in 18:23 2019/8/22 + */ +@Configuration +@Primary +public class WebConfiguration implements WebMvcConfigurer { + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(getUserAuthRestInterceptor()). + addPathPatterns(getIncludePathPatterns()); + } + + @Bean + UserAuthRestInterceptor getUserAuthRestInterceptor() { + return new UserAuthRestInterceptor(); + } + + /** + * 需要用户路径 + * @return + */ + private ArrayList getIncludePathPatterns() { + ArrayList list = new ArrayList<>(); + String[] urls = { + "/fdfs/file/**", + "/fileManage/**" + }; + Collections.addAll(list, urls); + return list; + } + +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/config/log4j/DailyRollingFileAppenderCustom.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/config/log4j/DailyRollingFileAppenderCustom.java new file mode 100644 index 0000000000000000000000000000000000000000..40cfc41e51cde20976abb7fd8737f5924ac6a8cb --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/config/log4j/DailyRollingFileAppenderCustom.java @@ -0,0 +1,25 @@ +package com.gitee.neuray.security.file.config.log4j; + +import org.apache.log4j.DailyRollingFileAppender; + +import java.io.IOException; + +/** + * log4j 日志动态路径 + * @author fansq + * @since 19-9-4 + */ +public class DailyRollingFileAppenderCustom extends DailyRollingFileAppender { + + @Override + public synchronized void setFile(String fileName, boolean append, boolean bufferedIO, int bufferSize) throws IOException { + super.setFile(getLog4jRoute(), append, bufferedIO, bufferSize); + + } + + public String getLog4jRoute(){ + String logBackRoute = Thread.currentThread(). + getContextClassLoader().getResource("").getPath(); + return logBackRoute+"/service-dfsfile/logs/all.log"; + } +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/contants/FileContants.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/contants/FileContants.java new file mode 100644 index 0000000000000000000000000000000000000000..43767071690a83c0f88cb7f48a42abd62d6d7f0c --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/contants/FileContants.java @@ -0,0 +1,71 @@ +package com.gitee.neuray.security.file.contants; + + +import com.gitee.neuray.security.file.util.DesCodeEnum; + +/** + * file服务用常量类 + * @author zhhongyu + * @since 2019-07-29 + */ +public class FileContants { + public final static String FILE_REGIX_VALUE = "."; + public final static String NO_SENSITIVE_TYPE = "0"; + /** + * 采用base64编码 + */ + public final static String SENSITIVE_BASE64_TYPE = "1"; + public final static String SENSITIVE_BYTEMOVE_TYPE = "2"; + public final static String SENSITIVE_CIPHER_TYPE = "3"; + /** + * 无效文件标识 + */ + public final static String INVALID_FILE = "0"; + /** + * 有效文件标识 + */ + public final static String EFECTIVE_FILE = "1"; + /** + * 如果数据库中没有文件名称,设置默认名称 + */ + public final static String DOWNLOAD_FILE_NAME = "test"; + /** + * 如果数据库中没有文件后缀,设置默认后缀 + */ + public final static String DOWNLOAD_FILE_EXT = "txt"; + + /** + * 加密类型 + */ + public static final String ENCRYPT_TYPE = DesCodeEnum.DESEDE_ECB_NoPadding.getCode(); + + public static final String KEY_ENCRYPT_TYPE = DesCodeEnum.DESEDE.getCode(); + /** + * key生成规则 + * + */ + public static final String ENCRYPT_ROLE = "FAST FILE DE-ENCRYPT"; + /** + * 加密标识 + */ + public static final String FILE_ENCRYPT = "encrypt"; + /** + * 解密标识 + */ + public static final String FILE_DECRYPT = "decrypt"; + /** + * 自定义加密补位规则 + */ + public static final byte FILE_ENCRYPT_SUB_RULE = 22; + /** + * 文件分块上传标识 + */ + public static final String REDIS_KEY_APPEND_FILE = "append_file"; + + public static final String REDIS_KEY_PRE_APPEND_FILE = "temp"; + + public static final String REDIS_KEY_CON_APPEND_FILE = ":"; + + public static final String REDIS_KEY_PRE = FileContants.REDIS_KEY_PRE_APPEND_FILE+ FileContants.REDIS_KEY_CON_APPEND_FILE; + +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/controller/FastDfsController.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/controller/FastDfsController.java new file mode 100644 index 0000000000000000000000000000000000000000..d37514dc9aa417ef600baa0b1de1209739df3f82 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/controller/FastDfsController.java @@ -0,0 +1,369 @@ +package com.gitee.neuray.security.file.controller; + +import com.gitee.neuray.security.auth.client.annotation.IgnoreUserToken; +import com.gitee.neuray.security.common.exception.BaseException; +import com.gitee.neuray.security.common.msg.ObjectRestResponse; +import com.gitee.neuray.security.common.msg.TableResultResponse; +import com.gitee.neuray.security.common.rest.BaseController; +import com.gitee.neuray.security.common.util.Query; +import com.gitee.neuray.security.common.util.UUIDUtils; +import com.gitee.neuray.security.file.biz.FileInfoBiz; +import com.gitee.neuray.security.file.contants.FileContants; +import com.gitee.neuray.security.file.entity.FileInfoEntity; +import com.gitee.neuray.security.file.jwt.FileJwtInfo; +import com.gitee.neuray.security.file.util.FastDFSClientWrapper; +import com.gitee.neuray.security.file.util.FileTypeEnum; +import com.gitee.neuray.security.file.vo.FileInfoVO; +import com.gitee.neuray.security.file.vo.JwtInfoVO; +import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; +import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.Map; + +/** + * file文件接口 + * + * @author zhhongyu + * @since 2019-06-18 + */ +@Slf4j +@RestController +@RequestMapping("/fdfs/file") +public class FastDfsController extends BaseController { + @Autowired + private FastDFSClientWrapper dfsClient; + @Autowired + private FileJwtInfo fileJwtInfo; + + +// @PostMapping("/upload") +// @ResponseBody +// public ObjectRestResponse upload(@RequestParam("file") MultipartFile file) throws Exception { +// String imgUrl = dfsClient.uploadFile(file); +// return new ObjectRestResponse<>().data(imgUrl).rel(true); +// } + + /** + * todo:使用 + * 上传接口 + * + * @param file file文件 + * @return 文件访问路径 + * @throws Exception + */ + @PostMapping("/upload") + @ResponseBody + public ObjectRestResponse upload(@RequestParam("file") MultipartFile file) throws Exception { + com.gitee.neuray.security.common.vo.FileInfoVO fileInfoVO = baseBiz.uploadFile(file); + return new ObjectRestResponse<>().data(fileInfoVO).rel(true); + } + +// @PostMapping("/sensitiveUpload") +// @ResponseBody +// public ObjectRestResponse uploadSensitiveFile(@RequestParam("file") MultipartFile file) throws Exception { +// String imgUrl = dfsClient.uploadSensitiveFile(file); +// return new ObjectRestResponse<>().data(imgUrl).rel(true); +// } + + /** + * 上传加密文件接口(base64加密方式) + * + * @param file file文件 + * @return 文件访问路径 + * @throws Exception + */ + @PostMapping("/sensitiveUpload") + @ResponseBody + public ObjectRestResponse uploadChiperSensitiveFile(@RequestParam("file") MultipartFile file) throws Exception { + //使用base64进行加密 + com.gitee.neuray.security.common.vo.FileInfoVO fileInforVO = baseBiz.uploadSensitiveFile(file, FileContants.SENSITIVE_CIPHER_TYPE); + return new ObjectRestResponse<>().data(fileInforVO).rel(true); + } + + /** + * 采用位移加密方式上传文件接口 + * + * @param file + * @return + * @throws Exception + */ + @PostMapping("/sensitiveUpload2") + @ResponseBody + public ObjectRestResponse uploadByteMoveSensitiveFile(@RequestParam("file") MultipartFile file) throws Exception { + //使用base64进行加密 + com.gitee.neuray.security.common.vo.FileInfoVO fileInfoVO = baseBiz.uploadSensitiveFile(file, FileContants.SENSITIVE_BYTEMOVE_TYPE); + return new ObjectRestResponse<>().data(fileInfoVO).rel(true); + } + + /** + * 删除文件接口 + * + * @param fileId 文件id + * @return + * @throws Exception + */ + @RequestMapping(value = "delete", method = RequestMethod.DELETE) + @ResponseBody + public ObjectRestResponse removeFile(@RequestParam String fileId) throws Exception { + baseBiz.deleteFile(fileId); + return new ObjectRestResponse<>().rel(true); + } + + /** + * 文件下载(普通文件下载,没有加密) + * + * @param fileId 文件id + * @param response + * @throws Exception + */ + @GetMapping("/download") + public void download(@RequestParam String fileId, HttpServletResponse response) throws Exception { + Map stringObjectMap = baseBiz.downLoadFile(fileId, FileContants.NO_SENSITIVE_TYPE); + String fileName = (String) stringObjectMap.get("fileName"); + byte[] data = (byte[]) stringObjectMap.get("fileByte"); + response.setCharacterEncoding("UTF-8"); + response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); + ServletOutputStream outputStream = response.getOutputStream(); + IOUtils.write(data, outputStream); + } + + /** + * 下载加密文件(文件流加密) + * todo:使用 + * @param fileId + * @param response + * @throws Exception + */ + @GetMapping("/sensitiveDownload") + public void downloadChiperSensitiveFile(@RequestParam String fileId, HttpServletResponse response) throws Exception { + Map stringObjectMap = baseBiz.downLoadFile(fileId, FileContants.SENSITIVE_CIPHER_TYPE); + String fileName = (String) stringObjectMap.get("fileName"); + byte[] data = (byte[]) stringObjectMap.get("fileByte"); + response.setHeader("Content-Length",data.length+""); + response.setCharacterEncoding("UTF-8"); + response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); + ServletOutputStream outputStream = response.getOutputStream(); + IOUtils.write(data, outputStream); + } + + /** + * 下载加密文件(位移加密下载) + * + * @param fileId + * @param response + * @throws Exception + */ + @GetMapping("/sensitiveDownload2") + public void downloadByteMoveSensitiveFile(@RequestParam String fileId, HttpServletResponse response) throws Exception { + Map stringObjectMap = baseBiz.downLoadFile(fileId, FileContants.SENSITIVE_BYTEMOVE_TYPE); + String fileName = (String) stringObjectMap.get("fileName"); + byte[] data = (byte[]) stringObjectMap.get("fileByte"); + response.setCharacterEncoding("UTF-8"); + response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); + ServletOutputStream outputStream = response.getOutputStream(); + IOUtils.write(data, outputStream); + } + + /** + * 图片展示接口(无加密图片) + * + * @param fileId + * @param response + * @throws IOException + */ + @RequestMapping("/getImage") + public void getFile(@RequestParam String fileId, HttpServletResponse response) throws IOException { + baseBiz.getImg(fileId, response, FileContants.NO_SENSITIVE_TYPE); + } + + /** + * todo:使用 + * 加密图片展示(文件流加密) + * + * @param fileId + * @param response + * @throws IOException + */ + @RequestMapping("/getSensitiveImage") + @IgnoreUserToken + public void getSensitiveImage(@RequestParam String fileId, HttpServletResponse response) throws IOException { + baseBiz.getImg(fileId, response, FileContants.SENSITIVE_CIPHER_TYPE); + } + + /** + * 加密图片展示(位移加密图片) + * + * @param fileId + * @param response + * @throws IOException + */ + @RequestMapping("/getSensitiveImage2") + public void getSensitiveImage2(@RequestParam String fileId, HttpServletResponse response) throws IOException { + baseBiz.getImg(fileId, response, FileContants.SENSITIVE_BYTEMOVE_TYPE); + } + + @PostMapping("/thumbImage") + @ResponseBody + public ObjectRestResponse crtThumbImage(@RequestParam("file") MultipartFile file) throws Exception { + String imgUrl = dfsClient.crtThumbImage(file); + return new ObjectRestResponse<>().data(imgUrl).rel(true); + } + + /** + * 分页获取文件列表,该接口包含path文件服务器路径,page接口不包含文件服务器路径 + * @param params + * @return + */ + @RequestMapping(value = "pageList",method = RequestMethod.GET) + @ResponseBody + public TableResultResponse pageList(@RequestParam Map params) { + //查询列表数据 + Query query = new Query(params); + return baseBiz.page(query); + } + + /** + * todo:使用 + * 文件分块上传接口(0到n-1块文件位数必须为8的倍数,最后一块文件可为任意) + * 下载这种文件时需要采用文件流加密下载接口,文件分块不能做秒传功能,因为不能确定唯一文件性 + * + * @param file 文件 + * @return 最后一块文件时返回文件基本信息实体,供前端使用 + * @throws Exception + */ + @ResponseBody + @RequestMapping(value = "/appendUploadFile",method = RequestMethod.POST) + @HystrixCommand( + fallbackMethod = "uploadAppendFileFallback", + threadPoolProperties = { + @HystrixProperty(name = "coreSize", value = "50"), + @HystrixProperty(name = "maxQueueSize", value = "500"), + @HystrixProperty(name = "queueSizeRejectionThreshold", value = "20")}, + commandProperties = { + @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "30000"), + @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "20") + }, + ignoreExceptions = BaseException.class + ) + public ObjectRestResponse uploadAppendFile(@RequestParam("file") MultipartFile file,HttpServletRequest request + ) throws Exception { + String currentNo = request.getHeader("currentNo"); + String totalSize = request.getHeader("totalSize"); + String key = request.getHeader("key"); + String fileName = request.getHeader("fileName"); + String fileSize = request.getHeader("fileSize"); + String levels = request.getHeader("levels"); + if (StringUtils.isEmpty(currentNo)) { + throw new BaseException("当前段数不能为空..."); + } + if (StringUtils.isEmpty(totalSize)) { + throw new BaseException("总段数不能为空..."); + } + if (StringUtils.isEmpty(key)) { + throw new BaseException("文件唯一性不能为空..."); + } + if (file == null || file.getBytes() == null) { + throw new BaseException("文件不能为空..."); + } + if (StringUtils.isEmpty(fileName)) { + throw new BaseException("文件名不能为空..."); + } + if (StringUtils.isEmpty(fileSize)) { + throw new BaseException("文件大小不能为空..."); + } + if(StringUtils.isEmpty(levels)){ + throw new BaseException("文件密级不能为空..."); + } + currentNo = URLDecoder.decode(currentNo, "UTF-8"); + totalSize = URLDecoder.decode(totalSize, "UTF-8"); + key = URLDecoder.decode(key, "UTF-8"); + fileName = URLDecoder.decode(fileName, "UTF-8"); + fileSize = URLDecoder.decode(fileSize, "UTF-8"); + log.info("接收到文件{}开始...", fileName); + FileInfoEntity fileInfoEntity = null; + JwtInfoVO jwtInfoVO = fileJwtInfo.getJwtInfoVO(request); + fileInfoEntity = this.transferFileInfo(fileName, Double.valueOf(fileSize),levels, jwtInfoVO); + //文件分块上传,加密方式采用文件流加密 + com.gitee.neuray.security.common.vo.FileInfoVO fileInfoVO = baseBiz.uploadAppendSensitiveFile(file, key, currentNo, totalSize, fileInfoEntity, jwtInfoVO); + fileInfoVO.setFileSize(Double.valueOf(fileSize)); + log.info("文件{}上传完成",fileName); + return new ObjectRestResponse().data(fileInfoVO).rel(true); + } + + public ObjectRestResponse uploadAppendFileFallback( MultipartFile file, + HttpServletRequest request, + Throwable throwable + ) throws Exception { + ObjectRestResponse result = new ObjectRestResponse(); + result.setStatus(503); + result.setMessage("服务忙...稍后重试"); + return result; + } + + /** + * 上传默认头像接口 + * @param file + * @return + * @throws Exception + */ + @PostMapping("/defaultAvator") + @ResponseBody + public ObjectRestResponse uploadDefaultAvator(@RequestParam("file") MultipartFile file) throws Exception { + com.gitee.neuray.security.common.vo.FileInfoVO fileInfoVO = baseBiz.uploadDefaultAvator(file); + return new ObjectRestResponse<>().data(fileInfoVO).rel(true); + } + + /** + * 分页获取默认头像接口 + * @param params + * @return + */ + @RequestMapping(value = "defaultAvatorPageList",method = RequestMethod.GET) + @ResponseBody + public TableResultResponse defaultAvatorPageList(@RequestParam Map params) { + //查询列表数据 + Query query = new Query(params); + return baseBiz.defaultAvatorPageList(query); + } + + private FileInfoEntity transferFileInfo(String fileName, Double fileSize,String levels, JwtInfoVO jwtInfoVO) throws Exception { + FileInfoEntity fileInfoEntity = new FileInfoEntity(); + fileInfoEntity.setId(UUIDUtils.generateShortUuid()); + if (jwtInfoVO != null) { + BeanUtils.copyProperties(jwtInfoVO, fileInfoEntity); + } + String suffix = ""; + String fileExt = ""; + String regixValue = FileContants.FILE_REGIX_VALUE; + if (fileName.indexOf(regixValue) != -1) { + suffix = fileName.substring(fileName.lastIndexOf(regixValue)); + fileName = fileName.substring(0, fileName.lastIndexOf(regixValue)); + } + if (!"".equals(suffix) && !regixValue.equals(suffix)) { + fileExt = suffix.substring(suffix.indexOf(regixValue) + 1); + } + fileInfoEntity.setFileExt(fileExt); + fileInfoEntity.setFileName(fileName); + String fileType = ""; + FileTypeEnum fileTypeEnum = FileTypeEnum.getEnumByValue(fileExt); + fileType = fileTypeEnum.getType(); + fileInfoEntity.setFileType(fileType.toLowerCase()); + fileInfoEntity.setFileSize(fileSize); + fileInfoEntity.setStatus(FileContants.EFECTIVE_FILE); + fileInfoEntity.setLevels(levels); + return fileInfoEntity; + } +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/controller/FastDfsNotTokenController.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/controller/FastDfsNotTokenController.java new file mode 100644 index 0000000000000000000000000000000000000000..38c1c971fe75926f61160511e9b1edcdfe145a03 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/controller/FastDfsNotTokenController.java @@ -0,0 +1,315 @@ +package com.gitee.neuray.security.file.controller; + + +import com.gitee.neuray.security.common.exception.BaseException; +import com.gitee.neuray.security.common.msg.ObjectRestResponse; +import com.gitee.neuray.security.common.msg.TableResultResponse; +import com.gitee.neuray.security.common.rest.BaseController; +import com.gitee.neuray.security.common.util.Query; +import com.gitee.neuray.security.common.util.UUIDUtils; +import com.gitee.neuray.security.file.biz.FileInfoBiz; +import com.gitee.neuray.security.file.contants.FileContants; +import com.gitee.neuray.security.file.entity.FileInfoEntity; +import com.gitee.neuray.security.file.jwt.FileJwtInfo; +import com.gitee.neuray.security.file.util.FastDFSClientWrapper; +import com.gitee.neuray.security.file.util.FileTypeEnum; +import com.gitee.neuray.security.file.vo.FileInfoVO; +import com.gitee.neuray.security.file.vo.JwtInfoVO; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.HashMap; +import java.util.Map; + +/** + * file文件接口(没有权限校验接口) + * + * @author zhhongyu + * @since 2019-06-18 + */ +@Slf4j +@Controller +@RequestMapping("/file") +public class FastDfsNotTokenController extends BaseController { + @Autowired + private FastDFSClientWrapper dfsClient; + @Autowired + private FileJwtInfo fileJwtInfo; + + + /** + * 上传接口 + * + * @param file file文件 + * @return 文件访问路径 + * @throws Exception + */ + @PostMapping("/upload") + public String upload(@RequestParam("file") MultipartFile file,Model model) throws Exception { + com.gitee.neuray.security.common.vo.FileInfoVO fileInfoVO = baseBiz.uploadFile(file); + return this.pageList(new HashMap<>(),model); + } + /** + * 上传默认头像接口 + * @param file + * @return + * @throws Exception + */ + @PostMapping("/defaultAvator") + public String uploadDefaultAvator(@RequestParam("file") MultipartFile file,Model model) throws Exception { + com.gitee.neuray.security.common.vo.FileInfoVO fileInfoVO = baseBiz.uploadDefaultAvator(file); + return this.pageList(new HashMap<>(),model); + } + + /** + * 上传加密文件接口(base64加密方式) + * + * @param file file文件 + * @return 文件访问路径 + * @throws Exception + */ + @PostMapping("/sensitiveUpload") + @ResponseBody + public ObjectRestResponse uploadChiperSensitiveFile(@RequestParam("file") MultipartFile file) throws Exception { + //使用base64进行加密 + com.gitee.neuray.security.common.vo.FileInfoVO fileInforVO = baseBiz.uploadSensitiveFile(file, FileContants.SENSITIVE_CIPHER_TYPE); + return new ObjectRestResponse<>().data(fileInforVO).rel(true); + } + + /** + * 采用位移加密方式上传文件接口 + * + * @param file + * @return + * @throws Exception + */ + @PostMapping("/sensitiveUpload2") + @ResponseBody + public ObjectRestResponse uploadByteMoveSensitiveFile(@RequestParam("file") MultipartFile file) throws Exception { + //使用base64进行加密 + com.gitee.neuray.security.common.vo.FileInfoVO fileInfoVO = baseBiz.uploadSensitiveFile(file, FileContants.SENSITIVE_BYTEMOVE_TYPE); + return new ObjectRestResponse<>().data(fileInfoVO).rel(true); + } + + /** + * 删除文件接口 + * + * @param fileId 文件id + * @return + * @throws Exception + */ + @RequestMapping(value = "delete", method = RequestMethod.DELETE) + @ResponseBody + public ObjectRestResponse removeFile(@RequestParam String fileId) throws Exception { + baseBiz.deleteFile(fileId); + return new ObjectRestResponse<>().rel(true); + } + + /** + * 文件下载(普通文件下载,没有加密) + * + * @param fileId 文件id + * @param response + * @throws Exception + */ + @GetMapping("/download") + public void download(@RequestParam String fileId, HttpServletResponse response) throws Exception { + Map stringObjectMap = baseBiz.downLoadFile(fileId, FileContants.NO_SENSITIVE_TYPE); + String fileName = (String) stringObjectMap.get("fileName"); + byte[] data = (byte[]) stringObjectMap.get("fileByte"); + response.setCharacterEncoding("UTF-8"); + response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); + ServletOutputStream outputStream = response.getOutputStream(); + IOUtils.write(data, outputStream); + } + + /** + * 下载加密文件(文件流加密) + * + * @param fileId + * @param response + * @throws Exception + */ + @GetMapping("/sensitiveDownload") + public void downloadChiperSensitiveFile(@RequestParam String fileId, HttpServletResponse response) throws Exception { + Map stringObjectMap = baseBiz.downLoadFile(fileId, FileContants.SENSITIVE_CIPHER_TYPE); + String fileName = (String) stringObjectMap.get("fileName"); + byte[] data = (byte[]) stringObjectMap.get("fileByte"); + response.setCharacterEncoding("UTF-8"); + response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); + ServletOutputStream outputStream = response.getOutputStream(); + IOUtils.write(data, outputStream); + } + + /** + * 下载加密文件(位移加密下载) + * + * @param fileId + * @param response + * @throws Exception + */ + @GetMapping("/sensitiveDownload2") + public void downloadByteMoveSensitiveFile(@RequestParam String fileId, HttpServletResponse response) throws Exception { + Map stringObjectMap = baseBiz.downLoadFile(fileId, FileContants.SENSITIVE_BYTEMOVE_TYPE); + String fileName = (String) stringObjectMap.get("fileName"); + byte[] data = (byte[]) stringObjectMap.get("fileByte"); + response.setCharacterEncoding("UTF-8"); + response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); + ServletOutputStream outputStream = response.getOutputStream(); + IOUtils.write(data, outputStream); + } + + /** + * 图片展示接口(无加密图片) + * + * @param fileId + * @param response + * @throws IOException + */ + @RequestMapping("/getImage") + public void getFile(@RequestParam String fileId, HttpServletResponse response) throws IOException { + baseBiz.getImg(fileId, response, FileContants.NO_SENSITIVE_TYPE); + } + + /** + * 加密图片展示(文件流加密) + * + * @param fileId + * @param response + * @throws IOException + */ + @RequestMapping("/getSensitiveImage") + public void getSensitiveImage(@RequestParam String fileId, HttpServletResponse response) throws IOException { + baseBiz.getImg(fileId, response, FileContants.SENSITIVE_CIPHER_TYPE); + } + + /** + * 加密图片展示(位移加密图片) + * + * @param fileId + * @param response + * @throws IOException + */ + @RequestMapping("/getSensitiveImage2") + public void getSensitiveImage2(@RequestParam String fileId, HttpServletResponse response) throws IOException { + baseBiz.getImg(fileId, response, FileContants.SENSITIVE_BYTEMOVE_TYPE); + } + + @PostMapping("/thumbImage") + @ResponseBody + public ObjectRestResponse crtThumbImage(@RequestParam("file") MultipartFile file) throws Exception { + String imgUrl = dfsClient.crtThumbImage(file); + return new ObjectRestResponse<>().data(imgUrl).rel(true); + } + + /** + * 文件分块上传接口(0到n-1块文件位数必须为8的倍数,最后一块文件可为任意) + * 下载这种文件时需要采用文件流加密下载接口,文件分块不能做秒传功能,因为不能确定唯一文件性 + * + * @param file 文件 + * @return 最后一块文件时返回文件基本信息实体,供前端使用 + * @throws Exception + */ + @ResponseBody + @RequestMapping(value = "/appendUploadFile",method = RequestMethod.POST) + public ObjectRestResponse uploadAppendFile(@RequestParam("file") MultipartFile file,HttpServletRequest request + ) throws Exception { + String path = request.getHeader("path"); + String currentNo = request.getHeader("currentNo"); + String totalSize = request.getHeader("totalSize"); + String key = request.getHeader("key"); + String fileName = request.getHeader("fileName"); + String fileSize = request.getHeader("fileSize"); + if (StringUtils.isEmpty(currentNo)) { + throw new BaseException("当前段数不能为空..."); + } + if (StringUtils.isEmpty(totalSize)) { + throw new BaseException("总段数不能为空..."); + } + if (StringUtils.isEmpty(key)) { + throw new BaseException("文件唯一性不能为空..."); + } + if (file == null || file.getBytes() == null) { + throw new BaseException("文件不能为空..."); + } + if (StringUtils.isEmpty(fileName)) { + throw new BaseException("文件名不能为空..."); + } + if (StringUtils.isEmpty(fileSize)) { + throw new BaseException("文件大小不能为空..."); + } + currentNo = URLDecoder.decode(currentNo, "UTF-8"); + totalSize = URLDecoder.decode(totalSize, "UTF-8"); + key = URLDecoder.decode(key, "UTF-8"); + fileName = URLDecoder.decode(fileName, "UTF-8"); + fileSize = URLDecoder.decode(fileSize, "UTF-8"); + log.info("接收到文件{}开始...", fileName); + FileInfoEntity fileInfoEntity = null; + JwtInfoVO jwtInfoVO = fileJwtInfo.getJwtInfoVO(request); + fileInfoEntity = this.transferFileInfo(fileName, Double.valueOf(fileSize), jwtInfoVO); + //文件分块上传,加密方式采用文件流加密 + com.gitee.neuray.security.common.vo.FileInfoVO fileInfoVO = baseBiz.uploadAppendSensitiveFile(file, key, currentNo, totalSize, fileInfoEntity, jwtInfoVO); + fileInfoVO.setFileSize(Double.valueOf(fileSize)); + log.info("文件{}上传完成",fileName); + return new ObjectRestResponse().data(fileInfoVO).rel(true); + } + + public ObjectRestResponse uploadAppendFileFallback( MultipartFile file, + HttpServletRequest request, + Throwable throwable + ) throws Exception { + ObjectRestResponse result = new ObjectRestResponse(); + result.setStatus(503); + result.setMessage("服务忙...稍后重试"); + return result; + } + @GetMapping("pageList") + public String pageList(@RequestParam Map params, Model model) { + //查询列表数据 + Query query = new Query(params); + TableResultResponse page = baseBiz.page(query); + model.addAttribute("page",page); + return "fileTable"; + } + + private FileInfoEntity transferFileInfo(String fileName, Double fileSize, JwtInfoVO jwtInfoVO) throws Exception { + FileInfoEntity fileInfoEntity = new FileInfoEntity(); + fileInfoEntity.setId(UUIDUtils.generateShortUuid()); + if (jwtInfoVO != null) { + BeanUtils.copyProperties(jwtInfoVO, fileInfoEntity); + } + String suffix = ""; + String fileExt = ""; + String regixValue = FileContants.FILE_REGIX_VALUE; + if (fileName.indexOf(regixValue) != -1) { + suffix = fileName.substring(fileName.lastIndexOf(regixValue)); + fileName = fileName.substring(0, fileName.lastIndexOf(regixValue)); + } + if (!"".equals(suffix) && !regixValue.equals(suffix)) { + fileExt = suffix.substring(suffix.indexOf(regixValue) + 1); + } + fileInfoEntity.setFileExt(fileExt); + fileInfoEntity.setFileName(fileName); + String fileType = ""; + FileTypeEnum fileTypeEnum = FileTypeEnum.getEnumByValue(fileExt); + fileType = fileTypeEnum.getType(); + fileInfoEntity.setFileType(fileType.toLowerCase()); + fileInfoEntity.setFileSize(fileSize); + fileInfoEntity.setStatus(FileContants.EFECTIVE_FILE); + + return fileInfoEntity; + } +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/controller/FileManageController.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/controller/FileManageController.java new file mode 100644 index 0000000000000000000000000000000000000000..b3e12c852fe3123d458e6b9cdf89f6d1713a7adc --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/controller/FileManageController.java @@ -0,0 +1,481 @@ +package com.gitee.neuray.security.file.controller; + +import com.gitee.neuray.security.common.msg.ObjectRestResponse; +import com.gitee.neuray.security.common.msg.TableResultResponse; +import com.gitee.neuray.security.common.util.UUIDUtils; +import com.gitee.neuray.security.file.entity.FileManageInf; +import com.gitee.neuray.security.file.service.FileMangeService; +import com.gitee.neuray.security.file.util.CommonUtil; +import com.gitee.neuray.security.file.util.EncryptionAndDeciphering; +import com.gitee.neuray.security.file.util.FastDFSClientWrapper; +import com.gitee.neuray.security.file.util.FileTypeEnum; +import com.gitee.neuray.security.file.vo.FileMonitoringVO; +import org.apache.commons.io.IOUtils; +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.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * file文件统一接口 + * @author zhuqz + * @since 2019-07-17 + */ +@RestController +@RequestMapping("fileManage") +public class FileManageController { + private static Logger log = LoggerFactory.getLogger(FileManageController.class); + @Autowired + private FastDFSClientWrapper dfsClient; + @Autowired + private HttpServletRequest request; + @Autowired + private FileMangeService fileMangeService; + + //上传 + @PostMapping("/upload") + @ResponseBody + public ObjectRestResponse upload(@RequestParam("file") MultipartFile file) throws Exception { + String imgUrl = dfsClient.uploadFile(file); + String userId = (request.getHeader("userId")==null)?"":request.getHeader("userId"); + String userName = URLDecoder.decode((request.getHeader("userName")==null)?"":request.getHeader("userName"),"UTF-8"); + String fileId = UUIDUtils.generateShortUuid(); + + FileManageInf fileManageInf = new FileManageInf(); + fileManageInf.setFileId(fileId); + fileManageInf.setCreator(userId); + fileManageInf.setCreatorName(userName); + fileManageInf.setFileEncrypeFlg("0"); + fileManageInf.setPath(imgUrl); + + String fileName = file.getOriginalFilename(); + String suffix = ""; + String file_ext = ""; + if (fileName.indexOf(".") != -1) { + suffix = fileName.substring(fileName.lastIndexOf(".")); + fileName = fileName.substring(0,fileName.lastIndexOf(".")); + } + if(!"".equals(suffix) && !".".equals(suffix)){ + file_ext=suffix.substring(suffix.indexOf(".")+1); + } + fileManageInf.setFileExt(file_ext); + fileManageInf.setFileName(fileName); + + String file_type = ""; + FileTypeEnum fileTypeEnum = FileTypeEnum.getEnumByValue(file_ext); + file_type = fileTypeEnum.getType(); + fileManageInf.setFileType(file_type.toLowerCase()); + fileManageInf.setSizes(Double.valueOf(file.getSize())); + fileManageInf.setSendFlg("0"); + try{ + this.fileMangeService.insert(fileManageInf); + }catch (Exception e){ + dfsClient.deleteFile(imgUrl); + log.error(CommonUtil.getExceptionMessage(e)); + throw e; + } + return new ObjectRestResponse<>().data(fileManageInf).rel(true); + } + /** + * 上传加密文件接口 + * @param file file文件 + * @return 文件访问路径 + * @throws Exception + */ + @PostMapping("/sensitiveUpload") + @ResponseBody + public ObjectRestResponse uploadSensitiveFile(@RequestParam("file") MultipartFile file) throws Exception { + String imgUrl = dfsClient.uploadbase64SensitiveFile(file); + String userId = (request.getHeader("userId")==null)?"":request.getHeader("userId"); + String userName = URLDecoder.decode((request.getHeader("userName")==null)?"":request.getHeader("userName"),"UTF-8"); + String fileId = UUIDUtils.generateShortUuid(); + + FileManageInf fileManageInf = new FileManageInf(); + fileManageInf.setFileId(fileId); + fileManageInf.setCreator(userId); + fileManageInf.setCreatorName(userName); + fileManageInf.setCreateTime(new Date()); + fileManageInf.setFileEncrypeFlg("1");//base64加密 + fileManageInf.setPath(imgUrl); + + String fileName = file.getOriginalFilename(); + String suffix = ""; + String file_ext = ""; + if (fileName.indexOf(".") != -1) { + suffix = fileName.substring(fileName.lastIndexOf(".")); + fileName = fileName.substring(0,fileName.lastIndexOf(".")); + } + if(!"".equals(suffix) && !".".equals(suffix)){ + file_ext=suffix.substring(suffix.indexOf(".")+1); + } + fileManageInf.setFileExt(file_ext); + fileManageInf.setFileName(fileName); + + String file_type = ""; + FileTypeEnum fileTypeEnum = FileTypeEnum.getEnumByValue(file_ext); + file_type = fileTypeEnum.getType(); + fileManageInf.setFileType(file_type.toLowerCase()); + fileManageInf.setSizes(Double.valueOf(file.getSize())); + fileManageInf.setSendFlg("0"); + try{ + this.fileMangeService.insert(fileManageInf); + }catch (Exception e){ + dfsClient.deleteFile(imgUrl); + log.error(CommonUtil.getExceptionMessage(e)); + throw e; + } + return new ObjectRestResponse<>().data(fileManageInf).rel(true); + } + /** + * 上传加密文件接口第二种方式(每个字节进行位移+5) + * @param file file文件 + * @return 文件访问路径 + * @throws Exception + */ + @PostMapping("/sensitiveUpload2") + @ResponseBody + public ObjectRestResponse uploadSensitiveFile2(@RequestParam("file") MultipartFile file) throws Exception { + + String fileName = file.getOriginalFilename(); + String suffix = ""; + String file_ext = ""; + if (fileName.indexOf(".") != -1) { + suffix = fileName.substring(fileName.lastIndexOf(".")); + fileName = fileName.substring(0,fileName.lastIndexOf(".")); + } + if(!"".equals(suffix) && !".".equals(suffix)){ + file_ext=suffix.substring(suffix.indexOf(".")+1); + } + + byte[] bytes = EncryptionAndDeciphering.encryptFile(file); + String imgUrl = dfsClient.uploadFile(bytes,file_ext); + String userId = (request.getHeader("userId")==null)?"":request.getHeader("userId"); + String userName = URLDecoder.decode((request.getHeader("userName")==null)?"":request.getHeader("userName"),"UTF-8"); + String fileId = UUIDUtils.generateShortUuid(); + + FileManageInf fileManageInf = new FileManageInf(); + fileManageInf.setFileId(fileId); + fileManageInf.setCreator(userId); + fileManageInf.setCreatorName(userName); + fileManageInf.setCreateTime(new Date()); + fileManageInf.setFileEncrypeFlg("2");//位移加密 + fileManageInf.setPath(imgUrl); + + + fileManageInf.setFileExt(file_ext); + fileManageInf.setFileName(fileName); + + String file_type = ""; + FileTypeEnum fileTypeEnum = FileTypeEnum.getEnumByValue(file_ext); + file_type = fileTypeEnum.getType(); + fileManageInf.setFileType(file_type.toLowerCase()); + fileManageInf.setSizes(Double.valueOf(file.getSize())); + fileManageInf.setSendFlg("0"); + try{ + this.fileMangeService.insert(fileManageInf); + }catch (Exception e){ + dfsClient.deleteFile(imgUrl); + log.error(CommonUtil.getExceptionMessage(e)); + throw e; + } + return new ObjectRestResponse<>().data(fileManageInf).rel(true); + } + /** + * 删除文件接口 + */ + @RequestMapping(value = "delete",method = RequestMethod.DELETE) + @ResponseBody + //@Transactional(rollbackFor = Exception.class) + public ObjectRestResponse remove(@RequestParam String fileId) throws Exception { + FileManageInf fileManageInf = this.fileMangeService.queryById(fileId); + try { + dfsClient.deleteFile(fileManageInf.getPath()); + }catch (Exception e){ + log.error(CommonUtil.getExceptionMessage(e)); + return new ObjectRestResponse<>().rel(false); + } + this.fileMangeService.deleteById(fileId); + return new ObjectRestResponse<>().rel(true); + } + + /** + * 文件下载 + */ + @GetMapping("/download") + public void download(@RequestParam String fileId, HttpServletResponse response) throws Exception{ + FileManageInf fileManageInf = this.fileMangeService.queryById(fileId); + String fileName = fileManageInf.getFileName();//下载名称 + String fileExt = fileManageInf.getFileExt();//后缀 + if(!"".equals(fileExt)){ + fileName=fileName+"."+fileExt; + } + byte[] data = dfsClient.download(fileManageInf.getPath()); + response.setCharacterEncoding("UTF-8"); + response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); + ServletOutputStream outputStream = response.getOutputStream(); + IOUtils.write(data, outputStream); + } + + /** + * 下载加密文件 + * @param response + * @throws Exception + */ + @GetMapping("/sensitiveDownload") + public void downloadSensitiveFile(@RequestParam String fileId, HttpServletResponse response) throws Exception{ + FileManageInf fileManageInf = this.fileMangeService.queryById(fileId); + String fileName = fileManageInf.getFileName();//下载名称 + String fileExt = fileManageInf.getFileExt();//后缀 + if(!"".equals(fileExt)){ + fileName=fileName+"."+fileExt; + } + byte[] data = dfsClient.downloadBase64SensitiveFile(fileManageInf.getPath()); + response.setCharacterEncoding("UTF-8"); + response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); + ServletOutputStream outputStream = response.getOutputStream(); + IOUtils.write(data, outputStream); + } + /** + * 下载加密文件(位移减去5) + * @param response + * @throws Exception + */ + @GetMapping("/sensitiveDownload2") + public void downloadSensitiveFile2(@RequestParam String fileId, HttpServletResponse response) throws Exception{ + FileManageInf fileManageInf = this.fileMangeService.queryById(fileId); + String fileName = fileManageInf.getFileName();//下载名称 + String fileExt = fileManageInf.getFileExt();//后缀 + if(!"".equals(fileExt)){ + fileName=fileName+"."+fileExt; + } + byte[] data = dfsClient.download(fileManageInf.getPath()); + data= EncryptionAndDeciphering.decipherFile(data); + response.setCharacterEncoding("UTF-8"); + response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); + ServletOutputStream outputStream = response.getOutputStream(); + IOUtils.write(data, outputStream); + } + //设置文件文已发送状态 + //附件id,附件密级,附件所属工作类型0研讨1工具 + @PostMapping("/fileUpdate") + @ResponseBody + public ObjectRestResponse fileUpdate(@RequestParam String fileId,@RequestParam String level,@RequestParam String type) throws Exception { + int i = this.fileMangeService.fileUpdate(fileId,level,type); + return new ObjectRestResponse<>().rel(true); + } + //图片展示 + @RequestMapping("/getImage") + public void getFile(HttpServletRequest request , HttpServletResponse response) throws IOException { + OutputStream outputStream = null; + try { + //读取路径下面的文件 + String fileId = request.getParameter("fileId"); + FileManageInf fileManageInf = this.fileMangeService.queryById(fileId); + //读取路径下面的文件 + if(fileManageInf == null) return; + byte[] data = dfsClient.download(fileManageInf.getPath()); + //获取文件后缀名格式 + String ext = ((fileManageInf.getFileExt()==null)?"":fileManageInf.getFileExt()); + //判断图片格式,设置相应的输出文件格式 + if(ext.equals("jpg")){ + response.setContentType("image/jpeg"); + }else if(ext.equals("JPG")){ + response.setContentType("image/jpeg"); + }else if(ext.equals("png")){ + response.setContentType("image/png"); + }else if(ext.equals("PNG")){ + response.setContentType("image/png"); + } + outputStream = new BufferedOutputStream(response.getOutputStream()); + outputStream.write(data); + outputStream.flush(); + }catch (Exception e){ + log.error(CommonUtil.getExceptionMessage(e)); + }finally { + //关流 + if(outputStream!=null){ + outputStream.close(); + } + } + + } + //加密图片展示 + @RequestMapping("/getSensitiveImage") + public void getSensitiveImage(HttpServletRequest request , HttpServletResponse response) throws IOException { + OutputStream outputStream = null; + try { + //读取路径下面的文件 + String fileId = request.getParameter("fileId"); + FileManageInf fileManageInf = this.fileMangeService.queryById(fileId); + //读取路径下面的文件 + if(fileManageInf == null) return; + byte[] data = dfsClient.downloadBase64SensitiveFile(fileManageInf.getPath()); + //获取文件后缀名格式 + String ext = ((fileManageInf.getFileExt()==null)?"":fileManageInf.getFileExt()); + //判断图片格式,设置相应的输出文件格式 + if(ext.equals("jpg")){ + response.setContentType("image/jpeg"); + }else if(ext.equals("JPG")){ + response.setContentType("image/jpeg"); + }else if(ext.equals("png")){ + response.setContentType("image/png"); + }else if(ext.equals("PNG")){ + response.setContentType("image/png"); + } + outputStream = new BufferedOutputStream(response.getOutputStream()); + outputStream.write(data); + outputStream.flush(); + }catch (Exception e){ + log.error(CommonUtil.getExceptionMessage(e)); + }finally { + //关流 + if(outputStream!=null){ + outputStream.close(); + } + } + + } + //加密图片展示(位移加密图片) + @RequestMapping("/getSensitiveImage2") + public void getSensitiveImage2(HttpServletRequest request , HttpServletResponse response) throws IOException { + OutputStream outputStream = null; + try { + //读取路径下面的文件 + String fileId = request.getParameter("fileId"); + FileManageInf fileManageInf = this.fileMangeService.queryById(fileId); + //读取路径下面的文件 + if(fileManageInf == null) return; + byte[] data = dfsClient.download(fileManageInf.getPath()); + data = EncryptionAndDeciphering.decipherFile(data); + //获取文件后缀名格式 + String ext = ((fileManageInf.getFileExt()==null)?"":fileManageInf.getFileExt()); + //判断图片格式,设置相应的输出文件格式 + if(ext.equals("jpg")){ + response.setContentType("image/jpeg"); + }else if(ext.equals("JPG")){ + response.setContentType("image/jpeg"); + }else if(ext.equals("png")){ + response.setContentType("image/png"); + }else if(ext.equals("PNG")){ + response.setContentType("image/png"); + } + outputStream = new BufferedOutputStream(response.getOutputStream()); + outputStream.write(data); + outputStream.flush(); + }catch (Exception e){ + log.error(CommonUtil.getExceptionMessage(e)); + }finally { + //关流 + if(outputStream!=null){ + outputStream.close(); + } + } + + } + @GetMapping("/getFileSizeByDB") + //查询附件大小(数据库统计) + //queryType 查询类型 0 天(默认),1 月,2 年 + //returnUnit 单位 0 M(默认),1 G,2 T + //queryDate 查询日期 天 2019-01-01 ,月 2019-01,年 2019 + public String getFileSizeByDB(@RequestParam("queryType") String queryType,@RequestParam("queryDate") String queryDate,@RequestParam("unit") String returnUnit) { + String res = "";//-1接口报错 + try { + res = fileMangeService.getFileSizeByDB((queryType==null||queryType.equals(""))?"0":queryType,queryDate,(returnUnit==null||returnUnit.equals(""))?"0":returnUnit); + }catch (Exception e){ + e.printStackTrace(); + res = "-1"; + } + + return res; + } + /*public String getFileSizeByDB(@RequestParam("queryType") String queryType,@RequestParam("queryDate") String queryDate) { + String res = "";//-1接口报错 + try { + res = fileMangeService.getFileSizeByDB((queryType==null||queryType.equals(""))?"0":queryType,queryDate,"0"); + }catch (Exception e){ + e.printStackTrace(); + res = "-1"; + } + + return res; + } + public String getFileSizeByDB(@RequestParam("queryDate") String queryDate) { + String res = "";//-1接口报错 + try { + res = fileMangeService.getFileSizeByDB("0",queryDate,"0"); + }catch (Exception e){ + e.printStackTrace(); + res = "-1"; + } + + return res; + }*/ + @GetMapping("/getFileSizeRangeByDB") + //查询区间附件大小(数据库统计) + //queryType 查询类型 0 天(默认),1 月,2 年 + //returnUnit 单位 0 M(默认),1 G,2 T + //queryDateBegin 查询日期开始 天 2019-01-01 ,月 2019-01,年 2019 + //queryDateEnd 查询日期结束 天 2019-01-02 ,月 2019-02,年 2020 + public List> getFileSizeRangeByDB(@RequestParam("queryType") String queryType, @RequestParam("queryDateBegin") String queryDateBegin, @RequestParam("queryDateEnd") String queryDateEnd, @RequestParam("unit") String returnUnit) { + List> res=null; + try { + res = fileMangeService.getFileSizeRangeByDB((queryType==null||queryType.equals(""))?"0":queryType,queryDateBegin,queryDateEnd,(returnUnit==null||returnUnit.equals(""))?"0":returnUnit); + }catch (Exception e){ + e.printStackTrace(); + } + + return res; + } + /* public List> getFileSizeRangeByDB(@RequestParam("queryType") String queryType, @RequestParam("queryDateBegin") String queryDateBegin, @RequestParam("queryDateEnd") String queryDateEnd) { + List> res=null; + try { + res = fileMangeService.getFileSizeRangeByDB((queryType==null||queryType.equals(""))?"0":queryType,queryDateBegin,queryDateEnd,"0"); + }catch (Exception e){ + e.printStackTrace(); + } + + return res; + } + + public List> getFileSizeRangeByDB(@RequestParam("queryDateBegin") String queryDateBegin, @RequestParam("queryDateEnd") String queryDateEnd) { + List> res=null; + try { + res = fileMangeService.getFileSizeRangeByDB("0",queryDateBegin,queryDateEnd,"0"); + }catch (Exception e){ + e.printStackTrace(); + } + + return res; + } +*/ + + /** + * 上传文件监控 + *参数说明:page 页码 size 每页几条 userName上传用户名称 dateBegin、dateEnd上传时间开始结束 isGroup 是否群主1是0否 + * fileName文件名称 level密级 + * @return + */ + @PostMapping("/fileMonitoring") + public TableResultResponse fileMonitoring(@RequestParam Map params){ + TableResultResponse pageInfo = null; + try { + pageInfo = this.fileMangeService.fileMonitoring(params); + } catch (Exception e) { + log.error(CommonUtil.getExceptionMessage(e)); + } + return pageInfo; + } +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/dao/FileManageDao.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/dao/FileManageDao.java new file mode 100644 index 0000000000000000000000000000000000000000..d72db077c25f9319fbc266d6e258ef04f62020a8 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/dao/FileManageDao.java @@ -0,0 +1,23 @@ +package com.gitee.neuray.security.file.dao; + +import com.gitee.neuray.security.file.entity.FileManageInf; +import com.gitee.neuray.security.file.vo.FileMonitoringVO; +import org.apache.ibatis.annotations.Param; +import tk.mybatis.mapper.common.Mapper; + +import java.util.List; +import java.util.Map; + +public interface FileManageDao extends Mapper { + FileManageInf queryById(@Param("fileId") String fileId); + int insert(FileManageInf fileManageInf); + int update(FileManageInf fileManageInf); + int deleteById(String fileId); + int fileUpdate(@Param("fileId") String fileId, @Param("level") String level, @Param("type") String type); + //查询附件大小 + double queryFileSize(@Param("dateFmat") String dateFmat, @Param("date") String date, @Param("unit") long unit); + //查询附件大小(日期范围) + List queryFileSizeRange(@Param("dateFmat") String dateFmat, @Param("dateBegin") String dateBegin, @Param("dateEnd") String dateEnd, @Param("unit") long unit); + List fileMonitoring(@Param("params") Map param); +} + diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/dao/JobDao.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/dao/JobDao.java new file mode 100644 index 0000000000000000000000000000000000000000..3a3d56ec8e8d70d3e20842a9e80ef90e81bc4ebb --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/dao/JobDao.java @@ -0,0 +1,22 @@ +package com.gitee.neuray.security.file.dao; + +import java.util.List; + +/** + * 定时任务 + * + * @author zhuqz + * @since 2019-06-12 + */ +public interface JobDao { + /** + * 定时任务-处理无用附件 + * + */ + List getUnUsedFileList(); + /** + * 定时任务-删除无用附件 + * + */ + int delUnUsedFileList(); +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/entity/FileInfoEntity.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/entity/FileInfoEntity.java new file mode 100644 index 0000000000000000000000000000000000000000..0e6394cdc37c03e51658029ec5aad3787b42b622 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/entity/FileInfoEntity.java @@ -0,0 +1,71 @@ +package com.gitee.neuray.security.file.entity; + +import com.gitee.neuray.security.common.entity.BaseEntity; +import lombok.Data; + +import javax.persistence.Column; +import javax.persistence.Table; + +/** + * 文件基础数据实体类 + * @author zhhongyu + */ +@Data +@Table(name = "FILE_INFO") +public class FileInfoEntity extends BaseEntity { + /** + * 附件名称 + */ + @Column(name = "FILE_NAME") + private String fileName; + /** + * 文件后缀名 + */ + @Column(name = "FILE_EXT") + private String fileExt; + /** + * 附件类型(text、img、doc) + */ + @Column(name = "FILE_TYPE") + private String fileType; + /** + * 文件密级 + */ + @Column(name = "LEVELS") + private String levels; + +// /** +// * 加密标记(0为未加密文件,1为使用base64加密文件,2为使用位移加密文件) +// */ +// @Column(name = "FILE_ENCRYPE") +// private String fileEncrype; + /** + * 文件大小 + */ + @Column(name = "FILE_SIZE") + private Double fileSize; +// /** +// * 附件路径 +// */ +// @Column(name = "PATH") +// private String path; + /** + * 附件转码为可读取的路径 + */ + @Column(name = "READ_PATH") + private String readPath; + /** + * 数据有效状态(1为有效,0为无效) + */ + @Column(name = "STATUS") + private String status; + + + /**以下为新增字段,以上被注释掉的字段为需要在表中将其删除*/ + /** + * 文件路径id + */ + @Column(name = "FILE_PATH_ID") + private String filePathId; + +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/entity/FileManageInf.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/entity/FileManageInf.java new file mode 100644 index 0000000000000000000000000000000000000000..28cc0962d3c8363ff59ac0a1e923b9f0d2004f19 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/entity/FileManageInf.java @@ -0,0 +1,170 @@ +package com.gitee.neuray.security.file.entity; + +import java.io.Serializable; +import java.util.Date; + +public class FileManageInf implements Serializable { + + private static final long serialVersionUID = 6076301102453313990L; + //附件id + private String fileId; + //附件名称 + private String fileName; + //文件后缀名 + private String fileExt; + //附件类型(text、img、doc) + private String fileType; + //文件大小 + private Double sizes; + //附件路径 + private String path; + //附件转码为可读取的路径 + private String readPath; + //创建时间 + private Date createTime; + //创建人 + private String creator; + //更新时间 + private Date updateTime; + //更新人 + private String updator; + //保密等级 + private String levels; + //创建人姓名 + private String creatorName; + + //是否已经发送 + private String sendFlg; + //加密标记 + private String fileEncrypeFlg; + + //类型0研讨服务1工具 + private String workType; + + public String getSendFlg() { + return sendFlg; + } + + public void setSendFlg(String sendFlg) { + this.sendFlg = sendFlg; + } + + public String getFileEncrypeFlg() { + return fileEncrypeFlg; + } + + public void setFileEncrypeFlg(String fileEncrypeFlg) { + this.fileEncrypeFlg = fileEncrypeFlg; + } + + public String getFileId() { + return fileId; + } + + public void setFileId(String fileId) { + this.fileId = fileId; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public String getFileExt() { + return fileExt; + } + + public void setFileExt(String fileExt) { + this.fileExt = fileExt; + } + + public String getFileType() { + return fileType; + } + + public void setFileType(String fileType) { + this.fileType = fileType; + } + + public Double getSizes() { + return sizes; + } + + public void setSizes(Double sizes) { + this.sizes = sizes; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getReadPath() { + return readPath; + } + + public void setReadPath(String readPath) { + this.readPath = readPath; + } + + public Date getCreateTime() { + return createTime; + } + + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + + public String getCreator() { + return creator; + } + + public void setCreator(String creator) { + this.creator = creator; + } + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } + + public String getUpdator() { + return updator; + } + + public void setUpdator(String updator) { + this.updator = updator; + } + + public String getLevels() { + return levels; + } + + public void setLevels(String levels) { + this.levels = levels; + } + public String getCreatorName() { + return creatorName; + } + + public void setCreatorName(String creatorName) { + this.creatorName = creatorName; + } + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/entity/FileServerPathEntity.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/entity/FileServerPathEntity.java new file mode 100644 index 0000000000000000000000000000000000000000..937e5430b878f2e22217eaab4078821bff72b40a --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/entity/FileServerPathEntity.java @@ -0,0 +1,33 @@ +package com.gitee.neuray.security.file.entity; + +import com.gitee.neuray.security.common.entity.BaseEntity; +import lombok.Data; + +import javax.persistence.Column; +import javax.persistence.Table; + +/** + * 文件映射fastdfs服务路径实体类 + * @author zhhongyu + */ +@Data +@Table(name = "FILE_SERVER_PATH") +public class FileServerPathEntity extends BaseEntity { + /** + * 加密标记(0为未加密文件,1为使用base64加密文件,2为使用位移加密文件) + */ + @Column(name = "FILE_ENCRYPE") + private String fileEncrype; + + /** + * 附件路径 + */ + @Column(name = "PATH") + private String path; + + /** + * 数据有效状态(1为有效,0为无效) + */ + @Column(name = "STATUS") + private String status; +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/jwt/FileJwtInfo.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/jwt/FileJwtInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..3382ad678786cbd1244588369c650f1986eac154 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/jwt/FileJwtInfo.java @@ -0,0 +1,61 @@ +package com.gitee.neuray.security.file.jwt; + + +import com.gitee.neuray.security.auth.client.config.UserAuthConfig; +import com.gitee.neuray.security.auth.client.jwt.UserAuthUtil; +import com.gitee.neuray.security.auth.common.util.jwt.IJWTInfo; +import com.gitee.neuray.security.common.util.ClientUtil; +import com.gitee.neuray.security.file.vo.JwtInfoVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import javax.servlet.http.HttpServletRequest; + +/** + * @author zhhongyu + * @since 2019-08-22 + * @deprecation token解析生成文件服务实体组件 + */ +@Component +public class FileJwtInfo { + + @Autowired + private UserAuthConfig userAuthConfig; + @Autowired + private UserAuthUtil userAuthUtil; + + public JwtInfoVO getJwtInfoVO(HttpServletRequest request) throws Exception{ + JwtInfoVO jwtInfoVO = null; + IJWTInfo infoFromToken = getJwtInfo(request); + if (infoFromToken != null) { + jwtInfoVO = new JwtInfoVO(); + String host = StringUtils.isEmpty(request.getHeader("clientIp")) ? + request.getHeader("clientIp") : ClientUtil.getClientIp(request); + jwtInfoVO.setCrtHost(host); + jwtInfoVO.setUpdHost(host); + jwtInfoVO.setCrtName(infoFromToken.getName()); + jwtInfoVO.setCrtUser(infoFromToken.getUniqueName()); + jwtInfoVO.setUpdName(infoFromToken.getName()); + jwtInfoVO.setUpdUser(infoFromToken.getUniqueName()); + } + return jwtInfoVO; + } + + public IJWTInfo getJwtInfo(HttpServletRequest request) throws Exception{ + IJWTInfo infoFromToken = null; + try { + String authToken = request.getHeader(userAuthConfig.getTokenHeader()); + if (StringUtils.isEmpty(authToken)) { + infoFromToken = null; + } else { + infoFromToken = userAuthUtil.getInfoFromToken(authToken); + } + } catch (Exception e) { + infoFromToken = null; + throw e; + } + return infoFromToken; + } + +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/mapper/FileInfoMapper.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/mapper/FileInfoMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..4d8094beedd1e46637e6471b31103ee96584aac4 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/mapper/FileInfoMapper.java @@ -0,0 +1,13 @@ +package com.gitee.neuray.security.file.mapper; + +import com.gitee.neuray.security.file.entity.FileInfoEntity; +import tk.mybatis.mapper.common.Mapper; + +/** + * 文件基础数据实体类数据库接口层 + * @author zhhongyu + * @since 2019-07-29 + */ +public interface FileInfoMapper extends Mapper { + +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/mapper/FileServerPathMapper.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/mapper/FileServerPathMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..1b121231562a24c7babdb12142397d90cd95e2f5 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/mapper/FileServerPathMapper.java @@ -0,0 +1,11 @@ +package com.gitee.neuray.security.file.mapper; + +import com.gitee.neuray.security.file.entity.FileServerPathEntity; +import tk.mybatis.mapper.common.Mapper; + +/** + * fast服务文件路径数据库接口层 + * @author zhhongyu + */ +public interface FileServerPathMapper extends Mapper { +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/redis/listener/RedisKeyExpirationListener.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/redis/listener/RedisKeyExpirationListener.java new file mode 100644 index 0000000000000000000000000000000000000000..43ab36c47cb366e6d2ecdafca51626698378850f --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/redis/listener/RedisKeyExpirationListener.java @@ -0,0 +1,149 @@ +package com.gitee.neuray.security.file.redis.listener; + +import cn.hutool.core.util.StrUtil; +import com.ace.cache.api.impl.CacheRedis; +import com.alibaba.fastjson.JSONObject; + +import com.gitee.neuray.security.common.util.UUIDUtils; +import com.gitee.neuray.security.file.contants.FileContants; +import com.gitee.neuray.security.file.entity.FileServerPathEntity; +import com.gitee.neuray.security.file.mapper.FileServerPathMapper; +import com.gitee.neuray.security.file.util.CommonUtil; +import com.gitee.neuray.security.file.util.DateUtils; +import com.gitee.neuray.security.file.util.FastDFSClientWrapper; +import com.gitee.neuray.security.file.vo.FileAppendInfoVO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import redis.clients.jedis.JedisPubSub; + +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; + +/** + * @author: zhhongyu + * @description: jedis发布/订阅监听类 + * @since: Create in 9:36 2019/8/19 + */ +@Component +@Slf4j +public class RedisKeyExpirationListener extends JedisPubSub { + @Autowired + private CacheRedis cacheRedis; + @Autowired + private FastDFSClientWrapper fastDFSClientWrapper; + @Autowired + private FileServerPathMapper fileServerPathMapper; + + private String pre = "i_"; + + /** + * 初始化按表达式的方式订阅时候的处理 + * @param pattern + * @param subscribedChannels + */ + @Override + public void onPSubscribe(String pattern, int subscribedChannels) { + this.startLog(pattern,subscribedChannels); + } + + /** + * 取得按表达式的方式订阅的消息后的处理 + * @param pattern + * @param channel + * @param message + */ + @Override + public void onPMessage(String pattern, String channel, String message) { + String serverPaht = ""; + String personId = ""; + try{ + if(message.contains(FileContants.REDIS_KEY_APPEND_FILE)&&message.contains(pre)){ + String key = message.substring(message.indexOf(FileContants.REDIS_KEY_APPEND_FILE) + + FileContants.REDIS_KEY_APPEND_FILE.length()+1,message.length()); + String[] split = key.split(FileContants.REDIS_KEY_CON_APPEND_FILE); + personId = split[0]; + String jsonStr = cacheRedis.get(FileContants.REDIS_KEY_PRE+key); + FileAppendInfoVO fileAppendInfoVO = JSONObject.parseObject(jsonStr, FileAppendInfoVO.class); + serverPaht = fileAppendInfoVO.getFilePath(); + fastDFSClientWrapper.deleteFile(serverPaht); + log.info("片段文件所对应的服务器路径为{},该文件由于用户没有再进行上传操作,已被删除",serverPaht); + } + }catch (Exception e){ + log.error(CommonUtil.getExceptionMessage(e)); + //记录日志采集,进行人工删除fastdfs没有用的文件,或保存在数据库中进行定时任务删除 + log.info("片段文件所对应的服务器路径为{}," + + "该文件由于用户没有再进行上传操作,需要手动进行删除",serverPaht); + //进行数据库保存,执行定时任务定时删除没有被清除掉的垃圾文件 + FileServerPathEntity fileServerPathEntity = new FileServerPathEntity(); + fileServerPathEntity.setId(UUIDUtils.generateShortUuid()); + fileServerPathEntity.setCrtUser(personId); + Date date = new Date(); + fileServerPathEntity.setUpdTime(date); + fileServerPathEntity.setCrtTime(date); + fileServerPathEntity.setUpdUser(personId); + fileServerPathEntity.setFileEncrype(FileContants.SENSITIVE_CIPHER_TYPE); + fileServerPathEntity.setPath(serverPaht); + fileServerPathEntity.setStatus(FileContants.INVALID_FILE); + fileServerPathEntity.setAttr1("文件分块上传产生的碎片文件,每天凌晨定时从文件服务删除"); + fileServerPathMapper.insertSelective(fileServerPathEntity); + } + } + + private void startLog(String partten,int subscribedChannels){ + long start = System.currentTimeMillis(); + String baseStr = "|----------------------------------------------------------------------------------------|"; + int baseLen = baseStr.length(); + StackTraceElement[] ses = Thread.currentThread().getStackTrace(); + StackTraceElement se = ses[ses.length - 1]; + int xxLen = 18; + int aaLen = baseLen - 3; + List infoList = new ArrayList(); + infoList.add(StrUtil.fillAfter("subscrber init", ' ', xxLen) + "| " + "success..."); + infoList.add(StrUtil.fillAfter("pattern", ' ', xxLen) + "| " + partten+".../"); + infoList.add(StrUtil.fillAfter("subscribedChannels", ' ', xxLen) + "| " + String.valueOf(subscribedChannels)); + infoList.add(StrUtil.fillAfter("-", '-', aaLen)); + infoList.add(StrUtil.fillAfter("Started at", ' ', xxLen) + "| " + DateUtils.formatDateTime(new Date())); + + String string; + try { + RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean(); + String runtimeName = runtimeMxBean.getName(); + string = runtimeName.split("@")[0]; + long startTime = runtimeMxBean.getStartTime(); + long startCost = System.currentTimeMillis() - startTime; + infoList.add(StrUtil.fillAfter("Jvm start time", ' ', xxLen) + "| " + startCost + " ms"); + infoList.add(StrUtil.fillAfter("Sub init time", ' ', xxLen) + "| " + (System.currentTimeMillis() - start) + " ms"); + infoList.add(StrUtil.fillAfter("Pid", ' ', xxLen) + "| " + string); + } catch (Exception var21) { + ; + } + + String printStr = "\r\n" + baseStr + "\r\n"; + + for(Iterator var23 = infoList.iterator(); var23.hasNext(); printStr = printStr + "| " + StrUtil.fillAfter(string, ' ', aaLen) + "|\r\n") { + string = (String)var23.next(); + } + + printStr = printStr + baseStr + "\r\n"; + if (log.isInfoEnabled()) { + log.info(printStr); + log.info("server on start ... "); + } else { + System.out.println(printStr); + System.out.println("server on start ... "); + } + } + + + public static void main(String[] args) { + String aa = "i_service-fastdfs:append_file:211322199306256312:fileMd5key"; + String bb = "append_file"; + aa.substring(aa.indexOf(bb)+ bb.length()+1,aa.length()); + System.out.println(aa.substring(aa.indexOf(bb)+ bb.length()+1,aa.length())); + } +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/redis/subscribe/AppendFileSubscriber.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/redis/subscribe/AppendFileSubscriber.java new file mode 100644 index 0000000000000000000000000000000000000000..a8e80b0d0714ee9329364eb5d891ebb2e059d3e8 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/redis/subscribe/AppendFileSubscriber.java @@ -0,0 +1,57 @@ +package com.gitee.neuray.security.file.redis.subscribe; + +import com.ace.cache.api.impl.CacheRedis; +import com.gitee.neuray.security.file.redis.listener.RedisKeyExpirationListener; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; + +/** + * @author: zhhongyu + * @description: 文件分块redis键失效订阅者 + * @since: Create in 10:14 2019/8/19 + */ +@Component +@Slf4j +public class AppendFileSubscriber{ + @Autowired + private JedisPool pool; + @Autowired + private RedisKeyExpirationListener redisKeyExpirationListener; + @Autowired + private CacheRedis cacheRedis; + @Value("${redis.database}") + private String database; + + /** + * 由于订阅模式使用的是阻塞式方法,该处使用多线程 + */ + public void generatorSubscriber(){ + SubscriberThread subscriberThread = new SubscriberThread(); + subscriberThread.start(); + } + class SubscriberThread extends Thread{ + @Override + public void run() { + Jedis jedis = null; + try { + jedis = pool.getResource(); + //生成订阅失效key规则,也就是频道 +// String keyRule = CacheConstants.PRE+cacheRedis.addSys("*"); + String keyRule = "__keyevent@4__:expired"; + jedis.psubscribe(redisKeyExpirationListener, keyRule); + } catch (Exception e) { + log.error(String.format("subsrcibe channel error, %s", e)); + throw e; + } finally { + if (jedis != null) { + jedis.close(); + } + } + } + } + +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/runner/AppendFileRedisSubRunner.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/runner/AppendFileRedisSubRunner.java new file mode 100644 index 0000000000000000000000000000000000000000..f1d5a40a21cafd0a1d46076840b9f087b8fd518a --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/runner/AppendFileRedisSubRunner.java @@ -0,0 +1,24 @@ +package com.gitee.neuray.security.file.runner; + +import com.gitee.neuray.security.file.redis.subscribe.AppendFileSubscriber; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.context.annotation.Configuration; + +/** + * @author: zhhongyu + * @description: 服务启动一次性生成redis定义规则key失效订阅者 + * @since: Create in 10:23 2019/8/19 + */ +@Configuration +@Slf4j +public class AppendFileRedisSubRunner implements CommandLineRunner { + @Autowired + private AppendFileSubscriber appendFileSubscriber; + + @Override + public void run(String... args) throws Exception { + appendFileSubscriber.generatorSubscriber(); + } +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/scheduling/TempFileDropSchede.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/scheduling/TempFileDropSchede.java new file mode 100644 index 0000000000000000000000000000000000000000..2503c72f9acf7cb62b587b21c573397e3e364164 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/scheduling/TempFileDropSchede.java @@ -0,0 +1,53 @@ +package com.gitee.neuray.security.file.scheduling; + + +import com.gitee.neuray.security.file.biz.FileServerPathBiz; +import com.gitee.neuray.security.file.contants.FileContants; +import com.gitee.neuray.security.file.entity.FileServerPathEntity; +import com.gitee.neuray.security.file.util.FastDFSClientWrapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; + +import java.util.List; + +/** + * @author: zhhongyu + * @description: 临时碎片文件清除定时任务 + * @since: Create in 14:05 2019/8/20 + */ +@Slf4j +@Component +@EnableScheduling +@Transactional(rollbackFor = Exception.class) +public class TempFileDropSchede { + @Autowired + private FileServerPathBiz fileServerPathBiz; + + @Autowired + private FastDFSClientWrapper dfsClient; + + /** + * 每天凌晨清除残存文件片 + */ + @Scheduled(cron = "0 0 0 * * ?") + public void fileFrash() { + FileServerPathEntity fileServerPathEntity = new FileServerPathEntity(); + fileServerPathEntity.setStatus(FileContants.INVALID_FILE); + List invalidFiles = fileServerPathBiz.selectList(fileServerPathEntity); + invalidFiles.stream().forEach((FileServerPathEntity fileEntity) ->{ + String path = fileEntity.getPath(); + if(StringUtils.isEmpty(path)){ + fileServerPathBiz.deleteById(fileEntity.getId()); + } + fileServerPathBiz.deleteById(fileEntity.getId()); + dfsClient.deleteFile(path); + log.info("残留文件片{},已经被清除",path); + }); + } +} + diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/service/FileMangeService.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/service/FileMangeService.java new file mode 100644 index 0000000000000000000000000000000000000000..c448990feb5ac6a6bbc9ca73aff0349fdb98c191 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/service/FileMangeService.java @@ -0,0 +1,22 @@ +package com.gitee.neuray.security.file.service; + + + +import com.gitee.neuray.security.common.msg.TableResultResponse; +import com.gitee.neuray.security.file.entity.FileManageInf; +import com.gitee.neuray.security.file.vo.FileMonitoringVO; + +import java.util.List; +import java.util.Map; + +public interface FileMangeService { + FileManageInf queryById(String fileId); + int insert(FileManageInf fileManageInf); + int update(FileManageInf fileManageInf); + int deleteById(String fileId); + int fileUpdate(String fileId, String level, String type); + String getFileSizeByDB(String queryType, String queryDate, String returnUnit); + List> getFileSizeRangeByDB(String queryType, String queryDateBegin, String queryDateEnd, String returnUnit); + //文件监控查询 + public TableResultResponse fileMonitoring(Map params) throws Exception; +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/service/JobService.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/service/JobService.java new file mode 100644 index 0000000000000000000000000000000000000000..ff148fb83c5a3e016b228f94bca472b37d73aab5 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/service/JobService.java @@ -0,0 +1,16 @@ +package com.gitee.neuray.security.file.service; + +/** + * 定时任务 + * + * @author zhuqz + * @since 2019-06-12 + */ +public interface JobService { + + /** + * 定时任务-处理无用附件 + * + */ + void dealUnUsedFileList() throws Exception; +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/service/impl/FileManageServiceImpl.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/service/impl/FileManageServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..8693daa8ec5b21320cc09035b8077a7dac780f1a --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/service/impl/FileManageServiceImpl.java @@ -0,0 +1,129 @@ +package com.gitee.neuray.security.file.service.impl; + + +import com.gitee.neuray.security.common.msg.TableResultResponse; +import com.gitee.neuray.security.file.dao.FileManageDao; +import com.gitee.neuray.security.file.entity.FileManageInf; +import com.gitee.neuray.security.file.service.FileMangeService; +import com.gitee.neuray.security.file.util.CommonUtil; +import com.gitee.neuray.security.file.vo.FileMonitoringVO; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service("fileManageService") +public class FileManageServiceImpl implements FileMangeService { + @Resource + FileManageDao fileManageDao; + + public FileManageInf queryById(String fileId){ + return this.fileManageDao.queryById(fileId); + } + public int insert(FileManageInf fileManageInf){ + return this.fileManageDao.insert(fileManageInf); + } + public int update(FileManageInf fileManageInf){ + return this.fileManageDao.update(fileManageInf); + } + public int deleteById(String fileId){ + return this.fileManageDao.deleteById(fileId); + } + public int fileUpdate(String fileId,String level,String type){ + return this.fileManageDao.fileUpdate(fileId,level,type); + } + /** + * 获取上传附件大小(数据库统计) + * + * @param queryType 查询类型0天(默认),1月,2年 + * @param queryDate 查询时间 + * @param returnUnit 返回结果单位 0 M(默认),1 G,2 T + * @return 文件大小:单位兆 + */ + public String getFileSizeByDB(String queryType, String queryDate, String returnUnit){ + String res=""; + String dateFmt=""; + long divide=1L; + if(queryType.equals("0")){ + dateFmt="yyyy-mm-dd"; + }else if(queryType.equals("1")){ + dateFmt="yyyy-mm"; + }else{ + dateFmt="yyyy"; + } + if(returnUnit.equals("0")){ + divide=1024*1024L; + }else if(returnUnit.equals("1")){ + divide=1024*1024*1024L; + }else{ + divide=1024*1024*1024*1024L; + } + double sizes = this.fileManageDao.queryFileSize(dateFmt,queryDate,divide); + res=String.valueOf(CommonUtil.formatDouble2(sizes)); + return res; + } + /** + * 获取上传附件区间段情况(数据库统计) + * + * @param queryType 查询类型0天(默认),1月,2年 + * @param queryDateBegin 查询时间开始 + * @param queryDateEnd 查询时间结束 + * @param returnUnit 返回结果单位 0 M(默认),1 G,2 T + * @return 文件去区间段大小 + */ + public List> getFileSizeRangeByDB(String queryType, String queryDateBegin, String queryDateEnd, String returnUnit) { + List> res=new ArrayList<>(); + String dateFmt=""; + long divide=1L; + if(queryType.equals("0")){ + dateFmt="yyyy-mm-dd"; + }else if(queryType.equals("1")){ + dateFmt="yyyy-mm"; + }else{ + dateFmt="yyyy"; + } + if(returnUnit.equals("0")){ + divide=1024*1024L; + }else if(returnUnit.equals("1")){ + divide=1024*1024*1024L; + }else{ + divide=1024*1024*1024*1024L; + } + List data = this.fileManageDao.queryFileSizeRange(dateFmt,queryDateBegin,queryDateEnd,divide); + for(Map temp : data){ + String date = (String)temp.get("DATES"); + String size = String.valueOf(CommonUtil.formatDouble2(((BigDecimal)temp.get("SIZES")).doubleValue())); + Map map=new HashMap<>(); + map.put("date",date); + map.put("size",size); + res.add(map); + } + return res; + } + //文件监控查询 + //参数说明:page 页码 size 每页几条 userName上传用户名称 dateBegin、dateEnd上传时间开始结束 isGroup 是否群主1是0否 + //fileName文件名称 level密级 + public TableResultResponse fileMonitoring(Map params) throws Exception{ + int page=Integer.valueOf(CommonUtil.nulToEmptyString(params.get("page"))); + int size=Integer.valueOf(CommonUtil.nulToEmptyString(params.get("size"))); + PageHelper.startPage(page, size); + List dataList =this.fileManageDao.fileMonitoring(params); + //null的String类型属性转换空字符串 + CommonUtil.putVoNullStringToEmptyString(dataList); + PageInfo pageInfo = new PageInfo<>(dataList); + TableResultResponse res = new TableResultResponse( + pageInfo.getPageSize(), + pageInfo.getPageNum(), + pageInfo.getPages(), + pageInfo.getTotal(), + pageInfo.getList() + ); + return res; + } +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/service/impl/JobServiceImpl.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/service/impl/JobServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..13a8d7ce77e8a4b5abd180525fb025c3148737db --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/service/impl/JobServiceImpl.java @@ -0,0 +1,52 @@ +package com.gitee.neuray.security.file.service.impl; + + +import com.gitee.neuray.security.file.dao.JobDao; +import com.gitee.neuray.security.file.service.JobService; +import com.gitee.neuray.security.file.util.CommonUtil; +import com.gitee.neuray.security.file.util.FastDFSClientWrapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 定时任务-历史消息处理 + * + * @author zhuqz + * @since 2019-06-12 + */ +@Service("jobServiceImpl") +public class JobServiceImpl implements JobService { + private static Logger log = LoggerFactory.getLogger(JobServiceImpl.class); + @Resource + private JobDao jobDao; + @Autowired + private FastDFSClientWrapper dfsClient; + /** + * 定时任务-处理无用附件 + * + */ + public void dealUnUsedFileList() throws Exception{ + try { + List filePathList=this.jobDao.getUnUsedFileList(); + this.jobDao.delUnUsedFileList(); + for(String path:filePathList){ + try { + dfsClient.deleteFile(path); + } catch (Exception e) { + throw e; + } + + } + log.info("定时任务执行成功,共删除无用附件"+filePathList.size()+"个"); + }catch (Exception e){ + log.error("定时任务删除无用附件出错:"); + log.error(CommonUtil.getExceptionMessage(e)); + } + + } +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/util/AppendFileUtils.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/util/AppendFileUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..722eea6fef8522e3d1a0037d4b5bac6e926819c0 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/util/AppendFileUtils.java @@ -0,0 +1,278 @@ +package com.gitee.neuray.security.file.util; + +import com.ace.cache.api.impl.CacheRedis; +import com.alibaba.fastjson.JSONObject; +import com.gitee.neuray.security.common.exception.BaseException; +import com.gitee.neuray.security.file.contants.FileContants; +import com.gitee.neuray.security.file.vo.FileAppendInfoVO; +import com.github.tobato.fastdfs.domain.FileInfo; +import com.github.tobato.fastdfs.domain.StorePath; +import com.github.tobato.fastdfs.service.AppendFileStorageClient; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FilenameUtils; +import org.joda.time.DateTime; +import org.joda.time.Interval; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import org.springframework.web.multipart.MultipartFile; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * @author: zhhongyu + * @description: 文件分块上传 + * @since: Create in 13:41 2019/8/13 + */ +@Slf4j +@Component +public class AppendFileUtils { + + @Autowired + private AppendFileStorageClient appendFileStorageClient; + @Autowired + private FastDFSClientWrapper fastDFSClientWrapper; + + /** + * 所在组卷 + */ + @Value("${fdfs.groupName}") + private String groupName = "group1"; + + @Value("${upload.sensitiveFile.original}") + private String sensitiveOriginalFile; + @Autowired + private CacheRedis cacheRedis; + + private DateTime sentiveStartDate; + + private DateTime sentiveEndDate; + + private DateTime uploadStartDate; + + private DateTime uploadEndDate; + + + /** + * 分块上传第一个文件 + * + * @param file + * @return path + * @throws IOException + */ + public String uploadFile(MultipartFile file) throws IOException { + StorePath group = appendFileStorageClient.uploadAppenderFile(groupName, file.getInputStream(), file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename())); + return group.getPath(); + } + + /** + * 采用文件流加密文件(分块中的n-1块必须为8的倍数的长度,第n块可以为任意长度) + * + * @param file + * @param fileKey 整体文件唯一性key + * @param personKey 上传人员唯一性key(防止高并发下不同上传人上传同样的文件出现文件拼接错误) + * @param currentNo 当前文件块 + * @param totalSize 总文件块数 + * @return 成功上传块数和文件所在服务器全路径 + * @throws Exception + */ + public Map uploadCipherSensitiveFile(MultipartFile file, + String fileKey, + String personKey, + String currentNo, + String totalSize) throws Exception { + if (Integer.parseInt(currentNo) > Integer.parseInt(totalSize)) { + throw new BaseException("currentNo more then totalSize..."); + } + if (StringUtils.isEmpty(personKey)) { + throw new BaseException("分块上传上传人唯一性不能为空..."); + } + String appendPersonKey = FileContants.REDIS_KEY_CON_APPEND_FILE + + personKey + + FileContants.REDIS_KEY_CON_APPEND_FILE; + log.info(fileKey); + Map result = new HashMap(256); + //先从缓存中获取已经传成功的文件块(包含文件唯一性,上传人唯一性) + String fileAppendInfoJson = cacheRedis.get(FileContants.REDIS_KEY_APPEND_FILE + + appendPersonKey + + fileKey + ); + if (StringUtils.isEmpty(fileAppendInfoJson)) { + //防止缓存穿透设置null值,时长30分钟 + cacheRedis.set(FileContants.REDIS_KEY_APPEND_FILE, null, 30); + } + FileAppendInfoVO fileAppendInfoVO = JSONObject.parseObject(fileAppendInfoJson, FileAppendInfoVO.class); + if (fileAppendInfoVO != null && Integer.parseInt(fileAppendInfoVO.getSuccessSize()) + >= Integer.parseInt(currentNo)) { + result.put("isSuccessNo", fileAppendInfoVO.getSuccessSize()); + result.put("path", fileAppendInfoVO.getFilePath()); + return result; + } + String path = null; + String fullPath = null; + //是传的是第一块以后的文件,path已经存在在缓存中 + if (fileAppendInfoVO != null) { + fullPath = fileAppendInfoVO.getFilePath(); + path = fileAppendInfoVO.getFilePath(); + path = path.substring(path.indexOf("/") + 1, path.length()); + } + sentiveStartDate = new DateTime(); + FileDeEncrypt deEncrypt = new FileDeEncrypt(FileContants.ENCRYPT_ROLE); + byte[] bytes = deEncrypt.encryptFile(file.getBytes()); + sentiveEndDate = new DateTime(); + log.info("加密文件时间为:"); + this.getDatePoor(sentiveStartDate, sentiveEndDate); + ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); + //1.传第一块的文件到服务器 + if (StringUtils.isEmpty(path)) { + return this.uploadFirstPart(inputStream, bytes.length, fileKey, appendPersonKey, currentNo, totalSize); + } + //2.续传文件到服务器 + return this.appendFile(inputStream, bytes.length, fileKey, appendPersonKey, path, fullPath, currentNo, totalSize); + } + + + /** + * 文件分块上传第一块文件到服务器处理 + * + * @param inputStream + * @param length + * @param fileKey + * @param appendKey + * @param currentNo + * @param totalSize + * @return + */ + private synchronized Map uploadFirstPart(ByteArrayInputStream inputStream, + int length, + String fileKey, + String appendKey, + String currentNo, + String totalSize) throws Exception{ + uploadStartDate = new DateTime(); + StorePath storePath = appendFileStorageClient.uploadAppenderFile(groupName, inputStream, length, FilenameUtils.getExtension(sensitiveOriginalFile)); + try { + //1.1 缓存成功的文件块信息,文件块有效时长30分钟 + FileAppendInfoVO fileAppendInfoCache = this.tranferVO(fileKey, currentNo, storePath.getFullPath(), totalSize); + cacheRedis.set(FileContants.REDIS_KEY_APPEND_FILE + + appendKey + + fileKey, + JSONObject.toJSONString(fileAppendInfoCache), + 30); + //1.2该缓存值用于如果用户分块时,没有全部上传文件,可能存在垃圾文件片,删除这种情况下的垃圾文件 + cacheRedis.set(FileContants.REDIS_KEY_PRE_APPEND_FILE + + appendKey + + fileKey, + JSONObject.toJSONString(fileAppendInfoCache), + 35, "该缓存值35分钟失效,防止存在垃圾文件片情况"); + uploadEndDate = new DateTime(); + log.info("上传文件并进行redies时间为:"); + this.getDatePoor(uploadStartDate, uploadEndDate); + } catch (Exception e) { + fastDFSClientWrapper.deleteFile(storePath.getFullPath()); + throw e; + } + Map result = new HashMap(256); + result.put("isSuccessNo", currentNo); + result.put("path", storePath.getFullPath()); + return result; + } + + /** + * 续传文件 + * + * @param inputStream 文件加密流 + * @param length 长度 + * @param fileKey 文件唯一性 + * @param appendKey 上传人唯一性 + * @param path 续传path(不带卷) + * @param fullPath 全路径 + * @param currentNo 当前文件块 + * @param totalSize 整体文件块数 + * @return + */ + private synchronized Map appendFile(ByteArrayInputStream inputStream, + int length, + String fileKey, + String appendKey, + String path, + String fullPath, + String currentNo, + String totalSize)throws Exception { + //解析fullpath + if(!StringUtils.isEmpty(fullPath)){ + groupName = fullPath.substring(0,fullPath.indexOf("/")); + } + uploadStartDate = new DateTime(); + //查询原始文件信息 + FileInfo fileInfo = appendFileStorageClient.queryFileInfo(groupName, path); + log.info("上传成功的文件长度为{}",fileInfo.getFileSize()); + appendFileStorageClient.appendFile(groupName, path, inputStream, length); + try { + //3.缓存成功的文件块信息,文件块有效时长30分钟 + FileAppendInfoVO fileAppendInfoCache = this.tranferVO(fileKey, currentNo, fullPath, totalSize); + cacheRedis.set(FileContants.REDIS_KEY_APPEND_FILE + + appendKey + + fileKey, + JSONObject.toJSONString(fileAppendInfoCache), 30); + //4. 该缓存值用于如果用户分块时,没有全部上传文件,可能存在垃圾文件片,删除这种情况下的垃圾文件 + cacheRedis.set(FileContants.REDIS_KEY_PRE_APPEND_FILE + + appendKey + + fileKey, + JSONObject.toJSONString(fileAppendInfoCache), + 35, "该缓存值35分钟失效,防止存在垃圾文件片情况"); + uploadEndDate = new DateTime(); + log.info("续传文件并进行redies时间为:"); + this.getDatePoor(uploadStartDate, uploadEndDate); + } catch (Exception e) { + //针对redis连接不上,fastdfs服务好用的情况,如果fast不好使的情况续传就异常了直接返回给前端 + appendFileStorageClient.truncateFile(groupName,path,fileInfo.getFileSize()); + throw e; + } + Map result = new HashMap(256); + result.put("isSuccessNo", currentNo); + result.put("path", fullPath); + return result; + } + + public String getDatePoor(DateTime startTime, DateTime endTime) { + Interval interval = new Interval(startTime, endTime); + log.info("响应时间:{}毫秒", interval.toDurationMillis()); + return ""; + } + + /** + * 缓存清除文件 + * + * @param path + * @param truncatedFileSize + */ + public void truncateFile(String path, long truncatedFileSize) { + appendFileStorageClient.truncateFile(groupName, path, truncatedFileSize); + } + + /** + * 文件分块要拼接的文件 + * + * @param file + * @param path + * @throws IOException + */ + private void appendFile(MultipartFile file, String path) throws IOException { + appendFileStorageClient.appendFile(groupName, path, file.getInputStream(), file.getSize()); + } + + private FileAppendInfoVO tranferVO(String md5Key, String currentNo, String path, String totalSize) { + FileAppendInfoVO fileAppendInfoVO = new FileAppendInfoVO(); + fileAppendInfoVO.setSuccessSize(currentNo); + fileAppendInfoVO.setFilePath(path); + fileAppendInfoVO.setMd5Key(md5Key); + fileAppendInfoVO.setTotalSize(totalSize); + return fileAppendInfoVO; + } + +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/util/Base64Utils.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/util/Base64Utils.java new file mode 100644 index 0000000000000000000000000000000000000000..98779aba242ef055cf2c446950a8f797f022cdac --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/util/Base64Utils.java @@ -0,0 +1,45 @@ +package com.gitee.neuray.security.file.util; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.util.Base64; + +/** + * base64转码工具类 + * @author zhhongyu + */ +public class Base64Utils { + + private static Base64.Encoder base64Encoder = Base64.getEncoder(); + private static Base64.Decoder base64Decoder =Base64.getDecoder(); + + /** + * 将file文件转为base64编码 + * @param multipartFile 文件 + * @return base64字符串 + */ + public static String fileToBase64(MultipartFile multipartFile) throws IOException{ + String base64EncoderImg = byteToString(multipartFile.getBytes()); + return base64EncoderImg; + } + /** + * base64将byte[]转为String + * @param source byte[] + * @return String + */ + public static String byteToString(byte[] source) { + //Base64 Encoded + String encoded = base64Encoder.encodeToString(source); + return encoded; + } + + /** + * base64将String转为byte[] + * @param source string + * @return byte[] + */ + public static byte[] stringToByte(String source) throws IOException { + return base64Decoder.decode(source); + } +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/util/CommonUtil.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/util/CommonUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..9b440b56a75b3c9a0b26ebae0ccd9bb849080d6e --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/util/CommonUtil.java @@ -0,0 +1,99 @@ +package com.gitee.neuray.security.file.util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.math.RoundingMode; + +public class CommonUtil { + private static Logger log = LoggerFactory.getLogger(CommonUtil.class); + //异常信息获取 + public static String getExceptionMessage(Exception e) { + StringWriter sw = null; + PrintWriter pw = null; + try { + sw = new StringWriter(); + pw = new PrintWriter(sw); + // 将出错的栈信息输出到printWriter中 + e.printStackTrace(pw); + pw.flush(); + sw.flush(); + } finally { + if (sw != null) { + try { + sw.close(); + } catch (IOException e1) { + e1.printStackTrace(); + } + } + if (pw != null) { + pw.close(); + } + } + return sw.toString(); + } + //格式化double + public static String formatDouble2(double d) { + // 新方法,如果不需要四舍五入,可以使用RoundingMode.DOWN + BigDecimal bg = new BigDecimal(d).setScale(2, RoundingMode.UP); + return String.valueOf(bg.doubleValue()); + } + //objec转字符串 null-> "" + public static String nulToEmptyString(Object object){ + try{ + if(object==null){ + return ""; + } + return object.toString(); + }catch (Exception e){ + e.printStackTrace(); + log.error(getExceptionMessage(e)); + } + return null; + } + /** + *@Description: 把返回给前端的VO 属性是字符串的且值是null的 转换成空字符串,其它类型在代码自行处理 + *@Param: vo + *@return: void + *@Author: zhuqz + *@date: 2019/06/26 + */ + public static void putVoNullStringToEmptyString (T vo) throws Exception{ + if(vo==null){ + return; + } + //遍历enity类 成员为String类型 属性为空的全部替换为“” + Field[] fields = vo.getClass().getDeclaredFields(); + for (int i = 0; i < fields.length; i++) { + // 获取属性的名字 + String name = fields[i].getName(); + // 将属性的首字符大写,方便构造get,set方法 + name = name.substring(0, 1).toUpperCase() + name.substring(1); + // 获取属性的类型 + String type = fields[i].getGenericType().toString(); + // 如果type是类类型,则前面包含"class ",后面跟类名 + if (type.equals("class java.lang.String")) { + Method m = vo.getClass().getMethod("get" + name); + // 调用getter方法获取属性值 + String value = (String) m.invoke(vo); + //System.out.println("数据类型为:String"); + if (value == null) { + //set值 + Class[] parameterTypes = new Class[1]; + parameterTypes[0] = fields[i].getType(); + m = vo.getClass().getMethod("set" + name, parameterTypes); + String string = new String(""); + Object[] objects = new Object[1]; + objects[0] = string; + m.invoke(vo, objects); + } + } + } + } +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/util/DateUtils.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/util/DateUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..e164d96353cc446eb7c1e6c306759220ceeb3c02 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/util/DateUtils.java @@ -0,0 +1,42 @@ +package com.gitee.neuray.security.file.util; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.text.SimpleDateFormat; +import java.util.Locale; + +/** + * @author: zhhongyu + * @description: + * @since: Create in 15:09 2020/1/8 + */ + + +public class DateUtils { + public DateUtils() { + } + + public static String httpDate() { + return httpDate(new Date()); + } + + public static String httpDate(Date date) { + SimpleDateFormat greenwichDate = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss 'GMT'", Locale.US); + return greenwichDate.format(date); + } + + public static String httpDate(long millis) { + return httpDate(new Date(millis)); + } + + public static String formatDateTime(Date date) { + if (null == date) { + return null; + } else { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return format.format(date); + } + } +} + diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/util/DesCodeEnum.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/util/DesCodeEnum.java new file mode 100644 index 0000000000000000000000000000000000000000..659b304fbc17f2a0e281af347482a51f8ff6726b --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/util/DesCodeEnum.java @@ -0,0 +1,38 @@ +package com.gitee.neuray.security.file.util; + +/** + * @author: zhhongyu + * @description: + * @since: Create in 16:59 2019/8/13 + */ +public enum DesCodeEnum { + DESEDE("DES"), + /** + * 使用不填充,文件服务自定义填充 + */ + DESEDE_ECB_NoPadding("DES/ECB/NoPadding"), + /* + * 加密前对数据字节长度对8取余, + * 余数大于0,则差几个字节就补几个字节, + * 字节数值即为补充的字节数,若为0则补充8个字节的8 , + * 解密后就取最后一个字节,值为m,则从数据尾部删除m个字节 + * ,剩余数据即为加密前的原文。 + */ + DESEDE_ECB_PKCS5Padding("DES/ECB/PKCS5Padding"), + DESEDE_ECB_PKCS7Padding("DES/ECB/PKCS71Padding"), + DESEDE_ECB_ISO10126Padding("DES/ECB/ISO10126Padding"); + + private String code; + + DesCodeEnum(String code) { + this.setCode(code); + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/util/EncryptionAndDeciphering.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/util/EncryptionAndDeciphering.java new file mode 100644 index 0000000000000000000000000000000000000000..e3d7d577d8509e6b4d66c485ae00c197ed663895 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/util/EncryptionAndDeciphering.java @@ -0,0 +1,171 @@ +package com.gitee.neuray.security.file.util; + +import com.gitee.neuray.security.common.util.UUIDUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; + +//文件加密解密 +public class EncryptionAndDeciphering { + private static Logger log = LoggerFactory.getLogger(EncryptionAndDeciphering.class); + private static final int OFFSET = 5; + private static final String ENCRYPTION_PREFIX = "Encrypted_"; + private static final String DECIPHER_PREFIX = "Deciphered_"; + + public static boolean changeFile(File inFile, int offset, String prefix) { + BufferedInputStream input = null; + BufferedOutputStream output = null; + //check input file + if (!inFile.exists()) { + log.error("文件加密错误:文件不存在"); + return false; + } + + //create output file + File outFile = new File(inFile.getParent()+"/"+prefix + inFile.getName()); + if (outFile.exists()) { + log.error("文件加密错误:文件已经存在"); + return false; + } + try { + if (!outFile.createNewFile()) { + log.error("文件加密错误:文件无法创建"); + return false; + } + } catch (IOException e) { + return false; + } + + //IO + try { + input = new BufferedInputStream(new FileInputStream(inFile)); + output = new BufferedOutputStream(new FileOutputStream(outFile)); + int value; + for (; ; ) { + value = input.read(); + if (value == -1) { + break; + } + output.write(value + offset); //change + } + output.flush(); + } catch (IOException e) { + log.error(CommonUtil.getExceptionMessage(e)); + return false; + }finally { + if(input!=null){ + try { + input.close(); + inFile.delete(); + } catch (IOException e) { + log.error(CommonUtil.getExceptionMessage(e)); + } + } + if(output!=null){ + try { + output.close(); + outFile.renameTo(inFile); + } catch (IOException e) { + log.error(CommonUtil.getExceptionMessage(e)); + } + } + } + return true; + } + public static byte[] changeFile(MultipartFile inFile, int offset) throws Exception{ + byte[] bytes = inFile.getBytes(); + for(int i=0;i 0) { + out.write(buffer, 0, r); + } + byte[] bytes = ((ByteArrayOutputStream) out).toByteArray(); + if(FileContants.FILE_DECRYPT.equals(flag)){ + //解密时去掉末尾为定义规则的数据 + bytes = trimByte(bytes); + } + out.flush(); + cis.close(); + is.close(); + out.close(); + return bytes; + } + + private byte[] bytesData(byte[] args) { + for(int i = 0;i !path.getFileName().toString().equals(filename)) + .sorted((o1, o2) -> { + String p1 = o1.getFileName().toString(); + String p2 = o2.getFileName().toString(); + int i1 = p1.lastIndexOf("-"); + int i2 = p2.lastIndexOf("-"); + return Integer.valueOf(p2.substring(i2)).compareTo(Integer.valueOf(p1.substring(i1))); + }) + .forEach(path -> { + try { + //以追加的形式写入文件 + Files.write(Paths.get(targetFile), Files.readAllBytes(path), StandardOpenOption.APPEND); + //合并后删除该块 + Files.delete(path); + } catch (IOException e) { + + } + }); + } catch (IOException e) { + + } + } +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/util/MD5Util.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/util/MD5Util.java new file mode 100644 index 0000000000000000000000000000000000000000..0eb7e716a7abecdd4f8b825898330b92f0362e20 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/util/MD5Util.java @@ -0,0 +1,59 @@ +package com.gitee.neuray.security.file.util; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * md5加密工具类 + */ +public class MD5Util { + + public final static String MD5(byte[] btInput) { + char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; +// try { +// // 获得MD5摘要算法的 MessageDigest 对象 +// MessageDigest mdInst = MessageDigest.getInstance("MD5"); +// // 使用指定的字节更新摘要 +// mdInst.update(btInput); +// // 获得密文 +// byte[] md = mdInst.digest(); +// // 把密文转换成十六进制的字符串形式 +// int j = md.length; +// char str[] = new char[j * 2]; +// int k = 0; +// for (int i = 0; i < j; i++) { +// byte byte0 = md[i]; +// str[k++] = hexDigits[byte0 >>> 4 & 0xf]; +// str[k++] = hexDigits[byte0 & 0xf]; +// } +// return new String(str); +// } catch (Exception e) { +// e.printStackTrace(); +// return null; +// } + // 消息签名(摘要) + MessageDigest md5 = null; + try { + // 参数代表的是算法名称 + md5 = MessageDigest.getInstance("MD5"); + byte[] result = md5.digest(btInput); + + StringBuilder sb = new StringBuilder(32); + // 将结果转为16进制字符 0~9 A~F + for (int i = 0; i < result.length; i++) { + // 一个字节对应两个字符 + byte x = result[i]; + // 取得高位 + int h = 0x0f & (x >>> 4); + // 取得低位 + int l = 0x0f & x; + sb.append(hexDigits[h]).append(hexDigits[l]); + } + return sb.toString(); + + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/vo/FileAppendInfoVO.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/vo/FileAppendInfoVO.java new file mode 100644 index 0000000000000000000000000000000000000000..ecdc0bf2d6a3f49be74da00a2fc1ec0f3734ec12 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/vo/FileAppendInfoVO.java @@ -0,0 +1,30 @@ +package com.gitee.neuray.security.file.vo; + +import lombok.Data; +import lombok.ToString; + +/** + * @author: zhhongyu + * @description: 文件分块缓存在redies中的文件块基本信息实体类 + * @since: Create in 13:09 2019/8/15 + */ +@Data +@ToString +public class FileAppendInfoVO { + /** + * 文件唯一性编码 + */ + private String md5Key; + /** + * 文件对应文件服务器路径 + */ + private String filePath; + /** + * 传成功的块数 + */ + private String successSize; + /** + * 总块数 + */ + private String totalSize; +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/vo/FileInfoVO.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/vo/FileInfoVO.java new file mode 100644 index 0000000000000000000000000000000000000000..aff043a0655fa715be474d47a97e8bef7b350121 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/vo/FileInfoVO.java @@ -0,0 +1,49 @@ +package com.gitee.neuray.security.file.vo; + +import lombok.Data; + +/** + * @author: zhhongyu + * @description: 文件信息前端页面展示 + * @since: Create in 10:20 2019/8/28 + */ +@Data +public class FileInfoVO { + private String id; + + private String fileName; + /** + * 文件后缀名 + */ + private String fileExt; + /** + * 附件类型(text、img、doc) + */ + private String fileType; + /** + * 文件密级 + */ + private String levels; + + /** + * 文件大小 + */ + private Double fileSize; + + /** + * 附件转码为可读取的路径 + */ + private String readPath; + /** + * 数据有效状态(1为有效,0为无效) + */ + private String status; + /** + * 加密类型 + */ + private String sensitiveType; + /** + * 文件服务器路径 + */ + private String path; +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/vo/FileMonitoringVO.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/vo/FileMonitoringVO.java new file mode 100644 index 0000000000000000000000000000000000000000..979ef1b29467a325c4b4c780a3786aa7edcfb755 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/vo/FileMonitoringVO.java @@ -0,0 +1,91 @@ +package com.gitee.neuray.security.file.vo; +//文件监控前端返回格式 +public class FileMonitoringVO { + //文件id + private String fileId; + + //文件名称 + private String fileName; + + //文件路径 + private String filePath; + + //文件大小(M) + private String fileSize; + + //上传时间 yyyy-MM-dd hh:mm:ss + private String uploadTime; + + //上传人姓名 + private String uploadUserName; + + //文件密级 + private String levels; + + //群/私 文件 0私人1群 + private String isGroup; + + public String getFileId() { + return fileId; + } + + public void setFileId(String fileId) { + this.fileId = fileId; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public String getFilePath() { + return filePath; + } + + public void setFilePath(String filePath) { + this.filePath = filePath; + } + + public String getFileSize() { + return fileSize; + } + + public void setFileSize(String fileSize) { + this.fileSize = fileSize; + } + + public String getUploadTime() { + return uploadTime; + } + + public void setUploadTime(String uploadTime) { + this.uploadTime = uploadTime; + } + + public String getUploadUserName() { + return uploadUserName; + } + + public void setUploadUserName(String uploadUserName) { + this.uploadUserName = uploadUserName; + } + + public String getLevels() { + return levels; + } + + public void setLevels(String levels) { + this.levels = levels; + } + + public String getIsGroup() { + return isGroup; + } + + public void setIsGroup(String isGroup) { + this.isGroup = isGroup; + } +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/vo/JwtInfoVO.java b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/vo/JwtInfoVO.java new file mode 100644 index 0000000000000000000000000000000000000000..edad6dcb103792c6a071fd27562b94c04f64a322 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/java/com/gitee/neuray/security/file/vo/JwtInfoVO.java @@ -0,0 +1,29 @@ +package com.gitee.neuray.security.file.vo; + +import lombok.Data; + +import java.util.Date; + +/** + * @author: zhhongyu + * @description: token生成jwt实体类接收 + * @since: Create in 15:04 2019/8/21 + */ +@Data +public class JwtInfoVO { + private Date crtTime = new Date(); + + private String crtUser; + + private String crtName; + + private String crtHost; + + private Date updTime = new Date(); + + private String updUser; + + private String updName; + + private String updHost; +} diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/resources/application.yml b/neuray-pm-base-server/base-dfsfile-client/src/main/resources/application.yml new file mode 100644 index 0000000000000000000000000000000000000000..91dd44ed8a3c7e71f3cf571e49b2ef3912db2161 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/resources/application.yml @@ -0,0 +1,138 @@ +spring: + application: + name: base-dfsfile + datasource: + url: jdbc:oracle:thin:@${ORACLE_HOST:192.168.1.205}:${ORACLE_PORT:5566}:arltr + username: NeurayPM_File + password: NeurayPM_File + # 使用druid数据源 + type: com.alibaba.druid.pool.DruidDataSource + driver-class-name: oracle.jdbc.OracleDriver + ###优化数据库连接池配置,该配置支持2000并发 + druid: + max-active: 18 + initial-size: 3 + min-idle: 3 + max-wait: 250000 + time-between-eviction-runs-millis: 250000 + min-evictable-idle-time-millis: 120000 + validation-query: select 'x' from dual + test-while-idle: true + test-on-borrow: false + test-on-return: false + max-open-prepared-statements: 20 + filter: stat,wall,log4j + servlet: + multipart: + enabled: true + max-file-size: 600MB + max-request-size: 600MB + #html具有缓存的特点,这里不用,每次刷新都请求服务器 + thymeleaf: + cache: false + encoding: UTF-8 + mode: HTML5 + prefix: classpath:/templates/ + suffix: .html +server: + port: 8771 + profiles: + active: dev +#eruka注册中心 +eureka: + client: + service-url: + defaultZone: http://${EUREKA_HOST:localhost}:${EUREKA_PORT:8070}/eureka/ + ###向注册中心上注册自己 + register-with-eureka: true + ###是否需要从eureka上获取注册信息 + fetch-registry: true + + +###fastdfs配置 +fdfs: + ###上传文件使用分组,后期对fastdfs扩容,改变这个参数即可,改为你想使用的卷进行上传 + groupName: group1 + soTimeout: 1500 #socket连接超时时长 + connectTimeout: 6000 #连接tracker服务器超时时长 + ###nginx反向监听storage服务配置,ip(nginx配置放在前台,后台只提供相对路径,防止后期迁移服务器后,所有的头像数据全部不显示了) + ##nginxHost: 10.12.97.34 + ###nginx端口 + ##nginxPort: 80 + thumbImage: #缩略图生成参数,可选 + width: 150 + height: 150 + trackerList: #TrackerList参数,支持多个,我这里只有一个,如果有多个在下方加- x.x.x.x:port + - 192.168.1.205:22122 +upload: + picture: + mast: jpg,png + sensitiveFile: + original: .lark +mybatis: + mapper-locations: classpath:mapper/*.xml +logging: + level: + com.github.hollykunge.dao: debug + +##durid数据监控页面配置 +druid: + enabled: true + whiteip: 127.0.0.1 + blackip: 192.168.1.1 + loginUsername: admin + loginPassword: 123456 +#redis-cache 相关 +redis: + pool: + maxActive: 300 + maxIdle: 100 + maxWait: 10000 + #需要修改地址 + host: 192.168.1.205 + port: 6379 + password: 123456 + timeout: 20000 + # 服务或应用名 + sysName: neuray-pm-fastdfs + enable: true + database: 4 +prop: + upload-folder: ./files + + +##hystrix禁止服务超时时间 +hystrix: + threadpool: + default: + coreSize: 10000 ##并发执行的最大线程数,默认10 + maxQueueSize: 10000 ##BlockingQueue的最大队列数 + queueSizeRejectionThreshold: 5000 ##即使maxQueueSize没有达到,达到queueSizeRejectionThreshold该值后,请求也会被拒绝 + command: + default: + execution: + isolation: + thread: + timeoutInMilliseconds: 60000 + +ribbon: + eureka: + enabled: true + ReadTimeout: 30000 + ConnectTimeout: 30000 + MaxAutoRetries: 0 + MaxAutoRetriesNextServer: 1 + OkToRetryOnAllOperations: false + httpclient: + enabled: false + okhttp: + enabled: true + +auth: + serviceId: neuray-pm-auth + user: + token-header: Authorization + client: + token-header: client-token + id: neuray-pm-dfsfile #不填则默认读取spring.application.name + secret: 123456 diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/resources/log4j.properties b/neuray-pm-base-server/base-dfsfile-client/src/main/resources/log4j.properties new file mode 100644 index 0000000000000000000000000000000000000000..84816bab696ba16e44bbb62b1fc993b1b08867d1 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/resources/log4j.properties @@ -0,0 +1,9 @@ +log4j.rootCategory=INFO, file + +# root��־��� +log4j.appender.file=org.apache.log4j.DailyRollingFileAppender +#log4j.appender.file.file=service-dfsfile/logs/all.log +log4j.appender.file.file=C:/lark_log/service-dfsfile/logs +log4j.appender.file.DatePattern='.'yyyy-MM-dd +log4j.appender.file.layout=org.apache.log4j.PatternLayout +log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n \ No newline at end of file diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/resources/mapper/FileInfoMapper.xml b/neuray-pm-base-server/base-dfsfile-client/src/main/resources/mapper/FileInfoMapper.xml new file mode 100644 index 0000000000000000000000000000000000000000..636a9e7dd417ed9fe7e715f67063010f8dd256f8 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/resources/mapper/FileInfoMapper.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/resources/mapper/FileManageDao.xml b/neuray-pm-base-server/base-dfsfile-client/src/main/resources/mapper/FileManageDao.xml new file mode 100644 index 0000000000000000000000000000000000000000..041484e8f2ab653dc37a840c759a0c27746b533e --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/resources/mapper/FileManageDao.xml @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select + FILE_ID, FILE_NAME, FILE_EXT, FILE_TYPE, SIZES, PATH, READ_PATH, CREATE_TIME, CREATOR, UPDATE_TIME, UPDATOR, LEVELS ,SEND_FLG,FILE_ENCRYPE_FLG,WORK_TYPE + from FILE_MANAGE_INF + where FILE_ID = #{fileId} + + + + insert into FILE_MANAGE_INF(FILE_ID, FILE_NAME, FILE_EXT, FILE_TYPE, SIZES, PATH, READ_PATH, CREATE_TIME, CREATOR, LEVELS,CREATOR_NAME,SEND_FLG,FILE_ENCRYPE_FLG) + values (#{fileId,jdbcType=VARCHAR},#{fileName,jdbcType=VARCHAR}, #{fileExt,jdbcType=VARCHAR}, #{fileType,jdbcType=VARCHAR}, #{sizes}, #{path,jdbcType=VARCHAR}, #{readPath,jdbcType=VARCHAR},sysdate, #{creator,jdbcType=VARCHAR}, #{levels,jdbcType=VARCHAR}, #{creatorName,jdbcType=VARCHAR}, #{sendFlg,jdbcType=VARCHAR}, #{fileEncrypeFlg,jdbcType=VARCHAR}) + + + + update FILE_MANAGE_INF + + + FILE_NAME = #{fileName}, + + + FILE_EXT = #{fileExt}, + + + FILE_TYPE = #{fileType}, + + + SIZES = #{sizes}, + + + PATH = #{path}, + + + READ_PATH = #{readPath}, + + + CREATE_TIME = #{createTime}, + + + CREATOR = #{creator}, + + + UPDATE_TIME = #{updateTime}, + + + UPDATOR = #{updator}, + + + LEVELS = #{levels}, + + + where FILE_ID = #{fileId} + + + + + delete from FILE_MANAGE_INF where FILE_ID = #{fileId} + + + + update FILE_MANAGE_INF + set SEND_FLG='1', + LEVELS=#{level}, + WORK_TYPE=#{type} + where FILE_ID=#{fileId} + + + + select nvl(sum(nvl(sizes,0)),0)/${unit} as sizes + from file_manage_inf + where 1 = 1 + and to_char(create_time, #{dateFmat}) = #{date} + + + + select sum(a.sizes)/${unit} sizes, + a.create_time dates + from (select nvl(sizes,0) sizes,to_char(create_time, #{dateFmat}) create_time from file_manage_inf) a + where 1 = 1 + and a.create_time <= #{dateEnd} + and a.create_time >= #{dateBegin} + group by a.create_time + + + + select f.file_id, + f.file_name || decode(nvl(f.file_ext, 'null'), 'null', '', '.' || f.file_ext) as file_name, + TO_CHAR(nvl(f.sizes, 0) / 1024 / 1024,'FM999999999990.00') as file_size, + f.path as file_path, + to_char(f.create_time,'yyyy-mm-dd hh24:mi:ss') as upload_time, + f.levels, + f.creator_name, + (case when f.file_id in ( select u.file_id from zz_upload_file u where u.is_group='1') then '1' else '0' END) is_group + from zz_group_file f + where f.send_flg = '1' + + and f.file_name || decode(nvl(f.file_ext, 'null'), 'null', '', '.' || f.file_ext) like '%'||#{params.fileName}||'%' + + + and f.creator_name like '%'||#{params.userName}||'%' + + + and f.levels = #{params.level} + + + and to_char(f.create_time, 'yyyy-mm-dd') >= #{params.dateBegin} + + + and to_char(f.create_time, 'yyyy-mm-dd') <= #{params.dateEnd} + + + and exists (select 1 from zz_upload_file g where g.file_id=f.file_id and g.is_group='1') + + + and not exists (select 1 from zz_upload_file g where g.file_id=f.file_id and g.is_group='1') + + + diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/resources/mapper/FileServerPathMapper.xml b/neuray-pm-base-server/base-dfsfile-client/src/main/resources/mapper/FileServerPathMapper.xml new file mode 100644 index 0000000000000000000000000000000000000000..2b275e1559c665ac6177ea619717d5f50e05b960 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/resources/mapper/FileServerPathMapper.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/resources/mapper/JobDao.xml b/neuray-pm-base-server/base-dfsfile-client/src/main/resources/mapper/JobDao.xml new file mode 100644 index 0000000000000000000000000000000000000000..ad3970ee33a427c13df2055efa2392ded8dd9eea --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/resources/mapper/JobDao.xml @@ -0,0 +1,17 @@ + + + + + + select t.path + from file_manage_inf t + where t.send_flg = '0' + and (sysdate - nvl(create_time, sysdate)) * 24 > 24 + + + + delete from file_manage_inf t + where t.send_flg = '0' + and (sysdate - nvl(create_time, sysdate)) * 24 > 24 + + diff --git a/neuray-pm-base-server/base-dfsfile-client/src/main/resources/templates/fileTable.html b/neuray-pm-base-server/base-dfsfile-client/src/main/resources/templates/fileTable.html new file mode 100644 index 0000000000000000000000000000000000000000..70785d9d9765315ec4e7eabc9d10d132e1b70433 --- /dev/null +++ b/neuray-pm-base-server/base-dfsfile-client/src/main/resources/templates/fileTable.html @@ -0,0 +1,54 @@ + + + + 文件分页列表 + + + + + +       + + + + + + +       + + + + + + + + + 文件名字 + 文件后缀 + 文件服务器路径 + 文件状态 + 操作 + + + + + + + + + + + 普通文件下载 + + + 加密文件下载 + + + + + + + + + + \ No newline at end of file diff --git a/neuray-pm-base-server/pom.xml b/neuray-pm-base-server/pom.xml index 506533839e066b3a081e286357d3f3f71dea82eb..45d13284a11a207b1853471e214331cee2445b88 100644 --- a/neuray-pm-base-server/pom.xml +++ b/neuray-pm-base-server/pom.xml @@ -16,6 +16,7 @@ base-gateway base-center base-code-generator + base-dfsfile-client diff --git a/neuray-pm-common/src/main/java/com/gitee/neuray/security/common/vo/FileInfoVO.java b/neuray-pm-common/src/main/java/com/gitee/neuray/security/common/vo/FileInfoVO.java new file mode 100644 index 0000000000000000000000000000000000000000..47be32d097b1448436465006edce3d3a2e378b0a --- /dev/null +++ b/neuray-pm-common/src/main/java/com/gitee/neuray/security/common/vo/FileInfoVO.java @@ -0,0 +1,49 @@ +package com.gitee.neuray.security.common.vo; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Data; + +/** + * @author zhhongyu + * fastdfs上传文件后返回文件基本信息实体类 + */ +@Data +@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) +public class FileInfoVO { + /** + * 附件id + */ + private String fileId; + /** + * 附件名称 + */ + private String fileName; + /** + * 文件后缀名 + */ + private String fileExt; + /** + * 文件大小 + */ + private Double fileSize; + /** + * 附件转码为可读取的路径 + */ + private String readPath; + /** + * 文件在fast服务全路径 + */ + private String fullPath; + /** + * 文件分块时,成功上传到服务器的块数 + */ + private String isSuccessNo; + /** + * 下一块 + */ + private String nextNo; + /** + * 总块数 + */ + private String totalSize; +}
+ 普通文件下载 +
+ 加密文件下载 +