ZQN
2025-05-19 0e12e4ab45db6768a0f45d8952f78b0ae9190723
project-framework/src/main/java/com/project/framework/web/service/SysLoginService.java
@@ -1,20 +1,23 @@
package com.project.framework.web.service;
import javax.annotation.Resource;
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.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.project.common.constant.AliyunSmsConstants;
import com.project.common.constant.CacheConstants;
import com.project.common.constant.Constants;
import com.project.common.core.domain.entity.SysUser;
import com.project.common.core.domain.model.LoginUser;
import com.project.common.core.redis.RedisCache;
import com.project.common.exception.ServiceException;
import com.project.common.exception.base.BaseException;
import com.project.common.exception.user.CaptchaException;
import com.project.common.exception.user.CaptchaExpireException;
import com.project.common.exception.user.UserPasswordNotMatchException;
@@ -26,36 +29,44 @@
import com.project.framework.manager.AsyncManager;
import com.project.framework.manager.factory.AsyncFactory;
import com.project.framework.security.context.AuthenticationContextHolder;
import com.project.system.domain.bo.editBo.UserPhoneLoginBo;
import com.project.system.mapper.SysUserMapper;
import com.project.system.service.ISysConfigService;
import com.project.system.service.ISysUserService;
import com.project.system.sms.YPSmsApi;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import java.util.Random;
import java.util.concurrent.TimeUnit;
/**
 * 登录校验方法
 *
 *
 * @author project
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class SysLoginService
{
    @Autowired
    private TokenService tokenService;
    private final TokenService tokenService;
    private final AuthenticationManager authenticationManager;
    private final RedisCache redisCache;
    private final ISysUserService userService;
    private final SysUserMapper userMapper;
    private final ISysConfigService configService;
    private final YPSmsApi smsApi;
    @Resource
    private AuthenticationManager authenticationManager;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private ISysConfigService configService;
    /**
     * 登录验证
     *
     *
     * @param username 用户名
     * @param password 密码
     * @param code 验证码
@@ -71,7 +82,7 @@
            validateCaptcha(username, code, uuid);
        }
        // 用户验证
        Authentication authentication = null;
        Authentication authentication;
        try
        {
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
@@ -105,12 +116,126 @@
    }
    /**
     * 新注册获取验证码
     * @param phone 手机
     * @return  验证码
     */
    public Boolean getVerifyCodeNew(String phone) {
        // 生成4位随机数
        String code = "";
        Random ran = new Random();
        int randomNum = ran.nextInt(10000);
        code = String.format("%04d", randomNum);
        log.info("手机号:"+phone+"->验证码:"+code);
        boolean send = sendYp(phone, code);
        if (send){
            redisCache.setCacheObject(getCacheKey(phone), code, Constants.PHONE_EXPIRATION, TimeUnit.MINUTES);
            return true;
        }
        redisCache.setCacheObject(getCacheKey(phone), code, Constants.PHONE_EXPIRATION, TimeUnit.MINUTES);
        return false;
    }
    /**
     * 获取验证码
     * @param phone 手机号
     * @return  验证码
     */
    public Boolean getVerifyCode(String phone)
    {
        SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhonenumber,phone));
        if (user==null){
            throw new BaseException("您手机号尚未注册!");
        }
        return getVerifyCodeNew(phone);
    }
    /**
     * 云片验证码
     * @param phone 手机
     * @param code  验证码
     * @return  结果
     */
    private boolean sendYp(String phone, String code)
    {
        String result = smsApi.sendSms(phone, StringUtils.format(YPSmsApi.CODE_TMP, code, Constants.PHONE_EXPIRATION));
        if (result.contains("\"code\":0,\"msg\":\"OK\"")){
            log.info("发送成功 ->验证码:"+code);
            return true;
        }
        return false;
    }
    /**
     * 阿里验证码
     * @param phone 手机
     * @param code  验证码
     * @return  结果
     */
    private boolean sendAl(String phone, String code )
    {
        DefaultProfile profile = DefaultProfile.getProfile("cn-beijing", AliyunSmsConstants.SMS_APPID, AliyunSmsConstants.SMS_SECRET);
        IAcsClient client = new DefaultAcsClient(profile);
        CommonRequest request = new CommonRequest();
        request.setMethod(MethodType.POST);
        request.setDomain("dysmsapi.aliyuncs.com");
        request.setVersion("2017-05-25");
        request.setAction("SendSms");
        request.putQueryParameter("PhoneNumbers", phone);
        request.putQueryParameter("SignName", "盛商珠宝");
        request.putQueryParameter("TemplateCode", "SMS_460945884");
        request.putQueryParameter("TemplateParam", "{code:" + code + "}");
        try {
            CommonResponse response = client.getCommonResponse(request);
            JSONObject jsonObject = JSON.parseObject(response.getData());
            if ("OK".equals(jsonObject.get("Code"))) {
                log.info("发送成功 ->验证码:"+code);
                return true;
            }
        } catch (ClientException e) {
            e.printStackTrace();
        }
        return false;
    }
    /**
     * 验证码登录
     * @param bo    参数
     * @return  结果
     */
    public String phoneLogin(UserPhoneLoginBo bo)
    {
        String phone = bo.getPhone();
//        Boolean verified = verifyPhone(phone, bo.getCode());
//        if (!verified){
//            throw new BaseException("手机号验证码校验失败!");
//        }
        SysUser user = null;
        if ("01".equals(bo.getUserType())){
            user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                    .eq(SysUser::getPhonenumber,bo.getPhone())
                    .and(wrapper->wrapper.eq(SysUser::getUserType,"00").or().eq(SysUser::getUserType, "01")));
        } else {
            user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                    .eq(SysUser::getPhonenumber,bo.getPhone())
                    .eq(SysUser::getUserType,bo.getUserType())
                    );
        }
        if (user==null){
            throw new BaseException("您手机号尚未注册或您选择登录类型有误!");
        }
        if (!"0".equals(user.getStatus())){
            throw new BaseException("您账号已停用或待审批,请联系营商办管理人员!");
        }
        return this.login(user.getUserName(), user.getRecommendUser(), null, null);
    }
    /**
     * 校验验证码
     *
     *
     * @param username 用户名
     * @param code 验证码
     * @param uuid 唯一标识
     * @return 结果
     */
    public void validateCaptcha(String username, String code, String uuid)
    {
@@ -142,4 +267,39 @@
        sysUser.setLoginDate(DateUtils.getNowDate());
        userService.updateUserProfile(sysUser);
    }
    /**
     * 获取验证码前缀
     * @param phone 手机号
     * @return  验证码
     */
    private String getCacheKey(String phone)
    {
        return CacheConstants.PHONE_CODE_KEY + phone;
    }
    /**
     * 校验验证码
     * @param phone 手机号
     * @param code  验证码
     * @return  校验结果
     */
    public Boolean verifyPhone(String phone, String code)
    {
        String key = getCacheKey(phone);
        if (!redisCache.hasKey(key)) {
            return false;
        }
        String redisCode = redisCache.getCacheObject(key);
        boolean verify = redisCode.equals(code);
        if (verify){
            redisCache.deleteObject(getCacheKey(phone));
        }
        return verify;
    }
}