package cn.mb.cloud.auth.security.controller; import cn.hutool.core.util.RandomUtil; import cn.hutool.crypto.digest.BCrypt; import cn.mb.cloud.auth.security.entity.User; import cn.mb.cloud.auth.security.service.IUserService; import cn.mb.cloud.auth.security.util.SmsUtil; import cn.mb.cloud.auth.security.util.StringUtil; import cn.mb.cloud.auth.security.util.VerifyCode; import cn.mb.cloud.common.cache.RedisFastJsonTemplate; import cn.mb.cloud.common.core.constant.CacheConstants; import cn.mb.cloud.common.core.constant.enums.ErrorCodeConstants; import cn.mb.cloud.common.core.constant.enums.LoginTypeEnum; import cn.mb.cloud.common.core.exception.BusinessException; import cn.mb.cloud.common.core.exception.ValidateCodeException; import cn.mb.cloud.common.core.util.ResponseData; import com.aliyuncs.exceptions.ClientException; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.StringPool; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse; import com.tencentcloudapi.sms.v20210111.models.SendStatus; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.web.bind.annotation.*; import javax.validation.constraints.NotBlank; import java.time.LocalDateTime; import java.util.concurrent.TimeUnit; /** * 系统社交登录账号表 * * @author jason * @date 2018-08-16 21:30:41 */ @Slf4j @RestController @RequestMapping("/social") @AllArgsConstructor @Api(value = "三方账号管理模块", tags = "三方账号管理模块") public class SysSocialDetailsController { private final RedisFastJsonTemplate redisFastJsonTemplate; private final IUserService userService; @ResponseBody @PostMapping("/register") @ApiOperation(value = "小程序注册") @ApiImplicitParams({ @ApiImplicitParam(value = "手机号", name = "phone", required = true, dataType = "string"), @ApiImplicitParam(value = "验证码", name = "code", dataType = "string"), @ApiImplicitParam(value = "密码", name = "password", dataType = "string"), @ApiImplicitParam(value = "昵称(微信)", name = "nickName", dataType = "string"), @ApiImplicitParam(value = "头像(微信)", name = "avatarUrl", dataType = "string"), @ApiImplicitParam(value = "性别(微信)", name = "gender", dataType = "Integer"), @ApiImplicitParam(value = "来源(传名称)", name = "source", dataType = "string"), @ApiImplicitParam(value = "openId", name = "openId", dataType = "string"), }) public ResponseData phoneRegister(String phone, String code,String password,String source, String nickName,String avatarUrl,Integer gender,String openId){ try { //验证验证码 if (StringUtils.isEmpty(phone)) { return ResponseData.fail("手机号不能为空"); } if(StringUtils.isEmpty(openId)){ //验证验证码 ResponseData responseData = validateSms(1, phone, code); String dataCode = responseData.getCode(); if(!dataCode.equals(ErrorCodeConstants.SUCCESS.getValue())){ return responseData; } } //验证手机号是否注册 User user = userService.getOne(new QueryWrapper() .eq("username",phone) .eq("del_flag",0)); if(user == null){ user = new User(); if(StringUtils.isEmpty(password)){ password = phone; } //手机号注册 String pswMd5 = BCrypt.hashpw(password, BCrypt.gensalt()); user.setUsername(phone); user.setPassword(pswMd5); user.setSource(source); user.setName(nickName); user.setWechatName(nickName); user.setOpenId(openId); if(StringUtils.isEmpty(nickName)){ user.setName(phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")); } user.setAvatar(avatarUrl); user.setGender(gender); user.setCreateDate(LocalDateTime.now()); userService.save(user); }else { user.setWechatName(nickName); user.setOpenId(openId); userService.updateById(user); } return ResponseData.success(user.getId()); }catch (Exception e){ e.printStackTrace(); return ResponseData.fail(); } } @ResponseBody @PostMapping("/forgetPassword") @ApiOperation(value = "忘记密码") @ApiImplicitParams({ @ApiImplicitParam(value = "手机号", name = "phone", required = true, dataType = "string"), @ApiImplicitParam(value = "验证码", name = "code", required = true, dataType = "string"), @ApiImplicitParam(value = "密码", name = "password", required = true, dataType = "string"), }) public ResponseData forgetPassword(String phone,String code,String password){ try { if (StringUtils.isEmpty(phone)) { return ResponseData.fail("手机号不能为空"); } if (StringUtils.isEmpty(code)) { return ResponseData.fail("验证码不能为空"); } if (StringUtils.isEmpty(password)) { return ResponseData.fail("密码不能为空"); } //验证验证码 ResponseData responseData = validateSms(2, phone, code); String dataCode = responseData.getCode(); if(!dataCode.equals(ErrorCodeConstants.SUCCESS.getValue())){ return responseData; } //修改密码 String pswMd5 = BCrypt.hashpw(password, BCrypt.gensalt()); return userService.forgetPassword(phone,pswMd5); }catch (Exception e){ e.printStackTrace(); return ResponseData.fail(); } } @GetMapping("/sms/captcha") @ApiOperation(value = "获取验证码") @ApiImplicitParams({ @ApiImplicitParam(paramType = "query", name = "type", value = "类型(1=注册,2=忘记密码 )", required = true, dataType = "int"), @ApiImplicitParam(paramType = "query", name = "mobile", value = "手机号", required = true, dataType = "String"), }) public ResponseData sendSmsCode(@NotBlank(message = "手机号码不能为空") String mobile, @NotBlank(message = "类型不能为空") Byte type) throws BusinessException, ValidateCodeException, ClientException { if (StringUtils.isEmpty(mobile)) { return ResponseData.fail("请先绑定手机号码"); } User member = userService.getOne(Wrappers.query() .lambda().eq(User::getUsername, mobile).eq(User::getDelFlag, 0)); if (member == null && type == 2) { log.info("手机号未注册:{}", mobile); return ResponseData.fail("手机号未注册"); } StringUtil.checkNull(mobile, "手机账号不能为空"); //判格式 StringUtil.checkFormat(mobile, "请输入格式正确的11位号码"); Object codeObj = redisFastJsonTemplate.opsForValue() .get(CacheConstants.DEFAULT_CODE_KEY + type + StringPool.AT + mobile); if (codeObj != null) { log.info("手机号验证码未过期:{},{}", mobile, codeObj); //return ResponseData.fail("验证码发送过于频繁"); } String code = RandomUtil.randomNumbers(Integer.parseInt(VerifyCode.CODE_SIZE)); log.info("手机号生成验证码成功:{},{}", mobile, code); SendSmsResponse response = null; try { String[] mobileSet = {"+86"+mobile}; String[] templateParamSet={code+""}; response = SmsUtil.sendSms(mobileSet, templateParamSet); } catch (com.netflix.client.ClientException e) { e.printStackTrace(); } // 测试环境不发短信 //SendSmsResponse response = new SendSmsResponse(); SendStatus sendStatus = response.getSendStatusSet()[0]; if (sendStatus.getCode().equals("Ok")) { redisFastJsonTemplate.opsForValue().set( CacheConstants.DEFAULT_CODE_KEY + type + StringPool.AT + mobile, code, 5 * 60, TimeUnit.SECONDS); } else { // 判断存在时销毁 redisFastJsonTemplate.delete(CacheConstants.DEFAULT_CODE_KEY + type + StringPool.AT + mobile); } return ResponseData.success(code); } @PostMapping("/sms/captcha/validate") @ApiOperation(value = "验证短信") @ApiImplicitParams({ @ApiImplicitParam(name = "type", value = "类型(1=注册,2=忘记密码 )", required = true, dataType = "int", paramType = "query"), @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String", paramType = "query"), @ApiImplicitParam(name = "code", value = "验证码", required = true, dataType = "String", paramType = "query"), }) public ResponseData validateSms(Integer type, String phone, String code) { if (type==null) { return ResponseData.fail("类型不能为空"); } if (StringUtils.isEmpty(phone)) { return ResponseData.fail("手机号不能为空"); } if (StringUtils.isEmpty(code)) { return ResponseData.fail("验证码不能为空"); } return userService.verifyCode(type, phone, code); } }