From 9a9f4158fef099ad5eea5c3ec9c6bfa8a6226afc Mon Sep 17 00:00:00 2001 From: bynt Date: Fri, 10 Sep 2021 18:26:54 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=8F=91=E9=80=81=E7=9F=AD?= =?UTF-8?q?=E4=BF=A1=E9=80=BB=E8=BE=91=20=E8=8E=B7=E5=8F=96=E8=B5=84?= =?UTF-8?q?=E8=AE=AF=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- eladmin-common/pom.xml | 2 +- .../zhengjie/annotation/rest/RedisLock.java | 40 ++++ .../me/zhengjie/aspect/RedisLockAspect.java | 62 ++++++ .../config/RedissonAutoConfiguration.java | 69 +++++++ .../zhengjie/config/RedissonProperties.java | 39 ++++ .../me/zhengjie/constant/SmsConstant.java | 61 ++++-- .../main/java/me/zhengjie/utils/SpelUtil.java | 52 +++++ .../config/thread/ThreadPoolSendMessage.java | 46 +++++ .../modules/constant/DefaultConstant.java | 10 + .../security/config/SecurityConfig.java | 4 + .../security/JwtAuthenticationEntryPoint.java | 1 - .../modules/sms/domain/SmsConfiguration.java | 79 ++++++++ .../SmsConfigurationRepository.java | 35 ++++ .../modules/sms/rest/ConsultController.java | 66 +++++++ .../sms/rest/SmsConfigurationController.java | 124 ++++++++++++ .../sms/service/SmsConfigurationService.java | 104 ++++++++++ .../modules/sms/service/TbSendSmsService.java | 7 + .../sms/service/dto/SmsConfigurationDto.java | 61 ++++++ .../dto/SmsConfigurationQueryCriteria.java | 27 +++ .../impl/SmsConfigurationServiceImpl.java | 187 ++++++++++++++++++ .../service/impl/TbSendSmsServiceImpl.java | 11 +- .../mapstruct/SmsConfigurationMapper.java | 32 +++ .../me/zhengjie/modules/sms/util/SmsUtil.java | 40 +++- .../sms/vo/UploadAndSendMessageVo.java | 34 ++++ .../upload/rest/UploadFileController.java | 5 +- .../zhengjie/modules/upload/script/trans.sh | 8 - .../uploadnew/domain/TbUploadFileNew.java | 16 +- .../repository/TbUploadFileNewRepository.java | 8 +- .../rest/TbUploadFileNewController.java | 21 +- .../service/TbUploadFileNewService.java | 14 +- .../dto/TbUploadFileNewQueryCriteria.java | 6 +- .../impl/TbUploadFileNewServiceImpl.java | 21 +- .../uploadnew/task/SendMessageTask.java | 161 +++++++++++++++ .../main/resources/config/application-dev.yml | 19 +- .../resources/config/application-prod.yml | 21 +- .../src/main/resources/config/application.yml | 10 +- .../java/me/zhengjie/domain/vo/ConsultVo.java | 22 +++ .../service/impl/LocalStorageServiceImpl.java | 6 +- pom.xml | 14 ++ 39 files changed, 1471 insertions(+), 74 deletions(-) create mode 100644 eladmin-common/src/main/java/me/zhengjie/annotation/rest/RedisLock.java create mode 100644 eladmin-common/src/main/java/me/zhengjie/aspect/RedisLockAspect.java create mode 100644 eladmin-common/src/main/java/me/zhengjie/config/RedissonAutoConfiguration.java create mode 100644 eladmin-common/src/main/java/me/zhengjie/config/RedissonProperties.java create mode 100644 eladmin-common/src/main/java/me/zhengjie/utils/SpelUtil.java create mode 100644 eladmin-system/src/main/java/me/zhengjie/config/thread/ThreadPoolSendMessage.java create mode 100644 eladmin-system/src/main/java/me/zhengjie/modules/sms/domain/SmsConfiguration.java create mode 100644 eladmin-system/src/main/java/me/zhengjie/modules/sms/repository/SmsConfigurationRepository.java create mode 100644 eladmin-system/src/main/java/me/zhengjie/modules/sms/rest/ConsultController.java create mode 100644 eladmin-system/src/main/java/me/zhengjie/modules/sms/rest/SmsConfigurationController.java create mode 100644 eladmin-system/src/main/java/me/zhengjie/modules/sms/service/SmsConfigurationService.java create mode 100644 eladmin-system/src/main/java/me/zhengjie/modules/sms/service/dto/SmsConfigurationDto.java create mode 100644 eladmin-system/src/main/java/me/zhengjie/modules/sms/service/dto/SmsConfigurationQueryCriteria.java create mode 100644 eladmin-system/src/main/java/me/zhengjie/modules/sms/service/impl/SmsConfigurationServiceImpl.java create mode 100644 eladmin-system/src/main/java/me/zhengjie/modules/sms/service/mapstruct/SmsConfigurationMapper.java create mode 100644 eladmin-system/src/main/java/me/zhengjie/modules/sms/vo/UploadAndSendMessageVo.java create mode 100644 eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/task/SendMessageTask.java create mode 100644 eladmin-tools/src/main/java/me/zhengjie/domain/vo/ConsultVo.java diff --git a/eladmin-common/pom.xml b/eladmin-common/pom.xml index 2150b4b..93e9855 100644 --- a/eladmin-common/pom.xml +++ b/eladmin-common/pom.xml @@ -23,4 +23,4 @@ ${hutool.version} - \ No newline at end of file + diff --git a/eladmin-common/src/main/java/me/zhengjie/annotation/rest/RedisLock.java b/eladmin-common/src/main/java/me/zhengjie/annotation/rest/RedisLock.java new file mode 100644 index 0000000..93af5fd --- /dev/null +++ b/eladmin-common/src/main/java/me/zhengjie/annotation/rest/RedisLock.java @@ -0,0 +1,40 @@ + + +package me.zhengjie.annotation.rest; + +import java.lang.annotation.*; +import java.util.concurrent.TimeUnit; + +/** + * @author Enzo + * 使用redis进行分布式锁 + */ +@Target({ElementType.METHOD,ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface RedisLock { + + /** + * redis锁 名字 + */ + String lockName() default ""; + + /** + * redis锁 key 支持spel表达式 + */ + String key() default ""; + + /** + * 过期秒数,默认为5毫秒 + * + * @return 轮询锁的时间 + */ + int expire() default 5000; + + /** + * 超时时间单位 + * + * @return 秒 + */ + TimeUnit timeUnit() default TimeUnit.MILLISECONDS; +} diff --git a/eladmin-common/src/main/java/me/zhengjie/aspect/RedisLockAspect.java b/eladmin-common/src/main/java/me/zhengjie/aspect/RedisLockAspect.java new file mode 100644 index 0000000..77ba291 --- /dev/null +++ b/eladmin-common/src/main/java/me/zhengjie/aspect/RedisLockAspect.java @@ -0,0 +1,62 @@ + + +package me.zhengjie.aspect; + +import cn.hutool.core.util.StrUtil; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.rest.RedisLock; +import me.zhengjie.utils.SpelUtil; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.Signature; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.reflect.MethodSignature; +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Method; + +/** + * @author lgh + */ +@Aspect +@Component +@RequiredArgsConstructor +public class RedisLockAspect { + + private final RedissonClient redissonClient; + + private static final String REDISSON_LOCK_PREFIX = "redisson_lock:"; + + @Around("@annotation(redisLock)") + public Object around(ProceedingJoinPoint joinPoint, RedisLock redisLock) throws Throwable { + String key = redisLock.key(); + String lockName = redisLock.lockName(); + RLock rLock = redissonClient.getLock(getRedisKey(joinPoint, lockName, key)); + rLock.lock(redisLock.expire(), redisLock.timeUnit()); + Object result; + try { + //执行方法 + result = joinPoint.proceed(); + } finally { + rLock.unlock(); + } + return result; + } + + /** + * 将spel表达式转换为字符串 + * + * @param joinPoint 切点 + * @return redisKey + */ + private String getRedisKey(ProceedingJoinPoint joinPoint, String lockName, String spel) { + Signature signature = joinPoint.getSignature(); + MethodSignature methodSignature = (MethodSignature) signature; + Method targetMethod = methodSignature.getMethod(); + Object target = joinPoint.getTarget(); + Object[] arguments = joinPoint.getArgs(); + return REDISSON_LOCK_PREFIX + lockName + StrUtil.COLON + SpelUtil.parse(target, spel, targetMethod, arguments); + } +} diff --git a/eladmin-common/src/main/java/me/zhengjie/config/RedissonAutoConfiguration.java b/eladmin-common/src/main/java/me/zhengjie/config/RedissonAutoConfiguration.java new file mode 100644 index 0000000..b94cf1c --- /dev/null +++ b/eladmin-common/src/main/java/me/zhengjie/config/RedissonAutoConfiguration.java @@ -0,0 +1,69 @@ +package me.zhengjie.config; + +/** + * @author Enzo + * @date : 2021/9/7 + */ +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.redisson.Redisson; +import org.redisson.config.Config; +import org.redisson.api.RedissonClient; +import org.redisson.config.SentinelServersConfig; +import org.redisson.config.SingleServerConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + + +@Configuration +@RequiredArgsConstructor +@ConditionalOnClass(Config.class) +@EnableConfigurationProperties(RedissonProperties.class) +public class RedissonAutoConfiguration { + + private final RedissonProperties redissonProperties; + + /** + * 哨兵模式自动装配 + * @return + */ + @Bean + @ConditionalOnProperty(name="redisson.master-name") + RedissonClient redissonSentinel() { + Config config = new Config(); + SentinelServersConfig serverConfig = config.useSentinelServers().addSentinelAddress(redissonProperties.getSentinelAddresses()) + .setMasterName(redissonProperties.getMasterName()) + .setTimeout(redissonProperties.getTimeout()) + .setMasterConnectionPoolSize(redissonProperties.getMasterConnectionPoolSize()) + .setSlaveConnectionPoolSize(redissonProperties.getSlaveConnectionPoolSize()); + if(StringUtils.isNotBlank(redissonProperties.getPassword())) { + serverConfig.setPassword(redissonProperties.getPassword()); + } + return Redisson.create(config); + } + + /** + * 单机模式自动装配 + * @return + */ + @Bean + @ConditionalOnProperty(name="redisson.address") + RedissonClient redissonSingle() { + Config config = new Config(); + SingleServerConfig serverConfig = config.useSingleServer() + .setAddress(redissonProperties.getAddress()) + .setTimeout(redissonProperties.getTimeout()) + .setConnectionPoolSize(redissonProperties.getConnectionPoolSize()) + .setConnectionMinimumIdleSize(redissonProperties.getConnectionMinimumIdleSize()); + + if(StringUtils.isNotBlank(redissonProperties.getPassword())) { + serverConfig.setPassword(redissonProperties.getPassword()); + } + return Redisson.create(config); + } + +} diff --git a/eladmin-common/src/main/java/me/zhengjie/config/RedissonProperties.java b/eladmin-common/src/main/java/me/zhengjie/config/RedissonProperties.java new file mode 100644 index 0000000..ce7dd3b --- /dev/null +++ b/eladmin-common/src/main/java/me/zhengjie/config/RedissonProperties.java @@ -0,0 +1,39 @@ +package me.zhengjie.config; + +import lombok.Data; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +/** + * @author Enzo + * @date : 2021/9/7 + */ + +@Data +@Configuration +@ConfigurationProperties(prefix = "redisson") +@ConditionalOnProperty("redisson.password") +public class RedissonProperties { + + private int timeout = 3000; + + private String address; + + private String masterName; + + private String password; + + private int database = 0; + + private String[] sentinelAddresses; + + private int connectionPoolSize = 64; + + private int connectionMinimumIdleSize = 10; + + private int slaveConnectionPoolSize = 250; + + private int masterConnectionPoolSize = 250; + +} diff --git a/eladmin-common/src/main/java/me/zhengjie/constant/SmsConstant.java b/eladmin-common/src/main/java/me/zhengjie/constant/SmsConstant.java index db903a4..bdc3e6f 100644 --- a/eladmin-common/src/main/java/me/zhengjie/constant/SmsConstant.java +++ b/eladmin-common/src/main/java/me/zhengjie/constant/SmsConstant.java @@ -7,35 +7,72 @@ package me.zhengjie.constant; * 短信发送常量 */ public class SmsConstant { - /** APP ID*/ + + private SmsConstant() { + + } + + + /** + * APP ID + */ public static final String APP_ID = "app1"; - /** "|"分割*/ + /** + * "|"分割 + */ public static final String VERTICAL_LINE = "\\|"; - /** 时间格式*/ + /** + * 时间格式 + */ public static final String FORMATE_TIMESTAMP = "yyyyMMddHHmmss"; - /** TOKEN*/ - public static final String TOKEN = "f625d0a23493cd8aeb8ada97da7a7b65"; + /** + * 云峰批次号 + */ + public static final String YUN_FENG_BATH_NUM = "bai_ye_send_"; - /** 服务前缀*/ - public static final String SHORT_CHAIN_PREFIX = "s.tuoz.net/s/"; + /** + * 服务前缀 + */ + public static final String SHORT_CHAIN_PREFIX = "xx.tuoz.net/s/"; - /** 生成短链*/ - public static final String SHORT_GENERATION_LINK = "http://s.tuoz.net/trans"; - - /*** 短信url*/ - public static final String SMS_LINK = "http://api.hzdaba.cn/v2/Accounts/baiyekeji_label/Sms/send"; + /** + * 大坝TOKEN + */ + public static final String TOKEN = "f625d0a23493cd8aeb8ada97da7a7b65"; + /** + * 云峰appKey + */ + public static final String YUN_FENG_APP_KEY = "U7GJG5X6zwtQqkpykhG0jDf1bfS76q28"; + /** + * 云峰appSecret + */ + public static final String YUN_FENG_APP_SECRET = "6deccec15874ef40bc4064d95e7e59b6"; + /** + * 生成短链 + */ + public static final String SHORT_GENERATION_LINK = "https://xx.tuoz.net/trans/"; + /** + * 云峰请求接口 + */ + public static final String YUN_FENG_SMS_LINK = "https://api.zhuanxinyun.com/api/v2/sendSms.json"; + /*** 短信url*/ + public static final String DABA_SMS_LINK = "http://api.hzdaba.cn/v2/Accounts/baiyekeji_label/Sms/send"; + /** + * 线上html地址 + */ + public static final String LINK_ADDRESS = "https://byhl-openapplet-2glb7cr2d6d33545-1307374163.tcloudbaseapp.com/index.html?sign=1aab672f0a8b88de2d70b325a4ca6e87&t=1631243192&id="; } diff --git a/eladmin-common/src/main/java/me/zhengjie/utils/SpelUtil.java b/eladmin-common/src/main/java/me/zhengjie/utils/SpelUtil.java new file mode 100644 index 0000000..2169f0f --- /dev/null +++ b/eladmin-common/src/main/java/me/zhengjie/utils/SpelUtil.java @@ -0,0 +1,52 @@ + +package me.zhengjie.utils; + +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.StrUtil; +import org.springframework.context.expression.MethodBasedEvaluationContext; +import org.springframework.core.LocalVariableTableParameterNameDiscoverer; +import org.springframework.expression.ExpressionParser; +import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.expression.spel.support.StandardEvaluationContext; + +import java.lang.reflect.Method; + +/** + * 解析SPEL 表达式 + * @author huxingnan + * @date 2018/5/21 10:51 + */ +public class SpelUtil { + + + /** + * 支持 #p0 参数索引的表达式解析 + * @param rootObject 根对象,method 所在的对象 + * @param spel 表达式 + * @param method ,目标方法 + * @param args 方法入参 + * @return 解析后的字符串 + */ + public static String parse(Object rootObject,String spel, Method method, Object[] args) { + if (StrUtil.isBlank(spel)) { + return StrUtil.EMPTY; + } + //获取被拦截方法参数名列表(使用Spring支持类库) + LocalVariableTableParameterNameDiscoverer u = + new LocalVariableTableParameterNameDiscoverer(); + String[] paraNameArr = u.getParameterNames(method); + if (ArrayUtil.isEmpty(paraNameArr)) { + return spel; + } + //使用SPEL进行key的解析 + ExpressionParser parser = new SpelExpressionParser(); + //SPEL上下文 + StandardEvaluationContext context = new MethodBasedEvaluationContext(rootObject,method,args,u); + //把方法参数放入SPEL上下文中 + for (int i = 0; i < paraNameArr.length; i++) { + context.setVariable(paraNameArr[i], args[i]); + } + return parser.parseExpression(spel).getValue(context, String.class); + } + +} diff --git a/eladmin-system/src/main/java/me/zhengjie/config/thread/ThreadPoolSendMessage.java b/eladmin-system/src/main/java/me/zhengjie/config/thread/ThreadPoolSendMessage.java new file mode 100644 index 0000000..1877b2a --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/config/thread/ThreadPoolSendMessage.java @@ -0,0 +1,46 @@ +package me.zhengjie.config.thread; + +import me.zhengjie.modules.constant.DefaultConstant; +import org.apache.tomcat.util.threads.ThreadPoolExecutor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableAsync; + +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.TimeUnit; + +/** + * @author Enzo + * 线程池配置总类,用于配置线程池 + */ +@Configuration +@EnableAsync +public class ThreadPoolSendMessage { + + + /** + * produce + */ + @Value(value = "${save.task.sendMessage.corePoolSize}") + private int saveCorePoolSize = 2; + @Value(value = "${save.task.sendMessage.maxPoolSize}") + private int saveMaxPoolSize = 16; + @Value(value = "${save.task.sendMessage.queueCapacity}") + private int saveQueueCapacity = 3; + + + @Bean(value = "sendMessageTaskExecutor") + public Executor SendBigDataTaskExecutor(){ + return new ThreadPoolExecutor(saveCorePoolSize, + saveMaxPoolSize, + DefaultConstant.THREE_NUMBER, + TimeUnit.SECONDS, + new LinkedBlockingDeque<>(saveQueueCapacity), + Executors.defaultThreadFactory(), + new ThreadPoolExecutor.DiscardOldestPolicy()); + } + +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/constant/DefaultConstant.java b/eladmin-system/src/main/java/me/zhengjie/modules/constant/DefaultConstant.java index 20693ab..ed4876e 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/constant/DefaultConstant.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/constant/DefaultConstant.java @@ -39,5 +39,15 @@ public class DefaultConstant { */ public static final int TEN_NUMBER = 10; + /** + * 10 + */ + public static final int ELEVEN_NUMBER = 11; + + + /** + * 999999L + */ + public static final int SIX_LARGEST_NUMBER = 999999; } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java index fba604f..e7c1b06 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java @@ -119,6 +119,10 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { .antMatchers("/druid/**").permitAll() // 放行发送短信接口 By Enzo .antMatchers("/api/tbSendSms/url/**").permitAll() + + .antMatchers("/api/smsConfiguration/detail").permitAll() + // 爬取数据请求 用户小程序过审 By Enzo + .antMatchers("/api/consult/**").permitAll() // 放行OPTIONS请求 .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() // 自定义匿名访问所有url放行:允许匿名和带Token访问,细腻化到每个 Request 类型 diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/security/JwtAuthenticationEntryPoint.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/security/JwtAuthenticationEntryPoint.java index 2ec7e64..f881586 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/security/JwtAuthenticationEntryPoint.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/security/JwtAuthenticationEntryPoint.java @@ -22,7 +22,6 @@ import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.io.Serializable; /** * @author Zheng Jie diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/sms/domain/SmsConfiguration.java b/eladmin-system/src/main/java/me/zhengjie/modules/sms/domain/SmsConfiguration.java new file mode 100644 index 0000000..d3ed32e --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/sms/domain/SmsConfiguration.java @@ -0,0 +1,79 @@ +/* +* Copyright 2019-2020 Zheng Jie +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package me.zhengjie.modules.sms.domain; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.hibernate.annotations.CreationTimestamp; +import org.springframework.data.annotation.LastModifiedDate; + +import javax.persistence.*; +import java.io.Serializable; +import java.sql.Timestamp; + +/** +* @website https://el-admin.vip +* @description / +* @author Enzo +* @date 2021-09-07 +**/ +@Data +@Entity +@Table(name="tb_sms_configuration") +public class SmsConfiguration implements Serializable { + + @Id + @Column(name = "id") + @ApiModelProperty(value = "配置id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "user_id") + @ApiModelProperty(value = "角色ID") + private Long userId; + + @Column(name = "message_content") + @ApiModelProperty(value = "短信内容") + private String messageContent; + + @Column(name = "picture_path") + @ApiModelProperty(value = "图片路径") + private String picturePath; + + @Column(name = "image_url") + @ApiModelProperty(value = "图片路径") + private String imageUrl; + + @Column(name = "link_address") + @ApiModelProperty(value = "跳转链接") + private String linkAddress; + + @CreationTimestamp + @Column(name = "create_time") + @ApiModelProperty(value = "创建日期") + private Timestamp createTime; + + @LastModifiedDate + @Column(name = "update_time") + @ApiModelProperty(value = "更新时间") + private Timestamp updateTime; + + public void copy(SmsConfiguration source){ + BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/sms/repository/SmsConfigurationRepository.java b/eladmin-system/src/main/java/me/zhengjie/modules/sms/repository/SmsConfigurationRepository.java new file mode 100644 index 0000000..e56f976 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/sms/repository/SmsConfigurationRepository.java @@ -0,0 +1,35 @@ +/* +* Copyright 2019-2020 Zheng Jie +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package me.zhengjie.modules.sms.repository; + +import me.zhengjie.modules.sms.domain.SmsConfiguration; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +/** +* @website https://el-admin.vip +* @author Enzo +* @date 2021-09-07 +**/ +public interface SmsConfigurationRepository extends JpaRepository, JpaSpecificationExecutor { + /** + * 用户id查找 + * @param userId + * @return + */ + SmsConfiguration findByUserId(Long userId); + +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/sms/rest/ConsultController.java b/eladmin-system/src/main/java/me/zhengjie/modules/sms/rest/ConsultController.java new file mode 100644 index 0000000..2556116 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/sms/rest/ConsultController.java @@ -0,0 +1,66 @@ +package me.zhengjie.modules.sms.rest; + +import io.swagger.annotations.Api; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.Log; +import me.zhengjie.domain.vo.ConsultVo; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author Enzo + * @date : 2021/9/8 + * + */ +@Api("获取咨询类信息") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/consult") +public class ConsultController { + + @Log("查询短信配置参数") + @GetMapping("/detail") + public ResponseEntity detail(String linkUrl) throws Exception { + //document相当于是个js直接操作js一样必须要联网 这一步就是获取当前网页的所有元素,接下来的操作和js差不多了 + Document document = Jsoup.parse(new URL(linkUrl), 3000000); + Elements body = document.getElementsByClass("post_body"); + List list = new ArrayList<>(); + for (Element element : body) { + list.add(element.getElementsByTag("p").text()); + } + return new ResponseEntity<>(list, HttpStatus.OK); + } + + @Log("获取咨询类信息") + @GetMapping("/list") + public ResponseEntity> getData() throws Exception { + //爬取的网 + String url = "https://sports.163.com/"; + List consultVos = new ArrayList<>(); + //document相当于是个js直接操作js一样必须要联网 这一步就是获取当前网页的所有元素,接下来的操作和js差不多了 + Document document = Jsoup.parse(new URL(url), 3000000); + Elements titles = document.getElementsByClass("news_article"); + ConsultVo consultVo; + for (int i = titles.size() - 1; i >= 0; i--) { + consultVo = new ConsultVo(); + consultVo.setTitle(titles.get(i).text()); + consultVo.setLinkUrl(titles.get(i).getElementsByTag("a").attr("href")); + consultVo.setPicUrl(titles.get(i).getElementsByTag("a").get(0).getElementsByTag("img").get(0).absUrl("src")); + consultVos.add(consultVo); + } + Collections.shuffle(consultVos); + return new ResponseEntity<>(consultVos.subList(0, 20), HttpStatus.OK); + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/sms/rest/SmsConfigurationController.java b/eladmin-system/src/main/java/me/zhengjie/modules/sms/rest/SmsConfigurationController.java new file mode 100644 index 0000000..f6ba02a --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/sms/rest/SmsConfigurationController.java @@ -0,0 +1,124 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.sms.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import me.zhengjie.annotation.Log; +import me.zhengjie.common.http.CommonResponse; +import me.zhengjie.common.http.ResponseCode; +import me.zhengjie.modules.sms.domain.SmsConfiguration; +import me.zhengjie.modules.sms.service.SmsConfigurationService; +import me.zhengjie.modules.sms.service.dto.SmsConfigurationDto; +import me.zhengjie.modules.sms.service.dto.SmsConfigurationQueryCriteria; +import me.zhengjie.modules.sms.vo.UploadAndSendMessageVo; +import me.zhengjie.utils.SecurityUtils; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * @author Enzo + * @website https://el-admin.vip + * @date 2021-09-07 + **/ +@RestController +@RequiredArgsConstructor +@Api(tags = "短信配置管理") +@RequestMapping("/api/smsConfiguration") +public class SmsConfigurationController { + + private final SmsConfigurationService smsConfigurationService; + + @Log("导出数据") + @ApiOperation("导出数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('SmsConfiguration:list')") + public void download(HttpServletResponse response, SmsConfigurationQueryCriteria criteria) throws IOException { + smsConfigurationService.download(smsConfigurationService.queryAll(criteria), response); + } + + @GetMapping + @Log("查询短信配置参数") + @ApiOperation("查询短信配置参数") + @PreAuthorize("@el.check('SmsConfiguration:list')") + public ResponseEntity query(SmsConfigurationQueryCriteria criteria, Pageable pageable) { + return new ResponseEntity<>(smsConfigurationService.queryAll(criteria, pageable), HttpStatus.OK); + } + + @PostMapping + @Log("新增短信配置参数") + @ApiOperation("新增新增短信配置参数") + @PreAuthorize("@el.check('SmsConfiguration:add')") + public ResponseEntity create(@Validated @RequestBody SmsConfiguration resources) { + return new ResponseEntity<>(smsConfigurationService.create(resources, SecurityUtils.getCurrentUserId()), HttpStatus.CREATED); + } + + @GetMapping("/detail") + @Log("获取短信配置详情") + @ApiOperation("获取短信配置详情") + public ResponseEntity detail(Long id) { + return new ResponseEntity<>(smsConfigurationService. + getSmsConfiguration(id), HttpStatus.OK); + } + + @PutMapping + @Log("修改短信配置参数") + @ApiOperation("修改修改短信配置参数") + @PreAuthorize("@el.check('SmsConfiguration:edit')") + public ResponseEntity update(@Validated @RequestBody SmsConfiguration resources) { + smsConfigurationService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @Log("删除短信配置") + @ApiOperation("删除短信配置") + @PreAuthorize("@el.check('SmsConfiguration:del')") + @DeleteMapping + public ResponseEntity delete(@RequestBody Long[] ids) { + smsConfigurationService.deleteAll(ids); + return new ResponseEntity<>(HttpStatus.OK); + } + + + @Log("上传并发送短信") + @ApiOperation("上传发送短信") + @PostMapping("/fileSendMessage") + public ResponseEntity fileSendMessage(@RequestParam("file") MultipartFile file, + UploadAndSendMessageVo messageVo) { + // 校验上传是否有文件 + if (file == null) { + return new ResponseEntity<>(CommonResponse.createByError(ResponseCode.NO_FILE_INPUT), HttpStatus.OK); + } + Boolean result = smsConfigurationService. + uploadAndSendMessage(file, messageVo, SecurityUtils.getCurrentUserId()); + return result != null && result ? + new ResponseEntity<>(CommonResponse.createBySuccess + (ResponseCode.SUCCESS), HttpStatus.OK) + : new ResponseEntity<>(CommonResponse.createByError + (ResponseCode.ERROR), HttpStatus.INTERNAL_SERVER_ERROR); + } + + +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/sms/service/SmsConfigurationService.java b/eladmin-system/src/main/java/me/zhengjie/modules/sms/service/SmsConfigurationService.java new file mode 100644 index 0000000..1dfaa58 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/sms/service/SmsConfigurationService.java @@ -0,0 +1,104 @@ +/* +* Copyright 2019-2020 Zheng Jie +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package me.zhengjie.modules.sms.service; + +import me.zhengjie.modules.sms.domain.SmsConfiguration; +import me.zhengjie.modules.sms.service.dto.SmsConfigurationDto; +import me.zhengjie.modules.sms.service.dto.SmsConfigurationQueryCriteria; +import me.zhengjie.modules.sms.vo.UploadAndSendMessageVo; +import org.springframework.data.domain.Pageable; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +/** +* @website https://el-admin.vip +* @description 服务接口 +* @author Enzo +* @date 2021-09-07 +**/ +public interface SmsConfigurationService { + + /** + * 查询数据分页 + * @param criteria 条件 + * @param pageable 分页参数 + * @return Map + */ + Map queryAll(SmsConfigurationQueryCriteria criteria, Pageable pageable); + + /** + * 查询所有数据不分页 + * @param criteria 条件参数 + * @return List + */ + List queryAll(SmsConfigurationQueryCriteria criteria); + + /** + * 根据ID查询 + * @param userId ID + * @return SmsConfigurationDto + */ + SmsConfigurationDto findById(Long userId); + + /** + * 创建 + * @param resources / + * @param currentUserId 用户id + * @return SmsConfigurationDto + */ + SmsConfigurationDto create(SmsConfiguration resources, Long currentUserId); + + /** + * 编辑 + * @param resources / + */ + void update(SmsConfiguration resources); + + /** + * 多选删除 + * @param ids / + */ + void deleteAll(Long[] ids); + + /** + * 导出数据 + * @param all 待导出的数据 + * @param response / + * @throws IOException / + */ + void download(List all, HttpServletResponse response) throws IOException; + + /** + * 获取详情 + * @param id id + * @return SmsConfigurationDto + */ + SmsConfigurationDto getSmsConfiguration(Long id); + + /** + * 上传并发送消息 + * + * @param files + * @param messageVo + * @param currentUserId + * @return + */ + Boolean uploadAndSendMessage(MultipartFile files, UploadAndSendMessageVo messageVo, Long currentUserId); +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/sms/service/TbSendSmsService.java b/eladmin-system/src/main/java/me/zhengjie/modules/sms/service/TbSendSmsService.java index 9958722..c758f04 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/sms/service/TbSendSmsService.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/sms/service/TbSendSmsService.java @@ -95,4 +95,11 @@ public interface TbSendSmsService { * @return */ boolean updateSmsStatusByLinkUrl(String linkUrl); + + + /** + * 生成实体 + * @param tbSendSms + */ + void save(TbSendSms tbSendSms); } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/sms/service/dto/SmsConfigurationDto.java b/eladmin-system/src/main/java/me/zhengjie/modules/sms/service/dto/SmsConfigurationDto.java new file mode 100644 index 0000000..865487a --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/sms/service/dto/SmsConfigurationDto.java @@ -0,0 +1,61 @@ +/* +* Copyright 2019-2020 Zheng Jie +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package me.zhengjie.modules.sms.service.dto; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import lombok.Data; + +import java.io.Serializable; +import java.sql.Timestamp; + +/** +* @website https://el-admin.vip +* @description / +* @author Enzo +* @date 2021-09-07 +**/ +@Data +public class SmsConfigurationDto implements Serializable { + + /** 配置id */ + /** 防止精度丢失 */ + @JsonSerialize(using= ToStringSerializer.class) + private Long id; + + /** 角色ID */ + /** 防止精度丢失 */ + @JsonSerialize(using= ToStringSerializer.class) + private Long userId; + + /** 短信内容 */ + private String messageContent; + + /** 图片路径 */ + private String picturePath; + + /** 跳转链接 */ + private String linkAddress; + + /** 背景图片 */ + private String imageUrl; + + /** 创建日期 */ + private Timestamp createTime; + + /** 更新时间 */ + private Timestamp updateTime; +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/sms/service/dto/SmsConfigurationQueryCriteria.java b/eladmin-system/src/main/java/me/zhengjie/modules/sms/service/dto/SmsConfigurationQueryCriteria.java new file mode 100644 index 0000000..a03f753 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/sms/service/dto/SmsConfigurationQueryCriteria.java @@ -0,0 +1,27 @@ +/* +* Copyright 2019-2020 Zheng Jie +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package me.zhengjie.modules.sms.service.dto; + +import lombok.Data; + +/** +* @website https://el-admin.vip +* @author Enzo +* @date 2021-09-07 +**/ +@Data +public class SmsConfigurationQueryCriteria{ +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/sms/service/impl/SmsConfigurationServiceImpl.java b/eladmin-system/src/main/java/me/zhengjie/modules/sms/service/impl/SmsConfigurationServiceImpl.java new file mode 100644 index 0000000..8bb1e59 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/sms/service/impl/SmsConfigurationServiceImpl.java @@ -0,0 +1,187 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.modules.sms.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.lang.Snowflake; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.annotation.rest.RedisLock; +import me.zhengjie.common.http.ResponseCode; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.constant.DefaultConstant; +import me.zhengjie.modules.sms.domain.SmsConfiguration; +import me.zhengjie.modules.sms.repository.SmsConfigurationRepository; +import me.zhengjie.modules.sms.service.SmsConfigurationService; +import me.zhengjie.modules.sms.service.dto.SmsConfigurationDto; +import me.zhengjie.modules.sms.service.dto.SmsConfigurationQueryCriteria; +import me.zhengjie.modules.sms.service.mapstruct.SmsConfigurationMapper; +import me.zhengjie.modules.sms.vo.UploadAndSendMessageVo; +import me.zhengjie.modules.uploadnew.service.TbUploadFileNewService; +import me.zhengjie.modules.uploadnew.service.dto.TbUploadFileNewDto; +import me.zhengjie.modules.uploadnew.task.SendMessageTask; +import me.zhengjie.utils.FileUtil; +import me.zhengjie.utils.PageUtil; +import me.zhengjie.utils.QueryHelp; +import me.zhengjie.utils.ValidationUtil; +import org.apache.commons.lang3.StringUtils; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; + +import static me.zhengjie.modules.upload.consts.UploadFileConst.FILE_PATH_SPLIT; + +/** + * @author Enzo + * @website https://el-admin.vip + * @description 服务实现 + * @date 2021-09-07 + **/ +@Slf4j +@Service +@RequiredArgsConstructor +public class SmsConfigurationServiceImpl implements SmsConfigurationService { + + + private final SendMessageTask sendMessageTask; + + private final TbUploadFileNewService tbUploadFileNewService; + + private final SmsConfigurationMapper smsConfigurationMapper; + + private final SmsConfigurationRepository smsConfigurationRepository; + + @Override + public Map queryAll(SmsConfigurationQueryCriteria criteria, Pageable pageable) { + Page page = smsConfigurationRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable); + return PageUtil.toPage(page.map(smsConfigurationMapper::toDto)); + } + + @Override + public List queryAll(SmsConfigurationQueryCriteria criteria) { + return smsConfigurationMapper.toDto(smsConfigurationRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder))); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public SmsConfigurationDto findById(Long userId) { + SmsConfiguration smsConfiguration = smsConfigurationRepository.findById(userId).orElseGet(SmsConfiguration::new); + ValidationUtil.isNull(smsConfiguration.getUserId(), "SmsConfiguration", "userId", userId); + return smsConfigurationMapper.toDto(smsConfiguration); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public SmsConfigurationDto create(SmsConfiguration resources, Long currentUserId) { + Snowflake snowflake = IdUtil.createSnowflake(1, 1); + resources.setUserId(currentUserId); + resources.setId(snowflake.nextId()); + return smsConfigurationMapper.toDto(smsConfigurationRepository.save(resources)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(SmsConfiguration resources) { + SmsConfiguration smsConfiguration = smsConfigurationRepository.findById(resources.getUserId()).orElseGet(SmsConfiguration::new); + ValidationUtil.isNull(smsConfiguration.getUserId(), "SmsConfiguration", "id", resources.getUserId()); + smsConfiguration.copy(resources); + smsConfigurationRepository.save(smsConfiguration); + } + + @Override + public void deleteAll(Long[] ids) { + for (Long userId : ids) { + smsConfigurationRepository.deleteById(userId); + } + } + + @Override + public void download(List all, HttpServletResponse response) throws IOException { + List> list = new ArrayList<>(); + for (SmsConfigurationDto smsConfigurationDto : all) { + Map map = new LinkedHashMap<>(); + map.put("短信内容", smsConfigurationDto.getMessageContent()); + map.put("图片路径", smsConfigurationDto.getPicturePath()); + map.put("跳转链接", smsConfigurationDto.getLinkAddress()); + map.put("创建日期", smsConfigurationDto.getCreateTime()); + map.put("更新时间", smsConfigurationDto.getUpdateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } + + @Override + public SmsConfigurationDto getSmsConfiguration(Long id) { + SmsConfiguration smsConfiguration = smsConfigurationRepository.findById(id).orElseGet(SmsConfiguration::new); + ValidationUtil.isNull(smsConfiguration, "SmsConfiguration", "id", smsConfiguration.getId()); + return smsConfigurationMapper.toDto(smsConfiguration); + } + + @Override + @RedisLock(lockName = "uploadSendMessage", key = "#currentUserId") + public Boolean uploadAndSendMessage(MultipartFile file, UploadAndSendMessageVo messageVo, Long currentUserId) { + String name = file.getOriginalFilename(); + String taskName = messageVo.getTaskName(); + if (name != null) { + int lastIndexOf = name.lastIndexOf(StrUtil.DOT); + // 校验文件格式 + String nameStr = name.substring(lastIndexOf); + if (!((".xlsx".equals(nameStr) + || ".xls".equals(nameStr)) + || ".txt".equals(nameStr) + || ".csv".equals(nameStr))) { + throw new BadRequestException(ResponseCode.NO_FILE_FORMAT.getDesc()); + } + // 任务名称检验,为必填参数,且不能重复 + if (StringUtils.isNotBlank(taskName)) { + if (StringUtils.contains(taskName, FILE_PATH_SPLIT)) { + taskName = taskName.substring(0, taskName.length() - 1); + } + TbUploadFileNewDto tbUploadFileNewDto = tbUploadFileNewService.findByTaskName(taskName); + if (tbUploadFileNewDto != null) { + throw new BadRequestException(ResponseCode.TASK_NAME_IS_EXIST.getDesc()); + } + } + // 生成本地文件 + TbUploadFileNewDto tbUploadFileNewDto = tbUploadFileNewService. + encryptDataAndSaveToFileNew(file, messageVo.getUploadType(), taskName, DefaultConstant.ZERO_NUMBER); + // 如果临时生成失败就修改状态为失败 + if (Objects.isNull(tbUploadFileNewDto)) { + log.error("TbUploadFileNewController:fileUpload | Operation Fail.tbUploadFileNewDto is Null"); + throw new BadRequestException(ResponseCode.TASK_FILE_SAVE_FAIL.getDesc()); + } + SmsConfigurationDto configurationDto = createSmsConfiguration(messageVo, currentUserId); + // 调用异步任务 + sendMessageTask.doRunTask(tbUploadFileNewDto, configurationDto); + } + return Boolean.TRUE; + } + + private SmsConfigurationDto createSmsConfiguration(UploadAndSendMessageVo messageVo, Long currentUserId) { + SmsConfiguration smsConfiguration = new SmsConfiguration(); + BeanUtil.copyProperties(messageVo, smsConfiguration); + smsConfiguration.setUserId(currentUserId); + return smsConfigurationMapper.toDto(smsConfigurationRepository.save(smsConfiguration)); + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/sms/service/impl/TbSendSmsServiceImpl.java b/eladmin-system/src/main/java/me/zhengjie/modules/sms/service/impl/TbSendSmsServiceImpl.java index 55d0bff..f6b7778 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/sms/service/impl/TbSendSmsServiceImpl.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/sms/service/impl/TbSendSmsServiceImpl.java @@ -40,6 +40,7 @@ import me.zhengjie.modules.sms.service.TbSendSmsService; import me.zhengjie.modules.sms.service.dto.TbSendSmsDto; import me.zhengjie.modules.sms.service.dto.TbSendSmsQueryCriteria; import me.zhengjie.modules.sms.service.mapstruct.TbSendSmsMapper; +import me.zhengjie.modules.sms.util.SmsUtil; import me.zhengjie.modules.sms.vo.SendVo; import me.zhengjie.modules.upload.task.model.SendSmsJsonContent; import me.zhengjie.utils.FileUtil; @@ -200,7 +201,8 @@ public class TbSendSmsServiceImpl implements TbSendSmsService { sendSms.setSendMessage(sendMessage); sendSms.setTemplateId(template.getId()); sendSms.setSendTime(new Timestamp(System.currentTimeMillis())); - boolean sendResult = sendBusinessSms(phone, sendMessage); + /* update send sms service by Enzo 2021-9-10*/ + boolean sendResult = SmsUtil.sendSms(phone, sendMessage, template.getId()); sendSms.setSendStatus(sendResult ? StatusEnum.SUCCESS.getValue() : StatusEnum.UNSUCCESSFUL.getValue()); tbSendSmsRepository.save(sendSms); } @@ -219,6 +221,11 @@ public class TbSendSmsServiceImpl implements TbSendSmsService { return Boolean.FALSE; } + @Override + public void save(TbSendSms tbSendSms) { + tbSendSmsRepository.save(tbSendSms); + } + private boolean sendBusinessSms(String phone, String templateMessage) { SendSmsJsonContent sendSmsJsonContent = new SendSmsJsonContent(); sendSmsJsonContent.setMobile(phone); @@ -241,7 +248,7 @@ public class TbSendSmsServiceImpl implements TbSendSmsService { HttpResponse httpResponse; try { httpResponse = HttpRequest - .post(SmsConstant.SMS_LINK) + .post(SmsConstant.DABA_SMS_LINK) .header("Content-Type", "application/json;charset=utf-8") .body(readSendJsonStr) .execute(); diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/sms/service/mapstruct/SmsConfigurationMapper.java b/eladmin-system/src/main/java/me/zhengjie/modules/sms/service/mapstruct/SmsConfigurationMapper.java new file mode 100644 index 0000000..ba67b6b --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/sms/service/mapstruct/SmsConfigurationMapper.java @@ -0,0 +1,32 @@ +/* +* Copyright 2019-2020 Zheng Jie +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package me.zhengjie.modules.sms.service.mapstruct; + +import me.zhengjie.base.BaseMapper; +import me.zhengjie.modules.sms.domain.SmsConfiguration; +import me.zhengjie.modules.sms.service.dto.SmsConfigurationDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @website https://el-admin.vip +* @author Enzo +* @date 2021-09-07 +**/ +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface SmsConfigurationMapper extends BaseMapper { + +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/sms/util/SmsUtil.java b/eladmin-system/src/main/java/me/zhengjie/modules/sms/util/SmsUtil.java index a215a3b..e2569a9 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/sms/util/SmsUtil.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/sms/util/SmsUtil.java @@ -1,5 +1,7 @@ package me.zhengjie.modules.sms.util; +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONUtil; import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.IAcsClient; import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsRequest; @@ -9,11 +11,15 @@ import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse; import com.aliyuncs.exceptions.ClientException; import com.aliyuncs.profile.DefaultProfile; import com.aliyuncs.profile.IClientProfile; +import me.zhengjie.constant.SmsConstant; +import me.zhengjie.modules.constant.DefaultConstant; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.HashMap; +import java.util.Map; /** * @author aliyunsms @@ -40,10 +46,10 @@ public class SmsUtil { /** * 发送短信 * - * @param mobile 手机号 + * @param mobile 手机号 * @param templateCode 模板号 * @param signName 签名 - * @param param 参数 + * @param param 参数 * @return * @throws ClientException */ @@ -104,5 +110,35 @@ public class SmsUtil { return querySendDetailsResponse; } + + /** + * 单次,多次发送短信 + * + * @return + */ + public static Boolean sendSms(String phone, String sendMessage, Long id) { + Map map = new HashMap<>(DefaultConstant.ONE_NUMBER); + map.put("phones", phone); + map.put("content", sendMessage); + map.put("appKey", SmsConstant.YUN_FENG_APP_KEY); + map.put("appSecret", SmsConstant.YUN_FENG_APP_SECRET); + map.put("bathNum", SmsConstant.YUN_FENG_BATH_NUM. + concat(String.valueOf(id))); + map.put("extraNum", String.valueOf + (id > DefaultConstant.SIX_LARGEST_NUMBER + ? DefaultConstant.SIX_LARGEST_NUMBER : id)); + try { + String response = HttpUtil + .post(SmsConstant.YUN_FENG_SMS_LINK, map); + return "000000".equals(JSONUtil.parseObj(response).get("errorCode")); + } catch (Exception e) { + e.printStackTrace(); + } + return Boolean.FALSE; + } + + public static void main(String[] args) { + sendSms("13586541001", "【浩才旗舰店】链接为 123456", 30L); + } } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/sms/vo/UploadAndSendMessageVo.java b/eladmin-system/src/main/java/me/zhengjie/modules/sms/vo/UploadAndSendMessageVo.java new file mode 100644 index 0000000..f90ad72 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/sms/vo/UploadAndSendMessageVo.java @@ -0,0 +1,34 @@ +package me.zhengjie.modules.sms.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author Enzo + * @date 2021-9-7 + */ +@Data +public class UploadAndSendMessageVo { + + + + @ApiModelProperty("上传类型") + private Integer uploadType; + + @ApiModelProperty("任务名称") + private String taskName; + + @ApiModelProperty("背景图片") + private String imageUrl; + + @ApiModelProperty(value = "短信内容") + private String messageContent; + + @ApiModelProperty(value = "图片路径") + private String picturePath; + + + + @ApiModelProperty(value = "跳转链接") + private String linkAddress; +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/upload/rest/UploadFileController.java b/eladmin-system/src/main/java/me/zhengjie/modules/upload/rest/UploadFileController.java index 8d1e3be..200a20d 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/upload/rest/UploadFileController.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/upload/rest/UploadFileController.java @@ -208,6 +208,7 @@ public class UploadFileController { // @ResponseBody public ResponseEntity fileUpload(@RequestParam("file") MultipartFile file, @RequestParam(value = "taskName") String taskName, + @RequestParam(value = "uploadType") Integer uploadType, @RequestParam(value = "isEcryptionNew") String isEcryptionNew, ServletRequest servletRequest) { // 记录日志 @@ -271,7 +272,7 @@ public class UploadFileController { return new ResponseEntity<>(CommonResponse.createByError(ResponseCode.EMPTY_ARGUMENT), HttpStatus.OK); } // 生成本地文件 - TbUploadFileNewDto tbUploadFileNewDto = tbUploadFileNewService.encryptDataAndSaveToFileNew(file, taskName, isEcryption); + TbUploadFileNewDto tbUploadFileNewDto = tbUploadFileNewService.encryptDataAndSaveToFileNew(file, uploadType, taskName, isEcryption); // 如果临时生成失败就修改状态为失败 if (Objects.isNull(tbUploadFileNewDto)){ log.error("TbUploadFileNewController:fileUpload | Operation Fail.tbUploadFileNewDto is Null"); @@ -283,4 +284,4 @@ public class UploadFileController { return new ResponseEntity<>(CommonResponse.createBySuccess(ResponseCode.SUCCESS), HttpStatus.OK); } -} \ No newline at end of file +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/upload/script/trans.sh b/eladmin-system/src/main/java/me/zhengjie/modules/upload/script/trans.sh index dc53c5f..e69de29 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/upload/script/trans.sh +++ b/eladmin-system/src/main/java/me/zhengjie/modules/upload/script/trans.sh @@ -1,8 +0,0 @@ -#!/bin/bash -# please make the rsa key first - -read line < - -scp -i ~/.ssh/id_rsa devops@myserver.org:/path/to/bin/*.derp . - - diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/domain/TbUploadFileNew.java b/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/domain/TbUploadFileNew.java index db22b03..179cda4 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/domain/TbUploadFileNew.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/domain/TbUploadFileNew.java @@ -15,14 +15,14 @@ */ package me.zhengjie.modules.uploadnew.domain; -import lombok.Data; import cn.hutool.core.bean.BeanUtil; -import io.swagger.annotations.ApiModelProperty; import cn.hutool.core.bean.copier.CopyOptions; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + import javax.persistence.*; -import javax.validation.constraints.*; -import java.sql.Timestamp; import java.io.Serializable; +import java.sql.Timestamp; /** * @website https://el-admin.vip @@ -30,8 +30,8 @@ import java.io.Serializable; * @author weizhongxi * @date 2021-04-14 **/ -@Entity @Data +@Entity @Table(name="tb_upload_file_new") public class TbUploadFileNew implements Serializable { @@ -85,7 +85,11 @@ public class TbUploadFileNew implements Serializable { @ApiModelProperty(value = "文件格式") private String fileFormat; + @Column(name = "upload_type") + @ApiModelProperty(value = "上传类型") + private Integer uploadType; + public void copy(TbUploadFileNew source){ BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); } -} \ No newline at end of file +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/repository/TbUploadFileNewRepository.java b/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/repository/TbUploadFileNewRepository.java index ec9202e..5f6121a 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/repository/TbUploadFileNewRepository.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/repository/TbUploadFileNewRepository.java @@ -25,4 +25,10 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor; * @date 2021-04-14 **/ public interface TbUploadFileNewRepository extends JpaRepository, JpaSpecificationExecutor { -} \ No newline at end of file + /** + * 任务名称查找 + * @param taskName + * @return + */ + TbUploadFileNew findByUploadFileTaskName(String taskName); +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/rest/TbUploadFileNewController.java b/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/rest/TbUploadFileNewController.java index 7d4f67a..b1cac7f 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/rest/TbUploadFileNewController.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/rest/TbUploadFileNewController.java @@ -20,6 +20,7 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import io.swagger.models.auth.In; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import me.zhengjie.annotation.AnonymousAccess; @@ -259,6 +260,7 @@ public class TbUploadFileNewController { @PreAuthorize("@el.check('tbUploadFileNew:list')") // @ResponseBody public ResponseEntity fileUpload(@RequestParam("file") MultipartFile file, + @RequestParam("uploadType") Integer uploadType, @RequestParam(value = "taskName") String taskName, @RequestParam(value = "isEcryptionNew") String isEcryptionNew, ServletRequest servletRequest) { @@ -322,7 +324,7 @@ public class TbUploadFileNewController { return new ResponseEntity<>(CommonResponse.createByError(ResponseCode.EMPTY_ARGUMENT), HttpStatus.OK); } // 生成本地文件 - TbUploadFileNewDto tbUploadFileNewDto = tbUploadFileNewService.encryptDataAndSaveToFileNew(file, taskName, isEcryption); + TbUploadFileNewDto tbUploadFileNewDto = tbUploadFileNewService.encryptDataAndSaveToFileNew(file, uploadType, taskName, isEcryption); // 如果临时生成失败就修改状态为失败 if (Objects.isNull(tbUploadFileNewDto)) { log.error("TbUploadFileNewController:fileUpload | Operation Fail.tbUploadFileNewDto is Null"); @@ -334,22 +336,7 @@ public class TbUploadFileNewController { return new ResponseEntity<>(CommonResponse.createBySuccess(ResponseCode.SUCCESS), HttpStatus.OK); } - @Log("上传并加密任务") - @ApiOperation("上传并加密任务") - @AnonymousAccess - @PostMapping("/aa") -// @ResponseBody - public ResponseEntity aa() { - RedisParentDao redisParentDao = new RedisParentDao(); - redisParentDao.setRedisTemplate(redisTemplate); - redisParentDao.cacheValue("111", "2222", 180000); - String value = redisParentDao.getValue("111"); - System.out.println("value = " + value); - redisParentDao.remove("111"); - String value1 = redisParentDao.getValue("111"); - System.out.println("value = " + value1); - return new ResponseEntity<>(CommonResponse.createBySuccess(ResponseCode.SUCCESS), HttpStatus.OK); - } + } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/service/TbUploadFileNewService.java b/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/service/TbUploadFileNewService.java index 55befca..6a4c6cd 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/service/TbUploadFileNewService.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/service/TbUploadFileNewService.java @@ -85,10 +85,18 @@ public interface TbUploadFileNewService { /** * 加密并生成存储文件 - * * @param file + * @param uploadType * @param taskName * @param isEcryption + * @return */ - TbUploadFileNewDto encryptDataAndSaveToFileNew(MultipartFile file, String taskName,Integer isEcryption); -} \ No newline at end of file + TbUploadFileNewDto encryptDataAndSaveToFileNew(MultipartFile file, Integer uploadType, String taskName, Integer isEcryption); + + /** + * 任务名称查询 + * @param taskName + * @return + */ + TbUploadFileNewDto findByTaskName(String taskName); +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/service/dto/TbUploadFileNewQueryCriteria.java b/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/service/dto/TbUploadFileNewQueryCriteria.java index 070999d..d4a4144 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/service/dto/TbUploadFileNewQueryCriteria.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/service/dto/TbUploadFileNewQueryCriteria.java @@ -50,6 +50,10 @@ public class TbUploadFileNewQueryCriteria{ @Query(type = Query.Type.NOT_NULL) private Integer isEncryption; + /** 精准 */ + @Query + private Integer uploadType; + /** 模糊 */ @Query(type = Query.Type.INNER_LIKE) private String fileFormat; @@ -59,4 +63,4 @@ public class TbUploadFileNewQueryCriteria{ /** BETWEEN */ @Query(type = Query.Type.BETWEEN) private List uploadTime; -} \ No newline at end of file +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/service/impl/TbUploadFileNewServiceImpl.java b/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/service/impl/TbUploadFileNewServiceImpl.java index 834fadb..294a785 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/service/impl/TbUploadFileNewServiceImpl.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/service/impl/TbUploadFileNewServiceImpl.java @@ -144,7 +144,7 @@ public class TbUploadFileNewServiceImpl implements TbUploadFileNewService { } @Override - public TbUploadFileNewDto encryptDataAndSaveToFileNew(MultipartFile file, String taskName, Integer isEcryption) { + public TbUploadFileNewDto encryptDataAndSaveToFileNew(MultipartFile file, Integer uploadType, String taskName, Integer isEcryption) { // 1. 文件存储到本地 long count = 0; // 统计总数 String baseStr = ""; // 生成通用随机文件夹存放每次的文件 @@ -174,7 +174,7 @@ public class TbUploadFileNewServiceImpl implements TbUploadFileNewService { List list = null; //根据文件类型进行解析 try { - // FIXME: 2021/4/23 0023 + // FIXME: 2021/4/23 0023 if (nameStr.equals(".xlsx") || nameStr.equals(".xls")) { fileFormat = "excel文件"; ExcelUtils excelUtils = new ExcelUtils(); @@ -211,6 +211,9 @@ public class TbUploadFileNewServiceImpl implements TbUploadFileNewService { currentUsername = SecurityUtils.getCurrentUsername(); tbUploadFileNew.setOperation(currentUsername); } + + /* update by enzo update file upload type date 2021-9-7*/ + tbUploadFileNew.setUploadType(uploadType); tbUploadFileNew.setFileFormat(fileFormat); tbUploadFileNew.setIsEncryption(isEcryption); tbUploadFileNew.setFileCount(count); @@ -228,6 +231,7 @@ public class TbUploadFileNewServiceImpl implements TbUploadFileNewService { return tbUploadFileNewDto; } + /** * 构建文件上传保存路径 */ @@ -261,4 +265,15 @@ public class TbUploadFileNewServiceImpl implements TbUploadFileNewService { return ""; } } -} \ No newline at end of file + + + @Override + public TbUploadFileNewDto findByTaskName(String taskName) { + TbUploadFileNew byTaskName = tbUploadFileNewRepository.findByUploadFileTaskName(taskName); + if (byTaskName != null) { + return tbUploadFileNewMapper.toDto(byTaskName); + } + return null; + } + +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/task/SendMessageTask.java b/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/task/SendMessageTask.java new file mode 100644 index 0000000..f95a8bc --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/uploadnew/task/SendMessageTask.java @@ -0,0 +1,161 @@ +package me.zhengjie.modules.uploadnew.task; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSON; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.zhengjie.constant.SmsConstant; +import me.zhengjie.exception.BadRequestException; +import me.zhengjie.modules.constant.DefaultConstant; +import me.zhengjie.modules.sms.domain.TbSendSms; +import me.zhengjie.modules.sms.dto.ShortLinkUrlDto; +import me.zhengjie.modules.sms.service.TbSendSmsService; +import me.zhengjie.modules.sms.service.dto.SmsConfigurationDto; +import me.zhengjie.modules.sms.util.SmsUtil; +import me.zhengjie.modules.uploadnew.domain.TbUploadFileNew; +import me.zhengjie.modules.uploadnew.service.TbUploadFileNewService; +import me.zhengjie.modules.uploadnew.service.dto.TbUploadFileNewDto; +import me.zhengjie.modules.uploadnew.util.ExcelUtils; +import me.zhengjie.modules.uploadnew.util.TxtUtils; +import me.zhengjie.utils.ConvertUtil; +import me.zhengjie.utils.FileUtil; +import me.zhengjie.utils.enums.StatusEnum; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +import java.nio.charset.StandardCharsets; +import java.sql.Timestamp; +import java.time.Instant; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static me.zhengjie.modules.upload.consts.UploadFileConst.FAIL_TAG; +import static me.zhengjie.modules.upload.consts.UploadFileConst.SUCCESS_TAG; + +/** + * @author Enzo + * @date 2021-9-7 + */ +@RequiredArgsConstructor +@Component +@Slf4j +public class SendMessageTask { + + private final TbSendSmsService tbSendSmsService; + + private final TbUploadFileNewService tbUploadFileNewService; + + @Async(value = "sendMessageTaskExecutor") + public void doRunTask(TbUploadFileNewDto tbUploadFileNewDto, SmsConfigurationDto smsConfigurationDto) { + Long startMilliSecond = Instant.now().toEpochMilli(); + log.info("====== [ task start running, task name is {} ] ======", "sendMessageTask"); + runTask(tbUploadFileNewDto, smsConfigurationDto); + Long endMilliSecond = Instant.now().toEpochMilli(); + log.info("====== [ task start end, task name is {},cost milliSecond is {} ] ======", "sendMessageTask", ConvertUtil.secondToTime(endMilliSecond - startMilliSecond)); + } + + /** + * 执行异步任务 + * + * @param tbUploadFileNewDto 需要传输用到的Bean + * @param smsConfigurationDto + */ + private void runTask(TbUploadFileNewDto tbUploadFileNewDto, SmsConfigurationDto smsConfigurationDto) { + // 获取需求的地址 + String tempFilesPath = tbUploadFileNewDto.getLocalSavePath(); + // 单文件处理 + boolean finalTag = handleEachFileContent(tempFilesPath, tbUploadFileNewDto.getFileFormat(), smsConfigurationDto); + // 更新状态为成功,更新解析成功的条数 + TbUploadFileNew tbUploadFileNew = new TbUploadFileNew(); + BeanUtils.copyProperties(tbUploadFileNewDto, tbUploadFileNew); + tbUploadFileNew.setFileTransSuccessCount(tbUploadFileNewDto.getFileCount()); + tbUploadFileNew.setUploadTag(finalTag ? SUCCESS_TAG : FAIL_TAG); + tbUploadFileNewService.update(tbUploadFileNew); + } + + /** + * 对每一个文件的处理操作 + * + * @param filePath 进行操作的每一个文件的路径 + * @param smsConfigurationDto + */ + private boolean handleEachFileContent(String filePath, String fileFormat, SmsConfigurationDto smsConfigurationDto) { + //根据文件类型进行解析 + List list = null; + try { + if ("excel文件".equals(fileFormat)) { + ExcelUtils excelUtils = new ExcelUtils(); + list = excelUtils.excelParseListByUrl(filePath); + } else if ("txt文件".equals(fileFormat)) { + list = TxtUtils.txtParseListVyUrl(filePath); + } else if ("csv文件".equals(fileFormat)) { + list = TxtUtils.csvParseListByUrl(filePath); + } + } catch (Exception e) { + log.error("SaveToFileTaskNew|batchSendToEncrypt ready send json is : {}", ""); + throw new BadRequestException("解析文件异常"); + } + if (!CollectionUtils.isEmpty(list)) { + List stringList = list.stream().filter + (phone -> phone.trim().getBytes(StandardCharsets.UTF_8).length == DefaultConstant.ELEVEN_NUMBER). + collect((Collectors.toList())); + Map map = new HashMap<>(DefaultConstant.TWO_NUMBER); + if (!CollectionUtils.isEmpty(stringList)) { + map.put("baseUrlAddr", SmsConstant.LINK_ADDRESS.concat + (smsConfigurationDto.getId().toString())); + map.put("variableList", stringList); + // 接收生成短链参数 + ShortLinkUrlDto urlDto = + JSONUtil.toBean(HttpUtil.post + (SmsConstant.SHORT_GENERATION_LINK, + JSON.toJSONString(map)), + ShortLinkUrlDto.class); + String phone; + String linkUrl; + TbSendSms sendSms; + if (!CollectionUtils.isEmpty(urlDto.getData().getShortChainResult())) { + for (String resultUrl : urlDto.getData().getShortChainResult()) { + sendSms = new TbSendSms(); + // StrUtil 工具类 + String[] split = StringUtils.split(resultUrl, SmsConstant.VERTICAL_LINE); + phone = split[1]; + linkUrl = split[0]; + String sendMessage = smsConfigurationDto.getMessageContent().replace + ("${url}", + StrUtil.SPACE + + SmsConstant.SHORT_CHAIN_PREFIX + linkUrl + StrUtil.SPACE); + sendSms.setPhone(phone); + sendSms.setLinkUrl(linkUrl); + sendSms.setSendMessage(sendMessage); + sendSms.setIsLinkCallback(DefaultConstant.ZERO_NUMBER); + sendSms.setSendTime(new Timestamp(System.currentTimeMillis())); + boolean sendResult = SmsUtil.sendSms(phone, sendMessage, smsConfigurationDto.getId()); + sendSms.setSendStatus(sendResult ? StatusEnum.SUCCESS.getValue() : StatusEnum.UNSUCCESSFUL.getValue()); + tbSendSmsService.save(sendSms); + } + } + } + } + // 把临时存储的文件进行删除 + return delTempSaveFile(filePath); + } + + private boolean delTempSaveFile(String tempFilesPath) { + boolean del = FileUtil.del(tempFilesPath); + if (del) { + log.info("======== [success del file, file path is {} ] ========", tempFilesPath); + return Boolean.TRUE; + } else { + log.error("======== [fail del file, file path is {} ] ========", tempFilesPath); + return Boolean.FALSE; + } + } + +} diff --git a/eladmin-system/src/main/resources/config/application-dev.yml b/eladmin-system/src/main/resources/config/application-dev.yml index 5b837e2..cefeb38 100644 --- a/eladmin-system/src/main/resources/config/application-dev.yml +++ b/eladmin-system/src/main/resources/config/application-dev.yml @@ -6,7 +6,7 @@ spring: driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy url: jdbc:log4jdbc:mysql://localhost:3306/eladmin-plat2?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false username: root - password: 12345678 + password: '012099' # 初始连接数 initial-size: 5 # 最小连接数 @@ -43,6 +43,14 @@ spring: wall: config: multi-statement-allow: true + redis: + #数据库索引 + database: 0 + host: 127.0.0.1 + port: 6379 + password: '012099' + #连接超时时间 + timeout: 5000 # 登录相关配置 login: @@ -114,6 +122,11 @@ file: # 线程池配置 save: task: + sendMessage: + corePoolSize: 2 + maxPoolSize: 16 + queueCapacity: 3 + ThreadNamePrefix: sendMessageTaskExecutor thread_pool: corePoolSize: 2 maxPoolSize: 16 @@ -123,5 +136,9 @@ save: sys: debug: true +redisson: + address: redis://127.0.0.1:6379 + password: '012099' + diff --git a/eladmin-system/src/main/resources/config/application-prod.yml b/eladmin-system/src/main/resources/config/application-prod.yml index 823b5e1..c5a9a85 100644 --- a/eladmin-system/src/main/resources/config/application-prod.yml +++ b/eladmin-system/src/main/resources/config/application-prod.yml @@ -4,7 +4,7 @@ spring: druid: db-type: com.alibaba.druid.pool.DruidDataSource driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy - url: jdbc:log4jdbc:mysql://localhost:3306/eladmin?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false + url: jdbc:log4jdbc:mysql://47.110.11.213:3306/eladmin?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false username: root password: Yuyou@2020 # 初始连接数 @@ -45,6 +45,14 @@ spring: wall: config: multi-statement-allow: true + redis: + #数据库索引 + database: 0 + host: 127.0.0.1 + port: 6379 + password: + #连接超时时间 + timeout: 5000 # 登录相关配置 login: @@ -123,6 +131,11 @@ file: # 线程池配置 save: task: + sendMessage: + corePoolSize: 2 + maxPoolSize: 16 + queueCapacity: 3 + ThreadNamePrefix: sendMessageTaskExecutor thread_pool: corePoolSize: 2 maxPoolSize: 16 @@ -130,4 +143,8 @@ save: ThreadNamePrefix: SaveToFileTaskExecutor- # 切换系统环境相关的配置 sys: - debug: false \ No newline at end of file + debug: false + +redisson: + address: redis://127.0.0.1:6379 + password: diff --git a/eladmin-system/src/main/resources/config/application.yml b/eladmin-system/src/main/resources/config/application.yml index f022f0c..db79fa1 100644 --- a/eladmin-system/src/main/resources/config/application.yml +++ b/eladmin-system/src/main/resources/config/application.yml @@ -22,14 +22,6 @@ spring: dialect: org.hibernate.dialect.MySQL5InnoDBDialect open-in-view: true - redis: - #数据库索引 - database: 0 - host: 127.0.0.1 - port: 6379 - password: - #连接超时时间 - timeout: 5000 task: pool: # 核心线程池大小 @@ -71,4 +63,4 @@ upload: accessKeySecret: i93lzrZwb2BUgtB9r0y0LT2Dt7tNbP bucketName: hjrecording endpoint: oss-cn-shanghai.aliyuncs.com - url: https://app.hjdata.com/api/dymaticform/channel/save? \ No newline at end of file + url: https://app.hjdata.com/api/dymaticform/channel/save? diff --git a/eladmin-tools/src/main/java/me/zhengjie/domain/vo/ConsultVo.java b/eladmin-tools/src/main/java/me/zhengjie/domain/vo/ConsultVo.java new file mode 100644 index 0000000..0fa4646 --- /dev/null +++ b/eladmin-tools/src/main/java/me/zhengjie/domain/vo/ConsultVo.java @@ -0,0 +1,22 @@ +package me.zhengjie.domain.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author Enzo + * @date : 2021/9/8 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ConsultVo { + + private String picUrl; + + private String title; + + private String linkUrl; + +} diff --git a/eladmin-tools/src/main/java/me/zhengjie/service/impl/LocalStorageServiceImpl.java b/eladmin-tools/src/main/java/me/zhengjie/service/impl/LocalStorageServiceImpl.java index 77174c4..067fe5e 100644 --- a/eladmin-tools/src/main/java/me/zhengjie/service/impl/LocalStorageServiceImpl.java +++ b/eladmin-tools/src/main/java/me/zhengjie/service/impl/LocalStorageServiceImpl.java @@ -75,8 +75,8 @@ public class LocalStorageServiceImpl implements LocalStorageService { FileUtil.checkSize(properties.getMaxSize(), multipartFile.getSize()); String suffix = FileUtil.getExtensionName(multipartFile.getOriginalFilename()); String type = FileUtil.getFileType(suffix); - File file = FileUtil.upload(multipartFile, properties.getPath().getPath() + type + File.separator); - if(ObjectUtil.isNull(file)){ + File file = FileUtil.upload(multipartFile, properties.getPath().getPath() + File.separator); + if (ObjectUtil.isNull(file)) { throw new BadRequestException("上传失败"); } try { @@ -90,7 +90,7 @@ public class LocalStorageServiceImpl implements LocalStorageService { FileUtil.getSize(multipartFile.getSize()) ); return localStorageRepository.save(localStorage); - }catch (Exception e){ + } catch (Exception e) { FileUtil.del(file); throw e; } diff --git a/pom.xml b/pom.xml index 160ca92..8905301 100644 --- a/pom.xml +++ b/pom.xml @@ -211,6 +211,20 @@ UserAgentUtils 1.21 + + + + org.redisson + redisson + 3.11.1 + + + + org.jsoup + jsoup + 1.11.3 + +