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),
|
IMPROVE_USER_INFO(1021086,"请联系管理员,完善用户信息!",null),
|
||||||
PASSWORD_ERROR(1021087, "密码输入错误",null),
|
PASSWORD_ERROR(1021087, "密码输入错误",null),
|
||||||
PASSWORD_ERROR_MULTI(1021088, "密码错误{0}次,请使用验证码登录",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_SHOP_DECORATION_ATTRIBUTES(1022000, "获取红圈通装修属性错误", null),
|
||||||
HQT_PARAMS_ERROR(1022001, "构建红圈通请求参数错误", null),
|
HQT_PARAMS_ERROR(1022001, "构建红圈通请求参数错误", null),
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import lombok.Getter;
|
|||||||
public enum LoginTypeEnum {
|
public enum LoginTypeEnum {
|
||||||
|
|
||||||
PASSWORD("账号密码", "passwordLoginServiceImpl"),
|
PASSWORD("账号密码", "passwordLoginServiceImpl"),
|
||||||
|
SMS("短信验证码","smsLoginServiceImpl"),
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ package com.cool.store.enums;
|
|||||||
public enum SmsCodeTypeEnum {
|
public enum SmsCodeTypeEnum {
|
||||||
|
|
||||||
LOGIN("SMS_220325070","验证码登录", 10 * 60),
|
LOGIN("SMS_220325070","验证码登录", 10 * 60),
|
||||||
FORGOT_PWD("SMS_220325070","忘记密码", 10 * 60),
|
// FORGOT_PWD("SMS_220325070","忘记密码", 10 * 60),
|
||||||
MODIFY_PWD("SMS_220325070","修改密码", 10 * 60),
|
MODIFY_PWD("SMS_220325070","修改密码", 10 * 60),
|
||||||
IMPROVE_INFO("SMS_220325070","完善用户信息", 10 * 60),
|
IMPROVE_INFO("SMS_220325070","完善用户信息", 10 * 60),
|
||||||
USER_REGISTER("SMS_220325070","用户注册", 10 * 60),
|
USER_REGISTER("SMS_220325070","用户注册", 10 * 60),
|
||||||
ENTERPRISE_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
|
@PlatformDB
|
||||||
UserLoginDO getUserLoginByUnionid(@Param("unionid") String unionid);
|
UserLoginDO getUserLoginByUnionid(@Param("unionid") String unionid);
|
||||||
|
|
||||||
|
@PlatformDB
|
||||||
|
Integer modifyPasswordByMobile(@Param("mobile") String mobile, @Param("password") String password);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -241,4 +241,8 @@
|
|||||||
FROM enterprise_user
|
FROM enterprise_user
|
||||||
WHERE unionid = #{unionid} AND active = true
|
WHERE unionid = #{unionid} AND active = true
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<update id="modifyPasswordByMobile">
|
||||||
|
update enterprise_user set password = #{password} where mobile = #{mobile}
|
||||||
|
</update>
|
||||||
</mapper>
|
</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("密码")
|
@ApiModelProperty("密码")
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
|
@ApiModelProperty("验证码")
|
||||||
|
private String smsCode;
|
||||||
|
|
||||||
@NotNull(message = "登录类型不能为空")
|
@NotNull(message = "登录类型不能为空")
|
||||||
private LoginTypeEnum loginType;
|
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){
|
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){
|
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);
|
sendSms(Arrays.asList(poneNumber), templateCode, templateParamMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendSmsAsync(String poneNumber, SMSMsgEnum templateCode, Map<String, String> 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){
|
public void sendSms(List<String> poneNumbers, String templateCode, Map<String, String> templateParamMap){
|
||||||
log.info("templateCode:{}, request:{}, poneNumbers:{}", templateCode.getTitle(), JSONObject.toJSONString(templateParamMap), JSONObject.toJSONString(poneNumbers));
|
log.info("templateCode:{}, request:{}, poneNumbers:{}", templateCode, JSONObject.toJSONString(templateParamMap), JSONObject.toJSONString(poneNumbers));
|
||||||
if(CollectionUtils.isEmpty(poneNumbers)){
|
if(CollectionUtils.isEmpty(poneNumbers)){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -153,12 +157,12 @@ public class CommonService {
|
|||||||
SendBatchSmsRequest sendBatchSmsRequest = SendBatchSmsRequest.builder()
|
SendBatchSmsRequest sendBatchSmsRequest = SendBatchSmsRequest.builder()
|
||||||
.phoneNumberJson(JSONObject.toJSONString(poneNumbers))
|
.phoneNumberJson(JSONObject.toJSONString(poneNumbers))
|
||||||
.signNameJson(JSONObject.toJSONString(signNameList))
|
.signNameJson(JSONObject.toJSONString(signNameList))
|
||||||
.templateCode(templateCode.getTemplateCode())
|
.templateCode(templateCode)
|
||||||
.templateParamJson("[" + JSONObject.toJSONString(templateParamMap) + "]")
|
.templateParamJson("[" + JSONObject.toJSONString(templateParamMap) + "]")
|
||||||
.build();
|
.build();
|
||||||
CompletableFuture<SendBatchSmsResponse> response = client.sendBatchSms(sendBatchSmsRequest);
|
CompletableFuture<SendBatchSmsResponse> response = client.sendBatchSms(sendBatchSmsRequest);
|
||||||
SendBatchSmsResponse resp = response.get();
|
SendBatchSmsResponse resp = response.get();
|
||||||
log.info("短信发送templateCode:{}, response:{}", templateCode.getTemplateCode(), JSONObject.toJSONString(resp));
|
log.info("短信发送templateCode:{}, response:{}", templateCode, JSONObject.toJSONString(resp));
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (ExecutionException e) {
|
} 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.EnterpriseUserDO;
|
||||||
import com.cool.store.entity.login.UserLoginDO;
|
import com.cool.store.entity.login.UserLoginDO;
|
||||||
import com.cool.store.enums.ErrorCodeEnum;
|
import com.cool.store.enums.ErrorCodeEnum;
|
||||||
|
import com.cool.store.exception.ServiceException;
|
||||||
import com.cool.store.response.ResponseResult;
|
import com.cool.store.response.ResponseResult;
|
||||||
import com.cool.store.service.EnterpriseService;
|
import com.cool.store.service.EnterpriseService;
|
||||||
import com.cool.store.userholder.CurrentUser;
|
import com.cool.store.userholder.CurrentUser;
|
||||||
@@ -27,6 +28,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -63,6 +65,9 @@ public abstract class LoginBaseService implements LoginStrategy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
EnterpriseUserDO enterpriseUserDO = enterpriseUserDAO.selectByMobile(param.getMobile());
|
EnterpriseUserDO enterpriseUserDO = enterpriseUserDAO.selectByMobile(param.getMobile());
|
||||||
|
if (Objects.isNull(enterpriseUserDO)) {
|
||||||
|
throw new ServiceException(ErrorCodeEnum.PARTNER_MOBILE_INCORRECT);
|
||||||
|
}
|
||||||
UserLoginDO userLoginDO = enterpriseUserDAO.getUserLoginByUnionid(enterpriseUserDO.getUnionid());
|
UserLoginDO userLoginDO = enterpriseUserDAO.getUserLoginByUnionid(enterpriseUserDO.getUnionid());
|
||||||
return userLogin(param, userLoginDO);
|
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/**/api/license",
|
||||||
"/zxjp/pc/v3/login/accountLogin",
|
"/zxjp/pc/v3/login/accountLogin",
|
||||||
"/zxjp/pc/v3/login/refreshLogin",
|
"/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;
|
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.UserLoginDTO;
|
||||||
import com.cool.store.dto.login.UserRefreshLoginDTO;
|
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.response.ResponseResult;
|
||||||
|
import com.cool.store.service.enterprise.EnterpriseUserService;
|
||||||
import com.cool.store.service.login.LoginBaseService;
|
import com.cool.store.service.login.LoginBaseService;
|
||||||
import com.cool.store.service.login.LoginStrategy;
|
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.utils.SpringContextUtil;
|
||||||
import com.cool.store.vo.login.UserLoginVO;
|
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
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>
|
* <p>
|
||||||
* 登录 前端控制器
|
* 登录 前端控制器
|
||||||
@@ -25,17 +38,24 @@ import org.springframework.web.bind.annotation.*;
|
|||||||
@RequestMapping("/pc/v3/login")
|
@RequestMapping("/pc/v3/login")
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class LoginController {
|
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")
|
@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);
|
return SpringContextUtil.getBean(param.getLoginType().getClazzName(), LoginStrategy.class).login(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("refresh登录")
|
@ApiOperation("refresh登录")
|
||||||
@PostMapping("/refreshLogin")
|
@PostMapping("/refreshLogin")
|
||||||
public ResponseResult<UserLoginVO> refreshLogin(@RequestBody UserRefreshLoginDTO param) {
|
public ResponseResult refreshLogin(@RequestBody UserRefreshLoginDTO param) {
|
||||||
return loginBaseService.refreshLogin(param);
|
return loginBaseService.refreshLogin(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,4 +64,36 @@ public class LoginController {
|
|||||||
public ResponseResult logout() {
|
public ResponseResult logout() {
|
||||||
return loginBaseService.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