package com.zhongzheng.framework.web.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.zhongzheng.common.constant.Constants;
import com.zhongzheng.common.core.domain.AjaxResult;
import com.zhongzheng.common.core.redis.RedisCache;
import com.zhongzheng.common.enums.UserStatus;
import com.zhongzheng.common.exception.BaseException;
import com.zhongzheng.common.exception.CustomException;
import com.zhongzheng.common.utils.*;
import com.zhongzheng.common.utils.ip.IpUtils;
import com.zhongzheng.modules.alisms.service.IAliSmsService;
import com.zhongzheng.modules.collect.domain.CollectBank;
import com.zhongzheng.modules.collect.domain.CollectCourse;
import com.zhongzheng.modules.collect.domain.CollectNote;
import com.zhongzheng.modules.collect.mapper.CollectBankMapper;
import com.zhongzheng.modules.collect.mapper.CollectCourseMapper;
import com.zhongzheng.modules.collect.mapper.CollectNoteMapper;
import com.zhongzheng.modules.course.bo.CourseQueryBo;
import com.zhongzheng.modules.course.domain.MajorCategory;
import com.zhongzheng.modules.course.service.ICourseService;
import com.zhongzheng.modules.goods.vo.GoodsUserVo;
import com.zhongzheng.modules.grade.bo.ClassGradeUserQueryBo;
import com.zhongzheng.modules.grade.service.IClassGradeUserService;
import com.zhongzheng.modules.grade.vo.ClassGradeUserGoodsVo;
import com.zhongzheng.modules.user.bo.*;
import com.zhongzheng.modules.user.domain.User;
import com.zhongzheng.modules.user.domain.UserBankRecord;
import com.zhongzheng.modules.user.domain.UserSchoolInfo;
import com.zhongzheng.modules.user.entity.ClientLoginUser;
import com.zhongzheng.modules.user.mapper.UserMapper;
import com.zhongzheng.modules.user.service.IUserPlanService;
import com.zhongzheng.modules.user.service.IUserService;
import com.zhongzheng.modules.user.service.IUserUpdateService;
import com.zhongzheng.modules.user.vo.*;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;



/**
 * 用户Service业务层处理
 *
 * @author change
 * @date 2021-05-25
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private CollectCourseMapper collectCourseMapper;

    @Autowired
    private CollectBankMapper collectBankMapper;

    @Autowired
    private CollectNoteMapper collectNoteMapper;

    @Autowired
    private WxTokenService wxTokenService;

    @Autowired
    private IUserService userService;

    @Autowired
    private IAliSmsService iSmsService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private IUserUpdateService userUpdateService;

    @Autowired
    private IClassGradeUserService iClassGradeUserService;

    @Autowired
    private IUserPlanService userPlanService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ICourseService iCourseService;


    @Override
    public UserVo queryById(Long userId) {
        User db = this.baseMapper.selectById(userId);
        return BeanUtil.toBean(db, UserVo.class);
    }

    @Override
    public User queryByUnionId(String unionId) {
        User user = getOne(new LambdaQueryWrapper<User>()
                .eq(User::getUnionId, unionId)
                .last("limit 1"));
        if (Validator.isNotNull(user)) {
            return user;
        }
        return null;
    }

    @Override
    public User queryByAccount(String userAccount) {
        User user = getOne(new LambdaQueryWrapper<User>()
                .eq(User::getUserAccount, userAccount)
                .last("limit 1"));
        if (Validator.isNotNull(user)) {
            return user;
        }
        return null;
    }


    @Override
    public List<UserVo> queryList(UserQueryBo bo) {
        LambdaQueryWrapper<User> lqw = Wrappers.lambdaQuery();
        lqw.eq(StrUtil.isNotBlank(bo.getUserAccout()), User::getUserAccount, bo.getUserAccout());
        lqw.like(StrUtil.isNotBlank(bo.getNickname()), User::getNickname, bo.getNickname());
        lqw.like(StrUtil.isNotBlank(bo.getRealname()), User::getRealname, bo.getRealname());
        lqw.eq(bo.getSex() != null, User::getSex, bo.getSex());
        lqw.eq(StrUtil.isNotBlank(bo.getIdCard()), User::getIdCard, bo.getIdCard());
        lqw.eq(StrUtil.isNotBlank(bo.getTelphone()), User::getTelphone, bo.getTelphone());
        lqw.eq(bo.getUserLevel() != null, User::getUserLevel, bo.getUserLevel());
        lqw.eq(StrUtil.isNotBlank(bo.getUserBirth()), User::getUserBirth, bo.getUserBirth());
        lqw.eq(StrUtil.isNotBlank(bo.getEduLevel()), User::getEduLevel, bo.getEduLevel());
        lqw.eq(bo.getSchoolId() != null, User::getSchoolId, bo.getSchoolId());
        lqw.eq(StrUtil.isNotBlank(bo.getMajor()), User::getMajor, bo.getMajor());
        lqw.eq(bo.getEntranceTime() != null, User::getEntranceTime, bo.getEntranceTime());
        lqw.eq(StrUtil.isNotBlank(bo.getOpenId()), User::getOpenId, bo.getOpenId());
        lqw.eq(StrUtil.isNotBlank(bo.getIdCardImg1()), User::getIdCardImg1, bo.getIdCardImg1());
        lqw.eq(StrUtil.isNotBlank(bo.getIdCardImg2()), User::getIdCardImg2, bo.getIdCardImg2());
        lqw.eq(StrUtil.isNotBlank(bo.getCountry()), User::getCountry, bo.getCountry());
        lqw.eq(StrUtil.isNotBlank(bo.getProvince()), User::getProvince, bo.getProvince());
        lqw.eq(StrUtil.isNotBlank(bo.getCity()), User::getCity, bo.getCity());
        lqw.eq(bo.getIntegral() != null, User::getIntegral, bo.getIntegral());
        lqw.in(bo.getStatus() != null, User::getStatus, bo.getStatus());
        return entity2Vo(this.list(lqw));
    }

    @Override
    public List<UserVo> selectList(UserQueryBo bo) {
        List<UserVo> list = entity2UserVo(userMapper.selectList(bo));
        for (UserVo userVo : list) {
            ClassGradeUserQueryBo classGradeUserQueryBo = new ClassGradeUserQueryBo();
            classGradeUserQueryBo.setUserId(userVo.getUserId());
            List<Integer> status = new ArrayList<>();
            status.add(1);
            classGradeUserQueryBo.setStatus(status);
            List<ClassGradeUserGoodsVo> classGradeUserGoodsVos = iClassGradeUserService.listUser(classGradeUserQueryBo);
            userVo.setClassGradeUserGoodsVoList(classGradeUserGoodsVos);
            CourseQueryBo courseQueryBo = new CourseQueryBo();
            courseQueryBo.setUserId(userVo.getUserId());
            List<GoodsUserVo> goodsList = iCourseService.goodsList(courseQueryBo);
            userVo.setOrderNum(Convert.toLong(goodsList.size()));
        }
        return list;
    }

    @Override
    public List<UserStudyRecordVo> selectStudyRecordList(UserStudyRecordQueryBo bo) {
        return userMapper.selectStudyRecordList(bo);
    }

    private List<UserVo> entity2Vo(List<User> list) {
        List<UserVo> newList = new ArrayList<>();
        for(int i=0;i<list.size();i++){
            UserVo vo = BeanUtil.toBean(list.get(i), UserVo.class);
            vo.setNull(); //清除关键数据
            newList.add(vo);
        }
        return newList;
    }

    /**
     * 实体类转化成视图对象
     *
     * @param collection 实体类集合
     * @return
     */
    private List<UserVo> entity2Vo(Collection<User> collection) {
        List<UserVo> voList = collection.stream()
                .map(any -> BeanUtil.toBean(any, UserVo.class))
                .collect(Collectors.toList());
        if (collection instanceof Page) {
            Page<User> page = (Page<User>) collection;
            Page<UserVo> pageVo = new Page<>();
            BeanUtil.copyProperties(page, pageVo);
            pageVo.addAll(voList);
            voList = pageVo;
        }
        return voList;
    }

    /**
     * 实体类转化成视图对象
     *
     * @param collection 实体类集合
     * @return
     */
    private List<UserVo> entity2UserVo(Collection<User> collection) {
        List<UserVo> voList = collection.stream()
                .map(any -> BeanUtil.toBean(any, UserVo.class))
                .collect(Collectors.toList());
        if (collection instanceof Page) {
            Page<User> page = (Page<User>) collection;
            Page<UserVo> pageVo = new Page<>();
            BeanUtil.copyProperties(page, pageVo);
            pageVo.addAll(voList);
            voList = pageVo;
        }
        return voList;
    }

    @Override
    public Boolean insertByAddBo(UserAddBo bo) {
        User add = BeanUtil.toBean(bo, User.class);
        validEntityBeforeSave(add);
        add.setCreateTime(DateUtils.getNowTime());
        add.setUpdateTime(DateUtils.getNowTime());
        return this.save(add);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByEditBo(UserEditBo bo) throws IllegalAccessException {
        User update = BeanUtil.toBean(bo, User.class);
        validEntityBeforeUpdate(update);
        update.setUpdateTime(DateUtils.getNowTime());
        UserUpdateAddBo userUpdateAddBo = new UserUpdateAddBo();
        userUpdateAddBo.setUserId(bo.getUserId());
        if (!StringUtils.isBlank(update.getRealname())){
            userUpdateAddBo.setRealname(update.getRealname());
        }
        if (!StringUtils.isBlank(update.getTelphone())){
            userUpdateAddBo.setTelphone(update.getTelphone());
        }
        if (!StringUtils.isBlank(update.getIdCard())){
            userUpdateAddBo.setIdCard(update.getIdCard());
        }
        if (userUpdateAddBo != null) {
            userUpdateService.insertByAddBo(userUpdateAddBo);
        }
        return this.updateById(update);
    }




    private Boolean increaseUser(UserVo userVo,Long score){
        User user = BeanUtil.toBean(userVo, User.class);
        user.setIntegral(score);
        user.setUpdateTime(DateUtils.getNowTime());
        return userService.updateById(user);
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(User entity) {
        //TODO 做一些数据校验,如唯一约束

    }

    private void validEntityBeforeUpdate(User entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    public Integer  countUser(UserEditBo userVo) throws IllegalAccessException {
        // Java的反射
        Field[] field = userVo.getClass().getDeclaredFields();
        int count = 0;
        for(int i=0; i<field.length; i++){
            Field f = field[i];
            f.setAccessible(true);
            if (f.get(userVo) != null){
                count++;
            }
        }
        return count;
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return this.removeByIds(ids);
    }

    @Override
    public Integer getCollectTotal(Long userId) {
        Integer collectCourse = collectCourseMapper.selectCount(new LambdaQueryWrapper<CollectCourse>()
                .eq(CollectCourse::getUserId, userId));
        Integer collectBank = collectBankMapper.selectCount(new LambdaQueryWrapper<CollectBank>()
                .eq(CollectBank::getUserId, userId));
        Integer collectNote = collectNoteMapper.selectCount(new LambdaQueryWrapper<CollectNote>()
                .eq(CollectNote::getUserId, userId));
        return collectCourse + collectBank + collectNote;
    }

    @Override
    public RanKingUser rankingList(RanKingUserQuery query) {
        RanKingUser ranKingUser = new RanKingUser();
        Long time = System.currentTimeMillis(); //当前时间的时间戳
        if (query.getStatus() == 0) {
            long zero1 = time / (1000 * 3600 * 24) * (1000 * 3600 * 24) - TimeZone.getDefault().getRawOffset();
            long zero = zero1 / 1000;
            Calendar calendar = Calendar.getInstance();
            calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
            long tt = calendar.getTime().getTime() / 1000;
            query.setStartTime(zero);
            query.setEndTime(tt);
            ranKingUser = baseMapper.selectByRank(query);
            if (ranKingUser != null && ranKingUser.getHourse() != null) {
                Integer rank = baseMapper.selectByRankOneByTime(Convert.toInt(ranKingUser.getHourse()),zero,tt);
                ranKingUser.setRank(rank);
            } else {
                ranKingUser = baseMapper.selectByOneRank(query);
                ranKingUser.setRank(null);
            }
            List<RanKingUser> ranKingUsers = baseMapper.selectByRanks(query);
            if (ranKingUsers != null && ranKingUsers.size() != 0) {
                for (int i = 0; i < ranKingUsers.size(); i++) {
                    ranKingUsers.get(i).setRank(i+1);
                }
                ranKingUser.setRanKingUsers(ranKingUsers);
            } else {
                ranKingUser.setRanKingUsers(new ArrayList<>());
            }
        } else {
            ranKingUser = baseMapper.selectByRank(query);
            if (ranKingUser != null && ranKingUser.getHourse() != null) {
                Integer rank = baseMapper.selectByRankOne(Convert.toInt(ranKingUser.getHourse()));
                ranKingUser.setRank(rank);
            } else {
                ranKingUser = baseMapper.selectByOneRank(query);
                ranKingUser.setRank(null);
            }
            List<RanKingUser> ranKingUsers = baseMapper.selectByRanks(query);
            if (ranKingUsers != null && ranKingUsers.size() != 0) {
                for (int i = 0; i < ranKingUsers.size(); i++) {
                    ranKingUsers.get(i).setRank(i+1);
                }
                ranKingUser.setRanKingUsers(ranKingUsers);
            } else {
                ranKingUser.setRanKingUsers(new ArrayList<>());
            }
        }
        if (ranKingUser.getHourse() != null){
            ranKingUser.setHourse(getHour(ranKingUser.getHourse()));
        }
        if (!CollectionUtils.isEmpty(ranKingUser.getRanKingUsers())){
            ranKingUser.getRanKingUsers().stream().forEach(c -> {
                if (c.getHourse() ==null) {
                    c.setHourse("0");
                }
                    c.setHourse(getHour(c.getHourse()));

            });
        }
        return ranKingUser;

    }


    //Util.java
    public static String getHour(String date) {
        //秒数
		Integer dt = Integer.parseInt(date) ;
		if (dt < 3600) return Math.round(dt / 60) + "m";
		int hour = Math.round(dt / 3600);
		int minute = Math.round((dt - (hour * 3600)) / 60);
		return hour + "h" + (minute == 0 ? "" : minute + "m");
    }




    @Override
    public Integer getRank(Long userId) {
        RanKingUserQuery query = new RanKingUserQuery();
        query.setUserId(userId);
        Long time = System.currentTimeMillis();
        long zero1 = time / (1000 * 3600 * 24) * (1000 * 3600 * 24) - TimeZone.getDefault().getRawOffset();
        long zero = zero1 / 1000;
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
        long tt = calendar.getTime().getTime() / 1000;
        query.setStartTime(zero);
        query.setEndTime(tt);
        RanKingUser ranKingUser = baseMapper.selectByRank(query);
        if (ranKingUser != null && ranKingUser.getHourse() != null) {
            Integer rank = baseMapper.selectByRankOneByTime(Convert.toInt(ranKingUser.getHourse()),zero,tt);
            if (rank == 0) {
                return rank + 1;
            }
            return rank;
         }
        return 0;
    }

    @Override
    public Integer getIssue(Long userId) {

        return 0;
    }

    @Override
    public BigDecimal getMoney(Long userId) {
        User info = getOne(new QueryWrapper<User>()
                .select("money")
                .eq("user_id",userId)
                .last("limit 1"));
        if (Validator.isNotNull(info)) {
            return info.getMoney();
        }
        return null;
    }

    @Override
    public Integer selectUserNum(Integer grade) {
        return baseMapper.selectUserNum(grade);
    }

    @Override
    public Integer getLookNum(Long userId) {
        return baseMapper.selectLookNum(userId);
    }

    @Override
    public Long systemRegisterUser(UserSystemRegisterBo bo) {
        if(bo.getTel()==null){
            throw new CustomException("手机号不能为空");
        }
        if(bo.getIdCard()==null){
            throw new CustomException("身份证不能为空");
        }
        if(bo.getRealname()==null){
            throw new CustomException("真实姓名不能为空");
        }
        User user = getOne(new LambdaQueryWrapper<User>()
                .eq(User::getTelphone,bo.getTel()).last("limit 1"));
        if(Validator.isNotNull(user)){
            throw new CustomException("该手机号已注册");
        }
        User user2 = getOne(new LambdaQueryWrapper<User>()
                .eq(User::getIdCard,bo.getIdCard()).last("limit 1"));
        if(Validator.isNotNull(user2)){
            throw new CustomException("该身份证已被使用");
        }
        User inertData = new User();
        inertData.setTelphone(bo.getTel());
        //隐藏手机号作为初始昵称
        inertData.setNickname(TelPhoneUtils.hideTelPhone(bo.getTel()));
        //雪花算法产生账号ID
        SnowflakeIdUtils idWorker = new SnowflakeIdUtils(3, 1);
        inertData.setUserAccount(String.valueOf(idWorker.nextId()));
        inertData.setSex(1);
        inertData.setIdCard(bo.getIdCard());
        inertData.setRealname(bo.getRealname());
        inertData.setStatus(1);
        inertData.setRegisterPlat("3");
        inertData.setAvatar(Constants.DEFAULT_AVATAR);
        inertData.setLastLoginIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
        inertData.setLastLoginTime(DateUtils.getNowTime());
        inertData.setCreateTime(DateUtils.getNowTime());
        inertData.setUpdateTime(DateUtils.getNowTime());
        String pwd =  ToolsUtils.getSmsCode(); // 随机密码
        inertData.setPassword(SecurityUtils.encryptPassword(pwd));
        if(!save(inertData)){
            throw new CustomException("注册失败");
        }
        iSmsService.sendPwdSms(bo.getTel(),pwd);
        return inertData.getUserId();
    }

    @Override
    public Boolean registerUser(UserAppRegisterBo bo) {
        if(bo.getTel()==null){
            throw new CustomException("手机号不能为空");
        }
        if(bo.getPwd()==null){
            throw new CustomException("密码不能为空");
        }
        String key = Constants.REGISTER_SMS + bo.getTel();
        String code =  redisCache.getCacheObject(key);
        if(code==null){
            throw new CustomException("验证码错误");
        }
        if(!code.equals(bo.getCode())){
            throw new CustomException("验证码错误");
        }
        User user = getOne(new LambdaQueryWrapper<User>()
                .eq(User::getTelphone,bo.getTel()).last("limit 1"));
        if(Validator.isNotNull(user)){
            throw new CustomException("该手机号已注册");
        }
        User inertData = new User();
        inertData.setTelphone(bo.getTel());
        //隐藏手机号作为初始昵称
        inertData.setNickname(TelPhoneUtils.hideTelPhone(bo.getTel()));
        //雪花算法产生账号ID
        SnowflakeIdUtils idWorker = new SnowflakeIdUtils(3, 1);
        inertData.setUserAccount(String.valueOf(idWorker.nextId()));
        inertData.setSex(1);
        inertData.setStatus(1);
        inertData.setRegisterPlat("1");
        inertData.setAvatar(Constants.DEFAULT_AVATAR);
        inertData.setLastLoginIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
        inertData.setLastLoginTime(DateUtils.getNowTime());
        inertData.setCreateTime(DateUtils.getNowTime());
        inertData.setUpdateTime(DateUtils.getNowTime());
        inertData.setPassword(SecurityUtils.encryptPassword(bo.getPwd()));
        if(!save(inertData)){
            throw new CustomException("注册失败");
        }
        return true;
    }

    @Override
    public Boolean forgetUser(UserAppForgetBo bo) {
        if(bo.getTel()==null){
            throw new CustomException("手机号不能为空");
        }
        if(bo.getPwd()==null){
            throw new CustomException("密码不能为空");
        }
        String key = Constants.FORGET_SMS + bo.getTel();
        String code =  redisCache.getCacheObject(key);
        if(code==null){
            throw new CustomException("验证码错误");
        }
        if(!code.equals(bo.getCode())){
            throw new CustomException("验证码错误");
        }
        User user = getOne(new LambdaQueryWrapper<User>()
                .eq(User::getTelphone,bo.getTel()).last("limit 1"));
        if(Validator.isEmpty(user)){
            throw new CustomException("该手机号未注册");
        }
        user.setPassword(SecurityUtils.encryptPassword(bo.getPwd()));
        user.setUpdateTime(DateUtils.getNowTime());
        return userService.updateById(user);
    }

    @Override
    public  Map<String,Object> smsLogin(UserAppSmsLoginBo bo) {
        if(bo.getTel()==null){
            throw new CustomException("手机号不能为空");
        }
        String key = Constants.LOGIN_SMS + bo.getTel();
        String code =  redisCache.getCacheObject(key);
        if(code==null){
            throw new CustomException("验证码错误");
        }
        if(!code.equals(bo.getCode())){
            throw new CustomException("验证码错误");
        }
        User user = getOne(new LambdaQueryWrapper<User>()
                .eq(User::getTelphone,bo.getTel()).last("limit 1"));
        if(Validator.isEmpty(user)){
            throw new CustomException("该手机号未注册");
        }
        ClientLoginUser loginUser = new ClientLoginUser();
        loginUser.setUser(user);
        Map<String,Object> map = new HashMap<>();
        map.put(Constants.TOKEN,wxTokenService.createToken(loginUser));
        map.put("user_account",user.getUserAccount());
        map.put("full_info",Validator.isEmpty(user.getIdCard())?false:true); //是否完善身份信息
        return map;
    }

    @Override
    public Map<String, Object> accountLogin(UserAppAccountLoginBo bo) {
        if(Validator.isEmpty(bo.getAccount())){
            throw new CustomException("账号不能为空");
        }
        User user = getOne(new LambdaQueryWrapper<User>().eq(User::getTelphone,bo.getAccount())
                        .or().eq(User::getIdCard, bo.getAccount()));
        if(Validator.isEmpty(user)){
            throw new CustomException("该账号不存在");
        }
        else if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
        {
            throw new BaseException("对不起，您的账号：已停用");
        }
        if (!SecurityUtils.matchesPassword(bo.getPwd(),user.getPassword() ))
        {
            throw new BaseException("密码错误");
        }
        ClientLoginUser loginUser = new ClientLoginUser();
        loginUser.setUser(user);
        Map<String,Object> map = new HashMap<>();
        map.put(Constants.TOKEN,wxTokenService.createToken(loginUser));
        map.put("user_account",user.getUserAccount());
        map.put("full_info",Validator.isEmpty(user.getIdCard())?false:true); //是否完善身份信息
        return map;
    }

    @Override
    public Boolean bindIdCard(UserAppBindIdBo bo) {
        if(Validator.isEmpty(bo.getIdCard())){
            throw new CustomException("数据缺失");
        }
        if(Validator.isEmpty(bo.getRealname())){
            throw new CustomException("数据缺失");
        }
        User user = this.baseMapper.selectById(bo.getUserId());
        user.setRealname(bo.getRealname());
        user.setIdCard(bo.getIdCard());
        user.setUpdateTime(DateUtils.getNowTime());
        return userService.updateById(user);
    }

    @Override
    public Long planSum(Long userId) {
        UserPlanQueryBo userPlanQueryBo = new UserPlanQueryBo();
        userPlanQueryBo.setUserId(userId);
        userPlanQueryBo.setStatus(new ArrayList<Integer>(Arrays.asList(1)));
        List<UserPlanVo> userPlanVos = userPlanService.queryList(userPlanQueryBo);
        Calendar now = Calendar.getInstance();
        Long planSum =0L;
        for (UserPlanVo userPlanVo : userPlanVos) {
            List<CalendarStudyVo> collect = userPlanVo.getCalendarStudyVo().stream().filter(CalendarStudyVo -> CalendarStudyVo.getMonth().equals((now.get(Calendar.MONTH) + 1))).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(collect)){
                for (CalendarStudyVo calendarStudyVo : collect) {
                    List<DayStudyVo> dayStudyVos = calendarStudyVo.getDayStudyList().stream().filter(CalendarStudyVo -> CalendarStudyVo.getDate().equals(now.get(Calendar.DAY_OF_MONTH))).collect(Collectors.toList());
                    for (DayStudyVo dayStudyVo : dayStudyVos) {
                        if (dayStudyVo.getPerform() != 1){
                            planSum ++;
                        }
                    }
                }
            }
        }
        return planSum;
    }

    @Override
    public Long periodSum(Long userId) {
        return baseMapper.periodSum(userId);
    }

    @Override
    public Long subscribeSum(Long userId) {
        return baseMapper.subscribeSum(userId);
    }

    @Override
    public Long informSum(Long userId) {
        return baseMapper.informSum(userId);
    }

    @Override
    public Long orderSum(Long userId) {
        return baseMapper.orderSum(userId);
    }


    /**
     * 获取当前月第一天
     * @param month
     * @return
     */
    public static Long getFirstDayOfMonth(int month) {
        Calendar calendar = Calendar.getInstance();
        // 设置月份
        calendar.set(Calendar.MONTH, month - 1);
        // 获取某月最小天数
        int firstDay = calendar.getActualMinimum(Calendar.DAY_OF_MONTH);
        // 设置日历中月份的最小天数
        calendar.set(Calendar.DAY_OF_MONTH, firstDay);
        //将小时至0
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        //将分钟至0
        calendar.set(Calendar.MINUTE, 0);
        //将秒至0
        calendar.set(Calendar.SECOND,0);
        Date time = calendar.getTime();
        return time.getTime() / 1000;
    }

    public static Long getLastDayOfMonth(int month) {
        Calendar calendar = Calendar.getInstance();
        // 设置月份
        calendar.set(Calendar.MONTH, month - 1);
        // 获取某月最大天数
        int lastDay=0;
        //2月的平年瑞年天数
        if(month==2) {
            lastDay = calendar.getLeastMaximum(Calendar.DAY_OF_MONTH);
        }else {
            lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        }
        // 设置日历中月份的最大天数
        calendar.set(Calendar.DAY_OF_MONTH, lastDay);
        //将小时至0
        calendar.set(Calendar.HOUR_OF_DAY, 24);
        //将分钟至0
        calendar.set(Calendar.MINUTE, 0);
        //将秒至0
        calendar.set(Calendar.SECOND,0);
        Date time = calendar.getTime();
        return time.getTime() / 1000;
    }
}
