Merge #49 into master from cc_20260302_login_password
验证码登录 * cc_20260302_login_password: (3 commits squashed) - fix:新增验证码登录,发送验证码,修改密码接口 - fix - fix Signed-off-by: 王非凡 <accounts_67eba0c5fee9c49c80c8e2b4@mail.teambition.com> Merged-by: 正新 <accounts_6964c7bcd2a2c377c5bbd01b@mail.teambition.com> CR-link: https://codeup.aliyun.com/692ea314dec569489f6f167c/hangzhou/java/custom_zxjp/change/49
This commit is contained in:
@@ -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),
|
||||
|
||||
@@ -16,6 +16,7 @@ import lombok.Getter;
|
||||
public enum LoginTypeEnum {
|
||||
|
||||
PASSWORD("账号密码", "passwordLoginServiceImpl"),
|
||||
SMS("短信验证码","smsLoginServiceImpl"),
|
||||
|
||||
;
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.cool.store.utils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
*
|
||||
* </p>
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 手机号统一存储格式
|
||||
* <p>
|
||||
* 国内手机号去除86/+86,国外手机号格式不变
|
||||
* </p>
|
||||
* @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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -241,4 +241,8 @@
|
||||
FROM enterprise_user
|
||||
WHERE unionid = #{unionid} AND active = true
|
||||
</select>
|
||||
|
||||
<update id="modifyPasswordByMobile">
|
||||
update enterprise_user set password = #{password} where mobile = #{mobile}
|
||||
</update>
|
||||
</mapper>
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -22,6 +22,9 @@ public class UserLoginDTO {
|
||||
@ApiModelProperty("密码")
|
||||
private String password;
|
||||
|
||||
@ApiModelProperty("验证码")
|
||||
private String smsCode;
|
||||
|
||||
@NotNull(message = "登录类型不能为空")
|
||||
private LoginTypeEnum loginType;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.cool.store.service.enterprise;
|
||||
|
||||
import com.cool.store.dto.login.ModifyPasswordDTO;
|
||||
import com.cool.store.response.ResponseResult;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户
|
||||
* </p>
|
||||
*
|
||||
* @author wangff
|
||||
* @since 2026/3/2
|
||||
*/
|
||||
public interface EnterpriseUserService {
|
||||
|
||||
/**
|
||||
* 修改密码
|
||||
*/
|
||||
ResponseResult modifyPassword(ModifyPasswordDTO param);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户
|
||||
* </p>
|
||||
*
|
||||
* @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();
|
||||
}
|
||||
}
|
||||
@@ -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<String, String> templateParamMap){
|
||||
sendSms(Arrays.asList(poneNumber), templateCode.getTemplateCode(), templateParamMap);
|
||||
}
|
||||
|
||||
public void sendSms(String poneNumber, String templateCode, Map<String, String> templateParamMap){
|
||||
sendSms(Arrays.asList(poneNumber), templateCode, templateParamMap);
|
||||
}
|
||||
|
||||
public void sendSmsAsync(String poneNumber, SMSMsgEnum templateCode, Map<String, String> templateParamMap){
|
||||
CompletableFuture.runAsync(() -> sendSms(Arrays.asList(poneNumber), templateCode, templateParamMap));
|
||||
CompletableFuture.runAsync(() -> sendSms(Arrays.asList(poneNumber), templateCode.getTemplateCode(), templateParamMap));
|
||||
}
|
||||
|
||||
public void sendSms(List<String> poneNumbers, SMSMsgEnum templateCode, Map<String, String> templateParamMap){
|
||||
log.info("templateCode:{}, request:{}, poneNumbers:{}", templateCode.getTitle(), JSONObject.toJSONString(templateParamMap), JSONObject.toJSONString(poneNumbers));
|
||||
public void sendSms(List<String> poneNumbers, String templateCode, Map<String, String> 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<SendBatchSmsResponse> 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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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<String, String> 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)));
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 登录 前端控制器
|
||||
@@ -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<UserLoginVO> 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<UserLoginVO> 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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user