From 64192e3a1dd4b2523558e4344c782599a99ac588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E9=9D=9E=E5=87=A1?= Date: Tue, 3 Mar 2026 03:29:16 +0000 Subject: [PATCH] Merge #49 into master from cc_20260302_login_password MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 验证码登录 * cc_20260302_login_password: (3 commits squashed) - fix:新增验证码登录,发送验证码,修改密码接口 - fix - fix Signed-off-by: 王非凡 Merged-by: 正新 CR-link: https://codeup.aliyun.com/692ea314dec569489f6f167c/hangzhou/java/custom_zxjp/change/49 --- .../com/cool/store/enums/ErrorCodeEnum.java | 8 +++ .../com/cool/store/enums/LoginTypeEnum.java | 1 + .../com/cool/store/enums/SmsCodeTypeEnum.java | 6 +- .../com/cool/store/enums/sms/SmsZoneEnum.java | 68 ++++++++++++++++++ .../java/com/cool/store/utils/HttpHelper.java | 27 +++++++ .../java/com/cool/store/utils/MobileUtil.java | 72 +++++++++++++++++++ .../store/mapper/EnterpriseUserMapper.java | 4 ++ .../resources/mapper/EnterpriseUserMapper.xml | 4 ++ .../store/dto/login/ModifyPasswordDTO.java | 31 ++++++++ .../cool/store/dto/login/UserLoginDTO.java | 3 + .../cool/store/dto/sms/SendSmsCodeDTO.java | 24 +++++++ .../enterprise/EnterpriseUserService.java | 20 ++++++ .../impl/EnterpriseUserServiceImpl.java | 49 +++++++++++++ .../store/service/impl/CommonService.java | 16 +++-- .../store/service/login/LoginBaseService.java | 5 ++ .../login/impl/SmsLoginServiceImpl.java | 48 +++++++++++++ .../store/service/sms/AliyunSmsService.java | 21 ++++++ .../sms/impl/AliyunSmsServiceImpl.java | 48 +++++++++++++ .../store/config/TokenValidateFilter.java | 5 +- .../controller/webb/LoginController.java | 62 ++++++++++++++-- 20 files changed, 507 insertions(+), 15 deletions(-) create mode 100644 coolstore-partner-common/src/main/java/com/cool/store/enums/sms/SmsZoneEnum.java create mode 100644 coolstore-partner-common/src/main/java/com/cool/store/utils/HttpHelper.java create mode 100644 coolstore-partner-common/src/main/java/com/cool/store/utils/MobileUtil.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/dto/login/ModifyPasswordDTO.java create mode 100644 coolstore-partner-model/src/main/java/com/cool/store/dto/sms/SendSmsCodeDTO.java create mode 100644 coolstore-partner-service/src/main/java/com/cool/store/service/enterprise/EnterpriseUserService.java create mode 100644 coolstore-partner-service/src/main/java/com/cool/store/service/enterprise/impl/EnterpriseUserServiceImpl.java create mode 100644 coolstore-partner-service/src/main/java/com/cool/store/service/login/impl/SmsLoginServiceImpl.java create mode 100644 coolstore-partner-service/src/main/java/com/cool/store/service/sms/AliyunSmsService.java create mode 100644 coolstore-partner-service/src/main/java/com/cool/store/service/sms/impl/AliyunSmsServiceImpl.java diff --git a/coolstore-partner-common/src/main/java/com/cool/store/enums/ErrorCodeEnum.java b/coolstore-partner-common/src/main/java/com/cool/store/enums/ErrorCodeEnum.java index 90a7a1587..5a220557a 100644 --- a/coolstore-partner-common/src/main/java/com/cool/store/enums/ErrorCodeEnum.java +++ b/coolstore-partner-common/src/main/java/com/cool/store/enums/ErrorCodeEnum.java @@ -68,6 +68,14 @@ public enum ErrorCodeEnum { IMPROVE_USER_INFO(1021086,"请联系管理员,完善用户信息!",null), PASSWORD_ERROR(1021087, "密码输入错误",null), PASSWORD_ERROR_MULTI(1021088, "密码错误{0}次,请使用验证码登录",null), + + MOBILE_NOT_MATCH(1023001, "修改失败,手机号与当前用户不匹配",null), + SMS_CODE_EXPIRE(1023002, "验证码已过期!",null), + SMS_CODE_ERROR(1023003, "验证码错误!",null), + SEND_SMS_LIMIT_COUNT(1023004, "短信发送失败,今日发送短信已达上限",null), + NONSUPPORT_MOBILE(1023005, "暂不支持的手机号格式", null), + SMS_CODE_MISSING(1023006, "验证码缺失!",null), + //红圈通 HQT_SHOP_DECORATION_ATTRIBUTES(1022000, "获取红圈通装修属性错误", null), HQT_PARAMS_ERROR(1022001, "构建红圈通请求参数错误", null), diff --git a/coolstore-partner-common/src/main/java/com/cool/store/enums/LoginTypeEnum.java b/coolstore-partner-common/src/main/java/com/cool/store/enums/LoginTypeEnum.java index f7b95f109..dad1a972f 100644 --- a/coolstore-partner-common/src/main/java/com/cool/store/enums/LoginTypeEnum.java +++ b/coolstore-partner-common/src/main/java/com/cool/store/enums/LoginTypeEnum.java @@ -16,6 +16,7 @@ import lombok.Getter; public enum LoginTypeEnum { PASSWORD("账号密码", "passwordLoginServiceImpl"), + SMS("短信验证码","smsLoginServiceImpl"), ; diff --git a/coolstore-partner-common/src/main/java/com/cool/store/enums/SmsCodeTypeEnum.java b/coolstore-partner-common/src/main/java/com/cool/store/enums/SmsCodeTypeEnum.java index b439c20e5..fdeeda5ac 100644 --- a/coolstore-partner-common/src/main/java/com/cool/store/enums/SmsCodeTypeEnum.java +++ b/coolstore-partner-common/src/main/java/com/cool/store/enums/SmsCodeTypeEnum.java @@ -4,14 +4,14 @@ package com.cool.store.enums; public enum SmsCodeTypeEnum { LOGIN("SMS_220325070","验证码登录", 10 * 60), - FORGOT_PWD("SMS_220325070","忘记密码", 10 * 60), +// FORGOT_PWD("SMS_220325070","忘记密码", 10 * 60), MODIFY_PWD("SMS_220325070","修改密码", 10 * 60), IMPROVE_INFO("SMS_220325070","完善用户信息", 10 * 60), USER_REGISTER("SMS_220325070","用户注册", 10 * 60), ENTERPRISE_REGISTER("SMS_220325070","企业注册", 10 * 60), - LOGIN2("SMS_232163403","验证码登录", 10 * 60), - + LOGIN2("SMS_498720063","验证码登录", 10 * 60), + LOGIN_INTERNATIONAL("SMS_474876096", "国际验证码登录", 10 * 60), diff --git a/coolstore-partner-common/src/main/java/com/cool/store/enums/sms/SmsZoneEnum.java b/coolstore-partner-common/src/main/java/com/cool/store/enums/sms/SmsZoneEnum.java new file mode 100644 index 000000000..ec62d9b36 --- /dev/null +++ b/coolstore-partner-common/src/main/java/com/cool/store/enums/sms/SmsZoneEnum.java @@ -0,0 +1,68 @@ +package com.cool.store.enums.sms; + +import cn.hutool.core.lang.PatternPool; +import cn.hutool.core.lang.Validator; +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.PhoneUtil; +import com.cool.store.enums.SmsCodeTypeEnum; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Pattern; + +/** + * describe: 短信手机区号类型 + * + * @author wangff + * @date 2024/11/8 + */ +@Getter +@AllArgsConstructor +public enum SmsZoneEnum { + INDONESIA("+62", "印度尼西亚", SmsCodeTypeEnum.LOGIN_INTERNATIONAL.getTemplateCode(), Pattern.compile("\\d{10,12}")), + + MALAYSIA("+60", "马来西亚", SmsCodeTypeEnum.LOGIN_INTERNATIONAL.getTemplateCode(), Pattern.compile("\\d{6,12}")), + + CHINA("+86", "中国", SmsCodeTypeEnum.LOGIN2.getTemplateCode(), PatternPool.MOBILE), + ; + + /** + * 区号 + */ + private final String code; + + /** + * 描述 + */ + private final String msg; + + /** + * 短信模板code + */ + private final String templateCode; + + /** + * 手机号格式 + */ + private final Pattern mobilePattern; + + /** + * 根据手机号获取枚举类型 + * @param mobile 手机号 + * @return 短信手机区号类型 + */ + public static SmsZoneEnum getByMobile(String mobile) { + if (StringUtils.isBlank(mobile)) { + return null; + } + if (PhoneUtil.isMobile(mobile)) { + return CHINA; + } + String[] split = mobile.split(" "); + if (split.length < 2) { + return null; + } + return ArrayUtil.firstMatch(v -> split[0].startsWith(v.getCode()) && Validator.isMatchRegex(v.getMobilePattern(), split[1]), values()); + } +} diff --git a/coolstore-partner-common/src/main/java/com/cool/store/utils/HttpHelper.java b/coolstore-partner-common/src/main/java/com/cool/store/utils/HttpHelper.java new file mode 100644 index 000000000..b4d846abb --- /dev/null +++ b/coolstore-partner-common/src/main/java/com/cool/store/utils/HttpHelper.java @@ -0,0 +1,27 @@ +package com.cool.store.utils; + +import javax.servlet.http.HttpServletRequest; + +/** + *

+ * + *

+ * + * @author wangff + * @since 2026/3/2 + */ +public class HttpHelper { + public static String getIpAddr(HttpServletRequest request) { + String ip = request.getHeader("x-forwarded-for"); + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + return ip; + } +} diff --git a/coolstore-partner-common/src/main/java/com/cool/store/utils/MobileUtil.java b/coolstore-partner-common/src/main/java/com/cool/store/utils/MobileUtil.java new file mode 100644 index 000000000..b7737c571 --- /dev/null +++ b/coolstore-partner-common/src/main/java/com/cool/store/utils/MobileUtil.java @@ -0,0 +1,72 @@ +package com.cool.store.utils; + +import cn.hutool.core.util.ObjectUtil; +import com.cool.store.enums.ErrorCodeEnum; +import com.cool.store.enums.sms.SmsZoneEnum; +import com.cool.store.exception.ServiceException; +import org.apache.commons.lang3.StringUtils; + +/** + * describe: 手机号工具类 + * + * @author wangff + * @date 2024/11/8 + */ +public class MobileUtil { + + /** + * 根据手机号获取短信手机区号类型枚举 + * @param mobile 手机号 + * @return 短信手机区号类型枚举 + */ + public static String getSmsTemplateCode(String mobile) { + SmsZoneEnum smsZoneEnum = SmsZoneEnum.getByMobile(mobile); + if (ObjectUtil.isNull(smsZoneEnum)) { + throw new ServiceException(ErrorCodeEnum.NONSUPPORT_MOBILE); + } + return smsZoneEnum.getTemplateCode(); + } + + /** + * 去除手机号中的+号和空格 + * @param mobile 手机号 + * @return 手机号 + */ + public static String transNoPlusAndBlank(String mobile) { + if (StringUtils.isBlank(mobile)) { + return mobile; + } + String[] array = StringUtils.split(mobile, ' '); + if (array.length < 2) { + return mobile; + } + return array[0].substring(1).trim() + array[1].trim(); + } + + /** + * 校验手机号格式 + * @param mobile 手机号 + * @return 格式是否正确 + */ + public static boolean validateMobile(String mobile) { + SmsZoneEnum smsZoneEnum = SmsZoneEnum.getByMobile(mobile); + return ObjectUtil.isNotNull(smsZoneEnum); + } + + /** + * 手机号统一存储格式 + *

+ * 国内手机号去除86/+86,国外手机号格式不变 + *

+ * @param mobile 手机号 + * @return 格式化后手机号 + */ + public static String unifyMobile(String mobile) { + SmsZoneEnum smsZoneEnum = SmsZoneEnum.getByMobile(mobile); + if (SmsZoneEnum.CHINA.equals(smsZoneEnum) && (mobile.startsWith("+86") || mobile.startsWith("86"))) { + mobile = mobile.substring(mobile.indexOf("86") + 2).trim(); + } + return mobile; + } + +} diff --git a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/EnterpriseUserMapper.java b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/EnterpriseUserMapper.java index ae0c77f3d..1a6504221 100644 --- a/coolstore-partner-dao/src/main/java/com/cool/store/mapper/EnterpriseUserMapper.java +++ b/coolstore-partner-dao/src/main/java/com/cool/store/mapper/EnterpriseUserMapper.java @@ -113,4 +113,8 @@ public interface EnterpriseUserMapper { */ @PlatformDB UserLoginDO getUserLoginByUnionid(@Param("unionid") String unionid); + + @PlatformDB + Integer modifyPasswordByMobile(@Param("mobile") String mobile, @Param("password") String password); + } \ No newline at end of file diff --git a/coolstore-partner-dao/src/main/resources/mapper/EnterpriseUserMapper.xml b/coolstore-partner-dao/src/main/resources/mapper/EnterpriseUserMapper.xml index 5a019939f..c9f3cd704 100644 --- a/coolstore-partner-dao/src/main/resources/mapper/EnterpriseUserMapper.xml +++ b/coolstore-partner-dao/src/main/resources/mapper/EnterpriseUserMapper.xml @@ -241,4 +241,8 @@ FROM enterprise_user WHERE unionid = #{unionid} AND active = true + + + update enterprise_user set password = #{password} where mobile = #{mobile} + \ No newline at end of file diff --git a/coolstore-partner-model/src/main/java/com/cool/store/dto/login/ModifyPasswordDTO.java b/coolstore-partner-model/src/main/java/com/cool/store/dto/login/ModifyPasswordDTO.java new file mode 100644 index 000000000..babe51152 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/dto/login/ModifyPasswordDTO.java @@ -0,0 +1,31 @@ +package com.cool.store.dto.login; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * @author zhangchenbiao + * @FileName: ModifyPasswordDTO + * @Description: 修改密码 + * @date 2021-07-20 14:23 + */ +@Data +public class ModifyPasswordDTO { + + @NotBlank(message = "手机号不能为空") + private String mobile; + + /** + * 短信验证码 + */ + @NotBlank(message = "验证码不能为空") + private String smsCode; + + /** + * 密码 + */ + @NotBlank(message = "密码不能为空") + private String password; + +} diff --git a/coolstore-partner-model/src/main/java/com/cool/store/dto/login/UserLoginDTO.java b/coolstore-partner-model/src/main/java/com/cool/store/dto/login/UserLoginDTO.java index e309d2826..d240a04d6 100644 --- a/coolstore-partner-model/src/main/java/com/cool/store/dto/login/UserLoginDTO.java +++ b/coolstore-partner-model/src/main/java/com/cool/store/dto/login/UserLoginDTO.java @@ -22,6 +22,9 @@ public class UserLoginDTO { @ApiModelProperty("密码") private String password; + @ApiModelProperty("验证码") + private String smsCode; + @NotNull(message = "登录类型不能为空") private LoginTypeEnum loginType; } diff --git a/coolstore-partner-model/src/main/java/com/cool/store/dto/sms/SendSmsCodeDTO.java b/coolstore-partner-model/src/main/java/com/cool/store/dto/sms/SendSmsCodeDTO.java new file mode 100644 index 000000000..2339c9bf2 --- /dev/null +++ b/coolstore-partner-model/src/main/java/com/cool/store/dto/sms/SendSmsCodeDTO.java @@ -0,0 +1,24 @@ +package com.cool.store.dto.sms; + +import com.cool.store.enums.SmsCodeTypeEnum; +import lombok.Data; + +/** + * @author zhangchenbiao + * @FileName: SendSmsCodeDTO + * @Description:发送验证码 + * @date 2021-07-21 11:20 + */ +@Data +public class SendSmsCodeDTO { + + /** + * 手机号 + */ + private String mobile; + + /** + * 验证码类型 + */ + private SmsCodeTypeEnum codeType; +} diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/enterprise/EnterpriseUserService.java b/coolstore-partner-service/src/main/java/com/cool/store/service/enterprise/EnterpriseUserService.java new file mode 100644 index 000000000..c022802c2 --- /dev/null +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/enterprise/EnterpriseUserService.java @@ -0,0 +1,20 @@ +package com.cool.store.service.enterprise; + +import com.cool.store.dto.login.ModifyPasswordDTO; +import com.cool.store.response.ResponseResult; + +/** + *

+ * 用户 + *

+ * + * @author wangff + * @since 2026/3/2 + */ +public interface EnterpriseUserService { + + /** + * 修改密码 + */ + ResponseResult modifyPassword(ModifyPasswordDTO param); +} diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/enterprise/impl/EnterpriseUserServiceImpl.java b/coolstore-partner-service/src/main/java/com/cool/store/service/enterprise/impl/EnterpriseUserServiceImpl.java new file mode 100644 index 000000000..5b12cb0f7 --- /dev/null +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/enterprise/impl/EnterpriseUserServiceImpl.java @@ -0,0 +1,49 @@ +package com.cool.store.service.enterprise.impl; + +import com.cool.store.constants.CommonConstants; +import com.cool.store.dto.login.ModifyPasswordDTO; +import com.cool.store.enums.ErrorCodeEnum; +import com.cool.store.enums.SmsCodeTypeEnum; +import com.cool.store.mapper.EnterpriseUserMapper; +import com.cool.store.response.ResponseResult; +import com.cool.store.service.enterprise.EnterpriseUserService; +import com.cool.store.utils.Md5Utils; +import com.cool.store.utils.RedisUtilPool; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + *

+ * 用户 + *

+ * + * @author wangff + * @since 2026/3/2 + */ +@Service(value = "enterpriseUserService") +@Slf4j +public class EnterpriseUserServiceImpl implements EnterpriseUserService { + @Resource + private RedisUtilPool redisUtilPool; + @Resource + private EnterpriseUserMapper enterpriseUserMapper; + + @Override + public ResponseResult modifyPassword(ModifyPasswordDTO param) { + String smsCodeKey = SmsCodeTypeEnum.MODIFY_PWD + ":" + param.getMobile(); + String smsCode = param.getSmsCode(); + String codeValue = redisUtilPool.getString(smsCodeKey); + if (StringUtils.isBlank(codeValue)) { + return ResponseResult.fail(ErrorCodeEnum.SMS_CODE_EXPIRE); + } + if (!smsCode.equals(codeValue)) { + return ResponseResult.fail(ErrorCodeEnum.SMS_CODE_ERROR); + } + enterpriseUserMapper.modifyPasswordByMobile(param.getMobile(), Md5Utils.md5(param.getPassword() + CommonConstants.USER_AUTH_KEY)); + redisUtilPool.delKey(smsCodeKey); + return ResponseResult.success(); + } +} diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/CommonService.java b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/CommonService.java index 05f1505b9..061934d79 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/service/impl/CommonService.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/impl/CommonService.java @@ -118,19 +118,23 @@ public class CommonService { } public void sendSms(String poneNumber, SMSMsgEnum templateCode){ - sendSms(Arrays.asList(poneNumber), templateCode, null); + sendSms(Arrays.asList(poneNumber), templateCode.getTemplateCode(), null); } public void sendSms(String poneNumber, SMSMsgEnum templateCode, Map templateParamMap){ + sendSms(Arrays.asList(poneNumber), templateCode.getTemplateCode(), templateParamMap); + } + + public void sendSms(String poneNumber, String templateCode, Map templateParamMap){ sendSms(Arrays.asList(poneNumber), templateCode, templateParamMap); } public void sendSmsAsync(String poneNumber, SMSMsgEnum templateCode, Map templateParamMap){ - CompletableFuture.runAsync(() -> sendSms(Arrays.asList(poneNumber), templateCode, templateParamMap)); + CompletableFuture.runAsync(() -> sendSms(Arrays.asList(poneNumber), templateCode.getTemplateCode(), templateParamMap)); } - public void sendSms(List poneNumbers, SMSMsgEnum templateCode, Map templateParamMap){ - log.info("templateCode:{}, request:{}, poneNumbers:{}", templateCode.getTitle(), JSONObject.toJSONString(templateParamMap), JSONObject.toJSONString(poneNumbers)); + public void sendSms(List poneNumbers, String templateCode, Map templateParamMap){ + log.info("templateCode:{}, request:{}, poneNumbers:{}", templateCode, JSONObject.toJSONString(templateParamMap), JSONObject.toJSONString(poneNumbers)); if(CollectionUtils.isEmpty(poneNumbers)){ return; } @@ -153,12 +157,12 @@ public class CommonService { SendBatchSmsRequest sendBatchSmsRequest = SendBatchSmsRequest.builder() .phoneNumberJson(JSONObject.toJSONString(poneNumbers)) .signNameJson(JSONObject.toJSONString(signNameList)) - .templateCode(templateCode.getTemplateCode()) + .templateCode(templateCode) .templateParamJson("[" + JSONObject.toJSONString(templateParamMap) + "]") .build(); CompletableFuture response = client.sendBatchSms(sendBatchSmsRequest); SendBatchSmsResponse resp = response.get(); - log.info("短信发送templateCode:{}, response:{}", templateCode.getTemplateCode(), JSONObject.toJSONString(resp)); + log.info("短信发送templateCode:{}, response:{}", templateCode, JSONObject.toJSONString(resp)); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/login/LoginBaseService.java b/coolstore-partner-service/src/main/java/com/cool/store/service/login/LoginBaseService.java index c7de70b03..af0f8b941 100644 --- a/coolstore-partner-service/src/main/java/com/cool/store/service/login/LoginBaseService.java +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/login/LoginBaseService.java @@ -12,6 +12,7 @@ import com.cool.store.dto.login.UserRefreshLoginDTO; import com.cool.store.entity.EnterpriseUserDO; import com.cool.store.entity.login.UserLoginDO; import com.cool.store.enums.ErrorCodeEnum; +import com.cool.store.exception.ServiceException; import com.cool.store.response.ResponseResult; import com.cool.store.service.EnterpriseService; import com.cool.store.userholder.CurrentUser; @@ -27,6 +28,7 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.text.MessageFormat; import java.time.LocalDate; +import java.util.Objects; /** *

@@ -63,6 +65,9 @@ public abstract class LoginBaseService implements LoginStrategy { } } EnterpriseUserDO enterpriseUserDO = enterpriseUserDAO.selectByMobile(param.getMobile()); + if (Objects.isNull(enterpriseUserDO)) { + throw new ServiceException(ErrorCodeEnum.PARTNER_MOBILE_INCORRECT); + } UserLoginDO userLoginDO = enterpriseUserDAO.getUserLoginByUnionid(enterpriseUserDO.getUnionid()); return userLogin(param, userLoginDO); } diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/login/impl/SmsLoginServiceImpl.java b/coolstore-partner-service/src/main/java/com/cool/store/service/login/impl/SmsLoginServiceImpl.java new file mode 100644 index 000000000..20a837f3d --- /dev/null +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/login/impl/SmsLoginServiceImpl.java @@ -0,0 +1,48 @@ +package com.cool.store.service.login.impl; + +import com.cool.store.dto.login.UserLoginDTO; +import com.cool.store.entity.login.UserLoginDO; +import com.cool.store.enums.ErrorCodeEnum; +import com.cool.store.enums.SmsCodeTypeEnum; +import com.cool.store.response.ResponseResult; +import com.cool.store.service.login.LoginBaseService; +import com.cool.store.utils.RedisUtilPool; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * @author zhangchenbiao + * @FileName: SmsLoginService + * @Description: 验证码登录实现类 + * @date 2021-07-16 11:45 + */ +@Service("smsLoginServiceImpl") +@Slf4j +public class SmsLoginServiceImpl extends LoginBaseService { + + @Resource + private RedisUtilPool redisUtilPool; + + @Override + public ResponseResult userLogin(UserLoginDTO param, UserLoginDO userLoginDO) { + String mobile = param.getMobile(); + String smsCode = param.getSmsCode(); + if (StringUtils.isBlank(smsCode)) { + return ResponseResult.fail(ErrorCodeEnum.SMS_CODE_MISSING); + } + String smsCodeKey = SmsCodeTypeEnum.LOGIN + ":" + mobile; + String code = redisUtilPool.getString(smsCodeKey); + if (StringUtils.isBlank(code)) { + return ResponseResult.fail(ErrorCodeEnum.SMS_CODE_EXPIRE); + } + if (!smsCode.equals(code)) { + return ResponseResult.fail(ErrorCodeEnum.SMS_CODE_ERROR); + } + redisUtilPool.delKey(smsCodeKey); + return ResponseResult.success(getUserLoginInfo(userLoginDO)); + } + +} diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/sms/AliyunSmsService.java b/coolstore-partner-service/src/main/java/com/cool/store/service/sms/AliyunSmsService.java new file mode 100644 index 000000000..42d0c23c7 --- /dev/null +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/sms/AliyunSmsService.java @@ -0,0 +1,21 @@ +package com.cool.store.service.sms; + + +import com.cool.store.enums.SmsCodeTypeEnum; +import com.cool.store.response.ResponseResult; + +/** + * @author zhangchenbiao + * @FileName: AliyunSmsService + * @Description: 阿里云短信 + * @date 2021-07-23 11:33 + */ +public interface AliyunSmsService { + + /** + * 发送短信 + * @param mobile 手机号 + * @param codeType 验证码类型 + */ + ResponseResult sendSmsCode(String mobile, SmsCodeTypeEnum codeType); +} diff --git a/coolstore-partner-service/src/main/java/com/cool/store/service/sms/impl/AliyunSmsServiceImpl.java b/coolstore-partner-service/src/main/java/com/cool/store/service/sms/impl/AliyunSmsServiceImpl.java new file mode 100644 index 000000000..341ce206a --- /dev/null +++ b/coolstore-partner-service/src/main/java/com/cool/store/service/sms/impl/AliyunSmsServiceImpl.java @@ -0,0 +1,48 @@ +package com.cool.store.service.sms.impl; + +import com.cool.store.enums.SmsCodeTypeEnum; +import com.cool.store.response.ResponseResult; +import com.cool.store.service.impl.CommonService; +import com.cool.store.service.sms.AliyunSmsService; +import com.cool.store.utils.MobileUtil; +import com.cool.store.utils.RedisUtilPool; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.Map; + +/** + * @author zhangchenbiao + * @FileName: AliyunSmsServiceImpl + * @Description: 发送短信 + * @date 2021-07-23 11:37 + */ +@Service +@Slf4j +public class AliyunSmsServiceImpl implements AliyunSmsService { + + @Resource + private RedisUtilPool redisUtilPool; + @Resource + private CommonService commonService; + + @Override + public ResponseResult sendSmsCode(String mobile, SmsCodeTypeEnum codeType) { + String smsCodeKey = codeType + ":" + mobile; + String smsCode = getRandNum(); + String templateCode = MobileUtil.getSmsTemplateCode(mobile); + + Map templateParamMap = new HashMap<>(); + templateParamMap.put("code", smsCode); + commonService.sendSms(mobile, templateCode, templateParamMap); + redisUtilPool.setString(smsCodeKey, smsCode, codeType.getCacheSeconds()); + + return ResponseResult.success(true); + } + + public static String getRandNum() { + return String.valueOf((int) ((Math.random() * 9 + 1) * Math.pow(10, 5))); + } +} diff --git a/coolstore-partner-web/src/main/java/com/cool/store/config/TokenValidateFilter.java b/coolstore-partner-web/src/main/java/com/cool/store/config/TokenValidateFilter.java index 93d16ade2..9bc10784d 100644 --- a/coolstore-partner-web/src/main/java/com/cool/store/config/TokenValidateFilter.java +++ b/coolstore-partner-web/src/main/java/com/cool/store/config/TokenValidateFilter.java @@ -55,7 +55,10 @@ public class TokenValidateFilter implements Filter { "/zxjp/**/api/license", "/zxjp/pc/v3/login/accountLogin", "/zxjp/pc/v3/login/refreshLogin", - "/zxjp/ws/**" + "/zxjp/ws/**", + "/zxjp/pc/v3/login/sendSmsCode", + "/zxjp/pc/v3/login/sendSmsCode/test", + "/zxjp/pc/v3/login/modifyPassword" ); diff --git a/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/LoginController.java b/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/LoginController.java index 9eb1b27c7..e1ab3f61f 100644 --- a/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/LoginController.java +++ b/coolstore-partner-web/src/main/java/com/cool/store/controller/webb/LoginController.java @@ -1,17 +1,30 @@ package com.cool.store.controller.webb; +import com.cool.store.dto.login.ModifyPasswordDTO; import com.cool.store.dto.login.UserLoginDTO; import com.cool.store.dto.login.UserRefreshLoginDTO; +import com.cool.store.dto.sms.SendSmsCodeDTO; +import com.cool.store.enums.ErrorCodeEnum; import com.cool.store.response.ResponseResult; +import com.cool.store.service.enterprise.EnterpriseUserService; import com.cool.store.service.login.LoginBaseService; import com.cool.store.service.login.LoginStrategy; +import com.cool.store.service.sms.AliyunSmsService; +import com.cool.store.utils.HttpHelper; +import com.cool.store.utils.RedisUtilPool; import com.cool.store.utils.SpringContextUtil; -import com.cool.store.vo.login.UserLoginVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.time.LocalDate; + +import static com.cool.store.service.sms.impl.AliyunSmsServiceImpl.getRandNum; + /** *

* 登录 前端控制器 @@ -25,17 +38,24 @@ import org.springframework.web.bind.annotation.*; @RequestMapping("/pc/v3/login") @RequiredArgsConstructor public class LoginController { - private final LoginBaseService loginBaseService; + @Resource(name = "passwordLoginServiceImpl") + private LoginBaseService loginBaseService; + private final EnterpriseUserService enterpriseUserService; + private final RedisUtilPool redisUtilPool; + private final AliyunSmsService aliyunSmsService; - @ApiOperation("账号密码登录") + private final int SEND_SMS_LIMIT_COUNT = 10; + private final int SEND_SMS_IP_LIMIT_COUNT = 100; + + @ApiOperation("登录") @PostMapping("/accountLogin") - public ResponseResult accountLogin(@RequestBody UserLoginDTO param) { + public ResponseResult accountLogin(@RequestBody UserLoginDTO param) { return SpringContextUtil.getBean(param.getLoginType().getClazzName(), LoginStrategy.class).login(param); } @ApiOperation("refresh登录") @PostMapping("/refreshLogin") - public ResponseResult refreshLogin(@RequestBody UserRefreshLoginDTO param) { + public ResponseResult refreshLogin(@RequestBody UserRefreshLoginDTO param) { return loginBaseService.refreshLogin(param); } @@ -44,4 +64,36 @@ public class LoginController { public ResponseResult logout() { return loginBaseService.logout(); } + + @ApiOperation("修改密码") + @PostMapping("/modifyPassword") + public ResponseResult modifyPassword(@Validated @RequestBody ModifyPasswordDTO param) { + return enterpriseUserService.modifyPassword(param); + } + + @ApiOperation("发送验证码") + @PostMapping("/sendSmsCode") + public ResponseResult sendSmsCode(@Validated @RequestBody SendSmsCodeDTO param, HttpServletRequest request) { + //一天同一个手机号限制发送10条短信 + String codeKey = "sendSmsCode_" + LocalDate.now() + ":" + param.getMobile(); + Long sendCount = redisUtilPool.incrby(codeKey, 1, 24 * 60 * 60); + if (sendCount > SEND_SMS_LIMIT_COUNT) { + return ResponseResult.fail(ErrorCodeEnum.SEND_SMS_LIMIT_COUNT); + } + String ip = HttpHelper.getIpAddr(request); + String ipCacheKey = "sendSmsCode_IP_" + LocalDate.now() + ":" + ip; + Long ipSendCount = redisUtilPool.incrby(ipCacheKey, 1, 24 * 60 * 60); + if (ipSendCount > SEND_SMS_IP_LIMIT_COUNT) { + return ResponseResult.fail(ErrorCodeEnum.SEND_SMS_LIMIT_COUNT); + } + return aliyunSmsService.sendSmsCode(param.getMobile(), param.getCodeType()); + } + + @ApiOperation("测试发送验证码") + @PostMapping("/sendSmsCode/test") + public ResponseResult sendSmsCodeTest(@Validated @RequestBody SendSmsCodeDTO param){ + String smsCode = getRandNum(); + redisUtilPool.setString(param.getCodeType() + ":" + param.getMobile(), smsCode, param.getCodeType().getCacheSeconds()); + return ResponseResult.success(smsCode); + } }