无关风月
2024-12-31 bf765893039bc7968b8160a70bda778526dca98c
applet/src/main/java/com/jilongda/applet/controller/LoginController.java
@@ -1,30 +1,15 @@
package com.jilongda.applet.controller;
import com.alibaba.fastjson.JSONObject;
import com.alipay.v3.ApiException;
import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiUserGetuserinfoRequest;
import com.dingtalk.api.request.OapiV2UserGetRequest;
import com.dingtalk.api.response.OapiUserGetuserinfoResponse;
import com.dingtalk.api.response.OapiV2UserGetResponse;
import com.github.xiaoymin.knife4j.core.util.StrUtil;
import com.jilongda.applet.dto.*;
import com.jilongda.applet.model.SecUser;
import com.jilongda.applet.security.SecurityUserDetails;
import com.jilongda.applet.security.SysUserDetailsService;
import com.jilongda.applet.service.SecUserService;
import com.jilongda.applet.utils.ALiSendSms;
import com.jilongda.applet.utils.LoginInfoUtil;
import com.jilongda.applet.utils.dingding.DingTalkAccessTokenRequest;
import com.jilongda.applet.model.TAppUser;
import com.jilongda.applet.service.TAppUserService;
import com.jilongda.applet.wx.body.resp.Code2SessionRespBody;
import com.jilongda.applet.wx.body.resq.Code2SessionResqBody;
import com.jilongda.applet.wx.pojo.AppletUserDecodeData;
import com.jilongda.applet.wx.pojo.AppletUserEncrypteData;
import com.jilongda.applet.wx.utils.WeixinProperties;
import com.jilongda.applet.wx.utils.WxAppletTools;
import com.jilongda.applet.wx.utils.WxUtils;
import com.jilongda.common.basic.ApiResult;
import com.jilongda.common.basic.Constant;
import com.jilongda.common.exception.ServiceException;
import com.jilongda.common.log.OperLoginLog;
import com.jilongda.common.log.OperationLog;
import com.jilongda.common.msg.HuaweiCloudSMSUtil;
import com.jilongda.common.redis.RedisAutoTemplate;
import com.jilongda.common.security.SecurityUtils;
import com.jilongda.common.utils.WebUtils;
@@ -33,16 +18,11 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
 * <p>
@@ -57,303 +37,36 @@
@RestController
@RequestMapping("/")
public class LoginController {
    private final SecurityUtils securityUtils;
    private final AuthenticationManager authenticationManager;
    private final RedisAutoTemplate redisAutoTemplate;
    private final HuaweiCloudSMSUtil msgUtils;
    private final LoginInfoUtil loginInfoUtil;
    private final SysUserDetailsService loadUserDetailsService;
    @Autowired
    private SecUserService secUserService;
    private SecurityUtils securityUtils;
    @Autowired
    private PasswordEncoder passwordEncoder;
    private AuthenticationManager authenticationManager;
    @Autowired
    public LoginController(SecurityUtils securityUtils, AuthenticationManager authenticationManager, RedisAutoTemplate redisAutoTemplate, HuaweiCloudSMSUtil msgUtils, LoginInfoUtil loginInfoUtil,SysUserDetailsService loadUserDetailsService) {
        this.securityUtils = securityUtils;
        this.authenticationManager = authenticationManager;
        this.redisAutoTemplate = redisAutoTemplate;
        this.msgUtils = msgUtils;
        this.loginInfoUtil = loginInfoUtil;
        this.loadUserDetailsService = loadUserDetailsService;
    }
    private RedisAutoTemplate redisAutoTemplate;
    @Autowired
    private TAppUserService appUserService;
    @Autowired
    private WeixinProperties wxConfig;
    @Autowired
    private RestTemplate wxRestTemplate;
//    @ApiOperation(value = "通过code获得openid")
//    @GetMapping("openId-by-jscode2session/{code}")
//    public ApiResult<Map<String, Object>> jscode2session(@PathVariable("code") String code) {
////        log.info("<<<<<<<<换取openid开始<<<<<<<<:{}", code);
////        WxAppletTools appletTools = new WxAppletTools(wxRestTemplate, wxConfig);
////        Code2SessionRespBody body = appletTools.getOpenIdByJscode2session(new Code2SessionResqBody().build(code));
////        String openid = body.getOpenid();
////        String sessionKey = body.getSessionKey();
////        SecUser secUser = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class).eq(SecUser::getOpenId, openid).last("limit 1"));
////        if (Objects.isNull(secUser)) {
////            return ApiResult.failed(500, "请绑定账号");
////        }
////        // 提前对sessionKey进行删除
////        //redisTemplate.delete(openid);
////        log.info("换取sessionKey:{}", sessionKey);
////        // 将sessionKey进行存储,后续获取信息需要
////        redisAutoTemplate.setStr(openid, sessionKey);
//        Map<String, Object> tokenInfos = securityUtils.login(null, null, authenticationManager, SecUser.class, 3);
//        return ApiResult.success(tokenInfos);
//    }
//    @ApiOperation(value = "账号与小程序进行绑定")
//    @GetMapping("openidBindPhone/{code}/{account}")
//    public ApiResult<String> openidBindPhone(@PathVariable("code") String code, @PathVariable("account") String account) {
//        SecUser secUser = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class).eq(SecUser::getAccount, account).last("limit 1"));
//        Assert.isTrue(!StringUtils.hasLength(secUser.getOpenId()), "该账号已绑定微信");
//        log.info("<<<<<<<<换取openid开始<<<<<<<<:{}", code);
//        WxAppletTools appletTools = new WxAppletTools(wxRestTemplate, wxConfig);
//        Code2SessionRespBody body = appletTools.getOpenIdByJscode2session(new Code2SessionResqBody().build(code));
    @ApiOperation(value = "通过code获得openid,获取用户信息",tags = {"微信小程序登录"})
    @PostMapping("openIdByJsCode")
    public ApiResult<Map<String, Object>> openIdByJsCode(@RequestBody AppletUserEncrypteData data) {
        log.info("<<<<<<<<换取openid开始<<<<<<<<:{}", data.getCode());
//        WxAppletTools appletTools = new WxAppletTools(wxRestTemplate, wxConfig, redisAutoTemplate);
//        Code2SessionRespBody body = appletTools.getOpenIdByJscode2session(new Code2SessionResqBody().build(data.getCode()));
//        String openid = body.getOpenid();
//        // 手机号绑定微信
//        secUser.setOpenId(openid);
//        secUserService.updateById(secUser);
//        return ApiResult.success();
//    }
    /**
     * 登录接口
     */
//    @OperLoginLog
//    @ApiOperation("用户账号登录")
//    @PostMapping(value = "login")
//    public ApiResult<Map<String, Object>> login(@Validated @RequestBody LoginDTO loginDto) {
//        // 先检验是否登录
//        String username = loginDto.getAccount();
//        String password = loginDto.getPassword();
//
//        log.info("<<<<<<<<换取openid开始<<<<<<<<:{}", loginDto.getCode());
////        WxAppletTools appletTools = new WxAppletTools(wxRestTemplate, wxConfig);
////        Code2SessionRespBody body = appletTools.getOpenIdByJscode2session(new Code2SessionResqBody().build(loginDto.getCode()));
////        String openid = body.getOpenid();
////        loginDto.setOpenId(openid);
//
//        try {
//            Map<String, Object> token = securityUtils.login(username, password, authenticationManager, SecurityUserDetails.class, 2);
//            return ApiResult.success(token);
//        } catch (Exception e) {
//            e.printStackTrace();
//            ApiResult<Map<String, Object>> failed = ApiResult.failed(new HashMap<>(1));
//            failed.setCode(0);
//            failed.setSuccess(false);
//            failed.setMsg(e.getMessage());
//            return failed;
//        String sessionKey = body.getSessionKey();
//        if(!StringUtils.hasLength(data.getEncryptedData()) || !StringUtils.hasLength(data.getIv())){
//            return ApiResult.failed("已拒绝授权",null);
//        }
//    }
    /**
     * 登录接口
     */
    @OperLoginLog
    @ApiOperation("后台登录")
    @PostMapping(value = "login")
    public ApiResult<Map<String, Object>> login1(@Validated @RequestBody LoginDTO loginDto) {
        //验证是否通过验证
//        if (ObjectUtils.isEmpty(loginDto.getVerify()) || !loginDto.getVerify()) {
//            ApiResult<Map<String, Object>> failed = new ApiResult<>();
//            failed.setMsg("登录失败,请正确验证!");
//            return failed;
//        }
        // 先检验是否登录
        String username = loginDto.getPhone();
        String password = loginDto.getPassword();
        try {
            SecUser secUser = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class)
                    .eq(SecUser::getAccount, loginDto.getPhone()));
            Assert.isTrue(Objects.nonNull(secUser), "该账号不存在");
            SecUser one = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class).eq(SecUser::getAccount, username));
            if (one.getState()){
                return ApiResult.failed(500, "该账号已被冻结,请联系管理员");
            }
            Map<String, Object> token = securityUtils.login(username, password, authenticationManager, SecurityUserDetails.class, 1);
            return ApiResult.success(token);
        } catch (Exception e) {
            ApiResult<Map<String, Object>> failed = ApiResult.failed(new HashMap<>(1));
            failed.setCode(0);
            failed.setSuccess(false);
            failed.setMsg(e.getMessage());
            return failed;
        }
    }
    /**
     * 登录接口
     */
//    @OperLoginLog
//    @ApiOperation("选择用户账号登录")
//    @PostMapping(value = "choose-login")
//    public ApiResult<Map<String, Object>> chooseLogin(@Validated @RequestBody LoginDTO loginDto) {
        // 先检验是否登录
//        String username = loginDto.getAccount();
//
////        SecUser one = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class)
////                .eq(SecUser::getAccount, username));
//
//        log.info("<<<<<<<<换取openid开始<<<<<<<<:{}", loginDto.getCode());
//        WxAppletTools appletTools = new WxAppletTools(wxRestTemplate, wxConfig);
//        Code2SessionRespBody body = appletTools.getOpenIdByJscode2session(new Code2SessionResqBody().build(loginDto.getCode()));
//        String openid = body.getOpenid();
//        loginDto.setOpenId(openid);
//
//        try {
//            Map<String, Object> token = securityUtils.login(username, one, authenticationManager, SecUser.class, 2);
//
//            //保存登录记录
//            try {
//                loginRecordService.saveNew((SecurityUserDetails) token.get("userInfo"));
//            } catch (Exception e) {
//                log.error("登录记录失败!");
//            }
//
//            return ApiResult.success(token);
//        } catch (Exception e) {
//            ApiResult<Map<String, Object>> failed = ApiResult.failed(new HashMap<>(1));
//            failed.setCode(0);
//            failed.setSuccess(false);
//            failed.setMsg(e.getMessage());
//            return failed;
//        }
//        return ApiResult.success(new HashMap<>());
//    }
    /**
     * 登录接口
     */
//    @ApiOperation("短信登录")
//    @PostMapping(value = "code/login")
//    public ApiResult<List<SecUser>> loginByCode(@Validated @RequestBody LoginCodeDTO dto) {
//        // 先检验是否登录
//        String phone = dto.getPhone();
//        String code = dto.getCode();
//        // 校验验证码是否正确
//        String redisCode = redisAutoTemplate.getStr(dto.getPhone());
//        Assert.isTrue(StringUtils.hasLength(redisCode), "验证码已过期");
//        if (!code.equals(redisCode)) {
//            throw new ServiceException(500, "验证码错误,请重新输入验证码!");
//        }
//        try {
////            List<SecUser> list = secUserService.list(Wrappers.lambdaQuery(SecUser.class)
////                    .eq(SecUser::getPhone, phone));
////            list = list.stream().filter(o -> !o.getShortName().contains("admin")).collect(Collectors.toList());
////            Map<String, Object> token = securityUtils.login(phone, code, authenticationManager, SecurityUserDetails.class, true);
//            //保存登录记录
//            return ApiResult.success(new ArrayList<>());
//        } catch (Exception e) {
//            ApiResult<List<SecUser>> failed = ApiResult.failed(new ArrayList<>(1));
//            failed.setCode(0);
//            failed.setSuccess(false);
//            failed.setMsg(e.getMessage());
//            return failed;
//        }
//    }
    @ApiOperation("发送验证码")
    @PostMapping(value = "sendCode")
    public ApiResult<String> sendCode(@RequestBody VerificationCodeDTO dto) throws ClientException {
        // 账号查询用户
        SecUser secUser = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class)
                .eq(SecUser::getAccount, dto.getPhone()));
        Assert.isTrue(Objects.nonNull(secUser), "该账号不存在");
        // 发送验证码并存储到redis
        if (StringUtils.hasLength(dto.getPhone())) {
            if(!loginInfoUtil.checkPhoneExits(dto.getPhone())){
                throw new ServiceException("无效手机号码");
            }
            String code = String.valueOf((int) (Math.random() * 1000000));
            //TODO 临时验证码,短信未开通前测试用
//            code = "666666";
            redisAutoTemplate.setStr("code:"+dto.getPhone(), code);
            redisAutoTemplate.expire(dto.getPhone(), Constant.REDIS_EXPIRE);
//            msgUtils.sendSMS(dto.getPhone(), code);
            AliSms aliSms =new AliSms();
            aliSms.setCode(code);
            aliSms.setProduct(dto.getPhone());
            String json = JSONObject.toJSONString(aliSms);
            aLiSendSms.sendSms(dto.getPhone(), "SMS_58880127", json);
            return ApiResult.success("发送短信验证码成功!15分钟内有效");
        }
        return ApiResult.failed(500, "发送短信验证码失败,请确认手机号码!");
    }
    @ApiOperation("发送修改密码验证码")
    @PostMapping(value = "sendPassCode")
    public ApiResult<String> sendPassCode(@RequestBody VerificationCodeDTO dto) throws ClientException {
        // 账号查询用户
        SecUser secUser = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class)
                .eq(SecUser::getAccount, dto.getPhone()));
        Assert.isTrue(Objects.nonNull(secUser), "该账号不存在");
        // 发送验证码并存储到redis
        if (StringUtils.hasLength(dto.getPhone())) {
            if(!loginInfoUtil.checkPhoneExits(dto.getPhone())){
                throw new ServiceException("无效手机号码");
            }
            String code = String.valueOf((int) (Math.random() * 1000000));
            //TODO 临时验证码,短信未开通前测试用
//            code = "666666";
            redisAutoTemplate.setStr("code:"+dto.getPhone(), code);
            redisAutoTemplate.expire(dto.getPhone(), Constant.REDIS_EXPIRE);
//            msgUtils.sendSMS(dto.getPhone(), code);
            AliSms aliSms =new AliSms();
            aliSms.setCode(code);
            aliSms.setProduct(dto.getPhone());
            String json = JSONObject.toJSONString(aliSms);
            aLiSendSms.sendSms(dto.getPhone(), "SMS_58880123", json);
            return ApiResult.success("发送短信验证码成功!15分钟内有效");
        }
        return ApiResult.failed(500, "发送短信验证码失败,请确认手机号码!");
    }
    @OperLoginLog
    @ApiOperation("短信登录")
    @PostMapping(value = "code/login")
    public ApiResult<Map<String, Object>> loginByCode(@Validated @RequestBody LoginCodeDTO dto) {
        String phone = dto.getPhone();
        String code = dto.getCode();
        // 校验验证码是否正确
        if(!redisAutoTemplate.hasKey("code:"+phone)){
            throw new ServiceException(500, "验证码错误");
        }
        String redisCode = redisAutoTemplate.getStr("code:"+phone);
        if (!code.equals(redisCode)) {
            throw new ServiceException(500, "验证码错误");
        }
        try {
            SecUser one = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class).eq(SecUser::getAccount, phone));
            if (Objects.isNull(one)){
                return ApiResult.failed(500, "请输入正确的账号");
            }
            if (one.getState()){
                return ApiResult.failed(500, "该账号已被冻结,请联系管理员");
            }
            Map<String, Object> token = securityUtils.login(phone, code, authenticationManager, SecurityUserDetails.class, 2);
            SecurityUserDetails userDetails = loadUserDetailsService.loadUserByUsername(phone);
            token.put("userInfo", userDetails);
            return ApiResult.success(token);
        } catch (Exception e) {
            ApiResult<Map<String, Object>> failed = ApiResult.failed(new HashMap<>(1));
            failed.setCode(0);
            failed.setSuccess(false);
            failed.setMsg(e.getMessage());
            return failed;
        }
//        AppletUserDecodeData appletUserDecodeData = WxUtils.encryptedData(data.getEncryptedData(), sessionKey,  data.getIv());
//        appletUserDecodeData.setOpenId(openid);
//        TAppUser appUser = appUserService.wxLogin(appletUserDecodeData);
        TAppUser appUser = appUserService.getById(1);
        Map<String, Object> tokenInfos = securityUtils.login(appUser.getOpenId(), appUser, authenticationManager, TAppUser.class, 3);
        return ApiResult.success(tokenInfos);
    }
    @ApiOperation("退出登录")
@@ -365,99 +78,6 @@
        }
        return ApiResult.success();
    }
    @OperationLog(operType = "修改", operDesc = "密码修改", operModul = "用户")
    @ApiOperation("首页密码修改")
    @PostMapping("/pageResetPassword")
    public ApiResult<String> pageResetPassword(@Validated @RequestBody ResetPasswordDTO dto) {
        // 账号查询用户
        SecUser secUser = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class)
                .eq(SecUser::getPhone, dto.getPhone()));
        Assert.isTrue(Objects.nonNull(secUser), "该账号不存在");
        // 校验短信验证码
        String str = redisAutoTemplate.getStr("code:"+secUser.getPhone());
        if(!StringUtils.hasLength(str)){
            return ApiResult.failed("验证码已过期!");
        }
        if(!str.equals(dto.getCode())){
            return ApiResult.failed("验证码错误");
        }
//        if (StrUtil.isNotBlank(dto.getPassword())) {
//            // 根据加密算法加密用户输入的密码,然后和数据库中保存的密码进行比较
//            if (!this.passwordEncoder.matches(dto.getOldPassword(), secUser.getPassword())) {
//                throw new BadCredentialsException("输入原密码不正确");
//            }
            // 修改密码
            secUser.setPassword(passwordEncoder.encode(dto.getPassword()));
//        } else {
//            // 重置密码
//            secUser.setPassword(passwordEncoder.encode(Constant.DEF_PASSWORD));
//        }
        secUserService.updateById(secUser);
        return ApiResult.success();
    }
    @ApiOperation("钉钉登录")
    @RequestMapping(value = "/dingding", method = RequestMethod.GET)
    public ApiResult login (@RequestParam("code") String requestAuthCode) throws Exception {
        OapiUserGetuserinfoResponse response;
        String accessTokenRequest = DingTalkAccessTokenRequest.getAccessTokenRequest();
        String access_token = accessTokenRequest;
        try {
        //
        // 获取用户信息
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/getuserinfo");
        OapiUserGetuserinfoRequest request = new OapiUserGetuserinfoRequest();
        request.setCode(requestAuthCode);
        request.setHttpMethod("GET");
            response = client.execute(request, access_token);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
        // 查询得到当前用户的userId
        // 获得到userId之后应用应该处理应用自身的登录会话管理(session),避免后续的业务交互(前端到应用服务端)每次都要重新获取用户身份,提升用户体验
        String userId = response.getUserid();
        Map<String, Object> returnMap = new HashMap<String,Object>();
        returnMap.put("userId", userId);
//        return ServiceResult.success(returnMap);
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
        OapiV2UserGetRequest req = new OapiV2UserGetRequest();
        req.setUserid(userId);
        OapiV2UserGetResponse rsp = client.execute(req, access_token);
        System.out.println(rsp.getBody());
        return ApiResult.success();
    }
    @Autowired
    private ALiSendSms aLiSendSms;
//    @ApiOperation(value = "发送验证码", notes = "发送验证码")
//    @PostMapping(value = "sendMsg")
//    public ApiResult<String> sendMsg(@RequestBody VerificationCodeDTO dto) throws Exception {
//        // 发送验证码并存储到redis
//        if (StringUtils.hasLength(dto.getPhone())) {
//            String code = String.valueOf((int) (Math.random() * 1000000));
//            redisAutoTemplate.setStr(dto.getPhone(), code);
//            redisAutoTemplate.expire(dto.getPhone(), Constant.REDIS_EXPIRE);
//            AliSms aliSms =new AliSms();
//            aliSms.setCode(code);
//            aliSms.setProduct(dto.getPhone());
//            String json = JSONObject.toJSONString(aliSms);
//            aLiSendSms.sendSms(dto.getPhone(), "SMS_58880127", json);
//            return ApiResult.success("发送短信验证码成功!15分钟内有效");
//        }
//        return ApiResult.failed(500, "发送短信验证码失败,请确认手机号码!");
//    }