# MorDepartmentServiceImpl.java

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

    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.cons.BaseConstant;
    import cloud.wconnect.commonlib.cons.BaseErrorCodeEnum;
    import cloud.wconnect.commonlib.cons.CommonErrorI18nConstant;
    import cloud.wconnect.commonlib.exception.BadRequestException;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.commonlib.util.DateTimeUtils;
    import cloud.wconnect.workperformance.entity.mor.MorDepartment;
    import cloud.wconnect.workperformance.mapper.mor.MorDepartmentMapper;
    import cloud.wconnect.workperformance.pojo.bo.mor.overtime.OvertimeDailyBO;
    import cloud.wconnect.workperformance.pojo.dto.mor.MorDepartmentDTO;
    import cloud.wconnect.workperformance.pojo.query.mor.MorDepartmentQuery;
    import cloud.wconnect.workperformance.service.mor.IMorDepartmentService;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import org.apache.commons.collections.CollectionUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import java.util.*;
    import java.util.stream.Collectors;

    /**
     * <p>
     * 服务实现类
     * </p>
     *
     * @author zc
     * @since 2023-11-22
     */
    @Service
    @DS("work_performance")
    public class MorDepartmentServiceImpl extends ServiceImpl<MorDepartmentMapper, MorDepartment> implements IMorDepartmentService {

        @Autowired
        private BeanMapper beanMapper;

        /**
         * 获取部门
         *
         * @param propertyId      资产 id
         * @param departmentQuery 查询条件
         * @return MorDepartmentDTO 集合
         * @author zc
         * @date 2023/11/24
         */
        @Override
        public List<MorDepartmentDTO> list(int propertyId, MorDepartmentQuery departmentQuery) {
            List<MorDepartment> list = list(new QueryWrapper<MorDepartment>().lambda()
                    .eq(MorDepartment::getPropertyId, propertyId)
                    .eq(StringUtils.isNotBlank(departmentQuery.getCode()),
                            MorDepartment::getCode, departmentQuery.getCode())
                    .eq(StringUtils.isNotBlank(departmentQuery.getDesc()),
                            MorDepartment::getDesc, departmentQuery.getDesc()));
            return beanMapper.mapList(list, MorDepartmentDTO.class);
        }

        /**
         * 校验数据是否存在，并返回对象
         *
         * @param propertyId 资产 id
         * @param id         部门 id
         * @return MorDepartment
         * @author zc
         * @date 2023/11/24
         */
        @Override
        public MorDepartment checkExist(int propertyId, int id) {
            MorDepartment department = getById(id);
            if (Objects.isNull(department)) {
                throw new BadRequestException(CommonErrorI18nConstant.DATA_NOT_FOUND,
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(),
                        "The department is not found by id; id: " + id);
            }
            return department;
        }

        /**
         * 保存部门
         *
         * @param propertyId       资产 id
         * @param operatorId       操作人 id
         * @param morDepartmentDTO 部门数据
         * @author zc
         * @date 2023/11/24
         */
        @Override
        public void saveDepartment(int propertyId, int operatorId, MorDepartmentDTO morDepartmentDTO) {
            long nowTimestamp = DateTimeUtils.nowTimestamp();
            save(new MorDepartment()
                    .setPropertyId(propertyId)
                    .setCode(morDepartmentDTO.getCode())
                    .setDesc(morDepartmentDTO.getDesc())
                    .setCreatedTime(nowTimestamp)
                    .setUpdatedBy(operatorId)
                    .setUpdatedTime(nowTimestamp));
        }

        /**
         * 编辑部门
         *
         * @param operatorId       操作人 id
         * @param originDepartment 原部门数据
         * @param morDepartmentDTO 部门数据
         * @author zc
         * @date 2023/12/1
         */
        @Override
        public void updateDepartment(int operatorId, MorDepartment originDepartment, MorDepartmentDTO morDepartmentDTO) {
            updateById(new MorDepartment()
                    .setId(morDepartmentDTO.getId())
                    .setDesc(morDepartmentDTO.getDesc())
                    .setUpdatedBy(operatorId)
                    .setUpdatedTime(DateTimeUtils.nowTimestamp()));
        }

        /**
         * 根据部门 code 获取数据
         *
         * @param propertyId      资产 id
         * @param departmentCodes 部门 code
         * @return MorDepartment 集合
         * @author zc
         * @date 2023/11/24
         */
        @Override
        public List<MorDepartment> listByCodes(int propertyId, List<String> departmentCodes) {
            if (CollectionUtils.isEmpty(departmentCodes)) {
                return Collections.emptyList();
            }
            return list(new QueryWrapper<MorDepartment>().lambda()
                    .eq(MorDepartment::getPropertyId, propertyId)
                    .in(MorDepartment::getCode, departmentCodes));
        }

        /**
         * 校验部门 code 是否重复
         *
         * @param propertyId       资产 id
         * @param morDepartmentDTO 部门数据
         * @param id               部门 id
         * @author zc
         * @date 2023/12/1
         */
        @Override
        public void checkRepeat(int propertyId, MorDepartmentDTO morDepartmentDTO, Integer id) {
            long codeCount = count(new QueryWrapper<MorDepartment>().lambda()
                    .eq(MorDepartment::getPropertyId, propertyId)
                    .eq(MorDepartment::getCode, morDepartmentDTO.getCode())
                    .ne(Objects.nonNull(id), MorDepartment::getId, id));
            if (codeCount > BaseConstant.LONG_ZERO) {
                throw new BadRequestException(CommonErrorI18nConstant.DATA_EXISTED,
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(),
                        "The departmentCode has been used");
            }
        }

        /**
         * 更新部门数据
         *
         * @param propertyList 资产 id
         * @param boList       文件数据 BO
         * @author zc
         * @date 2025/6/19
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void updateDepartment(List<PropertyDTO> propertyList, List<OvertimeDailyBO> boList) {
            if (CollectionUtils.isEmpty(boList)) {
                return;
            }
            Map<String, PropertyDTO> abbr2Property = propertyList.stream()
                    .collect(Collectors.toMap(PropertyDTO::getAbbr, v -> v));
            long nowTimestamp = DateTimeUtils.nowTimestamp();
            List<MorDepartment> morDepartmentList = boList.stream().map(item ->
                            MorDepartment.builder()
                                    .propertyId(abbr2Property.get(item.getProperty()).getId())
                                    .code(item.getWorkDepartmentCode())
                                    .descByReport(item.getWorkDepartmentDesc())
                                    .createdTime(nowTimestamp)
                                    .build())
                    .distinct()
                    // 按唯一索引字段排序，避免死锁
                    .sorted(Comparator.comparing(MorDepartment::getPropertyId)
                            .thenComparing(MorDepartment::getCode))
                    .collect(Collectors.toList());

            baseMapper.insertOrUpdateBatchByUnique(morDepartmentList);
        }
    }