ludc
2023-04-26 7f0570d20aac189f1b170942bd7100b281a1c824
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/CodeClassifyValueServiceImpl.java
@@ -1,14 +1,343 @@
package com.vci.ubcs.code.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vci.ubcs.code.dto.CodeClassifyValueDTO;
import com.vci.ubcs.code.entity.CodeClassifyValue;
import com.vci.ubcs.code.enumpack.FrameworkDataLCStatus;
import com.vci.ubcs.code.mapper.CodeClassifyValueMapper;
import com.vci.ubcs.code.service.ICodeBasicSecService;
import com.vci.ubcs.code.service.ICodeClassifyValueService;
import com.vci.ubcs.code.vo.pagemodel.CodeClassifyValueVO;
import com.vci.ubcs.code.wrapper.CodeClassifyValueWrapper;
import com.vci.ubcs.starter.exception.VciBaseException;
import com.vci.ubcs.starter.revision.model.TreeQueryObject;
import com.vci.ubcs.starter.revision.model.TreeWrapperOptions;
import com.vci.ubcs.starter.revision.service.RevisionModelUtil;
import com.vci.ubcs.starter.web.pagemodel.Tree;
import com.vci.ubcs.starter.web.util.BeanUtilForVCI;
import com.vci.ubcs.starter.web.util.VciBaseUtil;
import org.springblade.core.tool.api.R;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import static com.vci.ubcs.code.constant.FrameWorkDefaultValueConstant.LC_STATUS;
import static com.vci.ubcs.code.constant.FrameWorkLangCodeConstant.DATA_CASCADE_LINKED_NOT_DELETE;
import static com.vci.ubcs.code.constant.FrameWorkLangCodeConstant.DATA_OID_NOT_EXIST;
@Service
public class CodeClassifyValueServiceImpl  extends ServiceImpl<CodeClassifyValueMapper, CodeClassifyValue> implements ICodeClassifyValueService {
   @Resource
   private RevisionModelUtil revisionModelUtil;
   @Resource
   private CodeClassifyValueMapper codeClassifyValueMapper;
   @Resource
   @Lazy
   private ICodeBasicSecService codeBasicSecService;
   /**
    * 上级节点的属性名称
    */
   private static  final String PARENT_FIELD_NAME = "parentClassifyValueOid";
   /**
    * 查询分类码段的码值 树
    * @param treeQueryObject 树查询对象
    * @return 分类码段的码值 显示树
    * @throws VciBaseException 查询条件不符合要求的时候会抛出异常
    */
   @Override
   public List<Tree> treeCodeClassifyValue(TreeQueryObject treeQueryObject) throws VciBaseException {
      // List<CodeClassifyValueDO> doList =selectCodeClassifyValueDOByTree(treeQueryObject);
      List<CodeClassifyValue> doList =selectCodeClassifyValueDO4Tree(treeQueryObject);
      List<CodeClassifyValueVO> voList = CodeClassifyValueWrapper.build().listVO(doList);
      TreeWrapperOptions treeWrapperOptions = new TreeWrapperOptions(PARENT_FIELD_NAME);
      treeWrapperOptions.copyFromTreeQuery(treeQueryObject);
      return revisionModelUtil.doList2Trees(voList,treeWrapperOptions,(CodeClassifyValueVO s) ->{
         //可以在这里处理树节点的显示
         return s.getId() + " " + s.getName() + (FrameworkDataLCStatus.DISABLED.getValue().equalsIgnoreCase(s
            .getLcStatus()) ? (" 【停用】 ") : "");
      });
   }
   /**
    * 增加分类码段的码值
    * @param codeClassifyValueDTO 分类码段的码值数据传输对象
    * @return 执行结果
    * @throws VciBaseException 参数为空,唯一项,必输项不通过时会抛出异常
    */
   @Override
   public boolean addSave(CodeClassifyValueDTO codeClassifyValueDTO) throws VciBaseException{
      VciBaseUtil.alertNotNull(codeClassifyValueDTO,"需要添加的数据对象");
      //添加对码值子父级的判断
      if(StringUtils.isNotBlank(codeClassifyValueDTO.getParentclassifyvalueoid())){
         String parentclassifyvalueoid = codeClassifyValueDTO.getParentclassifyvalueoid();
         String codeclassifysecoid = codeClassifyValueDTO.getCodeclassifysecoid();
         CodeClassifyValue parentDO = codeClassifyValueMapper.selectById(parentclassifyvalueoid);
         if (parentDO.getCodeClassifySecOid().equalsIgnoreCase(codeclassifysecoid)){
            throw new VciBaseException("不允许在父码值中直接添加子码值");
         }
      }
      //将DTO转换为DO
      CodeClassifyValue codeClassifyValueDO = new CodeClassifyValue();
      BeanUtilForVCI.copyPropertiesIgnoreCase(codeClassifyValueDTO,codeClassifyValueDO);
      //查询
      List<CodeClassifyValue> existList = codeClassifyValueMapper.selectList(Wrappers.<CodeClassifyValue>query()
         .lambda().eq(CodeClassifyValue::getCodeClassifySecOid, codeClassifyValueDO.getCodeClassifySecOid())
         .eq(CodeClassifyValue::getParentClassifyValueOid, codeClassifyValueDO.getParentClassifyValueOid())
      );
      codeClassifyValueDO.setOrderNum(existList.size() + 1);
      boolean resBoolean = codeClassifyValueMapper.insert(codeClassifyValueDO) > 0;
      return resBoolean;
   }
   /**
    * 修改分类码段的码值
    * @param codeClassifyValueDTO 分类码段的码值数据传输对象
    * @return 执行结果
    * @throws VciBaseException 参数为空,唯一项,必输项不通过时会抛出异常
    */
   @Override
   public boolean editSave(CodeClassifyValueDTO codeClassifyValueDTO) throws VciBaseException{
      VciBaseUtil.alertNotNull(codeClassifyValueDTO,"数据对象",codeClassifyValueDTO.getOid(),"分类码段的码值主键");
      //将DTO转换为DO
      CodeClassifyValue codeClassifyValueDO = selectByOid(codeClassifyValueDTO.getOid());
      revisionModelUtil.copyFromDTOIgnore(codeClassifyValueDTO,codeClassifyValueDO);
      boolean resBoolean = codeClassifyValueMapper.updateById(codeClassifyValueDO) > 0;
      return resBoolean;
   }
   /**
    * 检查 分类码段的码值是否删除
    * @param codeClassifyValueDTO 分类码段的码值数据传输对象,必须要有oid和ts属性
    * @return 执行结果 success为true为可以删除,false表示有数据引用,obj为true表示有下级
    * @throws VciBaseException 参数为空,被引用时抛出异常
    */
   @Override
   public R checkIsCanDelete(CodeClassifyValueDTO codeClassifyValueDTO) throws VciBaseException{
      VciBaseUtil.alertNotNull(codeClassifyValueDTO,"数据传输对象",codeClassifyValueDTO.getOid(),"主键");
      CodeClassifyValue codeClassifyValueDO = selectByOid(codeClassifyValueDTO.getOid());
      return checkIsCanDeleteForDO(codeClassifyValueDTO,codeClassifyValueDO);
   }
   /**
    * 校验是否可以删除,如果存在下级,并且下级有数据引用则不能删除
    * @param codeClassifyValueDTO 数据传输对象
    * @param codeClassifyValueDO 数据库中的数据对象
    * @return success为true为可以删除,false表示有数据引用,obj为true表示有下级
    */
   private R checkIsCanDeleteForDO(CodeClassifyValueDTO codeClassifyValueDTO, CodeClassifyValue codeClassifyValueDO) {
      //boService.checkTs(codeClassifyValueDTO);
      //校验下级是否有引用
      if(checkChildIsLinked(codeClassifyValueDO.getOid())){
         return R.fail(DATA_CASCADE_LINKED_NOT_DELETE);
      }
      return R.status(checkHasChild(codeClassifyValueDO.getOid()));
   }
   /**
    * 检查是否有下级是否关联了数据
    *
    * @param oid 主键
    * @return true 表示有引用,false表示没有引用
    * @throws VciBaseException 参数为空和有引用的时候会抛出异常
    */
   @Override
   public boolean checkChildIsLinked(String oid) throws VciBaseException {
      VciBaseUtil.alertNotNull(oid,"主键");
      List<String> childOids = codeClassifyValueMapper.selectAllLevelChildOid(oid.trim());
      if(!CollectionUtils.isEmpty(childOids)){
         for(String childOid: childOids){
            if(!checkIsLinked(childOid)){
               return false;
            }
         }
         return true;
      }
      return false;
   }
   /**
    * 校验是否有下级节点,不校验是否关联了数据
    *
    * @param oid 主键
    * @return true表示有下级,false表示没有下级
    * @throws VciBaseException 参数错误,或者数据不存在的时候会抛出异常
    */
   @Override
   public boolean checkHasChild(String oid) throws VciBaseException {
      VciBaseUtil.alertNotNull(oid,"主键");
      return codeClassifyValueMapper.countAllLevelChildOid(oid.trim()) > 0;
   }
   /**
    * 校验是否被引用
    * @param oid 主键
    * @throws VciBaseException 被引用的时候会抛出异常
    */
   private boolean checkIsLinked(String oid) throws VciBaseException{
      //TODO 添加需要校验引用的地方
      return false;
   }
   /**
    * 删除分类码段的码值
    * @param codeClassifyValueDTO 分类码段的码值数据传输对象,oid和ts需要传输
    * @return 删除结果反馈::success:成功,fail:失败
    * @throws VciBaseException 参数为空,被引用时抛出异常
    */
   @Override
   @Transactional(rollbackFor = Exception.class)
   public R deleteCodeClassifyValue(CodeClassifyValueDTO codeClassifyValueDTO) throws VciBaseException{
      VciBaseUtil.alertNotNull(codeClassifyValueDTO,"分类码段的码值数据对象",codeClassifyValueDTO.getOid(),"分类码段的码值的主键");
      CodeClassifyValue codeClassifyValueDO = selectByOid(codeClassifyValueDTO.getOid());
      R baseResult = checkIsCanDeleteForDO(codeClassifyValueDTO,codeClassifyValueDO);
      if(baseResult.isSuccess()) {
         //找下级的,这个是可以删除的时候R
         List<String> childrenOids = codeClassifyValueMapper.selectAllLevelChildOid(codeClassifyValueDO.getOid().trim());
         if (!CollectionUtils.isEmpty(childrenOids)) {
            Collection<Collection<String>> childrenCollections = VciBaseUtil.switchCollectionForOracleIn(childrenOids);
            for(Collection<String> s : childrenCollections){
               codeClassifyValueMapper.delete(Wrappers.<CodeClassifyValue>query().lambda().eq(CodeClassifyValue::getOid,s));
            }
         }
      }else{
         return baseResult;
      }
      //执行删除操作
      boolean resBoolean = codeClassifyValueMapper.deleteById(codeClassifyValueDO.getOid()) > 0;
      return R.status(resBoolean);
   }
   /**
    * 主键获取分类码段的码值
    * @param oid 主键
    * @return 分类码段的码值显示对象
    * @throws VciBaseException 参数为空,数据不存在时会抛出异常
    */
   @Override
   public  CodeClassifyValueVO getObjectByOid(String oid) throws VciBaseException{
      return CodeClassifyValueWrapper.build().entityVO(selectByOid(oid));
   }
   /**
    * 主键批量获取分类码段的码值
    * @param oidCollections 主键集合,但是受性能影响,建议一次查询不超过10000个
    * @return 分类码段的码值显示对象
    * @throws VciBaseException 查询出现异常时会抛出
    */
   @Override
   public Collection<CodeClassifyValueVO> listCodeClassifyValueByOids(Collection<String> oidCollections) throws VciBaseException{
      VciBaseUtil.alertNotNull(oidCollections,"数据对象主键集合");
      List<CodeClassifyValue> codeClassifyValueDOList = listCodeClassifyValueDOByOidCollections(oidCollections);
      return CodeClassifyValueWrapper.build().listVO(codeClassifyValueDOList);
   }
   /**
    * 参照树 分类码段的码值
    * @param treeQueryObject 树形查询对象
    * @return 分类码段的码值显示树
    * @throws VciBaseException 查询条件和分页出错的时候会抛出异常
    */
   @Override
   public List<Tree> referTree(TreeQueryObject treeQueryObject)  throws VciBaseException {
      if(treeQueryObject == null){
         treeQueryObject = new TreeQueryObject();
      }
      if(treeQueryObject.getConditionMap() == null){
         treeQueryObject.setConditionMap(new HashMap<>());
      }
      if(treeQueryObject.getConditionMap().containsKey(LC_STATUS)) {
         treeQueryObject.getConditionMap().remove(LC_STATUS);
      }
      return treeCodeClassifyValue(treeQueryObject);
   }
   /**
    * 批量添加分类码段的码值。主要是保存码值的序号
    * @param dtoList 分类码段的码值列表
    * @param codeclassifysecoid 分类码段的主键
    * @return 执行结果
    */
   @Override
   @Transactional(rollbackFor = Exception.class)
   public R batchSave4Order(List<CodeClassifyValueDTO> dtoList, String codeclassifysecoid) {
      VciBaseUtil.alertNotNull(codeclassifysecoid,"分类码段主键");
      List<CodeClassifyValue> valueDOList = codeClassifyValueMapper.selectList(Wrappers.<CodeClassifyValue>query()
         .lambda().eq(CodeClassifyValue::getCodeClassifySecOid,codeclassifysecoid)
      );
      List<CodeClassifyValue> updateList = new ArrayList<>();
      dtoList.forEach(dto -> {
         if( StringUtils.isNotBlank( dto.getOid() )){
            List<CodeClassifyValue> collect = valueDOList.stream().filter(value -> {
               return dto.getOid().equals(value.getOid());
            }).collect(Collectors.toList());
            collect.forEach(ccv -> {
               ccv.setOrderNum(dto.getOrdernum());
               ccv.setId(dto.getId());
               ccv.setName(dto.getName());
               updateList.add(ccv);
            });
         }
      });
      boolean resBoolean = this.updateBatchById(updateList);
      return R.status(resBoolean);
   }
   /**
    * 使用主键集合查询数据对象
    * @param oidCollections 主键的集合
    * @return 数据对象列表
    */
   private List<CodeClassifyValue> listCodeClassifyValueDOByOidCollections(Collection<String> oidCollections){
      List<CodeClassifyValue> codeClassifyValueDOList = new ArrayList<CodeClassifyValue>();
      if(!CollectionUtils.isEmpty(oidCollections)){
         Collection<Collection<String>> oidCollectionsList = VciBaseUtil.switchCollectionForOracleIn(oidCollections);
         for(Collection<String> oids: oidCollectionsList){
            List<CodeClassifyValue> tempDOList =  codeClassifyValueMapper.selectBatchIds(oids);
            if(!CollectionUtils.isEmpty(tempDOList)){
               codeClassifyValueDOList.addAll(tempDOList);
            }
         }
      }
      return  codeClassifyValueDOList;
   }
   /**
    * 主键查询数据对象
    * @param oid 主键
    * @return  数据对象
    * @throws VciBaseException 参数为空,并且数据不存在的时候会抛出异常
    */
   private CodeClassifyValue selectByOid(String oid) throws VciBaseException{
      VciBaseUtil.alertNotNull(oid,"主键");
      CodeClassifyValue codeClassifyValueDO = codeClassifyValueMapper.selectById(oid.trim());
      if(codeClassifyValueDO == null || StringUtils.isBlank(codeClassifyValueDO.getOid())){
         throw new VciBaseException(DATA_OID_NOT_EXIST);
      }
      return codeClassifyValueDO;
   }
   private List<CodeClassifyValue> selectCodeClassifyValueDO4Tree(TreeQueryObject treeQueryObject){
      Map<String, String> conditionMap = treeQueryObject.getConditionMap();
      List<String> oids = codeBasicSecService.getOidByCodeclassifysecOid(conditionMap.get("codeclassifysecoid"));
      LambdaQueryWrapper<CodeClassifyValue> wrapper = Wrappers.<CodeClassifyValue>query()
         .lambda().in(CodeClassifyValue::getCodeClassifySecOid,oids)
         .orderByDesc(CodeClassifyValue::getOrderNum);
      return codeClassifyValueMapper.selectList(wrapper);
   }
}