diff --git a/pqs-common/common-redis/src/main/java/com/njcn/redis/pojo/enums/AppRedisKey.java b/pqs-common/common-redis/src/main/java/com/njcn/redis/pojo/enums/AppRedisKey.java index 7ec1eb4e6..b61bd9486 100644 --- a/pqs-common/common-redis/src/main/java/com/njcn/redis/pojo/enums/AppRedisKey.java +++ b/pqs-common/common-redis/src/main/java/com/njcn/redis/pojo/enums/AppRedisKey.java @@ -41,4 +41,9 @@ public interface AppRedisKey { */ String LINE_POSITION = "LINEPOSITION"; + /** + * rocketMQ消费key + */ + String RMQ_CONSUME_KEY="rocketMQConsumeKey:"; + } diff --git a/pqs-common/common-web/src/main/java/com/njcn/web/annotation/ReturnMsg.java b/pqs-common/common-web/src/main/java/com/njcn/web/annotation/ReturnMsg.java new file mode 100644 index 000000000..a55dd3855 --- /dev/null +++ b/pqs-common/common-web/src/main/java/com/njcn/web/annotation/ReturnMsg.java @@ -0,0 +1,21 @@ +package com.njcn.web.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 自定义注解,用来判断返回信息是否需要做处理 + * @author xy + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER}) +public @interface ReturnMsg { + + /** + * 是否需要被处理 + */ + boolean isChannel() default false; + +} diff --git a/pqs-common/common-web/src/main/java/com/njcn/web/exception/GlobalBusinessExceptionHandler.java b/pqs-common/common-web/src/main/java/com/njcn/web/exception/GlobalBusinessExceptionHandler.java index 35cadf378..d186abcc2 100644 --- a/pqs-common/common-web/src/main/java/com/njcn/web/exception/GlobalBusinessExceptionHandler.java +++ b/pqs-common/common-web/src/main/java/com/njcn/web/exception/GlobalBusinessExceptionHandler.java @@ -3,12 +3,14 @@ package com.njcn.web.exception; import cn.hutool.core.text.StrFormatter; import cn.hutool.core.util.StrUtil; //import com.alibaba.excel.exception.ExcelAnalysisException; +import com.njcn.common.pojo.annotation.OperateInfo; import com.njcn.common.pojo.response.HttpResult; import com.njcn.common.pojo.enums.response.CommonResponseEnum; import com.njcn.common.pojo.exception.BusinessException; import com.njcn.common.utils.HttpResultUtil; import com.njcn.common.utils.LogUtil; import com.njcn.common.utils.ReflectCommonUtil; +import com.njcn.web.annotation.ReturnMsg; import com.njcn.web.service.ILogService; import com.njcn.web.utils.ControllerUtil; import lombok.AllArgsConstructor; @@ -24,8 +26,10 @@ import org.springframework.web.util.NestedServletException; import javax.servlet.http.HttpServletRequest; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -52,6 +56,12 @@ public class GlobalBusinessExceptionHandler { public HttpResult handleBusinessException(HttpServletRequest httpServletRequest, BusinessException businessException) { String operate = ReflectCommonUtil.getMethodDescribeByException(businessException); logService.recodeBusinessExceptionLog(businessException, httpServletRequest, businessException.getMessage()); + //判断方法上是否有自定义注解,做特殊处理 + Method method = ReflectCommonUtil.getMethod(businessException); + if(method.isAnnotationPresent(ReturnMsg.class)){ + log.info("存在自定义注解"); + return HttpResultUtil.assembleResult(businessException.getCode(), null, StrFormatter.format("{}",businessException.getMessage())); + } return HttpResultUtil.assembleBusinessExceptionResult(businessException, null, operate); } @@ -219,6 +229,12 @@ public class GlobalBusinessExceptionHandler { } LogUtil.logExceptionStackInfo(exceptionCause, tempException); logService.recodeBusinessExceptionLog(tempException, httpServletRequest, exceptionCause); + //判断方法上是否有自定义注解,做特殊处理 + Method method = ReflectCommonUtil.getMethod(exception); + if(method.isAnnotationPresent(ReturnMsg.class)){ + log.info("存在自定义注解"); + return HttpResultUtil.assembleResult(code, null, StrFormatter.format("{}",exceptionCause)); + } return HttpResultUtil.assembleResult(code, null, StrFormatter.format("{}{}{}", ReflectCommonUtil.getMethodDescribeByException(tempException), StrUtil.C_COMMA, exceptionCause)); } diff --git a/pqs-user/user-api/src/main/java/com/njcn/user/config/Message.java b/pqs-user/user-api/src/main/java/com/njcn/user/config/Message.java new file mode 100644 index 000000000..9201e751c --- /dev/null +++ b/pqs-user/user-api/src/main/java/com/njcn/user/config/Message.java @@ -0,0 +1,44 @@ +package com.njcn.user.config; + +import lombok.Data; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; + +/** + * 类的介绍:短信配置获取实体 + * + * @author xuyang + * @version 1.0.0 + * @createTime 2023/8/25 15:19 + */ +@Data +@Configuration +@Order(10) +public class Message { + + /** + * accessKeyId + */ + @Value("${message.access-key}") + private String accessKeyId; + + /** + * accessKeySecret + */ + @Value("${message.secret-key}") + private String accessKeySecret; + + /** + * 短信签名 + */ + @Value("${message.auto-graph}") + private String autoGraph; + + /** + * 连接时间参数 + */ + @Value("${message.connect-time}") + private String time; + +} diff --git a/pqs-user/user-api/src/main/java/com/njcn/user/enums/UserResponseEnum.java b/pqs-user/user-api/src/main/java/com/njcn/user/enums/UserResponseEnum.java index 2e79619ac..e7552904f 100644 --- a/pqs-user/user-api/src/main/java/com/njcn/user/enums/UserResponseEnum.java +++ b/pqs-user/user-api/src/main/java/com/njcn/user/enums/UserResponseEnum.java @@ -51,6 +51,7 @@ public enum UserResponseEnum { APP_PASSWORD("A0101", "密码长度为8-16"), REPEAT_PASSWORD("A0101", "新密码与旧密码不能一致"), + MESSAGE_SEND_FAIL("A0102", "短信发送失败"), REGISTER_FAIL("A0102", "注册失败"), REGISTER_PHONE_FAIL("A0102", "该号码已注册,请检查phone字段"), REGISTER_LOGIN_NAME_FAIL("A0102", "该账号已注册"), diff --git a/pqs-user/user-boot/src/main/java/com/njcn/user/service/impl/AppUserServiceImpl.java b/pqs-user/user-boot/src/main/java/com/njcn/user/service/impl/AppUserServiceImpl.java index 548ee1713..46925683c 100644 --- a/pqs-user/user-boot/src/main/java/com/njcn/user/service/impl/AppUserServiceImpl.java +++ b/pqs-user/user-boot/src/main/java/com/njcn/user/service/impl/AppUserServiceImpl.java @@ -1,13 +1,7 @@ package com.njcn.user.service.impl; -import com.aliyuncs.DefaultAcsClient; -import com.aliyuncs.IAcsClient; -import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest; import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse; import com.aliyuncs.exceptions.ClientException; -import com.aliyuncs.http.MethodType; -import com.aliyuncs.profile.DefaultProfile; -import com.aliyuncs.profile.IClientProfile; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.njcn.common.pojo.constant.PatternRegex; @@ -29,6 +23,7 @@ import com.njcn.user.pojo.po.User; import com.njcn.user.pojo.po.UserSet; import com.njcn.user.pojo.po.app.AppSendMsg; import com.njcn.user.service.*; +import com.njcn.user.util.SmsUtil; import lombok.AllArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -66,6 +61,8 @@ public class AppUserServiceImpl extends ServiceImpl impleme private final AppInfoSetFeignClient appInfoSetFeignClient; + private final SmsUtil smsUtil; + @Override @Transactional(rollbackFor = Exception.class) public String setMessage(String phone, String devCode, String type) { @@ -73,40 +70,9 @@ public class AppUserServiceImpl extends ServiceImpl impleme throw new BusinessException(UserResponseEnum.REGISTER_PHONE_WRONG); } SendSmsResponse sendSmsResponse = null; - String msgTemplate = null; + String msgTemplate = SmsUtil.getMessageTemplate(type); String vcode = null; try { - switch (type) { - case "0": - msgTemplate = MessageEnum.getTemplateByCode(0); - break; - case "1": - msgTemplate = MessageEnum.getTemplateByCode(1); - break; - case "2": - msgTemplate = MessageEnum.getTemplateByCode(2); - break; - case "3": - msgTemplate = MessageEnum.getTemplateByCode(3); - break; - case "4": - msgTemplate = MessageEnum.getTemplateByCode(4); - break; - case "5": - msgTemplate = MessageEnum.getTemplateByCode(5); - break; - case "6": - msgTemplate = MessageEnum.getTemplateByCode(6); - break; - case "7": - msgTemplate = MessageEnum.getTemplateByCode(7); - break; - case "8": - msgTemplate = MessageEnum.getTemplateByCode(8); - break; - default: - throw new BusinessException(UserResponseEnum.CODE_TYPE_ERROR); - } //type为4,账号替换为新手机号 if (!msgTemplate.equalsIgnoreCase(MessageEnum.REGISTER.getTemplateCode())) { User user = this.lambdaQuery().eq(User::getPhone,phone).one(); @@ -125,36 +91,9 @@ public class AppUserServiceImpl extends ServiceImpl impleme } } } - //开始执行短信发送 - //设置超时时间-可自行调整 - System.setProperty("sun.net.client.defaultConnectTimeout", "10000"); - System.setProperty("sun.net.client.defaultReadTimeout", "10000"); - //初始化ascClient需要的几个参数 - //短信API产品名称(短信产品名固定,无需修改) - final String product = "Dysmsapi"; - //短信API产品域名(接口地址固定,无需修改) - final String domain = "dysmsapi.aliyuncs.com"; - //替换成你的AK - //你的accessKeyId,参考本文档步骤2 - final String accessKeyId = "LTAI4FxsR76x2dq3w9c5puUe"; - //你的accessKeySecret,参考本文档步骤2 - final String accessKeySecret = "GxkTR8fsrvHtixTlD9UPmOGli35tZs"; - //初始化ascClient,暂时不支持多region(请勿修改) - IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret); - DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain); - IAcsClient acsClient = new DefaultAcsClient(profile); - SendSmsRequest request = new SendSmsRequest(); - request.setMethod(MethodType.POST); - request.setPhoneNumbers(phone); - //必填:短信签名-可在短信控制台中找到 - request.setSignName("灿能云"); - //必填:短信模板-可在短信控制台中找到,发送国际/港澳台消息时,请使用国际/港澳台短信模版 - request.setTemplateCode(msgTemplate); vcode = getMessageCode(); - String code = "{\"code\":\"" + vcode + "\"}"; - request.setTemplateParam(code); - //请求失败这里会抛ClientException异常 - sendSmsResponse = acsClient.getAcsResponse(request); + //获取短信发送结果 + sendSmsResponse = smsUtil.sendSms(phone,msgTemplate,"code",vcode); String key = RedisKeyEnum.SMS_LOGIN_KEY.getKey() + phone; if (sendSmsResponse.getCode() != null && "OK".equals(sendSmsResponse.getCode())) { //成功发送短信验证码后,保存进redis,验证码失效为5分钟 @@ -169,6 +108,9 @@ public class AppUserServiceImpl extends ServiceImpl impleme //短信入库 addSendMessage(phone,vcode,msgTemplate,sendSmsResponse); } + if (Objects.isNull(sendSmsResponse)){ + throw new BusinessException(UserResponseEnum.MESSAGE_SEND_FAIL); + } return sendSmsResponse.getCode(); } @@ -182,6 +124,8 @@ public class AppUserServiceImpl extends ServiceImpl impleme throw new BusinessException(UserResponseEnum.DEV_CODE_WRONG); } judgeCode(phone, code); + String password = null; + SendSmsResponse sendSmsResponse = null; //先根据手机号查询是否已被注册 User user = this.lambdaQuery().eq(User::getPhone,phone).one(); if (!Objects.isNull(user)){ @@ -203,7 +147,20 @@ public class AppUserServiceImpl extends ServiceImpl impleme appInfoSet.setDataInfo(1); appInfoSetFeignClient.add(appInfoSet); //发送用户初始密码 - sendPasswordMessage(phone,newUser.getId()); + try { + password = redisUtil.getStringByKey(newUser.getId()); + sendSmsResponse = smsUtil.sendSms(phone,MessageEnum.getTemplateByCode(3),"pwd",password); + if (sendSmsResponse.getCode() != null && "OK".equals(sendSmsResponse.getCode())) { + //成功发送短信验证码后,删除用户密码信息 + redisUtil.delete(newUser.getId()); + } else { + throw new BusinessException(UserResponseEnum.SEND_CODE_FAIL); + } + addSendMessage(phone,password,MessageEnum.getTemplateByCode(3),sendSmsResponse); + } catch (ClientException e) { + logger.error("发送短信异常,异常为:"+e.getMessage()); + addSendMessage(phone,password,MessageEnum.getTemplateByCode(3),sendSmsResponse); + } //删除验证码 deleteCode(phone); } @@ -281,7 +238,6 @@ public class AppUserServiceImpl extends ServiceImpl impleme if (!Objects.isNull(user)){ throw new BusinessException(UserResponseEnum.REGISTER_PHONE_REPEAT); } - user = new User(); User user2 = this.lambdaQuery().eq(User::getId,userId).one(); user2.setName(phoneNew); user2.setLoginName(phoneNew); @@ -299,7 +255,6 @@ public class AppUserServiceImpl extends ServiceImpl impleme this.update(lambdaUpdateWrapper); } - /** * 自定义获取验证码,固定为字母和数字的组合 */ @@ -328,60 +283,6 @@ public class AppUserServiceImpl extends ServiceImpl impleme redisUtil.delete(key); } - /** - * 发送默认密码短信给用户 - * @param phone - * @param userId - */ - public void sendPasswordMessage(String phone, String userId) { - SendSmsResponse sendSmsResponse = null; - String password = null; - String msgTemplate = MessageEnum.getTemplateByCode(3); - //开始执行短信发送 - //设置超时时间-可自行调整 - System.setProperty("sun.net.client.defaultConnectTimeout", "10000"); - System.setProperty("sun.net.client.defaultReadTimeout", "10000"); - //初始化ascClient需要的几个参数 - //短信API产品名称(短信产品名固定,无需修改) - final String product = "Dysmsapi"; - //短信API产品域名(接口地址固定,无需修改) - final String domain = "dysmsapi.aliyuncs.com"; - //替换成你的AK - //你的accessKeyId,参考本文档步骤2 - final String accessKeyId = "LTAI4FxsR76x2dq3w9c5puUe"; - //你的accessKeySecret,参考本文档步骤2 - final String accessKeySecret = "GxkTR8fsrvHtixTlD9UPmOGli35tZs"; - //初始化ascClient,暂时不支持多region(请勿修改) - IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret); - try { - DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain); - IAcsClient acsClient = new DefaultAcsClient(profile); - SendSmsRequest request = new SendSmsRequest(); - request.setMethod(MethodType.POST); - request.setPhoneNumbers(phone); - //必填:短信签名-可在短信控制台中找到 - request.setSignName("灿能云"); - //必填:短信模板-可在短信控制台中找到,发送国际/港澳台消息时,请使用国际/港澳台短信模版 - request.setTemplateCode(msgTemplate); - password = redisUtil.getStringByKey(userId); - String code = "{\"pwd\":\"" + password + "\"}"; - request.setTemplateParam(code); - //请求失败这里会抛ClientException异常 - sendSmsResponse = acsClient.getAcsResponse(request); - if (sendSmsResponse.getCode() != null && "OK".equals(sendSmsResponse.getCode())) { - //成功发送短信验证码后,删除用户密码信息 - redisUtil.delete(userId); - } else { - throw new BusinessException(UserResponseEnum.SEND_CODE_FAIL); - } - addSendMessage(phone,password,msgTemplate,sendSmsResponse); - } catch (ClientException e) { - logger.error("发送短信异常,异常为:"+e.getMessage()); - addSendMessage(phone,password,msgTemplate,sendSmsResponse); - } - } - - private User cloneUserBoToUser(String phone, String devCode, UserSet userSet) { User user = new User(); //设置用户id @@ -423,8 +324,13 @@ public class AppUserServiceImpl extends ServiceImpl impleme appSendMsg.setPhone(phone); appSendMsg.setMessage(vcode); appSendMsg.setSendTime(LocalDateTime.now()); - appSendMsg.setSendStatus(sendSmsResponse.getCode() == null ? "无状态" : sendSmsResponse.getCode()); - appSendMsg.setRemark(sendSmsResponse.getMessage()); + if (Objects.isNull(sendSmsResponse)){ + appSendMsg.setSendStatus("无状态"); + appSendMsg.setRemark(null); + } else { + appSendMsg.setSendStatus(sendSmsResponse.getCode() == null ? "无状态" : sendSmsResponse.getCode()); + appSendMsg.setRemark(sendSmsResponse.getMessage()); + } appSendMsg.setTemplate(template); appSendMsgService.save(appSendMsg); } diff --git a/pqs-user/user-boot/src/main/java/com/njcn/user/util/SmsUtil.java b/pqs-user/user-boot/src/main/java/com/njcn/user/util/SmsUtil.java new file mode 100644 index 000000000..9d4e17583 --- /dev/null +++ b/pqs-user/user-boot/src/main/java/com/njcn/user/util/SmsUtil.java @@ -0,0 +1,125 @@ +package com.njcn.user.util; + +import com.aliyuncs.DefaultAcsClient; +import com.aliyuncs.IAcsClient; +import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest; +import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse; +import com.aliyuncs.exceptions.ClientException; +import com.aliyuncs.http.MethodType; +import com.aliyuncs.profile.DefaultProfile; +import com.aliyuncs.profile.IClientProfile; +import com.njcn.common.pojo.exception.BusinessException; +import com.njcn.user.config.Message; +import com.njcn.user.enums.MessageEnum; +import com.njcn.user.enums.UserResponseEnum; +import lombok.AllArgsConstructor; +import lombok.Data; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; + +/** + * 类的介绍: + * + * @author xuyang + * @version 1.0.0 + * @createTime 2023/8/25 13:51 + */ +@Data +@Configuration +@AllArgsConstructor +public class SmsUtil { + + private final Message message; + + /** + * 短信API产品名称(短信产品名固定,无需修改) + */ + private static final String PRODUCT = "Dysmsapi"; + + /** + * 短信API产品域名(接口地址固定,无需修改) + */ + private static final String DOMAIN = "dysmsapi.aliyuncs.com"; + + /** + * 区域 + */ + private static final String AREA = "cn-hangzhou"; + + /** + * 超时时间参数 + */ + private static final String DEFAULTCONNECTTIMEOUT = "sun.net.client.defaultConnectTimeout"; + + /** + * 过期时间 + */ + private static final String DEFAULTREADTIMEOUT = "sun.net.client.defaultReadTimeout"; + + + public static String getMessageTemplate(String type) { + String msgTemplate = null; + switch (type) { + case "0": + msgTemplate = MessageEnum.getTemplateByCode(0); + break; + case "1": + msgTemplate = MessageEnum.getTemplateByCode(1); + break; + case "2": + msgTemplate = MessageEnum.getTemplateByCode(2); + break; + case "3": + msgTemplate = MessageEnum.getTemplateByCode(3); + break; + case "4": + msgTemplate = MessageEnum.getTemplateByCode(4); + break; + case "5": + msgTemplate = MessageEnum.getTemplateByCode(5); + break; + case "6": + msgTemplate = MessageEnum.getTemplateByCode(6); + break; + case "7": + msgTemplate = MessageEnum.getTemplateByCode(7); + break; + case "8": + msgTemplate = MessageEnum.getTemplateByCode(8); + break; + default: + throw new BusinessException(UserResponseEnum.CODE_TYPE_ERROR); + } + return msgTemplate; + } + + /** + * 发送消息 + * @param phone 手机号 + * @param template 模板号 + * @param param 短信模板中定义的参数名称 + * @param value 参数实际值 + * @return sendSmsResponse 发送消息结果 + * @throws ClientException + */ + public SendSmsResponse sendSms(String phone, String template, String param, String value) throws ClientException { + System.setProperty(DEFAULTCONNECTTIMEOUT, message.getTime()); + System.setProperty(DEFAULTREADTIMEOUT, message.getTime()); + //初始化ascClient,暂时不支持多region(请勿修改) + IClientProfile profile = DefaultProfile.getProfile(AREA, message.getAccessKeyId(), message.getAccessKeySecret()); + DefaultProfile.addEndpoint(AREA, AREA, PRODUCT, DOMAIN); + IAcsClient acsClient = new DefaultAcsClient(profile); + SendSmsRequest request = new SendSmsRequest(); + request.setMethod(MethodType.POST); + request.setPhoneNumbers(phone); + //必填:短信签名-可在短信控制台中找到 + request.setSignName(message.getAutoGraph()); + //必填:短信模板-可在短信控制台中找到,发送国际/港澳台消息时,请使用国际/港澳台短信模版 + request.setTemplateCode(template); + String code = "{\""+param+"\":\"" + value + "\"}"; + request.setTemplateParam(code); + //请求失败这里会抛ClientException异常 + return acsClient.getAcsResponse(request); + } + +}