|  | @@ -0,0 +1,189 @@
 | 
	
		
			
				|  |  | +package cn.newfeifan.mall.module.distri.service.usersigninlog;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.distri.controller.admin.orderpercentage.vo.OrderPercentageRedisVO;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.distri.controller.app.usersigninlog.vo.UserSignInLogPageReqVO;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.distri.controller.app.usersigninlog.vo.UserSignInLogSaveReqVO;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.distri.dal.dataobject.duser.DuserDO;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.distri.enums.SocialStatusEnum;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.distri.service.duser.DuserService;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.distri.service.socialstatus.SocialStatusService;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.member.controller.app.signin.vo.record.AppMemberSignInRecordRespVO;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.member.convert.signin.MemberSignInRecordConvert;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.member.dal.dataobject.signin.MemberSignInRecordDO;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.member.service.signin.MemberSignInRecordService;
 | 
	
		
			
				|  |  | +import com.alibaba.fastjson.JSONObject;
 | 
	
		
			
				|  |  | +import org.apache.commons.lang3.StringUtils;
 | 
	
		
			
				|  |  | +import org.springframework.data.redis.core.StringRedisTemplate;
 | 
	
		
			
				|  |  | +import org.springframework.stereotype.Service;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import javax.annotation.Resource;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import org.springframework.transaction.annotation.Transactional;
 | 
	
		
			
				|  |  | +import org.springframework.validation.annotation.Validated;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.distri.dal.dataobject.usersigninlog.UserSignInLogDO;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.framework.common.pojo.PageResult;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.framework.common.util.object.BeanUtils;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.distri.dal.mysql.usersigninlog.UserSignInLogMapper;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import java.time.LocalDateTime;
 | 
	
		
			
				|  |  | +import java.time.ZoneId;
 | 
	
		
			
				|  |  | +import java.time.ZonedDateTime;
 | 
	
		
			
				|  |  | +import java.time.temporal.ChronoUnit;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import static cn.newfeifan.mall.framework.common.exception.util.ServiceExceptionUtil.exception;
 | 
	
		
			
				|  |  | +import static cn.newfeifan.mall.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 | 
	
		
			
				|  |  | +import static cn.newfeifan.mall.module.distri.constant.DistriConstants.*;
 | 
	
		
			
				|  |  | +import static cn.newfeifan.mall.module.distri.enums.ErrorCodeConstants.*;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * 用户签到日志 Service 实现类
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * @author 非繁人
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +@Service
 | 
	
		
			
				|  |  | +@Validated
 | 
	
		
			
				|  |  | +public class UserSignInLogServiceImpl implements UserSignInLogService {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Resource
 | 
	
		
			
				|  |  | +    private UserSignInLogMapper userSignInLogMapper;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Resource
 | 
	
		
			
				|  |  | +    private MemberSignInRecordService signInRecordService;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Resource
 | 
	
		
			
				|  |  | +    private DuserService duserService;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Resource
 | 
	
		
			
				|  |  | +    private StringRedisTemplate stringRedisTemplate;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Resource
 | 
	
		
			
				|  |  | +    private SocialStatusService socialStatusService;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    @Transactional
 | 
	
		
			
				|  |  | +    public AppMemberSignInRecordRespVO createUserSignInLog() {
 | 
	
		
			
				|  |  | +        //用户签到
 | 
	
		
			
				|  |  | +        Long loginUserId = getLoginUserId();
 | 
	
		
			
				|  |  | +        MemberSignInRecordDO recordDO = signInRecordService.createSignRecord(loginUserId);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 插入用户签到日志
 | 
	
		
			
				|  |  | +        UserSignInLogDO userSignInLogDO = userSignInLogMapper.selectByUserId(loginUserId);
 | 
	
		
			
				|  |  | +        if (userSignInLogDO == null) {
 | 
	
		
			
				|  |  | +            //代表还没有过签到记录
 | 
	
		
			
				|  |  | +            userSignInLogDO = UserSignInLogDO
 | 
	
		
			
				|  |  | +                    .builder()
 | 
	
		
			
				|  |  | +                    .userId(loginUserId)
 | 
	
		
			
				|  |  | +                    .runningDays(DEFAULT_DAY)
 | 
	
		
			
				|  |  | +                    .build();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            userSignInLogMapper.insert(userSignInLogDO);
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            //如果是昨天签到过
 | 
	
		
			
				|  |  | +            if (isTargetYesterday(userSignInLogDO.getUpdateTime())) {
 | 
	
		
			
				|  |  | +                userSignInLogDO.setRunningDays(userSignInLogDO.getRunningDays() + ONE_DAY);
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                userSignInLogDO.setRunningDays(DEFAULT_DAY);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            userSignInLogDO.setUpdateTime(LocalDateTime.now());
 | 
	
		
			
				|  |  | +            userSignInLogMapper.updateById(userSignInLogDO);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //计算用户签到获得身价
 | 
	
		
			
				|  |  | +        OrderPercentageRedisVO orderPercentageRedisVO = getOrderPercentageRedisVO();
 | 
	
		
			
				|  |  | +        long social = Long.parseLong(orderPercentageRedisVO.getSignInSocialStatus());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if(userSignInLogDO.getRunningDays() >= Integer.parseInt(orderPercentageRedisVO.getSignInSocialStatusMax())){
 | 
	
		
			
				|  |  | +            social = social + Long.parseLong(orderPercentageRedisVO.getSignInSocialStatusMax());
 | 
	
		
			
				|  |  | +        }else{
 | 
	
		
			
				|  |  | +            social = social + userSignInLogDO.getRunningDays();
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //更新前用户身价等级
 | 
	
		
			
				|  |  | +        DuserDO duserByUserNow = duserService.getDuserByUser(loginUserId);
 | 
	
		
			
				|  |  | +        //更新用户身价
 | 
	
		
			
				|  |  | +        duserService.updateDuserSocial(loginUserId, social, SocialStatusEnum.SIGN_IN_SOCIAL.getStatus());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //更新后用户身价等级
 | 
	
		
			
				|  |  | +        DuserDO duserByUserAfter = duserService.getDuserByUser(loginUserId);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //判断是否升级
 | 
	
		
			
				|  |  | +        boolean upgradeOrNot = !duserByUserNow.getSocialStatusId().equals(duserByUserAfter.getSocialStatusId());
 | 
	
		
			
				|  |  | +        String socialStatusName = null;
 | 
	
		
			
				|  |  | +        if(upgradeOrNot){
 | 
	
		
			
				|  |  | +            socialStatusName = socialStatusService.getSocialStatusName(duserByUserAfter.getSocialStatusId());
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        // 返回
 | 
	
		
			
				|  |  | +        return MemberSignInRecordConvert.INSTANCE.coverRecordToAppRecordVo(recordDO,upgradeOrNot,social,socialStatusName);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 获取身价固定值
 | 
	
		
			
				|  |  | +     * @return 签到身价固定值
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    private OrderPercentageRedisVO getOrderPercentageRedisVO() {
 | 
	
		
			
				|  |  | +        String s = stringRedisTemplate.opsForValue().get(DISTRI_ORDER_PERCENTAGE);
 | 
	
		
			
				|  |  | +        if (StringUtils.isEmpty(s)) {
 | 
	
		
			
				|  |  | +            throw exception(REDIS_ORDER_PERCENTAGE_NOT_EXISTS);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return JSONObject.parseObject(s, OrderPercentageRedisVO.class);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 判断给定的LocalDateTime是否为昨天
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @param targetTime 目标时间
 | 
	
		
			
				|  |  | +     * @return 如果目标时间是昨天,返回true;否则返回false
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    private boolean isTargetYesterday(LocalDateTime targetTime) {
 | 
	
		
			
				|  |  | +        // 获取当前系统时间的LocalDateTime
 | 
	
		
			
				|  |  | +        LocalDateTime now = LocalDateTime.now();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 获取参考时间的ZonedDateTime,用于处理时区
 | 
	
		
			
				|  |  | +        ZonedDateTime referenceZonedDateTime = now.atZone(ZoneId.systemDefault());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 获取目标时间的ZonedDateTime
 | 
	
		
			
				|  |  | +        ZonedDateTime targetZonedDateTime = targetTime.atZone(ZoneId.systemDefault());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 计算两个时间之间的差值
 | 
	
		
			
				|  |  | +        long daysDiff = ChronoUnit.DAYS.between(referenceZonedDateTime.toLocalDate(), targetZonedDateTime.toLocalDate());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return daysDiff == -1; // 如果差值是-1,说明目标时间是昨天
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public void updateUserSignInLog(UserSignInLogSaveReqVO updateReqVO) {
 | 
	
		
			
				|  |  | +        // 校验存在
 | 
	
		
			
				|  |  | +        validateUserSignInLogExists(updateReqVO.getId());
 | 
	
		
			
				|  |  | +        // 更新
 | 
	
		
			
				|  |  | +        UserSignInLogDO updateObj = BeanUtils.toBean(updateReqVO, UserSignInLogDO.class);
 | 
	
		
			
				|  |  | +        userSignInLogMapper.updateById(updateObj);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public void deleteUserSignInLog(Long id) {
 | 
	
		
			
				|  |  | +        // 校验存在
 | 
	
		
			
				|  |  | +        validateUserSignInLogExists(id);
 | 
	
		
			
				|  |  | +        // 删除
 | 
	
		
			
				|  |  | +        userSignInLogMapper.deleteById(id);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private void validateUserSignInLogExists(Long id) {
 | 
	
		
			
				|  |  | +        if (userSignInLogMapper.selectById(id) == null) {
 | 
	
		
			
				|  |  | +            throw exception(USER_SIGN_IN_LOG_NOT_EXISTS);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public UserSignInLogDO getUserSignInLog(Long id) {
 | 
	
		
			
				|  |  | +        return userSignInLogMapper.selectById(id);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public PageResult<UserSignInLogDO> getUserSignInLogPage(UserSignInLogPageReqVO pageReqVO) {
 | 
	
		
			
				|  |  | +        return userSignInLogMapper.selectPage(pageReqVO);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +}
 |