GarUserServiceImpl.java 10.3 KB
package com.trash.garbage.service.impl;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.trash.common.core.domain.entity.SysRole;
import com.trash.common.core.domain.entity.SysUser;
import com.trash.common.core.domain.model.LoginUser;
import com.trash.common.core.redis.RedisCache;
import com.trash.common.utils.SecurityUtils;
import com.trash.framework.web.service.TokenService;
import com.trash.garbage.config.WxConfig;
import com.trash.garbage.custom.BizException;
import com.trash.garbage.global.GlobalRedisProperties;
import com.trash.garbage.global.GlobalStatus;
import com.trash.garbage.global.ResultCode;
import com.trash.garbage.pojo.domain.GarAddress;
import com.trash.garbage.pojo.domain.GarUser;
import com.trash.garbage.pojo.dto.AddressDto;
import com.trash.garbage.pojo.dto.LoginDto;
import com.trash.garbage.service.GarAddressService;
import com.trash.garbage.service.GarUserService;
import com.trash.garbage.mapper.GarUserMapper;
import com.trash.garbage.utils.*;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.spec.AlgorithmParameterSpec;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author 20412
 * @description 针对表【gar_user(建筑垃圾-用户表)】的数据库操作Service实现
 * @createDate 2023-11-20 16:03:15
 */
@Service
@Transactional
public class GarUserServiceImpl extends ServiceImpl<GarUserMapper, GarUser>
        implements GarUserService {
    @Resource
    private WxConfig wxConfig;

    @Autowired
    private GarAddressService garAddressService;


    @Resource
    private RedisCache redisCache;

    @Autowired
    private TokenService tokenService;


    @Override
    public String login(LoginDto loginDto) {
        if (Objects.isNull(loginDto)) {
            throw new UsernameNotFoundException("当前用户不存在!");
        }
        // TODO 微信登录
        if (loginDto.getLoginType().equals(GlobalStatus.UserStatusEnum.WX_LOGIN.getStatus())) {
            String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + wxConfig.getAppId() + "&secret=" + wxConfig.getSecret() + "&js_code=" + loginDto.getWxCode() + "&grant_type=authorization_code";
            String body = HttpUtil.createGet(url).header("cache-control", "no-cache").execute().body();
            JSONObject open = JSONObject.parseObject(body);
            String sessionKey = open.getString("session_key");
            try {
                loginDto.setTel(decrypt(loginDto.getEncryptedData(), sessionKey, loginDto.getIv()));
            } catch (Exception e) {
                throw new RuntimeException("解密失败");
            }
        }
        // 验证码验证
        String code = redisCache.getCacheObject(GlobalRedisProperties.REDIS_USER_CODE.getValue() + loginDto.getTel());
        if (loginDto.getCode() == null || !loginDto.getCode().equals(code)) {
            throw new BizException(ResultCode.CODE_400, "验证码错误!!");
        }
        // 查询用户
        QueryWrapper<GarUser> qw = new QueryWrapper<>();
        qw.lambda().eq(GarUser::getGarUserTel, loginDto.getTel());
        GarUser nUser = this.getOne(qw);
        if (Objects.isNull(nUser)) {
            // 不存在就创建用户
            nUser = new GarUser();
            nUser.setGarUserTel(loginDto.getTel());
            nUser.setGarUserDelFlag(GlobalStatus.DEL_FLAG_NO);
            nUser.setGarUserType(GlobalStatus.UserStatusEnum.NORMAL_USER.getDescription());
            this.save(nUser);
        }
        LoginUser loginUser = new LoginUser();
        ArrayList<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
        loginUser.setAuthorities(authorities);
        Set<String> set = new HashSet<String>();
        SysUser user = new SysUser();
        user.setUserId(nUser.getGarUserId());
        user.setUserName(nUser.getGarUserName());
        user.setPhonenumber(loginDto.getTel());
        loginUser.setUser(user);
        set.add("*:*:*");
        SysRole role = new SysRole();
        role.setRoleKey("admin");
        ArrayList<SysRole> roles = new ArrayList<SysRole>();
        roles.add(role);
        user.setRoles(roles);
        loginUser.setPermissions(set);
        String token = JwtUtils.createToken(nUser.getGarUserId(), nUser.getGarUserTel());
        if (!token.contains("Bearer ")) {
            token = "Bearer " + token;
        }
        loginUser.setToken(token);
        tokenService.refreshToken(loginUser);
        return token;
    }

    @Override
    public void sendVerify(String tel) throws ClientException {
        //随机生成6位数字验证码
        String validateCode = ValidateCodeUtil.generatorCode(4);
        //给用户发送验证码
//        SMSUtils.sendMessage("", tel, validateCode.toString(), "");
        // 保存redis
        System.out.println("code:" + validateCode);
        redisCache.setCacheObject(GlobalRedisProperties.REDIS_USER_CODE.getValue() + tel, validateCode, 60, TimeUnit.SECONDS);
    }

    @Override
    public List<GarAddress> queryAddress(String type) {
        LoginUser user = SecurityUtils.getLoginUser();
        String garUserId = user.getUser().getUserId();
        LambdaQueryWrapper<GarAddress> qw = new LambdaQueryWrapper<>();
        qw.eq(GarAddress::getGarUserId, garUserId);
        if (GlobalStatus.QUERY_ADDRESS_TYPE_CURRENT.equals(type)) {
            qw.eq(GarAddress::getGarUserDefault, GlobalStatus.GarAddressStatus.CURRENT_ADDRESS.getValue());
            GarAddress one = garAddressService.getOne(qw);
            return Arrays.asList(one);
        }
        return garAddressService.list(qw);
    }

    @Override
    public String saveAddress(AddressDto dto) {
        LoginUser userCustom = SecurityUtils.getLoginUser();
        // 限制地址数
        LambdaQueryWrapper<GarAddress> qw = new LambdaQueryWrapper<>();
        qw.eq(GarAddress::getGarUserId, userCustom.getUser().getUserId());
        List<GarAddress> list = garAddressService.list(qw);
        if (list.size() > 19) {
            throw new BizException(ResultCode.CODE_201, "新增地址数已达上线,请删除地址后新增地址或编辑已有地址!");
        }
        GarAddress address = new GarAddress();
        address.setGarUserId(userCustom.getUser().getUserId());
        address.setGarUserAddress(dto.getAddressArea());
        address.setGarUserDefault(dto.getDefaultFlag() ? GlobalStatus.GarAddressStatus.CURRENT_ADDRESS.getValue() : GlobalStatus.GarAddressStatus.NORMAL_ADDRESS.getValue());
        address.setGarUserContactName(dto.getContactPerson());
        address.setGarUserContactTel(dto.getContactIphoneNumber());
        address.setGarRemark(dto.getAddressDetail());
        handleCurrentAddress(address);
        garAddressService.save(address);
        return "新增地址成功!";
    }

    @Override
    public String updateAddress(AddressDto dto) {
        GarAddress address = new GarAddress();
        String userId = SecurityUtils.getLoginUser().getUser().getUserId();
        address.setGarAddressId(dto.getGarAddressId());
        address.setGarUserId(userId);
        address.setGarUserAddress(dto.getAddressArea());
        address.setGarRemark(dto.getAddressDetail());
        address.setGarUserDefault(dto.getDefaultFlag() ? GlobalStatus.GarAddressStatus.CURRENT_ADDRESS.getValue() : GlobalStatus.GarAddressStatus.NORMAL_ADDRESS.getValue());
        handleCurrentAddress(address);
        address.setGarUserContactName(dto.getContactPerson());
        address.setGarUserContactTel(dto.getContactIphoneNumber());
        LambdaUpdateWrapper<GarAddress> up = new LambdaUpdateWrapper<>();
        up.eq(GarAddress::getGarUserId, address.getGarUserId())
                .eq(GarAddress::getGarAddressId, address.getGarAddressId());
        garAddressService.update(address, up);
        return "地址修改成功!";
    }

    private void handleCurrentAddress(GarAddress address) {
        if (address.getGarUserDefault().equals(GlobalStatus.GarAddressStatus.CURRENT_ADDRESS.getValue())) {
            LambdaUpdateWrapper<GarAddress> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(GarAddress::getGarUserId, address.getGarUserId())
                    .set(GarAddress::getGarUserDefault, GlobalStatus.GarAddressStatus.NORMAL_ADDRESS.getValue());
            garAddressService.update(wrapper);
        }
    }

    @Override
    public String deleteAddress(String addressId) {
        String garUserId = SecurityUtils.getLoginUser().getUser().getUserId();
        LambdaQueryWrapper<GarAddress> qw = new LambdaQueryWrapper<>();
        qw.eq(GarAddress::getGarUserId, garUserId)
                .eq(GarAddress::getGarAddressId, addressId);
        garAddressService.remove(qw);
        return "删除成功!";
    }


    /**
     * 微信小程序解密
     *
     * @param encrypted
     * @param session_key
     * @param iv
     * @return
     * @throws Exception
     */
    private String decrypt(String encrypted, String session_key, String iv) throws Exception {
        byte[] encrypData = Base64.decodeBase64(encrypted);
        byte[] ivData = Base64.decodeBase64(iv);
        byte[] sessionKey = Base64.decodeBase64(session_key);
        AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivData);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec keySpec = new SecretKeySpec(sessionKey, "AES");
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
        // 解析解密后的字符串
        return new String(cipher.doFinal(encrypData), "UTF-8");
    }


}