# MonthlyReportWeeklySalesPlanDetailServiceImpl.java

    package cloud.wconnect.workperformance.service.monthlyreport.impl;

    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.pojo.bo.weeklyplan.WeeklySalesPlanBO;
    import cloud.wconnect.commonlib.pojo.bo.weeklyplan.WeeklySalesPlanStatusBO;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.workperformance.entity.monthlyreport.MonthlyReportWeeklySalesPlanDetail;
    import cloud.wconnect.workperformance.mapper.monthlyreport.MonthlyReportWeeklySalesPlanDetailMapper;
    import cloud.wconnect.workperformance.service.monthlyreport.IMonthlyReportWeeklySalesPlanDetailService;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.collections.CollectionUtils;
    import org.redisson.api.RLock;
    import org.redisson.api.RedissonClient;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import jakarta.annotation.Resource;
    import java.util.Collection;
    import java.util.Collections;
    import java.util.List;
    import java.util.Map;
    import java.util.stream.Collectors;

    /**
     * <p>
     * 月报weekly sales plan明细表 服务实现类
     * </p>
     *
     * @author lichen
     * @since 2024-12-09
     */
    @Service
    @DS("monthly_report")
    @Slf4j
    public class MonthlyReportWeeklySalesPlanDetailServiceImpl extends ServiceImpl<MonthlyReportWeeklySalesPlanDetailMapper, MonthlyReportWeeklySalesPlanDetail> implements IMonthlyReportWeeklySalesPlanDetailService {

        @Autowired
        private BeanMapper beanMapper;
        @Resource
        private RedissonClient redissonClient;
        //key
        private static final String KEY = "monthly-report:weekly-sales-plan";

        /**
         * 查询Weekly Sales Plan明细
         *
         * @param propertyId    资产id
         * @param yearMonthList 查询月份集合
         * @return java.util.List<cloud.wconnect.workperformance.entity.monthlyreport.MonthlyReportWeeklySalesPlanDetail>
         * @author lichen
         * @date 2024/12/9
         */
        @Override
        public List<MonthlyReportWeeklySalesPlanDetail> listByYearMonth(Integer propertyId, Collection<String> yearMonthList) {
            if (CollectionUtils.isEmpty(yearMonthList)) return Collections.emptyList();
            return list(new LambdaQueryWrapper<MonthlyReportWeeklySalesPlanDetail>()
                    .eq(MonthlyReportWeeklySalesPlanDetail::getPropertyId, propertyId)
                    .in(MonthlyReportWeeklySalesPlanDetail::getYearMonth, yearMonthList));
        }

        /**
         * 处理Weekly Sales Plan数据
         *
         * @param propertyDTO       资产DTO
         * @param weeklySalesPlanBO weekly sales plan数据
         * @return void
         * @author lichen
         * @date 2024/12/9
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void handleData(PropertyDTO propertyDTO, WeeklySalesPlanBO weeklySalesPlanBO) {
            //获取锁对象
            RLock lock = redissonClient.getLock(KEY);
            //尝试上锁
            if (lock.tryLock()) {
                try {
                    //执行业务逻辑
                    doHandleData(propertyDTO, weeklySalesPlanBO);
                } finally {
                    lock.unlock();
                }
            } else { //上锁失败
                //休眠100ms
                try {
                    Thread.sleep(100);
                } catch (InterruptedException exception) {
                    log.error(exception.getMessage(), exception);
                }
                //递归执行
                handleData(propertyDTO, weeklySalesPlanBO);
            }
        }

        /**
         * 处理Weekly Sales Plan数据
         *
         * @param propertyDTO       资产DTO
         * @param weeklySalesPlanBO weekly sales plan数据
         * @return void
         * @author lichen
         * @date 2024/12/11
         */
        private void doHandleData(PropertyDTO propertyDTO, WeeklySalesPlanBO weeklySalesPlanBO) {
            //查询指定用户的指标数据集合
            List<MonthlyReportWeeklySalesPlanDetail> monthlyReportWeeklySalesPlanDetails = list(new LambdaQueryWrapper<MonthlyReportWeeklySalesPlanDetail>()
                    .eq(MonthlyReportWeeklySalesPlanDetail::getPropertyId, propertyDTO.getId())
                    .eq(MonthlyReportWeeklySalesPlanDetail::getYearMonth, weeklySalesPlanBO.getYearMonth())
                    .eq(MonthlyReportWeeklySalesPlanDetail::getUserId, weeklySalesPlanBO.getUserId()));

            //数据数据的执行时间小于原时间，则说明数据已过期，不用处理
            if (CollectionUtils.isNotEmpty(monthlyReportWeeklySalesPlanDetails)) {
                Long oriOperationTime = monthlyReportWeeklySalesPlanDetails.get(0).getOperationTime();
                if (weeklySalesPlanBO.getOperationTime().compareTo(oriOperationTime) < 0) {
                    log.info("The data operation time is shorter than the original operation time, Unprocessed data");
                    return;
                }
            }

            //先删除用户的指标数据
            remove(new LambdaQueryWrapper<MonthlyReportWeeklySalesPlanDetail>()
                    .eq(MonthlyReportWeeklySalesPlanDetail::getPropertyId, propertyDTO.getId())
                    .eq(MonthlyReportWeeklySalesPlanDetail::getYearMonth, weeklySalesPlanBO.getYearMonth())
                    .eq(MonthlyReportWeeklySalesPlanDetail::getUserId, weeklySalesPlanBO.getUserId()));

            if (weeklySalesPlanBO.getOperationType() == WeeklySalesPlanBO.SAVE) {
                //周对应的审批状态
                Map<Integer, Integer> week2ApproveStatus = weeklySalesPlanBO.getWeekStatus().stream()
                        .collect(Collectors.toMap(WeeklySalesPlanStatusBO::getWeek, WeeklySalesPlanStatusBO::getApproveStatus));

                List<MonthlyReportWeeklySalesPlanDetail> weeklySalesPlanDetails = beanMapper.mapList(weeklySalesPlanBO.getItems(),
                        MonthlyReportWeeklySalesPlanDetail.class, (bo, entity) -> {
                            entity.setTenantId(propertyDTO.getTenantId());
                            entity.setPropertyId(propertyDTO.getId());
                            entity.setYearMonth(weeklySalesPlanBO.getYearMonth());
                            entity.setUserId(weeklySalesPlanBO.getUserId());
                            entity.setItemName(bo.getName().trim());
                            entity.setWeekOneApproveStatus(week2ApproveStatus.get(1));
                            entity.setWeekTwoApproveStatus(week2ApproveStatus.get(2));
                            entity.setWeekThreeApproveStatus(week2ApproveStatus.get(3));
                            entity.setWeekFourApproveStatus(week2ApproveStatus.get(4));
                            entity.setWeekFiveApproveStatus(week2ApproveStatus.get(5));
                            entity.setOperationTime(weeklySalesPlanBO.getOperationTime());
                        });
                //批量新增
                saveBatch(weeklySalesPlanDetails);
            }
        }
    }