123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- /*
- * Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the dreamlu.net developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: Chill 庄骞 (smallchill@163.com)
- */
- package org.springblade.modules.api.controller;
- import cn.hutool.core.util.DesensitizedUtil;
- import cn.hutool.core.util.IdcardUtil;
- import cn.hutool.core.util.ObjectUtil;
- import cn.hutool.core.util.PhoneUtil;
- import com.baomidou.mybatisplus.core.toolkit.Wrappers;
- import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
- import io.swagger.annotations.Api;
- import io.swagger.annotations.ApiOperation;
- import io.swagger.annotations.ApiParam;
- import lombok.AllArgsConstructor;
- import org.springblade.common.cache.ParamCache;
- import org.springblade.common.constant.CommonConstant;
- import org.springblade.common.enums.ResultCode;
- import org.springblade.common.utils.CommonUtil;
- import org.springblade.core.boot.ctrl.BladeController;
- import org.springblade.core.cache.utils.CacheUtil;
- import org.springblade.core.jwt.JwtUtil;
- import org.springblade.core.jwt.props.JwtProperties;
- import org.springblade.core.launch.constant.TokenConstant;
- import org.springblade.core.log.annotation.ApiLog;
- import org.springblade.core.redis.cache.BladeRedis;
- import org.springblade.core.secure.BladeUser;
- import org.springblade.core.secure.utils.AuthUtil;
- import org.springblade.core.sms.model.SmsCode;
- import org.springblade.core.tool.api.R;
- import org.springblade.core.tool.support.Kv;
- import org.springblade.core.tool.utils.*;
- import org.springblade.modules.api.request.MerchantRegisterRequest;
- import org.springblade.modules.auth.enums.UserEnum;
- import org.springblade.modules.auth.granter.PasswordTokenGranter;
- import org.springblade.modules.auth.provider.ITokenGranter;
- import org.springblade.modules.auth.provider.TokenGranterBuilder;
- import org.springblade.modules.auth.provider.TokenParameter;
- import org.springblade.modules.auth.utils.TokenUtil;
- import org.springblade.modules.platform.entity.UserRecom;
- import org.springblade.modules.platform.entity.UserScores;
- import org.springblade.modules.platform.service.IUserRecomService;
- import org.springblade.modules.platform.service.IUserScoresService;
- import org.springblade.modules.platform.service.UserAppService;
- import org.springblade.modules.resource.builder.sms.SmsBuilder;
- import org.springblade.modules.system.entity.User;
- import org.springblade.modules.system.entity.UserApp;
- import org.springblade.modules.system.entity.UserInfo;
- import org.springblade.modules.system.entity.UserMerchant;
- import org.springblade.modules.system.service.IUserMerchantService;
- import org.springblade.modules.system.service.IUserService;
- import org.springblade.modules.system.service.IUserWeChatService;
- import org.springframework.transaction.annotation.Transactional;
- import org.springframework.web.bind.annotation.*;
- import javax.annotation.Resource;
- import javax.servlet.http.HttpServletResponse;
- import javax.validation.Valid;
- import static org.springblade.core.cache.constant.CacheConstant.USER_CACHE;
- import static org.springblade.modules.resource.utils.SmsUtil.VALIDATE_FAIL;
- import static org.springblade.modules.resource.utils.SmsUtil.VALIDATE_SUCCESS;
- /**
- * 控制器
- *
- * @author xuwei
- * @since 2022-02-12
- */
- @RestController
- @AllArgsConstructor
- @RequestMapping(CommonConstant.API_URL)
- @Api(value = "登录注册", tags = "03.登录注册")
- public class LoginController extends BladeController {
- private final IUserService userService;
- private final IUserRecomService userRecomService;
- private final IUserScoresService userScoresService;
- private final BladeRedis bladeRedis;
- private final JwtProperties jwtProperties;
- private final UserAppService userAppService;
- private final IUserWeChatService userWeChatService;
- private final IUserMerchantService iUserMerchantService;
- @ApiLog("用户注册")
- @PostMapping("/user-register")
- @ApiOperationSupport(order = 1)
- @ApiOperation(value = "用户注册", notes = "手机号注册")
- @Transactional(rollbackFor = Exception.class)
- public R userRegister(@ApiParam(value = "邀请码", required = true) @RequestParam(value = "inviteCode", required = false) String inviteCode,
- @ApiParam(value = "手机号", required = true) @RequestParam(value = "phone") String phone,
- @ApiParam(value = "密码", required = true) @RequestParam(value = "password") String password,
- @ApiParam(value = "验证码", required = true) @RequestParam(value = "captchaCode", required = false) String captchaCode,
- @ApiParam(value = "验证ID, 发送验证码返回的ID", required = true) @RequestParam(value = "captchaId") String captchaId){
- if(StringUtil.isEmpty(inviteCode)){
- inviteCode = "TPSL5I";
- }
- User query = userService.getOne(Wrappers.<User>query().lambda().eq(User::getCode, inviteCode));
- if (query == null){
- return R.fail("邀请码输入错误!");
- }
- if (!PhoneUtil.isPhone(phone)){
- return R.fail("请输入正确的手机号!");
- }
- if (StringUtil.isBlank(captchaCode) || StringUtil.isBlank(captchaId)){
- return R.fail("请输入手机验证码!");
- }
- User query1 = userService.getOne(Wrappers.<User>query().lambda().eq(User::getAccount, phone));
- if (query1 != null){
- return R.fail("手机号已注册!");
- }
- boolean flg = captchaCode(phone, captchaId, captchaCode);
- if (!flg){
- return R.fail(VALIDATE_FAIL);
- }
- String tenantId = WebUtil.getRequest().getHeader(TokenUtil.TENANT_HEADER_KEY);
- User user = new User();
- user.setAccount(phone);
- user.setPhone(phone);
- user.setTenantId(tenantId);
- user.setPassword(password);
- user.setName(DesensitizedUtil.mobilePhone(phone));
- CacheUtil.clear(USER_CACHE);
- flg = userService.registerApp(user, query.getId());
- if (flg){
- //添加用户推荐记录表数据
- query1 = userService.getOne(Wrappers.<User>query().lambda().eq(User::getAccount, phone));
- UserRecom userRecom = new UserRecom();
- userRecom.setUserId(query1.getId()); //团队用户
- userRecom.setRecomId(query.getId()); //推荐人
- userRecom.setCreateTime(DateUtil.now());
- userRecomService.save(userRecom);
- UserApp userApp = new UserApp();
- UserApp userAppQuery = userApp.selectOne(Wrappers.<UserApp>query().lambda().eq(UserApp::getUserId, query.getId()));
- //邀请好友注册完善资料(+5信誉分)
- UserScores userScores = new UserScores();
- userScores.setUserId(query.getId());//推荐人
- int score = Integer.parseInt(ParamCache.getValue(CommonConstant.SCORE_USER_REGISTER));
- userScores.setScore(score);
- String dataRemarks = "推荐用户注册";
- if (userAppQuery.getCreditScore() >= 500){
- score = Integer.parseInt(ParamCache.getValue(CommonConstant.SCORE_CONSIGN_REGISTER));
- userScores.setScore(score);
- dataRemarks = "推荐用户注册(500信誉分以上或含有500信誉分)";
- }
- userScores.setDataSrc("1");
- userScores.setDataId(query1.getId());
- userScores.setDataType(1);
- userScores.setDataRemarks(dataRemarks);
- userScoresService.save(userScores);
- //修改用户信誉积分
- UserApp userAppUpdate = new UserApp();
- userAppUpdate.setId(userAppQuery.getId());
- userAppUpdate.setCreditScore(userAppQuery.getCreditScore() + score);
- userAppUpdate.updateById();
- return R.success("注册成功");
- }else{
- return R.success("注册失败");
- }
- }
- @ApiLog("修改支付密码")
- @PostMapping("/modifyPayPassword")
- @ApiOperationSupport(order = 2)
- @ApiOperation(value = "修改支付密码", notes = "通过验证码修改支付密码")
- public R modifyPayPassword(@ApiParam(value = "验证码", required = true) @RequestParam(value = "captchaCode") String captchaCode,
- @ApiParam(value = "验证ID, 发送验证码返回的ID", required = true) @RequestParam(value = "captchaId") String captchaId,
- @ApiParam(value = "支付密码", required = true) @RequestParam(value = "payPassword") String payPassword){
- BladeUser user = getUser();
- boolean flg = captchaCode(user.getAccount(), captchaId, captchaCode);
- if (!flg){
- return R.fail(VALIDATE_FAIL);
- }
- String offsetCode = CommonUtil.genTimeID();
- UserApp userApp = userAppService.getOne(Wrappers.<UserApp>query().lambda().eq(UserApp::getUserId, user.getUserId()));
- userApp.setPayPassword(DigestUtil.encrypt(offsetCode + payPassword));
- userApp.setOffsetCode(offsetCode);
- userAppService.updateById(userApp);
- return R.success("修改支付密码成功");
- }
- @ApiLog("登录用户验证-账号密码")
- @PostMapping("/login_account")
- @ApiOperationSupport(order = 2)
- @ApiOperation(value = "账号密码登录", notes = "账号:account,密码:password")
- public R accountLogin(@ApiParam(value = "账号", required = true) @RequestParam String username,
- @ApiParam(value = "密码", required = true) @RequestParam String password,
- @ApiParam(value = "微信小程序code") @RequestParam(required = false) String code) {
- String tenantId = WebUtil.getRequest().getHeader(TokenUtil.TENANT_HEADER_KEY);
- String refreshToken = WebUtil.getRequest().getParameter("refresh_token");
- String userType = Func.toStr(WebUtil.getRequest().getHeader(TokenUtil.USER_TYPE_HEADER_KEY), UserEnum.APP.getName());
- TokenParameter tokenParameter = new TokenParameter();
- tokenParameter.getArgs().set("tenantId", tenantId)
- .set("username", username)
- .set("password", password)
- .set("grantType", PasswordTokenGranter.GRANT_TYPE)
- .set("refreshToken", refreshToken)
- .set("userType", userType);
- ITokenGranter granter = TokenGranterBuilder.getGranter(PasswordTokenGranter.GRANT_TYPE);
- UserInfo userInfo = granter.grant(tokenParameter);
- if (userInfo == null || userInfo.getUser() == null) {
- return R.fail("用户名或密码不正确");
- }
- if (StringUtil.isNoneBlank(code)) {
- userWeChatService.saveUserInfo(userInfo, code);
- }
- User user = userService.getById(userInfo.getUser().getId());
- if(ObjectUtil.isNotNull(user.getLogOut()) && user.getLogOut() == 1){
- return R.fail("用户已注销无法正常使用,如需使用请联系管理员");
- }
- return R.data(TokenUtil.createAuthInfo(userInfo));
- }
- @ApiLog("微信授权登录")
- @PostMapping("/login/wx-auth")
- @ApiOperationSupport(order = 2)
- @ApiOperation(value = "微信授权登录", tags = "通过 getPhoneNumberCode 获取手机号")
- public R wxAuthLogin(@ApiParam(value = "微信code", required = true) @RequestParam String code,
- @ApiParam(value = "获取手机号的code,五分钟有效", required = true) @RequestParam String getPhoneNumberCode) {
- String tenantId = WebUtil.getRequest().getHeader(TokenUtil.TENANT_HEADER_KEY);
- TokenParameter tokenParameter = new TokenParameter();
- tokenParameter.getArgs()
- .set("tenantId", tenantId)
- .set("getPhoneNumberCode", getPhoneNumberCode)
- .set("code", code);
- ITokenGranter granter = TokenGranterBuilder.getGranter("wxAuth");
- UserInfo userInfo;
- userInfo = granter.grant(tokenParameter);
- if (userInfo == null || userInfo.getUser() == null) {
- return R.fail(ResultCode.USER_NOT_EXIST);
- }
- User user = userService.getById(userInfo.getUser().getId());
- if(ObjectUtil.isNotNull(user.getLogOut()) && user.getLogOut() == 1){
- return R.fail("用户已注销无法正常使用,如需使用请联系管理员");
- }
- return R.data(TokenUtil.createAuthInfo(userInfo));
- }
- @ApiLog("登录用户验证-手机验证码登录")
- @PostMapping("/login_phone")
- @ApiOperationSupport(order = 3)
- @ApiOperation(value = "手机验证码登录", notes = "账号:account,密码:password")
- public R phoneLogin(@ApiParam(value = "账号", required = true) @RequestParam String username,
- @ApiParam(value = "验证码", required = true) @RequestParam(value = "captchaCode") String captchaCode,
- @ApiParam(value = "验证ID, 发送验证码返回的ID", required = true) @RequestParam(value = "captchaId") String captchaId) {
- if (!PhoneUtil.isPhone(username)){
- return R.fail("请输入正确的手机号!");
- }
- if (StringUtil.isEmpty(captchaCode) ||StringUtil.isEmpty(captchaId)){
- return R.fail("请输入手机验证码!");
- }
- String tenantId = WebUtil.getRequest().getHeader(TokenUtil.TENANT_HEADER_KEY);
- String grantType = "phone";
- String userType = Func.toStr(WebUtil.getRequest().getHeader(TokenUtil.USER_TYPE_HEADER_KEY), UserEnum.APP.getName());
- TokenParameter tokenParameter = new TokenParameter();
- tokenParameter.getArgs().set("tenantId", tenantId)
- .set("username", username)
- .set("captchaId", captchaId)
- .set("captchaCode", captchaCode)
- .set("grantType", grantType)
- .set("userType", userType);
- ITokenGranter granter = TokenGranterBuilder.getGranter(grantType);
- UserInfo userInfo = granter.grant(tokenParameter);
- return R.data(TokenUtil.createAuthInfo(userInfo));
- }
- @ApiLog("修改密码")
- @PostMapping("/reset_password")
- @ApiOperationSupport(order = 4)
- @ApiOperation(value = "修改密码", notes = "账号:account,密码:password")
- public R resetPassword(@ApiParam(value = "手机号", required = true) @RequestParam String username,
- @ApiParam(value = "密码", required = true) @RequestParam String password,
- @ApiParam(value = "验证码", required = true) @RequestParam(value = "captchaCode") String captchaCode,
- @ApiParam(value = "验证ID, 发送验证码返回的ID", required = true) @RequestParam(value = "captchaId") String captchaId) {
- String tenantId = WebUtil.getRequest().getHeader(TokenUtil.TENANT_HEADER_KEY);
- if (!PhoneUtil.isPhone(username)){
- return R.fail("请输入正确的手机号!");
- }
- if (StringUtil.isEmpty(captchaCode) ||StringUtil.isEmpty(captchaId)){
- return R.fail("请输入手机验证码!");
- }
- User user = userService.userByAccount(tenantId, username);
- if (user == null){
- return R.fail("该手机号为注册!");
- }
- boolean flg = captchaCode(username, captchaId,captchaCode);
- if (!flg){
- return R.fail(VALIDATE_FAIL);
- }
- User updateUser = new User();
- updateUser.setId(user.getId());
- updateUser.setPassword(DigestUtil.encrypt(password));
- flg = userService.updateById(updateUser);
- if (!flg){
- return R.fail("操作失败");
- }
- CacheUtil.clear(USER_CACHE);
- return R.success("操作成功");
- }
- @GetMapping("/logout")
- @ApiOperation(value = "退出登录")
- @ApiOperationSupport(order = 5)
- public R logout() {
- BladeUser user = AuthUtil.getUser();
- if (user != null && jwtProperties.getState()) {
- String token = JwtUtil.getToken(WebUtil.getRequest().getHeader(TokenConstant.HEADER));
- JwtUtil.removeAccessToken(user.getTenantId(), String.valueOf(user.getUserId()), token);
- }
- return R.success("退出成功");
- }
- @ApiLog("商家注册")
- @PostMapping("/merchant-register")
- @ApiOperationSupport(order = 6)
- @ApiOperation(value = "商家注册", notes = "商家注册")
- @Transactional
- public R<Void> merchantRegister(@Valid @RequestBody MerchantRegisterRequest request) {
- if (!PhoneUtil.isPhone(request.getPhone())){
- return R.fail("请输入正确的手机号!");
- }
- if (!IdcardUtil.isValidCard(request.getIdCard())) {
- return R.fail("请输入正确的身份证号!");
- }
- if (!request.getPassword().equals(request.getRePassword())) {
- return R.fail("密码不一致");
- }
- User query1 = userService.getOne(Wrappers.<User>query().lambda().eq(User::getAccount, request.getPhone()));
- if (query1 != null){
- return R.fail("手机号已注册!");
- }
- boolean flg = captchaCode(request.getPhone(), request.getCaptchaId(), request.getCaptchaCode());
- if (!flg){
- return R.fail(VALIDATE_FAIL);
- }
- String tenantId = WebUtil.getRequest().getHeader(TokenUtil.TENANT_HEADER_KEY);
- User user = new User();
- user.setAccount(request.getPhone());
- user.setPhone(request.getPhone());
- user.setTenantId(tenantId);
- user.setUserType(UserEnum.MERCHANT.getCategory());
- user.setPassword(DigestUtil.encrypt(request.getPassword()));
- user.setName(request.getMerchantName());
- user.setRealName(request.getName());
- userService.save(user);
- UserMerchant userMerchant = new UserMerchant();
- userMerchant.setUserId(user.getId());
- userMerchant.setAddress(request.getAddress());
- userMerchant.setIdCard(request.getIdCard());
- userMerchant.setBusinessLicence(request.getBusinessLicence());
- userMerchant.setParentId(0L);
- iUserMerchantService.save(userMerchant);
- return R.success("注册成功");
- }
- private boolean captchaCode(String phone, String captchaId, String captchaCode){
- String key = "blade:sms::captcha:" + phone + ":" + captchaId;
- String cache = bladeRedis.get(key);
- if (captchaCode.equals(cache)){
- return true;
- }
- return false;
- }
- }
|