Administrator
2026-06-18 1852a2e7200f81435c08d1b668b87393f4496a61
src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java
@@ -1,34 +1,57 @@
package cc.mrbird.febs.mall.service.impl;
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.common.enumerates.DataDictionaryEnum;
import cc.mrbird.febs.common.enumerates.FlowTypeEnum;
import cc.mrbird.febs.common.enumerates.MoneyFlowTypeEnum;
import cc.mrbird.febs.common.enumerates.ScoreFlowTypeEnum;
import cc.mrbird.febs.common.exception.FebsException;
import cc.mrbird.febs.common.utils.AppContants;
import cc.mrbird.febs.common.utils.LoginUserUtil;
import cc.mrbird.febs.common.utils.RedisUtils;
import cc.mrbird.febs.common.utils.ShareCodeUtil;
import cc.mrbird.febs.mall.dto.ForgetPwdDto;
import cc.mrbird.febs.mall.dto.LoginDto;
import cc.mrbird.febs.mall.dto.RegisterDto;
import cc.mrbird.febs.mall.entity.MallMember;
import cc.mrbird.febs.mall.mapper.MallMemberMapper;
import cc.mrbird.febs.mall.service.IApiMallMemberService;
import cc.mrbird.febs.mall.service.ICommonService;
import cc.mrbird.febs.common.properties.XcxProperties;
import cc.mrbird.febs.common.utils.*;
import cc.mrbird.febs.mall.controller.dependentStation.enums.SalesServiceEnums;
import cc.mrbird.febs.mall.conversion.MallMemberConversion;
import cc.mrbird.febs.mall.conversion.MallShopApplyConversion;
import cc.mrbird.febs.mall.conversion.MallStoreConversion;
import cc.mrbird.febs.mall.dto.*;
import cc.mrbird.febs.mall.entity.*;
import cc.mrbird.febs.mall.mapper.*;
import cc.mrbird.febs.mall.service.*;
import cc.mrbird.febs.mall.vo.*;
import cc.mrbird.febs.pay.model.BrandWCPayRequestData;
import cc.mrbird.febs.pay.service.IXcxPayService;
import cc.mrbird.febs.pay.util.MD5;
import cc.mrbird.febs.vip.VipSettingUnAliveSettingBo;
import cc.mrbird.febs.vip.entity.MallVipConfig;
import cc.mrbird.febs.vip.mapper.MallVipConfigMapper;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
/**
 * @author wzy
@@ -39,82 +62,59 @@
@RequiredArgsConstructor
public class ApiMallMemberServiceImpl extends ServiceImpl<MallMemberMapper, MallMember> implements IApiMallMemberService {
    private final MallMemberWalletMapper mallMemberWalletMapper;
    private final ICommonService commonService;
    private final RedisUtils redisUtils;
    private final MallMoneyFlowMapper mallMoneyFlowMapper;
    private final DataDictionaryCustomMapper dataDictionaryCustomMapper;
    private final MallShopApplyMapper mallShopApplyMapper;
    private final MallAgentRecordMapper mallAgentRecordMapper;
    private final CouponGoodsMapper couponGoodsMapper;
    private final MallMemberCouponMapper mallMemberCouponMapper;
    private final MallAddressInfoMapper mallAddressInfoMapper;
    @Value("${spring.profiles.active}")
    private String active;
    @Transactional(rollbackFor = Exception.class)
    @Override
    public FebsResponse register(RegisterDto registerDto) {
        MallMember mallMember = this.baseMapper.selectInfoByAccount(registerDto.getAccount());
        if (mallMember != null) {
            throw new FebsException("该手机号/邮箱已被占用");
        }
        String account = registerDto.getAccount();
        String code = registerDto.getCode();
        boolean flags = commonService.verifyCode(account, code);
        if(!flags) {
            throw new FebsException("验证码错误");
        MallMember mallMember = this.baseMapper.selectInfoByAccount(account);
        if (mallMember != null) {
            throw new FebsException("Registered");
        }
        /**
         * 验证两次密码是否一致
         */
        String password = registerDto.getPassword();
        String confirmPassword = registerDto.getConfirmPassword();
        if (!password.equals(confirmPassword)) {
            throw new FebsException("The two passwords are inconsistent");
        }
        mallMember = new MallMember();
        mallMember.setPassword(SecureUtil.md5(registerDto.getPassword()));
        // 判断账号类型
        if (AppContants.ACCOUNT_TYPE_MOBILE.equals(registerDto.getType())) {
            mallMember.setPhone(registerDto.getAccount());
        } else {
            mallMember.setEmail(registerDto.getAccount());
        }
        Integer count = this.baseMapper.selectCount(null);
        if (count != null && count != 0) {
            MallMember inviteMember = this.baseMapper.selectInfoByInviteId(registerDto.getInviteId());
            if (inviteMember == null) {
                throw new FebsException("邀请码不存在");
            }
            mallMember.setReferrerId(registerDto.getInviteId());
        }
        mallMember.setName(registerDto.getAccount());
        mallMember.setName(registerDto.getLastName() + registerDto.getFirstName());
        mallMember.setPhone(registerDto.getPhoneNumber());
        mallMember.setEmail(registerDto.getAccount());
        mallMember.setPassword(SecureUtil.md5(password));
        mallMember.setAccountStatus(MallMember.ACCOUNT_STATUS_ENABLE);
        mallMember.setAccountType(MallMember.ACCOUNT_TYPE_NORMAL);
        mallMember.setLevel("1");
        mallMember.setSex("男");
        this.baseMapper.insert(mallMember);
        String inviteId = ShareCodeUtil.toSerialCode(mallMember.getId());
        mallMember.setInviteId(inviteId);
        MallAddressInfo mallAddressInfo = new MallAddressInfo();
        mallAddressInfo.setMemberId(mallMember.getId());
        mallAddressInfo.setName(registerDto.getLastName());
        mallAddressInfo.setFristName(registerDto.getFirstName());
        mallAddressInfo.setPhone(registerDto.getPhoneNumber());
        mallAddressInfoMapper.insert(mallAddressInfo);
        //推荐人和推荐人链
        boolean flag = false;
        String parentId = mallMember.getReferrerId();
        String ids = "";
        while (!flag) {
            if (StrUtil.isBlank(ids)) {
                ids += parentId;
            } else {
                ids += ("," + parentId);
            }
            MallMember parentMember = this.baseMapper.selectInfoByInviteId(parentId);
            if (parentMember == null) {
                break;
            }
            parentId = parentMember.getReferrerId();
            if (parentMember.getReferrerId().equals(parentMember.getInviteId())) {
                flag = true;
            }
        }
        if (StrUtil.isNotBlank(ids)) {
            mallMember.setReferrerIds(ids);
        }
        this.baseMapper.updateById(mallMember);
        return new FebsResponse().success().message("注册成功");
        MallMemberWallet wallet = new MallMemberWallet();
        wallet.setBalance(BigDecimal.ZERO);
        wallet.setMemberId(mallMember.getId());
        mallMemberWalletMapper.insert(wallet);
        return new FebsResponse().success().message("registered successfully");
    }
    @Override
@@ -123,11 +123,11 @@
        MallMember mallMember = this.baseMapper.selectInfoByAccountAndPwd(loginDto.getAccount(), md5Pwd);
        if (mallMember == null) {
            throw new FebsException("用户不存在或账号密码错误");
            throw new FebsException("The user does not exist or the account password is incorrect");
        }
        if (MallMember.ACCOUNT_STATUS_DISABLED.equals(mallMember.getAccountStatus())) {
            throw new FebsException("该账号存在异常, 暂限制登录");
            throw new FebsException("The account is abnormal and is temporarily restricted from logging in");
        }
        String redisKey = AppContants.APP_LOGIN_PREFIX + mallMember.getId();
@@ -144,41 +144,337 @@
        redisUtils.set(redisKey, token, 360000);
        Map<String, Object> authInfo = new HashMap<>();
        authInfo.put("token", token);
        if ("dev".equals(active)) {
            authInfo.put("rasToken", generateAsaToken(token));
        }
        authInfo.put("rasToken", generateAsaToken(token));
        return new FebsResponse().success().data(authInfo);
    }
    public String generateAsaToken(String token) {
        RSA rsa = new RSA(null, AppContants.PUBLIC_KEY);
        return rsa.encryptBase64(token + "_" + System.currentTimeMillis(), KeyType.PublicKey);
//        return rsa.encryptBase64(token + "_" + System.currentTimeMillis(), KeyType.PublicKey);
        //去掉时间戳
        return rsa.encryptBase64(token, KeyType.PublicKey);
    }
    @Override
    public FebsResponse forgetPwd(ForgetPwdDto forgetPwdDto) {
        MallMember mallMember = this.baseMapper.selectInfoByAccount(forgetPwdDto.getAccount());
        Long id = LoginUserUtil.getLoginUser().getId();
        MallMember mallMember = this.baseMapper.selectById(id);
        if (mallMember == null) {
            throw new FebsException("账号不存在");
            throw new FebsException("Setup failed");
        }
        boolean b = commonService.verifyCode(forgetPwdDto.getAccount(), forgetPwdDto.getCode());
        if (!b) {
            throw new FebsException("验证码错误");
        if (!forgetPwdDto.getNewPassword().equals(forgetPwdDto.getNewPasswordAgain())){
            throw new FebsException("Setup failed");
        }
        String pwd = SecureUtil.md5(forgetPwdDto.getPassword());
        String pwd = SecureUtil.md5(forgetPwdDto.getNewPassword());
        mallMember.setPassword(pwd);
        this.baseMapper.updateById(mallMember);
        return new FebsResponse().success().message("重置成功");
        this.baseMapper.update(
                null,
                Wrappers.lambdaUpdate(MallMember.class)
                .set(MallMember::getPassword, pwd)
                .eq(MallMember::getId, id)
        );
        return new FebsResponse().success().message("Setup successful");
    }
    @Override
    public FebsResponse logout() {
        Long id = LoginUserUtil.getLoginUser().getId();
        String redisKey = AppContants.APP_LOGIN_PREFIX + id;
        String existToken = redisUtils.getString(redisKey);
        if (StrUtil.isNotBlank(existToken)) {
            Object o = redisUtils.get(existToken);
            if (ObjectUtil.isNotEmpty(o)) {
                redisUtils.del(existToken);
            }
        }
        redisUtils.del(AppContants.APP_LOGIN_PREFIX + id);
        return new FebsResponse().success().message("退出登录");
        redisUtils.del(AppContants.XCX_LOGIN_PHONE_PREFIX + id);
        return new FebsResponse().success().message("Log out");
    }
    @Override
    public FebsResponse findMemberInfo() {
        Long id = LoginUserUtil.getLoginUser().getId();
        MallMember mallMember = this.baseMapper.selectById(id);
        MallMemberVo mallMemberVo = new MallMemberVo();
        mallMemberVo.setName(mallMember.getName());
        mallMemberVo.setEmail(mallMember.getEmail());
        mallMemberVo.setPhoneNumber(mallMember.getPhone());
        mallMemberVo.setAvatar(mallMember.getAvatar());
        return new FebsResponse().success().data(mallMemberVo);
    }
    @Override
    public FebsResponse modifyMemberInfo(ModifyMemberInfoDto modifyMemberInfoDto) {
        Long memberId = LoginUserUtil.getLoginUser().getId();
        MallMember mallMember = this.baseMapper.selectById(memberId);
        if (StrUtil.isNotBlank(modifyMemberInfoDto.getName())) {
            mallMember.setName(modifyMemberInfoDto.getName());
        }
        this.baseMapper.updateById(mallMember);
        return new FebsResponse().success().message("success");
    }
    @Override
    public void addMoneyFlow(Long memberId, BigDecimal amount, Integer type, String orderNo, String description, String remark, Long rtMemberId, Integer status, Integer flowType) {
        MallMoneyFlow flow = new MallMoneyFlow();
        flow.setMemberId(memberId);
        flow.setAmount(amount);
        flow.setType(type);
        flow.setOrderNo(orderNo);
        flow.setDescription(description);
        flow.setRemark(remark);
        flow.setRtMemberId(rtMemberId);
        flow.setStatus(status);
        flow.setFlowType(flowType);
        mallMoneyFlowMapper.insert(flow);
    }
    @Override
    public void bindPhone(AccountAndCodeDto accountAndCodeDto) {
        boolean b = commonService.verifyCode(accountAndCodeDto.getAccount(), accountAndCodeDto.getCode());
        if (!b) {
            throw new FebsException("验证码错误");
        }
        Long id = LoginUserUtil.getLoginUser().getId();
        MallMember member = this.baseMapper.selectById(id);
        member.setPhone(accountAndCodeDto.getAccount());
        this.baseMapper.updateById(member);
    }
    @Override
    public void shopApply(ShopApplyDto shopApplyDto) {
        MallMember member = LoginUserUtil.getLoginUser();
        MallShopApply hasApply = mallShopApplyMapper.selectNewestApplyByMemberId(member.getId());
        if (hasApply != null) {
            if (!hasApply.getStatus().equals(MallShopApply.APPLY_DISAGREE)) {
                throw new FebsException("请勿重复提交申请");
            }
        }
        MallShopApply mallShopApply = new MallShopApply();
        BeanUtil.copyProperties(shopApplyDto, mallShopApply);
        mallShopApply.setStatus(MallShopApply.APPLY_ING);
        mallShopApply.setMemberId(member.getId());
        mallShopApplyMapper.insert(mallShopApply);
    }
    @Override
    public MallShopApply findNewestApply() {
        MallMember member = LoginUserUtil.getLoginUser();
        return mallShopApplyMapper.selectNewestApplyByMemberId(member.getId());
    }
    @Override
    public List<ShopListVo> findShopListVo(ShopListDto shopListDto) {
        Page<MallShopApply> page = new Page<>(shopListDto.getPageNow(), shopListDto.getPageSize());
        MallShopApply shopApply = new MallShopApply();
        shopApply.setStatus(MallShopApply.APPLY_AGREE);
        IPage<MallShopApply> pageResult = mallShopApplyMapper.selectShopApplyInPage(shopApply, page);
        List<MallShopApply> list = pageResult.getRecords();
        if (CollUtil.isEmpty(list)) {
            list = new ArrayList<>();
        }
        return MallShopApplyConversion.INSTANCE.entitiesToVOs(list);
    }
    private final XcxProperties xcxProperties;
    @Override
    public void updateMemberAgent(Long memberId,String levelCode) {
        mallAgentRecordMapper.updateStateByMemberId(memberId);
        MallAgentRecord mallAgentRecord = mallAgentRecordMapper.selectById(memberId);
        //更新用户表中的LEVEL
        MallMember mallMember = this.baseMapper.selectById(mallAgentRecord.getMemberId());
        mallMember.setLevel(levelCode);
        this.baseMapper.updateById(mallMember);
    }
    @Override
    public FebsResponse memberPayCoupon(MallMemberCouponDto mallMemberCouponDto) {
        Long memberId = LoginUserUtil.getLoginUser().getId();
        mallMemberCouponDto.setMemberId(memberId);
        mallMemberCouponDto.setExpireTime(DateUtil.date());
//        List<Long> couponIds = couponGoodsMapper.selectByGoodId(mallMemberCouponDto.getGoodsId());
        List<Long> goodsIdList = mallMemberCouponDto.getGoodsIdList();
        List<Long> couponIds = couponGoodsMapper.selectByGoodIdList(goodsIdList);
        List<MallMemberCouponVo> mallMemberCouponVos = new ArrayList<>();
        if(CollUtil.isNotEmpty(couponIds)){
            mallMemberCouponVos = mallMemberCouponMapper.selectListCreateInPage(mallMemberCouponDto,couponIds);
        }
        return new FebsResponse().success().data(mallMemberCouponVos);
    }
    @Override
    public FebsResponse setInvite(ApiSetInviteDto apiSetInviteDto) {
        Long memberId = LoginUserUtil.getLoginUser().getId();
        MallMember mallMember = this.baseMapper.selectById(memberId);
        if(ObjectUtil.isNotEmpty(mallMember.getReferrerId())){
            throw new FebsException("已绑定");
        }
        String inviteId = apiSetInviteDto.getInviteId();
        if(inviteId.equals(mallMember.getInviteId())){
            return new FebsResponse().success();
        }
        MallMember member = this.baseMapper.selectInfoByInviteId(inviteId);
        if (member != null) {
            if (StrUtil.isNotBlank(member.getReferrerIds()) && member.getReferrerIds().contains(mallMember.getInviteId())) {
                log.info("下级不能邀请上级");
                return new FebsResponse().success();
            }
            mallMember.setReferrerId(member.getInviteId());
            //推荐人和推荐人链
            boolean flag = false;
            String parentId = mallMember.getReferrerId();
            if (StrUtil.isBlank(parentId)) {
                flag = true;
            }
            String ids = "";
            while (!flag) {
                if (StrUtil.isBlank(ids)) {
                    ids += parentId;
                } else {
                    ids += ("," + parentId);
                }
                MallMember parentMember = this.baseMapper.selectInfoByInviteId(parentId);
                if (parentMember == null) {
                    break;
                }
                parentId = parentMember.getReferrerId();
                if (StrUtil.isBlank(parentMember.getReferrerId())) {
                    flag = true;
                }
            }
            if (StrUtil.isNotBlank(ids)) {
                mallMember.setReferrerIds(ids);
            }
            this.baseMapper.updateById(mallMember);
        }
        return new FebsResponse().success();
    }
    private  String getXcxLoginUrl(String code) {
        String wechatLoginUrl =xcxProperties.getWecharLoginUrl();
        return String.format(wechatLoginUrl, xcxProperties.getXcxAppid(), xcxProperties.getXcxSecret(), code);
    }
    @Override
    public FebsResponse salesService() {
        MallSalesServiceVo mallSalesServiceVo = new MallSalesServiceVo();
        List<DataDictionaryCustom> dataDictionaryCustoms = dataDictionaryCustomMapper.selectDicByType(
                SalesServiceEnums.WHATSAPP.getType()
        );
        if (dataDictionaryCustoms.size() > 0){
            for (DataDictionaryCustom dataDictionaryCustom : dataDictionaryCustoms){
                if (SalesServiceEnums.WHATSAPP.getCode().equals(dataDictionaryCustom.getCode())){
                    mallSalesServiceVo.setWhatsApp(dataDictionaryCustom.getValue());
                }
                if (SalesServiceEnums.PHONE.getCode().equals(dataDictionaryCustom.getCode())){
                    mallSalesServiceVo.setPhone(dataDictionaryCustom.getValue());
                }
                if (SalesServiceEnums.EMAIL.getCode().equals(dataDictionaryCustom.getCode())){
                    mallSalesServiceVo.setEmail(dataDictionaryCustom.getValue());
                }
                if (SalesServiceEnums.WORKINGHOURS.getCode().equals(dataDictionaryCustom.getCode())){
                    mallSalesServiceVo.setWorkingHours(dataDictionaryCustom.getValue());
                }
                if (SalesServiceEnums.ADDRESS.getCode().equals(dataDictionaryCustom.getCode())){
                    mallSalesServiceVo.setAddress(dataDictionaryCustom.getValue());
                }
            }
        }
        return new FebsResponse().success().data(mallSalesServiceVo);
    }
    @Override
    public FebsResponse moneyChange() {
        List<MallMoneyChangeVo> vos = new ArrayList<>();
        List<DataDictionaryCustom> dataDictionaryCustoms = dataDictionaryCustomMapper.selectDicByType(
                SalesServiceEnums.USD.getType()
        );
        if (dataDictionaryCustoms.size() > 0){
            for (DataDictionaryCustom dataDictionaryCustom : dataDictionaryCustoms){
                MallMoneyChangeVo vo = new MallMoneyChangeVo();
                    vo.setMoneyChange(dataDictionaryCustom.getValue());
                    vo.setCode(dataDictionaryCustom.getCode());
                    vo.setMoneyCode(dataDictionaryCustom.getDescription());
                    vos.add(vo);
            }
        }
        return new FebsResponse().success().data(vos);
    }
    public static void main(String[] args) {
        Long userld = 173L;
        String shopAccount = "luohu";
        String shopPwd = "123456";
        HashMap<String, String> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("shopAccount",shopAccount);
        objectObjectHashMap.put("shopPwd",shopPwd);
        objectObjectHashMap.put("userId",userld.toString());
        //sign= MD5(shopAccount+shopPwd+userId)
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(shopAccount);
        stringBuffer.append(shopPwd);
        stringBuffer.append(userld);
        String sign = MD5.MD5Encode(stringBuffer.toString());
        objectObjectHashMap.put("sign",sign);
        System.out.println(sign);
        System.out.println(objectObjectHashMap);
        String url = "https://data.muchun.co/api/getCustomerCheckRecords";
        String result = HttpCurlUtil.sendPost(url, objectObjectHashMap);
        Integer retCode = JSONUtil.parseObj(result).getInt("retCode");
        String message = JSONUtil.parseObj(result).getStr("message");
        if(0 != retCode){
            System.out.println(message);
        }
        JSONArray data = JSONUtil.parseObj(result).getJSONArray("data");
        System.out.println(data);
    }
}