.gitignore
@@ -9,3 +9,11 @@ # Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties` # should NOT be excluded as they contain compiler settings and other important # information for Eclipse / Flash Builder. /.idea/ /screen-api/target/ /screen-common/target/ /screen-manage/target/ /.idea/ myBatisPlusGenerator/src/test/ screen-common/src/main/resources/ screen-manage/src/test/ moral.iml
New file @@ -0,0 +1,2 @@ <?xml version="1.0" encoding="UTF-8"?> <module type="JAVA_MODULE" version="4" /> myBatisPlusGenerator/pom.xml
New file @@ -0,0 +1,66 @@ <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>screen</artifactId> <groupId>org.moral</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>myBatisPlusGenerator</artifactId> <dependencies> <!--lombok工具--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!--mybatis-plus--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.3.2</version> </dependency> <!--代码生成器--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.3.2</version> </dependency> <!-- velocity 模板引擎, 默认 --> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>2.0</version> </dependency> <!-- freemarker 模板引擎 --> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.23</version> </dependency> <!--mysql依赖--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <!--连接池--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.5</version> </dependency> </dependencies> </project> myBatisPlusGenerator/src/main/java/com/moral/CodeGenerator.java
New file @@ -0,0 +1,134 @@ package com.moral; import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException; import com.baomidou.mybatisplus.core.toolkit.StringPool; import com.baomidou.mybatisplus.generator.AutoGenerator; import com.baomidou.mybatisplus.generator.InjectionConfig; import com.baomidou.mybatisplus.generator.config.*; import com.baomidou.mybatisplus.generator.config.po.TableInfo; import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine; import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class CodeGenerator { /** * <p> * 读取控制台内容 * </p> */ public static String scanner(String tip) { Scanner scanner = new Scanner(System.in); StringBuilder help = new StringBuilder(); help.append("请输入" + tip + ":"); System.out.println(help.toString()); if (scanner.hasNext()) { String ipt = scanner.next(); if (StringUtils.isNotEmpty(ipt)) { return ipt; } } throw new MybatisPlusException("请输入正确的" + tip + "!"); } //运行,填数据库表名开始生成代码 public static void main(String[] args) { // 代码生成器 AutoGenerator mpg = new AutoGenerator(); // 全局配置 GlobalConfig gc = new GlobalConfig(); //String projectPath = System.getProperty("user.dir"); String projectPath="E:\\workspace\\moral\\screen-api"; gc.setOutputDir(projectPath + "/src/main/java"); gc.setAuthor("moral"); gc.setOpen(false); // service 命名方式 gc.setServiceName("%sService"); // service impl 命名方式 gc.setServiceImplName("%sServiceImpl"); // 自定义文件命名,注意 %s 会自动填充表实体属性! gc.setMapperName("%sMapper"); gc.setXmlName("%sMapper"); gc.setFileOverride(true); gc.setActiveRecord(true); // XML 二级缓存 gc.setEnableCache(false); // XML ResultMap gc.setBaseResultMap(true); // XML columList gc.setBaseColumnList(false); // gc.setSwagger2(true); 实体属性 Swagger2 注解 mpg.setGlobalConfig(gc); // 数据源配置 DataSourceConfig dsc = new DataSourceConfig(); dsc.setUrl("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC"); dsc.setDriverName("com.mysql.cj.jdbc.Driver"); dsc.setUsername("root"); dsc.setPassword("123456"); mpg.setDataSource(dsc); // 包配置 PackageConfig pc = new PackageConfig(); pc.setParent("com.moral.api"); pc.setEntity("entity"); pc.setService("service"); pc.setServiceImpl("service.impl"); pc.setController("controller"); mpg.setPackageInfo(pc); // 自定义配置 InjectionConfig cfg = new InjectionConfig() { @Override public void initMap() { // to do nothing } }; // 如果模板引擎是 freemarker String templatePath = "/templates/mapper.xml.ftl"; // 如果模板引擎是 velocity // String templatePath = "/templates/mapper.xml.vm"; // 自定义输出配置 List<FileOutConfig> focList = new ArrayList<>(); // 自定义配置会被优先输出 focList.add(new FileOutConfig(templatePath) { @Override public String outputFile(TableInfo tableInfo) { // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!! String moduleName = pc.getModuleName() == null ? "" : pc.getModuleName(); return projectPath + "/src/main/resources/mapper/" + moduleName + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT + "xml"; } }); cfg.setFileOutConfigList(focList); mpg.setCfg(cfg); // 配置模板 TemplateConfig templateConfig = new TemplateConfig(); templateConfig.setController(""); templateConfig.setXml(null); mpg.setTemplate(templateConfig); // 策略配置 StrategyConfig strategy = new StrategyConfig(); strategy.setNaming(NamingStrategy.underline_to_camel); strategy.setColumnNaming(NamingStrategy.underline_to_camel); strategy.setEntityLombokModel(true); strategy.setRestControllerStyle(true); //strategy.setInclude(scanner("表名,多个英文逗号分割").split(",")); strategy.setControllerMappingHyphenStyle(true); // strategy.setTablePrefix(pc.getModuleName() + "_"); mpg.setStrategy(strategy); mpg.setTemplateEngine(new FreemarkerTemplateEngine()); mpg.execute(); } } myBatisPlusGenerator/src/main/resources/templates/mapper.xml.ftl
New file @@ -0,0 +1,39 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="${package.Mapper}.${table.mapperName}"> <#if enableCache> <!-- 开启二级缓存 --> <cache type="${cacheClassName}"/> </#if> <#if baseResultMap> <!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="${package.Entity}.${entity}"> <#list table.fields as field> <#if field.keyFlag><#--生成主键排在第一位--> <id column="${field.name}" property="${field.propertyName}" /> </#if> </#list> <#list table.commonFields as field><#--生成公共字段 --> <result column="${field.name}" property="${field.propertyName}" /> </#list> <#list table.fields as field> <#if !field.keyFlag><#--生成普通字段 --> <result column="${field.name}" property="${field.propertyName}" /> </#if> </#list> </resultMap> </#if> <#if baseColumnList> <!-- 通用查询结果列 --> <sql id="Base_Column_List"> <#list table.commonFields as field> ${field.columnName}, </#list> ${table.fieldNames} </sql> </#if> </mapper> pom.xml
New file @@ -0,0 +1,108 @@ <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.moral</groupId> <artifactId>screen</artifactId> <version>1.0-SNAPSHOT</version> <modules> <module>screen-common</module> <module>screen-api</module> <module>myBatisPlusGenerator</module> <module>screen-manage</module> </modules> <packaging>pom</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.13.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <com.alibaba.version>1.2.46</com.alibaba.version> <maven-filtering.version>1.1</maven-filtering.version> <maven-common-artifact-filters.version>1.4</maven-common-artifact-filters.version> <maven-resources-plugin.version>2.6</maven-resources-plugin.version> <maven-filtering.version>1.1</maven-filtering.version> <maven-common-artifact-filters.version>1.4</maven-common-artifact-filters.version> <maven-dependency-tree.version>2.1</maven-dependency-tree.version> <maven-shared-incremental.version>1.1</maven-shared-incremental.version> <spring-web.version>4.1.6.RELEASE</spring-web.version> <com.alibaba.druid.version>1.1.5</com.alibaba.druid.version> <org.mybatis-plus.spring.boot.version>3.3.2</org.mybatis-plus.spring.boot.version> <org.projectlombok.version>1.16.18</org.projectlombok.version> <io.springfox.version>2.7.0</io.springfox.version> <swagger-bootstrap-ui.version>1.9.6</swagger-bootstrap-ui.version> <spring.kafka.version>2.2.2</spring.kafka.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>${io.springfox.version}</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>${io.springfox.version}</version> </dependency> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>swagger-bootstrap-ui</artifactId> <version>${swagger-bootstrap-ui.version}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${org.projectlombok.version}</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>${org.mybatis-plus.spring.boot.version}</version> </dependency> <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> </dependency> <dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-streams</artifactId> <version>${spring.kafka.version}</version> </dependency> <dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-clients</artifactId> <version>${spring.kafka.version}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>${com.alibaba.druid.version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> </dependencies> </project> screen-api/pom.xml
New file @@ -0,0 +1,69 @@ <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>screen</artifactId> <groupId>org.moral</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>screen-api</artifactId> <dependencies> <dependency> <groupId>org.moral</groupId> <artifactId>screen-common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> <build> <finalName>screen-api</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>${java.version}</source> <target>${java.version}</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>${maven-resources-plugin.version}</version> <dependencies> <dependency> <groupId>org.apache.maven.shared</groupId> <artifactId>maven-filtering</artifactId> <version>${maven-filtering.version}</version> </dependency> <dependency> <groupId>org.apache.maven.shared</groupId> <artifactId>maven-common-artifact-filters</artifactId> <version>${maven-common-artifact-filters.version}</version> </dependency> <dependency> <groupId>org.apache.maven.shared</groupId> <artifactId>maven-dependency-tree</artifactId> <version>${maven-dependency-tree.version}</version> </dependency> <dependency> <groupId>org.apache.maven.shared</groupId> <artifactId>maven-shared-incremental</artifactId> <version>${maven-shared-incremental.version}</version> </dependency> </dependencies> </plugin> </plugins> </build> </project> screen-api/src/main/java/com/moral/ScreenApiBootstrap.java
New file @@ -0,0 +1,40 @@ package com.moral; import com.moral.util.SpringContextUtils; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; import java.util.Arrays; @MapperScan("com.moral.api.mapper") @SpringBootApplication @EnableTransactionManagement public class ScreenApiBootstrap { public static void main(String[] args) { ApplicationContext applicationContext = SpringApplication.run(ScreenApiBootstrap.class, args); SpringContextUtils.setApplicationContext(applicationContext); } @Bean public FilterRegistrationBean<CorsFilter> corsFilter() { FilterRegistrationBean<CorsFilter> corsFilterFilterRegistrationBean = new FilterRegistrationBean<>(); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.addAllowedHeader("*"); corsConfiguration.addAllowedOrigin("*"); corsConfiguration.setAllowedMethods(Arrays.asList("POST", "PUT", "GET", "OPTIONS", "DELETE")); corsConfiguration.setAllowCredentials(true); corsConfiguration.setMaxAge(3600L); source.registerCorsConfiguration("/**", corsConfiguration); corsFilterFilterRegistrationBean.setFilter(new CorsFilter(source)); corsFilterFilterRegistrationBean.setOrder(-1); return corsFilterFilterRegistrationBean; } } screen-api/src/main/java/com/moral/api/Swagger2.java
New file @@ -0,0 +1,34 @@ package com.moral.api; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration @EnableSwagger2 public class Swagger2 { @Bean public Docket petApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.moral.api")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("大屏接口文档") .description("大屏接口文档") .version("1.0") .build(); } } screen-api/src/main/java/com/moral/api/config/datasource/DataSourceConfig.java
New file @@ -0,0 +1,23 @@ package com.moral.api.config.datasource; import com.alibaba.druid.pool.DruidDataSource; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import javax.sql.DataSource; @Configuration public class DataSourceConfig { @Primary @Bean(name = "primaryDataSource") @Qualifier("primaryDataSource") @ConfigurationProperties(prefix = "spring.datasource") public DataSource primaryDataSource(){ return new DruidDataSource(); } } screen-api/src/main/java/com/moral/api/config/kafka/KafkaConsumerConfig.java
New file @@ -0,0 +1,67 @@ package com.moral.api.config.kafka; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.common.serialization.StringDeserializer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.kafka.annotation.EnableKafka; import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; import org.springframework.kafka.config.KafkaListenerContainerFactory; import org.springframework.kafka.core.ConsumerFactory; import org.springframework.kafka.core.DefaultKafkaConsumerFactory; import org.springframework.kafka.listener.ConcurrentMessageListenerContainer; import org.springframework.kafka.listener.ContainerProperties; import java.util.HashMap; import java.util.Map; /*@Configuration @EnableKafka*/ public class KafkaConsumerConfig { @Value("${kafka.consumer.servers}") private String servers; @Value("${kafka.consumer.enable.auto.commit}") private boolean enableAutoCommit; @Value("${kafka.consumer.session.timeout}") private String sessionTimeout; @Value("${kafka.consumer.auto.commit.interval}") private String autoCommitInterval; @Value("${kafka.consumer.group.id}") private String groupId; @Value("${kafka.consumer.auto.offset.reset}") private String autoOffsetReset; @Value("${kafka.consumer.concurrency}") private int concurrency; @Bean public KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<String, String>> kafkaListenerContainerFactory() { ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>(); factory.setConsumerFactory(consumerFactory()); factory.setConcurrency(concurrency); factory.getContainerProperties().setPollTimeout(1500); factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE); /*factory.setBatchListener(true);//@KafkaListener 批量消费 每个批次数量在Kafka配置参数中设置ConsumerConfig.MAX_POLL_RECORDS_CONFIG factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE);//设置提交偏移量的方式*/ return factory; } public ConsumerFactory<String, String> consumerFactory() { return new DefaultKafkaConsumerFactory<>(consumerConfigs()); } public Map<String, Object> consumerConfigs() { Map<String, Object> propsMap = new HashMap<>(); propsMap.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, servers); propsMap.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, enableAutoCommit); propsMap.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, autoCommitInterval); propsMap.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, sessionTimeout); propsMap.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); propsMap.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); propsMap.put(ConsumerConfig.GROUP_ID_CONFIG, groupId); propsMap.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, autoOffsetReset); return propsMap; } } screen-api/src/main/java/com/moral/api/config/kafka/KafkaProducerConfig.java
New file @@ -0,0 +1,55 @@ package com.moral.api.config.kafka; import org.apache.kafka.clients.producer.ProducerConfig; import org.apache.kafka.common.serialization.StringSerializer; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.kafka.annotation.EnableKafka; import org.springframework.kafka.core.DefaultKafkaProducerFactory; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.kafka.core.ProducerFactory; import java.util.HashMap; import java.util.Map; /*@Configuration @EnableKafka*/ public class KafkaProducerConfig { @Value("${kafka.producer.servers}") private String servers; @Value("${kafka.producer.retries}") private int retries; @Value("${kafka.producer.batch.size}") private int batchSize; @Value("${kafka.producer.linger}") private int linger; @Value("${kafka.producer.buffer.memory}") private int bufferMemory; public Map<String, Object> producerConfigs() { Map<String, Object> props = new HashMap<>(); props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, servers); props.put(ProducerConfig.RETRIES_CONFIG, retries); props.put(ProducerConfig.BATCH_SIZE_CONFIG, batchSize); props.put(ProducerConfig.LINGER_MS_CONFIG, linger); props.put(ProducerConfig.BUFFER_MEMORY_CONFIG, bufferMemory); props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class); return props; } public ProducerFactory<String, String> producerFactory() { return new DefaultKafkaProducerFactory<>(producerConfigs()); } @Bean public KafkaTemplate<String, String> kafkaTemplate() { return new KafkaTemplate<String, String>(producerFactory()); } } screen-api/src/main/java/com/moral/api/config/mybatis/MybatisPlusConfig.java
New file @@ -0,0 +1,22 @@ package com.moral.api.config.mybatis; import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MybatisPlusConfig { /** * 分页插件 */ @Bean public PaginationInterceptor paginationInterceptor() { PaginationInterceptor page = new PaginationInterceptor(); return page; } } screen-api/src/main/java/com/moral/api/config/redis/RedisConfig.java
New file @@ -0,0 +1,42 @@ package com.moral.api.config.redis; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration public class RedisConfig { @Bean(name="redisTemplate") @ConditionalOnMissingBean(StringRedisTemplate.class) //此注解的作用 如果容器中没有RedisTemplate 那就注入 有就不注入了 public RedisTemplate<String,Object> stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>(); redisTemplate.setConnectionFactory(redisConnectionFactory); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); // key采用String的序列化方式 redisTemplate.setKeySerializer(stringRedisSerializer); // hash的key也采用String的序列化方式 redisTemplate.setHashKeySerializer(stringRedisSerializer); // valuevalue采用jackson序列化方式 redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); // hash的value采用jackson序列化方式 redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); redisTemplate.afterPropertiesSet(); redisTemplate.afterPropertiesSet(); return redisTemplate; } } screen-api/src/main/java/com/moral/api/constant/TopicConstants.java
New file @@ -0,0 +1,11 @@ package com.moral.api.constant; public class TopicConstants { /** * Test 主题 */ public static final String TEST_TOPIC_MESSAGE = "test_topic"; } screen-api/src/main/java/com/moral/api/controller/TestController.java
New file @@ -0,0 +1,99 @@ package com.moral.api.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.moral.api.entity.Test; import com.moral.api.service.TestService; import com.moral.constant.ResultMessage; import com.moral.redis.RedisUtil; import com.moral.util.PageResult; import io.swagger.annotations.*; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.web.bind.annotation.*; @Slf4j @Api(tags = {"大屏"}) @RestController @RequestMapping("/api") public class TestController { @Autowired private KafkaTemplate kafkaTemplate; @Autowired private TestService testService; /** * name 姓名 * email 郵箱 * mobile 手機號 */ @ApiOperation(value = "测试插入", notes = "测试插入") @RequestMapping(value = "/saveTest", method = RequestMethod.POST) public ResultMessage save() { Test test=new Test(); test.setEmail("test@qq.com"); test.setName("name"); test.setMobile("13965898745"); testService.save(test); return ResultMessage.ok(); } /** * page 當前頁 * size 每頁大小 */ @ApiOperation(value = "分頁", notes = "分頁") @ApiImplicitParams({ @ApiImplicitParam(name="page",value="當前頁數",required=true,paramType="path",dataType="Int"), @ApiImplicitParam(name="size",value="每頁大小",required=true,paramType="path",dataType="Int") }) @RequestMapping(value = "search/{page}/{size}", method = RequestMethod.GET) public ResultMessage findBypage(@PathVariable("page") Integer page, @PathVariable("size") Integer size) { log.info("page is:"+ page+" size is:"+size); //根据条件分页查询 Page<Test> userPage = testService.selectByPage(null, page, size); //封装分页返回对象 PageResult<Test> pageResult = new PageResult<>( userPage.getTotal(), userPage.getPages(),userPage.getRecords() ); //返回数据 return ResultMessage.ok(pageResult); } /** * redis測試 */ @ApiOperation(value = "redis測試", notes = "redis測試") @RequestMapping(value = "redis", method = RequestMethod.GET) public ResultMessage testRedis() { RedisUtil.set("redistest","test"); return ResultMessage.ok(RedisUtil.get("redistest")); } /** * 事務 */ @ApiOperation(value = "事務測試", notes = "事務測試") @RequestMapping(value = "saveTest", method = RequestMethod.GET) public ResultMessage saveTest() throws Exception{ testService.saveTest(); return ResultMessage.ok(); } /** * kafka測試 */ @ApiOperation(value = "kafka測試", notes = "kafka測試") @RequestMapping(value = "kafkaTest", method = RequestMethod.GET) public void kafkaTest() { kafkaTemplate.send("test_topic","test111111111111111"); } } screen-api/src/main/java/com/moral/api/entity/Test.java
New file @@ -0,0 +1,51 @@ package com.moral.api.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.extension.activerecord.Model; import com.baomidou.mybatisplus.annotation.TableId; import java.io.Serializable; import lombok.Data; import lombok.EqualsAndHashCode; /** * <p> * * </p> * * @author moral * @since 2021-03-01 */ @Data @EqualsAndHashCode(callSuper = false) public class Test extends Model<Test> { private static final long serialVersionUID = 1L; /** * 主键 */ @TableId(value = "id", type = IdType.AUTO) private Integer id; /** * 名称 */ private String name; /** * 邮箱 */ private String email; /** * 手机号 */ private String mobile; @Override protected Serializable pkVal() { return this.id; } } screen-api/src/main/java/com/moral/api/exception/BusinessException.java
New file @@ -0,0 +1,72 @@ package com.moral.api.exception; /** * @author * @site * @company * @create 2021-02-26 11:20 */ public class BusinessException extends RuntimeException { /** * 错误码 */ private String code; /** * 错误信息 */ private String msg; /** */ private static final long serialVersionUID = 1L; public BusinessException() { super(); } public BusinessException(String msg) { super(msg); this.msg = msg; } public BusinessException(Throwable t) { super(t); } public BusinessException(String msg, Throwable t) { super(msg); this.msg = msg; } public BusinessException(String code, String msg) { super(msg); this.code = code; this.msg = msg; } public BusinessException(String code, String msg, Throwable t) { super(msg, t); this.code = code; this.msg = msg; } /** * Getter method for property <tt>code</tt>. * * @return property value of code */ public String getCode() { return code; } /** * Getter method for property <tt>msg</tt>. * * @return property value of msg */ public String getMsg() { return msg; } } screen-api/src/main/java/com/moral/api/exception/GlobalExceptionHandler.java
New file @@ -0,0 +1,37 @@ package com.moral.api.exception; import com.moral.constant.Constants; import com.moral.constant.ResultMessage; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; @ControllerAdvice @ResponseBody public class GlobalExceptionHandler { /** * 处理全部异常 */ @ExceptionHandler @ResponseBody @ResponseStatus(HttpStatus.OK) public ResultMessage handleException(Exception ex) { ex.printStackTrace(); return ResultMessage.fail(Constants.CODE_OPERATION_FAILED, "请求失败"); } /** * 处理BusinessException异常 */ @ExceptionHandler({BusinessException.class}) @ResponseBody @ResponseStatus(HttpStatus.OK) public ResultMessage handleUserNotExistException(BusinessException ex) { return ResultMessage.fail(Constants.CODE_OPERATION_FAILED, "请求用户数据失败"); } } screen-api/src/main/java/com/moral/api/kafka/consumer/KafkaConsumer.java
New file @@ -0,0 +1,37 @@ package com.moral.api.kafka.consumer; import com.moral.api.constant.TopicConstants; import lombok.extern.slf4j.Slf4j; import org.apache.kafka.clients.consumer.ConsumerRecord; import org.springframework.kafka.annotation.KafkaListener; import org.springframework.kafka.support.Acknowledgment; import org.springframework.stereotype.Component; import java.util.Random; @Component @Slf4j public class KafkaConsumer { /* *//** * 这是手动提交的消费方式 * @param record * @param ack * @throws Exception *//* @KafkaListener(topics = TopicConstants.TEST_TOPIC_MESSAGE,groupId = "test") public void listenTest(ConsumerRecord<String, String> record , Acknowledgment ack) throws Exception { String msg = record.value(); System.out.println(msg); if (new Random().nextInt(100)<50){ log.info(String.format("kafka 消费消息成功---------------- listen1 topic = %s, offset = %d, value = %s ", record.topic(), record.offset(), record.value())); ack.acknowledge(); } }*/ } screen-api/src/main/java/com/moral/api/mapper/TestMapper.java
New file @@ -0,0 +1,16 @@ package com.moral.api.mapper; import com.moral.api.entity.Test; import com.baomidou.mybatisplus.core.mapper.BaseMapper; /** * <p> * Mapper 接口 * </p> * * @author moral * @since 2021-02-25 */ public interface TestMapper extends BaseMapper<Test> { } screen-api/src/main/java/com/moral/api/service/TestService.java
New file @@ -0,0 +1,25 @@ package com.moral.api.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.moral.api.entity.Test; import com.baomidou.mybatisplus.extension.service.IService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; /** * <p> * 服务类 * </p> * * @author moral * @since 2021-02-25 */ @Service @Transactional public interface TestService extends IService<Test> { Page<Test> selectByPage(Test test, Integer page, Integer size); @Transactional void saveTest() throws Exception; } screen-api/src/main/java/com/moral/api/service/impl/TestServiceImpl.java
New file @@ -0,0 +1,53 @@ package com.moral.api.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.moral.api.entity.Test; import com.moral.api.exception.BusinessException; import com.moral.api.mapper.TestMapper; import com.moral.api.service.TestService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; /** * <p> * 服务实现类 * </p> * * @author moral * @since 2021-02-25 */ @Service public class TestServiceImpl extends ServiceImpl<TestMapper, Test> implements TestService { @Autowired private TestMapper testMapper; @Override public Page<Test> selectByPage(Test test, Integer page, Integer size) { //设置分页条件 Page<Test> pageData = new Page<>(page, size); //执行分页查询 IPage<Test> users = testMapper.selectPage(pageData, new QueryWrapper<>(test)); //设置结果集到分页对象中 pageData.setRecords(users.getRecords()); //返回结果 return pageData; } @Override @Transactional public void saveTest() throws Exception{ Test t=new Test(); t.setName("aaaa"); t.setMobile("139652555"); t.setEmail("33@qq.com"); testMapper.insert(t); if ("aaaa".equals(t.getName())){ throw new BusinessException("aaaa已存在,数据将不会回滚"); } } } screen-api/src/main/resources/application-dev.yml
New file @@ -0,0 +1,101 @@ server: port: 8081 tomcat: uri-encoding: UTF-8 #最小线程数 min-spare-threads: 500 #最大线程数 max-threads: 2500 #最大链接数 max-connections: 6500 #最大等待队列长度 accept-count: 1000 spring: profiles: active: dev application: name: screen-api redis: #cluster: #nodes: 47.112.126.78:7001,47.112.126.78:7002,47.112.126.132:7003,47.112.126.132:7004,47.112.132.193:7005,47.112.132.193:7006 #password: test #timeout: 500 host: 127.0.0.1 port: 6379 password: 123456 timeout: 30000 jedis: pool: max-active: 256 max-wait: 30000 max-idle: 64 min-idle: 32 lettuce: pool: max-active: 256 max-idle: 64 max-wait: 30000 min-idle: 32 datasource: minIdle: 1 time-between-eviction-runs-millis: 60000 max-active: 20 test-while-idle: true validation-query: select 'x' filters: stat type: com.alibaba.druid.pool.DruidDataSource max-wait: 60000 url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC password: 123456 test-on-borrow: false sql-script-encoding: utf-8 pool-prepared-statements: true min-evictable-idle-time-millis: 300000 initial-size: 1 driver-class-name: com.mysql.cj.jdbc.Driver max-conn-lifetime-millis: 20 test-on-return: false username: root mybatis-plus: mapper-locations: classpath:mapper/*.xml global-config: db-config: id-type: auto field-strategy: NOT_EMPTY db-type: MYSQL configuration: map-underscore-to-camel-case: true call-setters-on-nulls: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl kafka: listener: ack-mode: manual_immediate consumer: auto: commit: interval: 100 offset: reset: latest concurrency: 3 enable: auto: commit: false group: id: test servers: 192.168.0.16:9092,192.168.0.17:9092,192.168.0.18:9092 session: timeout: 6000 topic: test_topic zookeeper: connect: 192.168.0.16:2181,192.168.0.17:2181,192.168.0.18:2181 producer: batch: size: 4096 buffer: memory: 40960 linger: 1 retries: 0 servers: 192.168.0.16:9092,192.168.0.17:9092,192.168.0.18:9092 screen-api/src/main/resources/logback-spring.xml
New file @@ -0,0 +1,56 @@ <?xml version="1.0" encoding="UTF-8"?> <configuration> <include resource="org/springframework/boot/logging/logback/defaults.xml"/> <springProperty scope="context" name="springAppName" source="spring.application.name"/> <!-- 日志在工程中的输出位置 --> <property name="LOG_FILE" value="home/moral/soft/log/${springAppName}"/> <!-- 控制台的日志输出样式 --> <property name="CONSOLE_LOG_PATTERN" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}) [%X{logseq}]{faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr([${springAppName}]){yellow} %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/> <property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{logseq}] [%thread] %X{T} [%level] %logger.%method:%line %msg%n"/> <!-- 控制台Appender --> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>INFO</level> </filter> <encoder> <pattern>${CONSOLE_LOG_PATTERN}</pattern> <charset>utf8</charset> </encoder> </appender> <!-- 日志记录Appender --> <appender name="screenApiLog" class="ch.qos.logback.classic.sift.SiftingAppender"> <discriminator> <key>taskId</key> <defaultValue>default</defaultValue> </discriminator> <sift> <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>INFO</level> </filter> <file>${LOG_FILE}/%d{yyyy-MM-dd}/${springAppName}.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <maxFileSize>30MB</maxFileSize> <fileNamePattern>${LOG_FILE}/%d{yyyy-MM-dd}/${springAppName}-%d{yyyy-MM-dd}.log%i.log</fileNamePattern> <maxHistory>30</maxHistory> </rollingPolicy> <encoder> <pattern>${FILE_LOG_PATTERN}</pattern> <charset>utf8</charset> </encoder> </appender> </sift> </appender> <root level="INFO"> <appender-ref ref="console"/> <appender-ref ref="screenApiLog"/> </root> </configuration> screen-common/pom.xml
New file @@ -0,0 +1,75 @@ <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>screen</artifactId> <groupId>org.moral</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>screen-common</artifactId> <properties> <spring-boot-starter-data-redis.version>2.1.3.RELEASE</spring-boot-starter-data-redis.version> <jedis.version>2.9.0</jedis.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>${spring-boot-starter-data-redis.version}</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>${jedis.version}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${com.alibaba.version}</version> </dependency> </dependencies> <build> <finalName>screen-common</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>${maven-resources-plugin.version}</version> <dependencies> <dependency> <groupId>org.apache.maven.shared</groupId> <artifactId>maven-filtering</artifactId> <version>${maven-filtering.version}</version> </dependency> <dependency> <groupId>org.apache.maven.shared</groupId> <artifactId>maven-common-artifact-filters</artifactId> <version>${maven-common-artifact-filters.version}</version> </dependency> <dependency> <groupId>org.apache.maven.shared</groupId> <artifactId>maven-dependency-tree</artifactId> <version>${maven-dependency-tree.version}</version> </dependency> <dependency> <groupId>org.apache.maven.shared</groupId> <artifactId>maven-shared-incremental</artifactId> <version>${maven-shared-incremental.version}</version> </dependency> </dependencies> </plugin> </plugins> </build> </project> screen-common/src/main/java/com/moral/constant/Constants.java
New file @@ -0,0 +1,29 @@ package com.moral.constant; /** * 通用常量信息 */ public class Constants { /** * 操作成功 */ public static final String MSG_OPERATION_SUCCESS = "操作成功!"; /** * 操作失败 */ public static final String MSG_OPERATION_FAILED = "操作失败!"; /** * 操作成功code */ public static final int CODE_OPERATION_SUCCESS = 0; /** * 操作失败code */ public static final int CODE_OPERATION_FAILED = -1; } screen-common/src/main/java/com/moral/constant/ResultMessage.java
New file @@ -0,0 +1,130 @@ package com.moral.constant; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import java.util.HashMap; @ApiModel("返回值封装类") public class ResultMessage<T> { /** * 返回值 */ @ApiModelProperty("code") private int code; /** * 返回信息 */ @ApiModelProperty("msg") private String msg; /** * 返回数据 */ @ApiModelProperty("返回对象") private T data; public static ResultMessage ok() { ResultMessage resultMessage = new ResultMessage(); resultMessage.setCode(Constants.CODE_OPERATION_SUCCESS); resultMessage.setMessage(Constants.MSG_OPERATION_SUCCESS); resultMessage.setData(new HashMap<>()); return resultMessage; } public static ResultMessage ok(String msg) { ResultMessage resultMessage = new ResultMessage(); resultMessage.setCode(Constants.CODE_OPERATION_SUCCESS); resultMessage.setMessage(msg); resultMessage.setData(new HashMap<>()); return resultMessage; } public static ResultMessage ok(int code, String msg) { ResultMessage resultMessage = new ResultMessage(); resultMessage.setCode(code); resultMessage.setMessage(msg); resultMessage.setData(new HashMap<>()); return resultMessage; } public static <T> ResultMessage<T> ok(int code, T data) { ResultMessage resultMessage = new ResultMessage(); resultMessage.setCode(code); resultMessage.setData(data == null? new HashMap<>():data); return resultMessage; } public static <T> ResultMessage<T> ok(T data) { ResultMessage resultMessage = new ResultMessage(); resultMessage.setCode(Constants.CODE_OPERATION_SUCCESS); resultMessage.setMessage(Constants.MSG_OPERATION_SUCCESS); resultMessage.setData(data == null ?new HashMap<>():data); return resultMessage; } public static <T> ResultMessage<T> ok(int code, String msg, T data) { ResultMessage resultMessage = new ResultMessage(); resultMessage.setCode(code); resultMessage.setMessage(msg); resultMessage.setData(data == null?new HashMap<>():data); return resultMessage; } public static ResultMessage fail() { ResultMessage resultMessage = new ResultMessage(); resultMessage.setCode(Constants.CODE_OPERATION_FAILED); resultMessage.setMessage(Constants.MSG_OPERATION_FAILED); resultMessage.setData(new HashMap<>()); return resultMessage; } public static ResultMessage fail(String msg) { ResultMessage resultMessage = new ResultMessage(); resultMessage.setCode(Constants.CODE_OPERATION_FAILED); resultMessage.setMessage(msg); resultMessage.setData(new HashMap<>()); return resultMessage; } public static ResultMessage fail(int code, String msg) { ResultMessage resultMessage = new ResultMessage(); resultMessage.setCode(code); resultMessage.setMessage(msg); resultMessage.setData(new HashMap<>()); return resultMessage; } public static <T> ResultMessage<T> fail(T data) { ResultMessage resultMessage = new ResultMessage(); resultMessage.setCode(Constants.CODE_OPERATION_FAILED); resultMessage.setMessage(Constants.MSG_OPERATION_FAILED); resultMessage.setData(data == null ?new HashMap<>():data); return resultMessage; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMessage() { return msg; } public void setMessage(String message) { this.msg = message; } public T getData() { return data; } public void setData(T data) { this.data = data; } } screen-common/src/main/java/com/moral/redis/RedisUtil.java
New file @@ -0,0 +1,380 @@ package com.moral.redis; import com.moral.util.SpringContextUtils; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.util.CollectionUtils; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; public final class RedisUtil { @SuppressWarnings("rawtypes") private static RedisTemplate redisTemplate = SpringContextUtils.getBeanByName("redisTemplate"); // =============================common============================ /** * 设置过期时间内的key * * @param: key * @param: time * @return: boolean * @author: wuqp * @date: 2021/02/24 9:46 */ public static boolean expire(String key, long time) { try { if (time > 0) { redisTemplate.expire(key, time, TimeUnit.SECONDS); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 获取过期时间内的key * * @param: key * @param: time * @return: long * @author: wuqp * @date: 2021/02/24 9:46 */ public long getExpire(String key) { return redisTemplate.getExpire(key, TimeUnit.SECONDS); } /** * 获取key * * @param: key * @return: boolean * @author: wuqp * @date: 2021/02/24 9:46 */ public boolean hasKey(String key) { try { return redisTemplate.hasKey(key); } catch (Exception e) { e.printStackTrace(); return false; } } /** * 删除缓存 * * @param: key * @param: time * @return: boolean * @author: wuqp * @date: 2021/02/24 9:46 */ @SuppressWarnings("unchecked") public void del(String... key) { if (key != null && key.length > 0) { if (key.length == 1) { redisTemplate.delete(key[0]); } else { redisTemplate.delete(CollectionUtils.arrayToList(key)); } } } // ============================String============================= /** * 获取string类型的缓存 * * @param: key * @param: time * @return: Object * @author: wuqp * @date: 2021/02/24 9:46 */ public static Object get(String key) { return key == null ? null : redisTemplate.opsForValue().get(key); } /** * 设置string类型的缓存 * * @param: key * @param: value * @return: boolean * @author: wuqp * @date: 2021/02/24 9:46 */ public static boolean set(String key, Object value) { try { redisTemplate.opsForValue().set(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 设置string类型的缓存与过期时间 * * @param: key * @param: value * @param: time * @return: boolean * @author: wuqp * @date: 2021/02/24 9:46 */ public static boolean set(String key, Object value, long time) { try { if (time > 0) { redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); } else { set(key, value); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } // ================================Map================================= public Object hget(String key, String item) { return redisTemplate.opsForHash().get(key, item); } public Map<Object, Object> hmget(String key) { return redisTemplate.opsForHash().entries(key); } public boolean hmset(String key, Map<String, Object> map) { try { redisTemplate.opsForHash().putAll(key, map); return true; } catch (Exception e) { e.printStackTrace(); return false; } } public boolean hmset(String key, Map<String, Object> map, long time) { try { redisTemplate.opsForHash().putAll(key, map); if (time > 0) { expire(key, time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } public boolean hset(String key, String item, Object value) { try { redisTemplate.opsForHash().put(key, item, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } public boolean hset(String key, String item, Object value, long time) { try { redisTemplate.opsForHash().put(key, item, value); if (time > 0) { expire(key, time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } public void hdel(String key, Object... item) { redisTemplate.opsForHash().delete(key, item); } public boolean hHasKey(String key, String item) { return redisTemplate.opsForHash().hasKey(key, item); } public double hincr(String key, String item, double by) { return redisTemplate.opsForHash().increment(key, item, by); } public double hdecr(String key, String item, double by) { return redisTemplate.opsForHash().increment(key, item, -by); } // ============================set============================= public Set<Object> sGet(String key) { try { return redisTemplate.opsForSet().members(key); } catch (Exception e) { e.printStackTrace(); return null; } } public boolean sHasKey(String key, Object value) { try { return redisTemplate.opsForSet().isMember(key, value); } catch (Exception e) { e.printStackTrace(); return false; } } public long sSet(String key, Object... values) { try { return redisTemplate.opsForSet().add(key, values); } catch (Exception e) { e.printStackTrace(); return 0; } } public long sSetAndTime(String key, long time, Object... values) { try { Long count = redisTemplate.opsForSet().add(key, values); if (time > 0) expire(key, time); return count; } catch (Exception e) { e.printStackTrace(); return 0; } } public long sGetSetSize(String key) { try { return redisTemplate.opsForSet().size(key); } catch (Exception e) { e.printStackTrace(); return 0; } } public long setRemove(String key, Object... values) { try { Long count = redisTemplate.opsForSet().remove(key, values); return count; } catch (Exception e) { e.printStackTrace(); return 0; } } // ===============================list================================= public List<Object> lGet(String key, long start, long end) { try { return redisTemplate.opsForList().range(key, start, end); } catch (Exception e) { e.printStackTrace(); return null; } } public long lGetListSize(String key) { try { return redisTemplate.opsForList().size(key); } catch (Exception e) { e.printStackTrace(); return 0; } } public Object lGetIndex(String key, long index) { try { return redisTemplate.opsForList().index(key, index); } catch (Exception e) { e.printStackTrace(); return null; } } public boolean lSet(String key, Object value) { try { redisTemplate.opsForList().rightPush(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } public boolean lSet(String key, Object value, long time) { try { redisTemplate.opsForList().rightPush(key, value); if (time > 0) expire(key, time); return true; } catch (Exception e) { e.printStackTrace(); return false; } } public boolean lSet(String key, List<Object> value) { try { redisTemplate.opsForList().rightPushAll(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } public boolean lSet(String key, List<Object> value, long time) { try { redisTemplate.opsForList().rightPushAll(key, value); if (time > 0) expire(key, time); return true; } catch (Exception e) { e.printStackTrace(); return false; } } public boolean lUpdateIndex(String key, long index, Object value) { try { redisTemplate.opsForList().set(key, index, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } public long lRemove(String key, long count, Object value) { try { Long remove = redisTemplate.opsForList().remove(key, count, value); return remove; } catch (Exception e) { e.printStackTrace(); return 0; } } public Set<String> keys(String pattern) { try { Set<String> set = redisTemplate.keys(pattern); return set; } catch (Exception e) { e.printStackTrace(); return null; } } } screen-common/src/main/java/com/moral/util/DateUtils.java
New file @@ -0,0 +1,1267 @@ package com.moral.util; import org.springframework.util.StringUtils; import java.math.BigDecimal; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.*; public class DateUtils { /** 日期格式(yyyy-MM-dd) */ public static final String yyyy_MM_dd_EN = "yyyy-MM-dd"; /** 日期格式(yyyy/MM/dd) */ public static final String yyyy_MM_dd_decline = "yyyy/MM/dd"; /** 日期格式(yyyyMMdd) */ public static final String yyyyMMdd_EN = "yyyyMMdd"; /** 日期格式(yyyy-MM) */ public static final String yyyy_MM_EN = "yyyy-MM"; /** 日期格式(yyyyMM) */ public static final String yyyyMM_EN = "yyyyMM"; /** 日期格式(yyyy-MM-dd HH:mm:ss) */ public static final String yyyy_MM_dd_HH_mm_ss_EN = "yyyy-MM-dd HH:mm:ss"; /** 日期格式(yyyy-MM-dd HH:mm:ss.S) */ public static final String yyyy_MM_dd_HH_mm_ss_S_EN = "yyyy-MM-dd HH:mm:ss.S"; /** 日期格式(yyyyMMddHHmmss) */ public static final String yyyyMMddHHmmss_EN = "yyyyMMddHHmmss"; /** 日期格式(yyyy年MM月dd日) */ public static final String yyyy_MM_dd_CN = "yyyy年MM月dd日"; /** 日期格式(yyyy年MM月dd日HH时mm分ss秒) */ public static final String yyyy_MM_dd_HH_mm_ss_CN = "yyyy年MM月dd日HH时mm分ss秒"; /** 日期格式(yyyy年MM月dd日HH时mm分) */ public static final String yyyy_MM_dd_HH_mm_CN = "yyyy年MM月dd日HH时mm分"; /** 北京boss订购接口报文头日期格式 */ public static final String BJBOSS_DATE = "yyyy-MM-dd'T'HH:mm:ss'Z'"; /** 日期格式(HH:mm:ss) */ public static final String HH_mm_ss_EN = "HH:mm:ss"; /** DateFormat缓存 */ private static Map<String, DateFormat> dateFormatMap = new HashMap<String, DateFormat>(); /** * 获取DateFormat * * @param formatStr * @return */ public static DateFormat getDateFormat(String formatStr) { DateFormat df = dateFormatMap.get(formatStr); if (df == null) { df = new SimpleDateFormat(formatStr); dateFormatMap.put(formatStr, df); } return df; } public static Date getDate() { return Calendar.getInstance().getTime(); } /** * 按照默认formatStr的格式,转化dateTimeStr为Date类型 dateTimeStr必须是formatStr的形式 * * @param dateTimeStr * @param formatStr * @return */ public static Date getDate(String dateTimeStr, String formatStr) { try { if (dateTimeStr == null || dateTimeStr.equals("")) { return null; } DateFormat sdf = getDateFormat(formatStr); return sdf.parse(dateTimeStr); } catch (ParseException e) { throw new RuntimeException(e); } } /** * 转化dateTimeStr为Date类型 * * @param dateTimeStr * @return */ public static Date convertDate(String dateTimeStr) { try { if (dateTimeStr == null || dateTimeStr.equals("")) { return null; } DateFormat sdf = getDateFormat(yyyy_MM_dd_EN); Date d = sdf.parse(dateTimeStr); return d; } catch (ParseException e) { throw new RuntimeException(e); } } /** * 按照默认显示日期时间的格式"yyyy-MM-dd",转化dateTimeStr为Date类型 dateTimeStr必须是"yyyy-MM-dd"的形式 * * @param dateTimeStr * @return */ public static Date getDate(String dateTimeStr) { return getDate(dateTimeStr, yyyy_MM_dd_EN); } /** * 将YYYYMMDD转换成Date日期 * * @param date * @return * @throws Exception */ public static Date transferDate(String date) throws Exception { if (date == null || date.length() < 1) return null; if (date.length() != 8) throw new Exception("日期格式错误"); String con = "-"; String yyyy = date.substring(0, 4); String mm = date.substring(4, 6); String dd = date.substring(6, 8); int month = Integer.parseInt(mm); int day = Integer.parseInt(dd); if (month < 1 || month > 12 || day < 1 || day > 31) throw new Exception("日期格式错误"); String str = yyyy + con + mm + con + dd; return getDate(str, yyyy_MM_dd_EN); } /** * 将Date转换成字符串“yyyy-mm-dd hh:mm:ss”的字符串 * * @param date * @return */ public static String dateToDateString(Date date) { return dateToDateString(date, yyyy_MM_dd_HH_mm_ss_EN); } /** * 将Date转换成字符串“yyyymmddhhmmss”的字符串 * * @param date * @return */ public static String dateToDateFullString(Date date) { if (null == date) return null; else return dateToDateString(date, yyyyMMddHHmmss_EN); } /** * 将Date转换成formatStr格式的字符串 * * @param date * @param formatStr * @return */ public static String dateToDateString(Date date, String formatStr) { DateFormat df = getDateFormat(formatStr); return df.format(date); } /** * 将String转换成formatStr格式的字符串 * * @param date * @param formatStr1 * @param formatStr2 * @return */ public static String stringToDateString(String date, String formatStr1, String formatStr2) { Date d = getDate(date, formatStr1); DateFormat df = getDateFormat(formatStr2); return df.format(d); } /** * 获取当前日期yyyy-MM-dd的形式 * * @return */ public static String getCurDate() { return dateToDateString(new Date(), yyyy_MM_dd_EN); } /** * 获取当前日期 * * @return */ public static String getCurDate(String formatStr) { return dateToDateString(new Date(), formatStr); } /** * 获取当前日期yyyy年MM月dd日的形式 * * @return */ public static String getCurCNDate() { return dateToDateString(new Date(), yyyy_MM_dd_CN); } /** * 获取当前日期时间yyyy-MM-dd HH:mm:ss的形式 * * @return */ public static String getCurDateTime() { return dateToDateString(new Date(), yyyy_MM_dd_HH_mm_ss_EN); } /** * 获取当前日期时间yyyy年MM月dd日HH时mm分ss秒的形式 * * @return */ public static String getCurZhCNDateTime() { return dateToDateString(new Date(), yyyy_MM_dd_HH_mm_ss_CN); } /** * 比较两个"yyyy-MM-dd HH:mm:ss"格式的日期,之间相差多少毫秒,time2-time1 * * @param time1 * @param time2 * @return */ public static long compareDateStr(String time1, String time2) { Date d1 = getDate(time1); Date d2 = getDate(time2); return d2.getTime() - d1.getTime(); } /** * 比较任意格式时间相差毫秒数 * * @param time1 * @param time2 * @param format * @return */ public static long compareDateStr(String time1, String time2, String format) { Date d1 = getDate(time1, format); Date d2 = getDate(time2, format); return d2.getTime() - d1.getTime(); } /** * 比较起始时间与当前时间相差毫秒数 * * @param time * @param format * @return */ public static long compareDateNow(String time, String format) { Date date = getDate(time, format); return new Date().getTime() - date.getTime(); } /** * 比较两个"yyyy-MM-dd HH:mm:ss"格式的日期,之间相差多少毫秒,time2-time1 * * @param time1 * @param time2 * @return */ public static long compareDateStr(Date time1, Date time2) { return time2.getTime() - time1.getTime(); } /** * nows时间大于date时间 为true * * @param nows * @param date * @return */ public static boolean isTimeBefor(Date nows, Date date) { long hous = nows.getTime() - date.getTime(); if (hous > 0) { return true; } else { return false; } } /** * 将小时数换算成返回以毫秒为单位的时间 * * @param hours * @return */ public static long getMicroSec(BigDecimal hours) { BigDecimal bd; bd = hours.multiply(new BigDecimal(3600 * 1000)); return bd.longValue(); } /** * 获取当前日期years年后的一个(formatStr)的字符串 * * @param years * @param formatStr * @return */ public static String getDateStringOfYear(int years, String formatStr) { Calendar now = Calendar.getInstance(TimeZone.getDefault()); now.setTime(new Date()); now.add(Calendar.YEAR, years); return dateToDateString(now.getTime(), formatStr); } /** * 获取当前日期mon月后的一个(formatStr)的字符串 * * @param months * @param formatStr * @return */ public static String getDateStringOfMon(int months, String formatStr) { Calendar now = Calendar.getInstance(TimeZone.getDefault()); now.setTime(new Date()); now.add(Calendar.MONTH, months); return dateToDateString(now.getTime(), formatStr); } /** * 获取当前日期days天后的一个(formatStr)的字符串 * * @param days * @param formatStr * @return */ public static String getDateStringOfDay(int days, String formatStr) { Calendar now = Calendar.getInstance(TimeZone.getDefault()); now.setTime(new Date()); now.add(Calendar.DATE, days); return dateToDateString(now.getTime(), formatStr); } /** * 判断日期是否是今天 * * @param date * @return */ public static int theDateIsToday(String date, String format) { String theDate = stringToDateString(date, format, yyyyMMdd_EN); String today = getDateStringOfDay(0, yyyyMMdd_EN); if (theDate.equals(today)) { return 1; } else { return 0; } } /** * 获取当前日期hours小时后的一个(formatStr)的字符串 * * @param hours * @param formatStr * @return */ public static String getDateStringOfHour(int hours, String formatStr) { Calendar now = Calendar.getInstance(TimeZone.getDefault()); now.setTime(new Date()); now.add(Calendar.HOUR_OF_DAY, hours); return dateToDateString(now.getTime(), formatStr); } /** * 获取指定日期mon月后的一个(formatStr)的字符串 * * @param date * @param mon * @param formatStr * @return */ public static String getDateOfMon(String date, int mon, String formatStr) { Calendar now = Calendar.getInstance(TimeZone.getDefault()); now.setTime(getDate(date, formatStr)); now.add(Calendar.MONTH, mon); return dateToDateString(now.getTime(), formatStr); } /** * 获取指定日期day天后的一个(formatStr)的字符串 * * @param date * @param day * @param formatStr * @return */ public static String getDateOfDay(String date, int day, String formatStr) { Calendar now = Calendar.getInstance(TimeZone.getDefault()); now.setTime(getDate(date, formatStr)); now.add(Calendar.DATE, day); return dateToDateString(now.getTime(), formatStr); } public static Date getDate(Date beginDate, int ds) { if (ds == 0) return new Date(); try { SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd"); Calendar date = Calendar.getInstance(); date.setTime(beginDate); date.set(Calendar.DATE, date.get(Calendar.DATE) - ds); Date endDate = dft.parse(dft.format(date.getTime())); return endDate; } catch (ParseException e) { e.printStackTrace(); } return new Date(); } public static String getAfterNDays(Date date, int n, String formateStr) { SimpleDateFormat sdf = new SimpleDateFormat(formateStr); Calendar calendar = new GregorianCalendar(); calendar.setTime(date); calendar.add(Calendar.DATE, n); return sdf.format(calendar.getTime()); } /** * 获取指定日期mins分钟后的一个(formatStr)的字符串 * * @param date * @param mins * @param formatStr * @return */ public static String getDateOfMin(String date, int mins, String formatStr) { Calendar now = Calendar.getInstance(TimeZone.getDefault()); now.setTime(getDate(date, formatStr)); now.add(Calendar.SECOND, mins * 60); return dateToDateString(now.getTime(), formatStr); } /** * 获取指定日期mins分钟后的一个日期 * * @param date * @param mins * @return */ public static Date getDateOfMin(Date date, int mins) { Calendar now = Calendar.getInstance(TimeZone.getDefault()); now.setTime(date); now.add(Calendar.SECOND, mins * 60); return now.getTime(); } /** * 获取当前日期mins分钟后的一个(formatStr)的字符串 * * @param mins * @param formatStr * @return */ public static String getDateStringOfMin(int mins, String formatStr) { Calendar now = Calendar.getInstance(TimeZone.getDefault()); now.setTime(new Date()); now.add(Calendar.MINUTE, mins); return dateToDateString(now.getTime(), formatStr); } /** * 获取当前日期mins分钟后的一个日期 * * @param mins * @return */ public static Date getDateOfMin(int mins) { Calendar now = Calendar.getInstance(TimeZone.getDefault()); now.setTime(new Date()); now.add(Calendar.MINUTE, mins); return now.getTime(); } /** * 获取当前日期sec秒后的一个(formatStr)的字符串 * * @param sec * @param formatStr * @return */ public static String getDateStringOfSec(int sec, String formatStr) { Calendar now = Calendar.getInstance(TimeZone.getDefault()); now.setTime(new Date()); now.add(Calendar.SECOND, sec); return dateToDateString(now.getTime(), formatStr); } /** * 获得指定日期月份的天数 * * @return */ public static int getMonthDay(Date date) { Calendar c = Calendar.getInstance(); c.setTime(date); return c.getActualMaximum(Calendar.DAY_OF_MONTH); } /** * 获得系统当前月份的天数 * * @return */ public static int getCurentMonthDay() { Date date = Calendar.getInstance().getTime(); return getMonthDay(date); } /** * 获得指定日期月份的天数 yyyy-mm-dd * * @return */ public static int getMonthDay(String date) { Date strDate = getDate(date, yyyy_MM_dd_EN); return getMonthDay(strDate); } /** * 获取19xx,20xx形式的年 * * @param d * @return */ public static int getYear(Date d) { Calendar now = Calendar.getInstance(TimeZone.getDefault()); now.setTime(d); return now.get(Calendar.YEAR); } /** * 获取月份,1-12月 * * @param d * @return */ public static int getMonth(Date d) { Calendar now = Calendar.getInstance(TimeZone.getDefault()); now.setTime(d); return now.get(Calendar.MONTH) + 1; } /** * 获取xxxx-xx-xx的日 * * @param d * @return */ public static int getDay(Date d) { Calendar now = Calendar.getInstance(TimeZone.getDefault()); now.setTime(d); return now.get(Calendar.DAY_OF_MONTH); } /** * 获取Date中的小时(24小时) * * @param d * @return */ public static int getHour(Date d) { Calendar now = Calendar.getInstance(TimeZone.getDefault()); now.setTime(d); return now.get(Calendar.HOUR_OF_DAY); } /** * 获取Date中的分钟 * * @param d * @return */ public static int getMin(Date d) { Calendar now = Calendar.getInstance(TimeZone.getDefault()); now.setTime(d); return now.get(Calendar.MINUTE); } /** * 获取Date中的秒 * * @param d * @return */ public static int getSecond(Date d) { Calendar now = Calendar.getInstance(TimeZone.getDefault()); now.setTime(d); return now.get(Calendar.SECOND); } /** * 得到本周周一 * * @return yyyy-MM-dd */ public static String getMondayOfThisWeek() { Calendar c = Calendar.getInstance(); int day_of_week = c.get(Calendar.DAY_OF_WEEK) - 1; if (day_of_week == 0) day_of_week = 7; c.add(Calendar.DATE, -day_of_week + 1); return dateToDateString(c.getTime(), yyyy_MM_dd_EN); } /** * 得到本周周日 * * @return yyyy-MM-dd */ public static String getSundayOfThisWeek() { Calendar c = Calendar.getInstance(); int day_of_week = c.get(Calendar.DAY_OF_WEEK) - 1; if (day_of_week == 0) day_of_week = 7; c.add(Calendar.DATE, -day_of_week + 7); return dateToDateString(c.getTime()); } /** * 得到本周周(*) * * @return yyyy-MM-dd */ public static String getDayOfThisWeek(int num) { Calendar c = Calendar.getInstance(); int day_of_week = c.get(Calendar.DAY_OF_WEEK) - 1; if (day_of_week == 0) day_of_week = 7; c.add(Calendar.DATE, -day_of_week + num); return dateToDateString(c.getTime(), yyyy_MM_dd_EN); } /** * 得到本月指定天 * * @return yyyy-MM-dd */ public static String getDayOfThisMoon(String num) { String date = dateToDateString(new Date(), yyyy_MM_EN); date = date + "-" + num; return date; } /** * 获取两个日期相差的天数 * * @param beginDate * @param endDate * @return */ public static long getQuotByDays(String beginDate, String endDate) { long quot = 0; DateFormat df = getDateFormat(yyyy_MM_dd_EN); try { Date d1 = df.parse(beginDate); Date d2 = df.parse(endDate); quot = d2.getTime() - d1.getTime(); quot = quot / 1000 / 60 / 60 / 24; } catch (ParseException e) { throw new RuntimeException(e); } return quot; } /** * 根据日期追加的天数,得到一个新日期 * * @param date * @param days * @return */ public static String getDateAddDay(String date, int days, String format) { DateFormat df = getDateFormat(format); try { Calendar cal = Calendar.getInstance(); cal.setTime(df.parse(date)); cal.set(Calendar.DAY_OF_YEAR, cal.get(Calendar.DAY_OF_YEAR) + days); date = df.format(cal.getTime()); } catch (ParseException e) { throw new RuntimeException(e); } return date; } /** * 获取当前月的最后一天 * * @return */ public static Date getLastDayOfCurrMonth() { Calendar cal = Calendar.getInstance(); cal.add(Calendar.MONTH, 1); cal.set(Calendar.DAY_OF_MONTH, 0); return cal.getTime(); } /** * 根据日期追加的天数,得到一个新日期 * * @param date * @param m * @return */ public static String getDateAddMonth(String date, int m) { DateFormat df = getDateFormat(yyyyMM_EN); try { Calendar cal = Calendar.getInstance(); cal.setTime(df.parse(date)); cal.add(Calendar.MONTH, m); date = df.format(cal.getTime()); } catch (ParseException e) { throw new RuntimeException(e); } return date; } /** * 获取指定年月的第一天 * * @param year * @param month * @return */ public static String getFirstDayOfMonth(int year, int month) { Calendar cal = Calendar.getInstance(); // 设置年份 cal.set(Calendar.YEAR, year); // 设置月份 cal.set(Calendar.MONTH, month - 1); // 获取某月最小天数 int lastDay = cal.getActualMinimum(Calendar.DAY_OF_MONTH); // 设置日历中月份的最大天数 cal.set(Calendar.DAY_OF_MONTH, lastDay); // 格式化日期 DateFormat df = getDateFormat(yyyy_MM_dd_EN); return df.format(cal.getTime()); } /** * 获取指定年月的第一天 * * @param year * @param month * @return */ public static String getLastDayOfMonth(int year, int month) { Calendar cal = Calendar.getInstance(); // 设置年份 cal.set(Calendar.YEAR, year); // 设置月份 cal.set(Calendar.MONTH, month - 1); // 获取某月最大天数 int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH); // 设置日历中月份的最大天数 cal.set(Calendar.DAY_OF_MONTH, lastDay); // 格式化日期 DateFormat df = getDateFormat(yyyy_MM_dd_EN); return df.format(cal.getTime()); } /** * 获取昨天日期 * * @param date * @return * @throws ParseException */ public static String getYesterday(Date date) throws ParseException { DateFormat df = getDateFormat(yyyy_MM_dd_EN); Calendar calendar = Calendar.getInstance(); calendar.setTime(df.parse(df.format(date))); calendar.add(Calendar.DAY_OF_MONTH, -1); return df.format(calendar.getTime()); } /** * 10位时间戳转时间 * * @param dateInt * @param format * @return */ public static String getIntToStr(String dateInt, String format) { DateFormat df = getDateFormat(format); long times = Integer.parseInt(dateInt) * 1000L; Date date = new Date(times); return df.format(date); } /** * 获取 10位时间戳 * * @return */ public static Integer getDateInt() { return (int) (System.currentTimeMillis() / 1000); } /** * 13位时间戳转时间 * * @param time * @param format * @return */ public static String getLongToStr(long time, String format) { Date date = new Date(time); return dateToDateString(date, format); } /** * 获取两个小时间的间隔秒杀 * * @param start * @param end * @return */ public static int getIntervalSec(int start, int end) { return (end - start) * 60 * 60; } /** * 毫秒时间戳毫秒加小数点 * * @param time * @return */ public static String getMillsStr(long time) { String timeStr = String.valueOf(time); String suffix = timeStr.substring(0, timeStr.length() - 3); String prefix = timeStr.substring(timeStr.length() - 3, timeStr.length()); return suffix + "." + prefix; } /** * 带小数点的毫秒时间戳转时间格式 * * @param timeStr * @param formatStr * @return */ public static String longToString(String timeStr, String formatStr) { long times = Long.parseLong(timeStr.replace(".", "")); Date date = new Date(times); return dateToDateString(date, formatStr); } /** * 获取当天起始时间 * * @return */ public static Long getTodayTime() { Calendar todayStart = Calendar.getInstance(); todayStart.set(Calendar.HOUR_OF_DAY, 0); todayStart.set(Calendar.MINUTE, 0); todayStart.set(Calendar.SECOND, 0); todayStart.set(Calendar.MILLISECOND, 0); return todayStart.getTime().getTime(); } public static Integer getTodayInt() { return (int) (getTodayTime() / 1000); } /** * 获取当天结束时间 * * @return */ public static Long getEndTime() { Calendar todayEnd = Calendar.getInstance(); todayEnd.set(Calendar.HOUR, 23); todayEnd.set(Calendar.MINUTE, 59); todayEnd.set(Calendar.SECOND, 59); todayEnd.set(Calendar.MILLISECOND, 999); return todayEnd.getTime().getTime(); } public static Integer getTomorrowInt() { return (int) (getTomorrowTime() / 1000); } /** * 获取第二天起始时间 * * @return */ public static Long getTomorrowTime() { Calendar cal = Calendar.getInstance(); cal.setTime(new Date()); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); cal.add(Calendar.DAY_OF_MONTH, 1); return cal.getTime().getTime(); } /** * 获取当天指定小时的时间 * * @param hour * @return */ public static Long getPointHourTime(int hour) { Calendar todayStart = Calendar.getInstance(); todayStart.set(Calendar.HOUR_OF_DAY, hour); todayStart.set(Calendar.MINUTE, 0); todayStart.set(Calendar.SECOND, 0); todayStart.set(Calendar.MILLISECOND, 0); return todayStart.getTime().getTime(); } /** * 获取当天n天后的h小时 * * @param days * @param hour * @return */ public static Long getPointDateHourTime(int days, int hour) { Calendar todayStart = Calendar.getInstance(); todayStart.add(Calendar.DATE, days); todayStart.set(Calendar.HOUR_OF_DAY, hour); todayStart.set(Calendar.MINUTE, 0); todayStart.set(Calendar.SECOND, 0); todayStart.set(Calendar.MILLISECOND, 0); return todayStart.getTime().getTime(); } /** * 时分秒转成秒数 * * @param time * @return */ public static Integer hourTosec(String time) { if ("null".equals(time) || StringUtils.isEmpty(time)) { return null; } if (time.length() <= 5) { time += ":00"; } int index1 = time.indexOf(":"); int index2 = time.indexOf(":", index1 + 1); int hh = Integer.parseInt(time.substring(0, index1)); int mi = Integer.parseInt(time.substring(index1 + 1, index2)); int ss = Integer.parseInt(time.substring(index2 + 1)); return hh * 60 * 60 + mi * 60 + ss; } /** * 时分秒转成秒数 * * @param time * @return */ public static Integer minTosec(String time) { if (time.length() <= 5) { time += ":00"; } int index1 = time.indexOf(":"); int index2 = time.indexOf(":", index1 + 1); int mi = Integer.parseInt(time.substring(0, index1)); int ss = Integer.parseInt(time.substring(index1 + 1, index2)); return mi * 60 + ss; } public static boolean isDate(String dateTimeStr, String formatStr) { DateFormat df = getDateFormat(formatStr); try { df.parse(dateTimeStr); return true; } catch (Exception e) { return false; } } /** * 判断时间是否在时间段内 * * @param strDate * 当前时间 yyyy-MM-dd HH:mm:ss * @param strDateBegin * 开始时间 00:00:00 * @param strDateEnd * 结束时间 00:05:00 * @return */ public static boolean isInDate(String strDate, String strDateBegin, String strDateEnd) { // 截取当前时间时分秒 int strDateH = Integer.parseInt(strDate.substring(11, 13)); int strDateM = Integer.parseInt(strDate.substring(14, 16)); int strDateS = Integer.parseInt(strDate.substring(17, 19)); // 截取开始时间时分秒 int strDateBeginH = Integer.parseInt(strDateBegin.substring(0, 2)); int strDateBeginM = Integer.parseInt(strDateBegin.substring(3, 5)); int strDateBeginS = Integer.parseInt(strDateBegin.substring(6, 8)); // 截取结束时间时分秒 int strDateEndH = Integer.parseInt(strDateEnd.substring(0, 2)); int strDateEndM = Integer.parseInt(strDateEnd.substring(3, 5)); int strDateEndS = Integer.parseInt(strDateEnd.substring(6, 8)); if ((strDateH >= strDateBeginH && strDateH <= strDateEndH)) { // 当前时间小时数在开始时间和结束时间小时数之间 if (strDateH > strDateBeginH && strDateH < strDateEndH) { return true; // 当前时间小时数等于开始时间小时数,分钟数在开始和结束之间 } else if (strDateH == strDateBeginH && strDateM >= strDateBeginM && strDateM <= strDateEndM) { return true; // 当前时间小时数等于开始时间小时数,分钟数等于开始时间分钟数,秒数在开始和结束之间 } else if (strDateH == strDateBeginH && strDateM == strDateBeginM && strDateS >= strDateBeginS && strDateS <= strDateEndS) { return true; } // 当前时间小时数大等于开始时间小时数,等于结束时间小时数,分钟数小等于结束时间分钟数 else if (strDateH >= strDateBeginH && strDateH == strDateEndH && strDateM <= strDateEndM) { return true; // 当前时间小时数大等于开始时间小时数,等于结束时间小时数,分钟数等于结束时间分钟数,秒数小等于结束时间秒数 } else if (strDateH >= strDateBeginH && strDateH == strDateEndH && strDateM == strDateEndM && strDateS <= strDateEndS) { return true; } else { return false; } } else { return false; } } /** * 判断时间是否在时间段内 * * @param date * 当前时间 yyyy-MM-dd HH:mm:ss * @param strDateBegin * 开始时间 00:00:00 * @param strDateEnd * 结束时间 00:05:00 * @return */ public static boolean isInDate(Date date, String strDateBegin, String strDateEnd) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String strDate = sdf.format(date); // 截取当前时间时分秒 int strDateH = Integer.parseInt(strDate.substring(11, 13)); int strDateM = Integer.parseInt(strDate.substring(14, 16)); int strDateS = Integer.parseInt(strDate.substring(17, 19)); // 截取开始时间时分秒 int strDateBeginH = Integer.parseInt(strDateBegin.substring(0, 2)); int strDateBeginM = Integer.parseInt(strDateBegin.substring(3, 5)); int strDateBeginS = Integer.parseInt(strDateBegin.substring(6, 8)); // 截取结束时间时分秒 int strDateEndH = Integer.parseInt(strDateEnd.substring(0, 2)); int strDateEndM = Integer.parseInt(strDateEnd.substring(3, 5)); int strDateEndS = Integer.parseInt(strDateEnd.substring(6, 8)); if ((strDateH >= strDateBeginH && strDateH <= strDateEndH)) { // 当前时间小时数在开始时间和结束时间小时数之间 if (strDateH > strDateBeginH && strDateH < strDateEndH) { return true; // 当前时间小时数等于开始时间小时数,分钟数在开始和结束之间 } else if (strDateH == strDateBeginH && strDateM >= strDateBeginM && strDateM <= strDateEndM) { return true; // 当前时间小时数等于开始时间小时数,分钟数等于开始时间分钟数,秒数在开始和结束之间 } else if (strDateH == strDateBeginH && strDateM == strDateBeginM && strDateS >= strDateBeginS && strDateS <= strDateEndS) { return true; } // 当前时间小时数大等于开始时间小时数,等于结束时间小时数,分钟数小等于结束时间分钟数 else if (strDateH >= strDateBeginH && strDateH == strDateEndH && strDateM <= strDateEndM) { return true; // 当前时间小时数大等于开始时间小时数,等于结束时间小时数,分钟数等于结束时间分钟数,秒数小等于结束时间秒数 } else if (strDateH >= strDateBeginH && strDateH == strDateEndH && strDateM == strDateEndM && strDateS <= strDateEndS) { return true; } else { return false; } } else { return false; } } public static boolean isInTime(int time, int begin, int end) { if (time >= begin && time < end) { return true; } return false; } public static int getMinutest(String begin, String format) { String nowMinutes = getCurDate("HH:mm"); long time = compareDateStr("09:00", nowMinutes, "HH:mm"); return (int) time; } /** * <p> * Title: addDays * </p> * <p> * Description: 加减天数 * </p> * * @param days * @return */ public static Date addDays(Date date, int days) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.DATE, days); return calendar.getTime(); } /** * <p> * Title: addMonths * </p> * <p> * Description: 加减月份 * </p> * * @param date * @param months * @return */ public static Date addMonths(Date date, int months) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.MONTH, months); return calendar.getTime(); } /** * <p> * Title: getDays * </p> * <p> * Description: 获取两个日期之前相差的天数 * </p> * * @param minDate * @param maxDate * @return */ public static int getDays(Date minDate, Date maxDate) { int days = 0; if (null == minDate || null == maxDate) return days; days = (int) ((maxDate.getTime() - minDate.getTime()) / (24 * 60 * 60 * 1000)); return days; } /** * 时间戳转 date * * @param longDate 时间戳 * @return */ public static Date getConversionDateByLong(long longDate) { //1529398742830 ZoneId zid = ZoneId.systemDefault(); LocalDateTime time = LocalDateTime.ofInstant(Instant.ofEpochMilli(longDate), zid); ZonedDateTime zdt = time.atZone(zid); Date date = Date.from(zdt.toInstant()); return date; } /** * yyyyMMdd 转 yyyy_MM_dd * * @param strData 时间戳 * @return */ public static String getdatefor_yyyy_MM_dd(String strData) { //1529398742830 //20180205 String yyyy_MM_dd=""; if (null == strData || strData.length()==0) { return yyyy_MM_dd; }else { String yyyy = strData.substring(0, 4); String mm = strData.substring(4, 6); String dd = strData.substring(6, 8); yyyy_MM_dd = yyyy+"-"+mm +"-"+dd; } return yyyy_MM_dd; } public static String getdatefor_HH_mm_ss(String strData) { //1529398742830 //20180205 String HH_mm_ss=""; if (null == strData || strData.length()==0) { return HH_mm_ss; }else { String HH = strData.substring(0, 2); String mm = strData.substring(2, 4); String ss = strData.substring(4, 6); HH_mm_ss = HH+":"+mm +":"+ss; } return HH_mm_ss; } /** * yyyyMMdd * * @return */ public static String getdatefor_yyyyMMdd() { Date newdate = new Date(); SimpleDateFormat dft = new SimpleDateFormat("yyyyMMdd"); String date = dft.format(newdate); return date; } /** * yyyyMMdd * * @return */ public static String getdatefor_yyyy_MM_dd() { Date newdate = new Date(); SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd"); String date = dft.format(newdate); return date; } public static void main(String[] args) { Date newdate = new Date(); SimpleDateFormat dft = new SimpleDateFormat("yyyyMMdd"); String date = dft.format(newdate); System.out.println(date); // return endDate; } } screen-common/src/main/java/com/moral/util/PageResult.java
New file @@ -0,0 +1,34 @@ package com.moral.util; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.List; /** * 分页工具类 */ @Data @ApiModel("分页数据封装类") public class PageResult<T> { @ApiModelProperty("总条数") private Long total; @ApiModelProperty("总页数") private Long totalPage; @ApiModelProperty("当前页数据") private List<T> items; public PageResult(Long total, List<T> items) { this.total = total; this.items = items; } public PageResult(Long total, Long totalPage, List<T> items) { this.total = total; this.totalPage = totalPage; this.items = items; } } screen-common/src/main/java/com/moral/util/SpringContextUtils.java
New file @@ -0,0 +1,65 @@ package com.moral.util; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import java.lang.annotation.Annotation; import java.util.Map; public class SpringContextUtils { private static ApplicationContext applicationContext; public SpringContextUtils() { } /** * 获取applicationContext对象 * * @return */ public static ApplicationContext getApplicationContext() { return applicationContext; } public static void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringContextUtils.applicationContext = applicationContext; } /** * 根据 bean 的 name 来查找对象 * * @param beanName bean name * @param <T> * @return */ @SuppressWarnings("unchecked") public static <T> T getBeanByName(String beanName) { return (T) applicationContext.getBean(beanName); } /** * 根据 bean 的 类型 来查找对象 * * @param requiredType * @param <T> * @return */ @SuppressWarnings("unchecked") public static <T> T getBeanByClass(Class<?> requiredType) { return (T) applicationContext.getBean(requiredType); } public static <T> Map<String, T> getBeansByClass(Class<T> cls) { return applicationContext.getBeansOfType(cls); } public static Map<String, Object> getBeansByAnnotation(Class<? extends Annotation> annotationCls) { return applicationContext.getBeansWithAnnotation(annotationCls); } } screen-manage/pom.xml
New file @@ -0,0 +1,72 @@ <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>screen</artifactId> <groupId>org.moral</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>screen-manage</artifactId> <dependencies> <dependency> <groupId>org.moral</groupId> <artifactId>screen-common</artifactId> <version>1.0-SNAPSHOT</version> <scope>compile</scope> </dependency> </dependencies> <build> <finalName>screen-manage</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>${java.version}</source> <target>${java.version}</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>${maven-resources-plugin.version}</version> <dependencies> <dependency> <groupId>org.apache.maven.shared</groupId> <artifactId>maven-filtering</artifactId> <version>${maven-filtering.version}</version> </dependency> <dependency> <groupId>org.apache.maven.shared</groupId> <artifactId>maven-common-artifact-filters</artifactId> <version>${maven-common-artifact-filters.version}</version> </dependency> <dependency> <groupId>org.apache.maven.shared</groupId> <artifactId>maven-dependency-tree</artifactId> <version>${maven-dependency-tree.version}</version> </dependency> <dependency> <groupId>org.apache.maven.shared</groupId> <artifactId>maven-shared-incremental</artifactId> <version>${maven-shared-incremental.version}</version> </dependency> </dependencies> </plugin> </plugins> </build> </project> screen-manage/src/main/java/com/moral/ScreenManageBootstrap.java
New file @@ -0,0 +1,42 @@ package com.moral; import com.moral.util.SpringContextUtils; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; import java.util.Arrays; @MapperScan("com.moral.api.mapper") @EnableTransactionManagement @SpringBootApplication public class ScreenManageBootstrap { public static void main(String[] args) { ApplicationContext applicationContext = SpringApplication.run(ScreenManageBootstrap.class, args); SpringContextUtils.setApplicationContext(applicationContext); } @Bean public FilterRegistrationBean<CorsFilter> corsFilter() { FilterRegistrationBean<CorsFilter> corsFilterFilterRegistrationBean = new FilterRegistrationBean<>(); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.addAllowedHeader("*"); corsConfiguration.addAllowedOrigin("*"); corsConfiguration.setAllowedMethods(Arrays.asList("POST", "PUT", "GET", "OPTIONS", "DELETE")); corsConfiguration.setAllowCredentials(true); corsConfiguration.setMaxAge(3600L); source.registerCorsConfiguration("/**", corsConfiguration); corsFilterFilterRegistrationBean.setFilter(new CorsFilter(source)); corsFilterFilterRegistrationBean.setOrder(-1); return corsFilterFilterRegistrationBean; } } screen-manage/src/main/java/com/moral/api/Swagger2.java
New file @@ -0,0 +1,34 @@ package com.moral.api; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration @EnableSwagger2 public class Swagger2 { @Bean public Docket petApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.moral.api")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("后台管理接口文档") .description("后台管理接口文档") .version("1.0") .build(); } } screen-manage/src/main/java/com/moral/api/config/datasource/DataSourceConfig.java
New file @@ -0,0 +1,23 @@ package com.moral.api.config.datasource; import com.alibaba.druid.pool.DruidDataSource; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import javax.sql.DataSource; @Configuration public class DataSourceConfig { @Primary @Bean(name = "primaryDataSource") @Qualifier("primaryDataSource") @ConfigurationProperties(prefix = "spring.datasource") public DataSource primaryDataSource(){ return new DruidDataSource(); } } screen-manage/src/main/java/com/moral/api/config/kafka/KafkaConsumerConfig.java
New file @@ -0,0 +1,67 @@ package com.moral.api.config.kafka; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.common.serialization.StringDeserializer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.kafka.annotation.EnableKafka; import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; import org.springframework.kafka.config.KafkaListenerContainerFactory; import org.springframework.kafka.core.ConsumerFactory; import org.springframework.kafka.core.DefaultKafkaConsumerFactory; import org.springframework.kafka.listener.ConcurrentMessageListenerContainer; import org.springframework.kafka.listener.ContainerProperties; import java.util.HashMap; import java.util.Map; /*@Configuration @EnableKafka*/ public class KafkaConsumerConfig { @Value("${kafka.consumer.servers}") private String servers; @Value("${kafka.consumer.enable.auto.commit}") private boolean enableAutoCommit; @Value("${kafka.consumer.session.timeout}") private String sessionTimeout; @Value("${kafka.consumer.auto.commit.interval}") private String autoCommitInterval; @Value("${kafka.consumer.group.id}") private String groupId; @Value("${kafka.consumer.auto.offset.reset}") private String autoOffsetReset; @Value("${kafka.consumer.concurrency}") private int concurrency; @Bean public KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<String, String>> kafkaListenerContainerFactory() { ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>(); factory.setConsumerFactory(consumerFactory()); factory.setConcurrency(concurrency); factory.getContainerProperties().setPollTimeout(1500); factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE); /*factory.setBatchListener(true);//@KafkaListener 批量消费 每个批次数量在Kafka配置参数中设置ConsumerConfig.MAX_POLL_RECORDS_CONFIG factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE);//设置提交偏移量的方式*/ return factory; } public ConsumerFactory<String, String> consumerFactory() { return new DefaultKafkaConsumerFactory<>(consumerConfigs()); } public Map<String, Object> consumerConfigs() { Map<String, Object> propsMap = new HashMap<>(); propsMap.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, servers); propsMap.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, enableAutoCommit); propsMap.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, autoCommitInterval); propsMap.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, sessionTimeout); propsMap.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); propsMap.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); propsMap.put(ConsumerConfig.GROUP_ID_CONFIG, groupId); propsMap.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, autoOffsetReset); return propsMap; } } screen-manage/src/main/java/com/moral/api/config/kafka/KafkaProducerConfig.java
New file @@ -0,0 +1,55 @@ package com.moral.api.config.kafka; import org.apache.kafka.clients.producer.ProducerConfig; import org.apache.kafka.common.serialization.StringSerializer; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.kafka.annotation.EnableKafka; import org.springframework.kafka.core.DefaultKafkaProducerFactory; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.kafka.core.ProducerFactory; import java.util.HashMap; import java.util.Map; /*@Configuration @EnableKafka*/ public class KafkaProducerConfig { @Value("${kafka.producer.servers}") private String servers; @Value("${kafka.producer.retries}") private int retries; @Value("${kafka.producer.batch.size}") private int batchSize; @Value("${kafka.producer.linger}") private int linger; @Value("${kafka.producer.buffer.memory}") private int bufferMemory; public Map<String, Object> producerConfigs() { Map<String, Object> props = new HashMap<>(); props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, servers); props.put(ProducerConfig.RETRIES_CONFIG, retries); props.put(ProducerConfig.BATCH_SIZE_CONFIG, batchSize); props.put(ProducerConfig.LINGER_MS_CONFIG, linger); props.put(ProducerConfig.BUFFER_MEMORY_CONFIG, bufferMemory); props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class); return props; } public ProducerFactory<String, String> producerFactory() { return new DefaultKafkaProducerFactory<>(producerConfigs()); } @Bean public KafkaTemplate<String, String> kafkaTemplate() { return new KafkaTemplate<String, String>(producerFactory()); } } screen-manage/src/main/java/com/moral/api/config/mybatis/MybatisPlusConfig.java
New file @@ -0,0 +1,22 @@ package com.moral.api.config.mybatis; import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MybatisPlusConfig { /** * 分页插件 */ @Bean public PaginationInterceptor paginationInterceptor() { PaginationInterceptor page = new PaginationInterceptor(); return page; } } screen-manage/src/main/java/com/moral/api/config/redis/RedisConfig.java
New file @@ -0,0 +1,42 @@ package com.moral.api.config.redis; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration public class RedisConfig { @Bean(name="redisTemplate") @ConditionalOnMissingBean(StringRedisTemplate.class) //此注解的作用 如果容器中没有RedisTemplate 那就注入 有就不注入了 public RedisTemplate<String,Object> stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>(); redisTemplate.setConnectionFactory(redisConnectionFactory); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); // key采用String的序列化方式 redisTemplate.setKeySerializer(stringRedisSerializer); // hash的key也采用String的序列化方式 redisTemplate.setHashKeySerializer(stringRedisSerializer); // valuevalue采用jackson序列化方式 redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); // hash的value采用jackson序列化方式 redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); redisTemplate.afterPropertiesSet(); redisTemplate.afterPropertiesSet(); return redisTemplate; } } screen-manage/src/main/java/com/moral/api/constant/TopicConstants.java
New file @@ -0,0 +1,11 @@ package com.moral.api.constant; public class TopicConstants { /** * Test 主题 */ public static final String TEST_TOPIC_MESSAGE = "test_topic"; } screen-manage/src/main/java/com/moral/api/controller/TestController.java
New file @@ -0,0 +1,99 @@ package com.moral.api.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.moral.api.entity.Test; import com.moral.api.service.TestService; import com.moral.constant.ResultMessage; import com.moral.redis.RedisUtil; import com.moral.util.PageResult; import io.swagger.annotations.*; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.web.bind.annotation.*; @Slf4j @Api(tags = {"后台管理"}) @RestController @RequestMapping("/manage") public class TestController { @Autowired private KafkaTemplate kafkaTemplate; @Autowired private TestService testService; /** * name 姓名 * email 郵箱 * mobile 手機號 */ @ApiOperation(value = "测试插入", notes = "测试插入") @RequestMapping(value = "/saveTest", method = RequestMethod.POST) public ResultMessage save() { Test test=new Test(); test.setEmail("test@qq.com"); test.setName("name"); test.setMobile("13965898745"); testService.save(test); return ResultMessage.ok(); } /** * page 當前頁 * size 每頁大小 */ @ApiOperation(value = "分頁", notes = "分頁") @ApiImplicitParams({ @ApiImplicitParam(name="page",value="當前頁數",required=true,paramType="path",dataType="Int"), @ApiImplicitParam(name="size",value="每頁大小",required=true,paramType="path",dataType="Int") }) @RequestMapping(value = "search/{page}/{size}", method = RequestMethod.GET) public ResultMessage findBypage(@PathVariable("page") Integer page, @PathVariable("size") Integer size) { log.info("page is:"+ page+" size is:"+size); //根据条件分页查询 Page<Test> userPage = testService.selectByPage(null, page, size); //封装分页返回对象 PageResult<Test> pageResult = new PageResult<>( userPage.getTotal(), userPage.getPages(),userPage.getRecords() ); //返回数据 return ResultMessage.ok(pageResult); } /** * redis測試 */ @ApiOperation(value = "redis測試", notes = "redis測試") @RequestMapping(value = "redis", method = RequestMethod.GET) public ResultMessage testRedis() { RedisUtil.set("redistest","test"); return ResultMessage.ok(RedisUtil.get("redistest")); } /** * 事務 */ @ApiOperation(value = "事務測試", notes = "事務測試") @RequestMapping(value = "saveTest", method = RequestMethod.GET) public ResultMessage saveTest() throws Exception{ testService.saveTest(); return ResultMessage.ok(); } /** * kafka測試 */ @ApiOperation(value = "kafka測試", notes = "kafka測試") @RequestMapping(value = "kafkaTest", method = RequestMethod.GET) public void kafkaTest() { kafkaTemplate.send("test_topic","test111111111111111"); } } screen-manage/src/main/java/com/moral/api/entity/Test.java
New file @@ -0,0 +1,51 @@ package com.moral.api.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.extension.activerecord.Model; import com.baomidou.mybatisplus.annotation.TableId; import java.io.Serializable; import lombok.Data; import lombok.EqualsAndHashCode; /** * <p> * * </p> * * @author moral * @since 2021-03-01 */ @Data @EqualsAndHashCode(callSuper = false) public class Test extends Model<Test> { private static final long serialVersionUID = 1L; /** * 主键 */ @TableId(value = "id", type = IdType.AUTO) private Integer id; /** * 名称 */ private String name; /** * 邮箱 */ private String email; /** * 手机号 */ private String mobile; @Override protected Serializable pkVal() { return this.id; } } screen-manage/src/main/java/com/moral/api/exception/BusinessException.java
New file @@ -0,0 +1,72 @@ package com.moral.api.exception; /** * @author * @site * @company * @create 2021-02-26 11:20 */ public class BusinessException extends RuntimeException { /** * 错误码 */ private String code; /** * 错误信息 */ private String msg; /** */ private static final long serialVersionUID = 1L; public BusinessException() { super(); } public BusinessException(String msg) { super(msg); this.msg = msg; } public BusinessException(Throwable t) { super(t); } public BusinessException(String msg, Throwable t) { super(msg); this.msg = msg; } public BusinessException(String code, String msg) { super(msg); this.code = code; this.msg = msg; } public BusinessException(String code, String msg, Throwable t) { super(msg, t); this.code = code; this.msg = msg; } /** * Getter method for property <tt>code</tt>. * * @return property value of code */ public String getCode() { return code; } /** * Getter method for property <tt>msg</tt>. * * @return property value of msg */ public String getMsg() { return msg; } } screen-manage/src/main/java/com/moral/api/exception/GlobalExceptionHandler.java
New file @@ -0,0 +1,35 @@ package com.moral.api.exception; import com.moral.constant.Constants; import com.moral.constant.ResultMessage; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; @ControllerAdvice @ResponseBody public class GlobalExceptionHandler { /** * 处理全部异常 */ @ExceptionHandler @ResponseBody @ResponseStatus(HttpStatus.OK) public ResultMessage handleException(Exception ex) { return ResultMessage.fail(Constants.CODE_OPERATION_FAILED, "请求失败"); } /** * 处理BusinessException异常 */ @ExceptionHandler({BusinessException.class}) @ResponseBody @ResponseStatus(HttpStatus.OK) public ResultMessage handleUserNotExistException(BusinessException ex) { return ResultMessage.fail(Constants.CODE_OPERATION_FAILED, "请求用户数据失败"); } } screen-manage/src/main/java/com/moral/api/kafka/consumer/KafkaConsumer.java
New file @@ -0,0 +1,37 @@ package com.moral.api.kafka.consumer; import com.moral.api.constant.TopicConstants; import lombok.extern.slf4j.Slf4j; import org.apache.kafka.clients.consumer.ConsumerRecord; import org.springframework.kafka.annotation.KafkaListener; import org.springframework.kafka.support.Acknowledgment; import org.springframework.stereotype.Component; import java.util.Random; @Component @Slf4j public class KafkaConsumer { /* *//** * 这是手动提交的消费方式 * @param record * @param ack * @throws Exception *//* @KafkaListener(topics = TopicConstants.TEST_TOPIC_MESSAGE,groupId = "test") public void listenTest(ConsumerRecord<String, String> record , Acknowledgment ack) throws Exception { String msg = record.value(); System.out.println(msg); if (new Random().nextInt(100)<50){ log.info(String.format("kafka 消费消息成功---------------- listen1 topic = %s, offset = %d, value = %s ", record.topic(), record.offset(), record.value())); ack.acknowledge(); } }*/ } screen-manage/src/main/java/com/moral/api/mapper/TestMapper.java
New file @@ -0,0 +1,16 @@ package com.moral.api.mapper; import com.moral.api.entity.Test; import com.baomidou.mybatisplus.core.mapper.BaseMapper; /** * <p> * Mapper 接口 * </p> * * @author moral * @since 2021-02-25 */ public interface TestMapper extends BaseMapper<Test> { } screen-manage/src/main/java/com/moral/api/service/TestService.java
New file @@ -0,0 +1,24 @@ package com.moral.api.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.moral.api.entity.Test; import com.baomidou.mybatisplus.extension.service.IService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; /** * <p> * 服务类 * </p> * * @author moral * @since 2021-02-25 */ @Service @Transactional public interface TestService extends IService<Test> { Page<Test> selectByPage(Test test, Integer page, Integer size); void saveTest() throws Exception; } screen-manage/src/main/java/com/moral/api/service/impl/TestServiceImpl.java
New file @@ -0,0 +1,52 @@ package com.moral.api.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.moral.api.entity.Test; import com.moral.api.exception.BusinessException; import com.moral.api.mapper.TestMapper; import com.moral.api.service.TestService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; /** * <p> * 服务实现类 * </p> * * @author moral * @since 2021-02-25 */ @Service public class TestServiceImpl extends ServiceImpl<TestMapper, Test> implements TestService { @Autowired private TestMapper testMapper; @Override public Page<Test> selectByPage(Test test, Integer page, Integer size) { //设置分页条件 Page<Test> pageData = new Page<>(page, size); //执行分页查询 IPage<Test> users = testMapper.selectPage(pageData, new QueryWrapper<>(test)); //设置结果集到分页对象中 pageData.setRecords(users.getRecords()); //返回结果 return pageData; } @Override public void saveTest() throws Exception{ Test t=new Test(); t.setName("aaaa"); t.setMobile("139652555"); t.setEmail("33@qq.com"); testMapper.insert(t); if ("aaaa".equals(t.getName())){ throw new BusinessException("aaaa已存在,数据将不会回滚"); } } } screen-manage/src/main/resources/application-dev.yml
New file @@ -0,0 +1,101 @@ server: port: 8082 tomcat: uri-encoding: UTF-8 #最小线程数 min-spare-threads: 500 #最大线程数 max-threads: 2500 #最大链接数 max-connections: 6500 #最大等待队列长度 accept-count: 1000 spring: profiles: active: dev application: name: screen-manage redis: #cluster: #nodes: 47.112.126.78:7001,47.112.126.78:7002,47.112.126.132:7003,47.112.126.132:7004,47.112.132.193:7005,47.112.132.193:7006 #password: test #timeout: 500 host: 127.0.0.1 port: 6379 password: 123456 timeout: 30000 jedis: pool: max-active: 256 max-wait: 30000 max-idle: 64 min-idle: 32 lettuce: pool: max-active: 256 max-idle: 64 max-wait: 30000 min-idle: 32 datasource: minIdle: 1 time-between-eviction-runs-millis: 60000 max-active: 20 test-while-idle: true validation-query: select 'x' filters: stat type: com.alibaba.druid.pool.DruidDataSource max-wait: 60000 url: jdbc:mysql://192.168.0.18:4000/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC password: 123456 test-on-borrow: false sql-script-encoding: utf-8 pool-prepared-statements: true min-evictable-idle-time-millis: 300000 initial-size: 1 driver-class-name: com.mysql.cj.jdbc.Driver max-conn-lifetime-millis: 20 test-on-return: false username: root mybatis-plus: mapper-locations: classpath:mapper/*.xml global-config: db-config: id-type: auto field-strategy: NOT_EMPTY db-type: MYSQL configuration: map-underscore-to-camel-case: true call-setters-on-nulls: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl kafka: listener: ack-mode: manual_immediate consumer: auto: commit: interval: 100 offset: reset: latest concurrency: 3 enable: auto: commit: false group: id: test servers: 192.168.0.16:9092,192.168.0.17:9092,192.168.0.18:9092 session: timeout: 6000 topic: test_topic zookeeper: connect: 192.168.0.16:2181,192.168.0.17:2181,192.168.0.18:2181 producer: batch: size: 4096 buffer: memory: 40960 linger: 1 retries: 0 servers: 192.168.0.16:9092,192.168.0.17:9092,192.168.0.18:9092 screen-manage/src/main/resources/logback-spring.xml
New file @@ -0,0 +1,56 @@ <?xml version="1.0" encoding="UTF-8"?> <configuration> <include resource="org/springframework/boot/logging/logback/defaults.xml"/> <springProperty scope="context" name="springAppName" source="spring.application.name"/> <!-- 日志在工程中的输出位置 --> <property name="LOG_FILE" value="/home/moral/soft/log/${springAppName}"/> <!-- 控制台的日志输出样式 --> <property name="CONSOLE_LOG_PATTERN" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}) [%X{logseq}]{faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr([${springAppName}]){yellow} %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/> <property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{logseq}] [%thread] %X{T} [%level] %logger.%method:%line %msg%n"/> <!-- 控制台Appender --> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>INFO</level> </filter> <encoder> <pattern>${CONSOLE_LOG_PATTERN}</pattern> <charset>utf8</charset> </encoder> </appender> <!-- 日志记录Appender --> <appender name="screenManageLog" class="ch.qos.logback.classic.sift.SiftingAppender"> <discriminator> <key>taskId</key> <defaultValue>default</defaultValue> </discriminator> <sift> <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>INFO</level> </filter> <file>${LOG_FILE}/%d{yyyy-MM-dd}/${springAppName}.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <maxFileSize>30MB</maxFileSize> <fileNamePattern>${LOG_FILE}/%d{yyyy-MM-dd}/${springAppName}-%d{yyyy-MM-dd}.log%i.log</fileNamePattern> <maxHistory>30</maxHistory> </rollingPolicy> <encoder> <pattern>${FILE_LOG_PATTERN}</pattern> <charset>utf8</charset> </encoder> </appender> </sift> </appender> <root level="INFO"> <appender-ref ref="console"/> <appender-ref ref="screenManageLog"/> </root> </configuration>