ludc
2023-04-07 7df1d61319149a666e8b2801a3c89c1d80900d2e
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/CodeClassifyValueServiceImpl.java
@@ -1,481 +1,14 @@
package com.vci.ubcs.code.service.impl;
import com.vci.ubcs.code.dao.CodeBasicSecDaoI;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vci.ubcs.code.entity.CodeClassifyValue;
import com.vci.ubcs.code.mapper.CodeClassifyValueMapper;
import com.vci.ubcs.code.entity.CodeBasicSecDO;
import com.vci.ubcs.code.entity.CodeClassifyValueDO;
import com.vci.ubcs.code.service.CodeClassifyValueServiceI;
import com.vci.frameworkcore.lcstatuspck.FrameworkDataLCStatus;
import com.vci.starter.revision.bo.TreeWrapperOptions;
import com.vci.starter.revision.service.RevisionModelUtil;
import com.vci.starter.web.exception.VciBaseException;
import com.vci.starter.web.pagemodel.BaseResult;
import com.vci.starter.web.pagemodel.PageHelper;
import com.vci.starter.web.pagemodel.Tree;
import com.vci.starter.web.pagemodel.TreeQueryObject;
import com.vci.starter.web.util.BeanUtilForVCI;
import com.vci.starter.web.util.VciBaseUtil;
import com.vci.starter.web.wrapper.VciParentQueryOption;
import com.vci.starter.web.wrapper.VciQueryWrapperForDO;
import com.vci.web.pageModel.BatchCBO;
import com.vci.web.service.WebBoServiceI;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vci.ubcs.code.dto.CodeClassifyValueDTO;
import com.vci.ubcs.code.vo.pagemodel.CodeClassifyValueVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import com.vci.ubcs.code.service.ICodeClassifyValueService;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import plm.bs.bom.clientobject.ClientBusinessObject;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import static com.vci.frameworkcore.constant.FrameWorkDefaultValueConstant.LC_STATUS;
import static com.vci.frameworkcore.constant.FrameWorkLangCodeConstant.*;
/**
 * 分类码段的码值服务
 * @author weidy
 * @date 2022-01-24
 */
@Service
public class CodeClassifyValueServiceImpl implements CodeClassifyValueServiceI {
public class CodeClassifyValueServiceImpl  extends ServiceImpl<CodeClassifyValueMapper, CodeClassifyValue> implements ICodeClassifyValueService {
    /**
    * 日志
    */
    private Logger logger = LoggerFactory.getLogger(getClass());
    /**
    * 数据操作层
    */
    @Resource
    private CodeClassifyValueMapper codeClassifyValueMapper;
    /**
    * 业务类型操作的服务
    */
    @Autowired
    @Lazy
   private WebBoServiceI boService;
    /**
    * 对象的操作
    */
    @Autowired
    private RevisionModelUtil revisionModelUtil;
    /**
     * 码段的信息
     */
    @Autowired
    private CodeBasicSecDaoI basicSecMapper;
    /**
    * 上级节点的属性名称
    */
    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<CodeClassifyValueDO> doList =selectCodeClassifyValueDO4Tree(treeQueryObject);
        List<CodeClassifyValueVO> voList = codeClassifyValueDO2VOs(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 treeQueryObject 树形查询对象
      * @return 查询结果,数据对象
      */
    @Override
    public List<CodeClassifyValueDO> selectCodeClassifyValueDOByTree(TreeQueryObject treeQueryObject) {
        VciQueryWrapperForDO queryWrapperForDO = new VciQueryWrapperForDO(treeQueryObject.getConditionMap(),CodeClassifyValueDO.class);
        PageHelper ph = new PageHelper();
        ph.addDefaultAsc("ordernum");
        queryWrapperForDO.setPageHelper(ph);
        VciParentQueryOption parentQueryOption = new VciParentQueryOption();
        parentQueryOption.setParentFieldName(PARENT_FIELD_NAME);
        //queryWrapperForDO.parentQueryChild(treeQueryObject,parentQueryOption);
        parentQueryOption.setHasSelf(true);
        queryWrapperForDO.childQueryParent(parentQueryOption);
        return codeClassifyValueMapper.selectByWrapper(queryWrapperForDO);
    }
    private List<CodeClassifyValueDO> selectCodeClassifyValueDO4Tree(TreeQueryObject treeQueryObject){
        Map<String, String> conditionMap = treeQueryObject.getConditionMap();
        String currentSecOid = conditionMap.get("codeclassifysecoid");
        String sql = "select oid from PLATFORMBTM_CODEBASICSEC start with  oid = '"+currentSecOid+"' connect by prior PARENTCLASSIFYSECOID = OID";
        List<ClientBusinessObject> targetParentList = boService.queryBySql(sql, new HashMap<>());
        Set<String> secOidList = targetParentList.stream().map(ClientBusinessObject::getOid).collect(Collectors.toSet());
        conditionMap.clear();
        StringBuilder oidStrBuilder = new StringBuilder();
        secOidList.forEach(oid -> oidStrBuilder.append("'").append(oid).append("',"));
        String oidStr = oidStrBuilder.toString().substring(0,oidStrBuilder.toString().length() -1);
        VciQueryWrapperForDO wrapper = new VciQueryWrapperForDO(null,CodeClassifyValueDO.class);
        PageHelper ph = new PageHelper();
        ph.addDefaultAsc("ordernum");
        ph.setLimit(-1);
        wrapper.setPageHelper(ph);
        wrapper.in("codeclassifysecoid",oidStr);
        return codeClassifyValueMapper.selectByWrapper(wrapper);
    }
    /**
     * 批量数据对象转换为显示对象
     * @param codeClassifyValueDOs 数据对象列表
     * @return 显示对象
     * @throws VciBaseException 参数为空或者不存在的时候会抛出异常
     */
    @Override
    public List<CodeClassifyValueVO> codeClassifyValueDO2VOs(Collection<CodeClassifyValueDO>  codeClassifyValueDOs) throws VciBaseException{
        List<CodeClassifyValueVO> voList = new ArrayList<CodeClassifyValueVO>();
        if(!CollectionUtils.isEmpty(codeClassifyValueDOs)){
           for(CodeClassifyValueDO s: codeClassifyValueDOs){
                CodeClassifyValueVO vo =  codeClassifyValueDO2VO(s);
                if(vo != null){
                    voList.add(vo);
                }
            }
        }
        return voList;
    }
    /**
     * 数据对象转换为显示对象
     * @param  codeClassifyValueDO 数据对象
     * @return 显示对象
     * @throws VciBaseException 拷贝属性出错的时候会抛出异常
     */
    @Override
    public  CodeClassifyValueVO codeClassifyValueDO2VO(CodeClassifyValueDO codeClassifyValueDO) throws VciBaseException{
              CodeClassifyValueVO vo = new CodeClassifyValueVO();
        if(codeClassifyValueDO != null){
            BeanUtilForVCI.copyPropertiesIgnoreCase(codeClassifyValueDO,vo);
            //如果有lcstatus的类的话
        }
        return vo;
    }
    /**
     * 增加分类码段的码值
     * @param codeClassifyValueDTO 分类码段的码值数据传输对象
     * @return 执行结果
     * @throws VciBaseException 参数为空,唯一项,必输项不通过时会抛出异常
     */
    @Override
    public CodeClassifyValueVO addSave(CodeClassifyValueDTO codeClassifyValueDTO) throws VciBaseException{
        VciBaseUtil.alertNotNull(codeClassifyValueDTO,"需要添加的数据对象");
        //添加对码值子父级的判断
        if(StringUtils.isNotBlank(codeClassifyValueDTO.getParentclassifyvalueoid())){
            String parentclassifyvalueoid = codeClassifyValueDTO.getParentclassifyvalueoid();
            String codeclassifysecoid = codeClassifyValueDTO.getCodeclassifysecoid();
            CodeClassifyValueDO parentDO = codeClassifyValueMapper.selectByPrimaryKey(parentclassifyvalueoid);
            if (parentDO.getCodeClassifySecOid().equalsIgnoreCase(codeclassifysecoid)){
                throw new VciBaseException("不允许在父码值中直接添加子码值");
            }
        }
        //将DTO转换为DO
        CodeClassifyValueDO codeClassifyValueDO = new CodeClassifyValueDO();
        BeanUtilForVCI.copyPropertiesIgnoreCase(codeClassifyValueDTO,codeClassifyValueDO);
        Map<String,String> conditionMap = new HashMap<>();
        conditionMap.put("codeclassifysecoid", codeClassifyValueDO.getCodeClassifySecOid());
        conditionMap.put("parentclassifyvalueoid",codeClassifyValueDO.getParentClassifyValueOid());
        VciQueryWrapperForDO wrapper = new VciQueryWrapperForDO(conditionMap,CodeClassifyValueDO.class);
        List<CodeClassifyValueDO> existList = codeClassifyValueMapper.selectByWrapper(wrapper);
        codeClassifyValueDO.setOrderNum(existList.size() + 1);
        codeClassifyValueMapper.insert(codeClassifyValueDO);
        return codeClassifyValueDO2VO(codeClassifyValueDO);
    }
    /**
     * 修改分类码段的码值
     * @param codeClassifyValueDTO 分类码段的码值数据传输对象
     * @return 执行结果
     * @throws VciBaseException 参数为空,唯一项,必输项不通过时会抛出异常
     */
     @Override
     public CodeClassifyValueVO editSave(CodeClassifyValueDTO codeClassifyValueDTO) throws VciBaseException{
         VciBaseUtil.alertNotNull(codeClassifyValueDTO,"数据对象",codeClassifyValueDTO.getOid(),"分类码段的码值主键");
         //将DTO转换为DO
         CodeClassifyValueDO codeClassifyValueDO = selectByOid(codeClassifyValueDTO.getOid());
         revisionModelUtil.copyFromDTOIgnore(codeClassifyValueDTO,codeClassifyValueDO);
         codeClassifyValueMapper.updateByPrimaryKey(codeClassifyValueDO);
         return codeClassifyValueDO2VO(codeClassifyValueDO);
     }
/**
 * 检查 分类码段的码值是否删除
 * @param codeClassifyValueDTO 分类码段的码值数据传输对象,必须要有oid和ts属性
 * @return 执行结果 success为true为可以删除,false表示有数据引用,obj为true表示有下级
 * @throws VciBaseException 参数为空,被引用时抛出异常
 */
@Override
public BaseResult checkIsCanDelete(CodeClassifyValueDTO codeClassifyValueDTO) throws VciBaseException{
    VciBaseUtil.alertNotNull(codeClassifyValueDTO,"数据传输对象",codeClassifyValueDTO.getOid(),"主键");
    CodeClassifyValueDO codeClassifyValueDO = selectByOid(codeClassifyValueDTO.getOid());
    return checkIsCanDeleteForDO(codeClassifyValueDTO,codeClassifyValueDO);
}
    /**
     * 校验是否可以删除,如果存在下级,并且下级有数据引用则不能删除
     * @param codeClassifyValueDTO 数据传输对象
     * @param codeClassifyValueDO 数据库中的数据对象
     * @return success为true为可以删除,false表示有数据引用,obj为true表示有下级
     */
    private BaseResult checkIsCanDeleteForDO(CodeClassifyValueDTO codeClassifyValueDTO, CodeClassifyValueDO codeClassifyValueDO) {
        //boService.checkTs(codeClassifyValueDTO);
        //校验下级是否有引用
        if(checkChildIsLinked(codeClassifyValueDO.getOid())){
            return BaseResult.fail(DATA_CASCADE_LINKED_NOT_DELETE,new String[]{""});
        }
        return BaseResult.success(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
    public BaseResult deleteCodeClassifyValue(CodeClassifyValueDTO codeClassifyValueDTO) throws VciBaseException{
        VciBaseUtil.alertNotNull(codeClassifyValueDTO,"分类码段的码值数据对象",codeClassifyValueDTO.getOid(),"分类码段的码值的主键");
        CodeClassifyValueDO codeClassifyValueDO = selectByOid(codeClassifyValueDTO.getOid());
        BaseResult baseResult = checkIsCanDeleteForDO(codeClassifyValueDTO,codeClassifyValueDO);
        if(baseResult.isSuccess()) {
                        //找下级的,这个是可以删除的时候
            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.batchDeleteByOids(s);
                }
            }
                    }else{
            return baseResult;
        }
        //执行删除操作
        BatchCBO batchCBO = codeClassifyValueMapper.deleteByPrimaryKey(codeClassifyValueDO.getOid());
        return (batchCBO!=null && batchCBO.getDeleteCbos() !=null &&batchCBO.getDeleteCbos().size() > 0)?BaseResult.successMsg(DELETE_SUCCESS):BaseResult.fail(DELETE_FAIL);
    }
    /**
    * 主键获取分类码段的码值
    * @param oid 主键
    * @return 分类码段的码值显示对象
    * @throws VciBaseException 参数为空,数据不存在时会抛出异常
    */
    @Override
    public  CodeClassifyValueVO getObjectByOid(String oid) throws VciBaseException{
        return codeClassifyValueDO2VO(selectByOid(oid));
    }
    /**
    * 主键查询数据对象
    * @param oid 主键
    * @return  数据对象
    * @throws VciBaseException 参数为空,并且数据不存在的时候会抛出异常
    */
    private CodeClassifyValueDO selectByOid(String oid) throws VciBaseException{
        VciBaseUtil.alertNotNull(oid,"主键");
        CodeClassifyValueDO codeClassifyValueDO = codeClassifyValueMapper.selectByPrimaryKey(oid.trim());
        if(codeClassifyValueDO == null || StringUtils.isBlank(codeClassifyValueDO.getOid())){
            throw new VciBaseException(DATA_OID_NOT_EXIST);
        }
        return codeClassifyValueDO;
    }
    /**
     * 主键批量获取分类码段的码值
     * @param oidCollections 主键集合,但是受性能影响,建议一次查询不超过10000个
     * @return 分类码段的码值显示对象
     * @throws VciBaseException 查询出现异常时会抛出
     */
    @Override
    public Collection<CodeClassifyValueVO> listCodeClassifyValueByOids(Collection<String> oidCollections) throws VciBaseException{
        VciBaseUtil.alertNotNull(oidCollections,"数据对象主键集合");
        List<CodeClassifyValueDO> codeClassifyValueDOList = listCodeClassifyValueDOByOidCollections(oidCollections);
        return codeClassifyValueDO2VOs(codeClassifyValueDOList);
    }
    /**
    * 使用主键集合查询数据对象
    * @param oidCollections 主键的集合
    * @return 数据对象列表
    */
    private List<CodeClassifyValueDO> listCodeClassifyValueDOByOidCollections(Collection<String> oidCollections){
        List<CodeClassifyValueDO> codeClassifyValueDOList = new ArrayList<CodeClassifyValueDO>();
        if(!CollectionUtils.isEmpty(oidCollections)){
            Collection<Collection<String>> oidCollectionsList = VciBaseUtil.switchCollectionForOracleIn(oidCollections);
            for(Collection<String> oids: oidCollectionsList){
                List<CodeClassifyValueDO> tempDOList =  codeClassifyValueMapper.selectByPrimaryKeyCollection(oids);
                if(!CollectionUtils.isEmpty(tempDOList)){
                        codeClassifyValueDOList.addAll(tempDOList);
                }
            }
        }
        return  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 classifySecOid         码段的主键
     * @param parentClassifyValueOid 上级分类的主键
     * @return 分类码值的内容
     */
    @Override
    public List<CodeClassifyValueVO> listCodeClassifyValueBySecOid(String classifySecOid, String parentClassifyValueOid) {
        if(StringUtils.isBlank(classifySecOid)){
            return new ArrayList<>();
        }
        CodeBasicSecDO secDO = basicSecMapper.selectByPrimaryKey(classifySecOid);
        if(secDO == null || StringUtils.isBlank(secDO.getOid())){
            throw new VciBaseException("码段的内容在系统中不存在");
        }
        if(StringUtils.isNotBlank(secDO.getParentClassifySecOid()) && StringUtils.isBlank(parentClassifyValueOid)){
            return new ArrayList<>();
            //因为有上级分类的时候,必须先选择上级分类的内容
        }
        Map<String,String> conditionMap = new HashMap<>();
        conditionMap.put("codeClassifySecOid",classifySecOid);
        if(StringUtils.isNotBlank(parentClassifyValueOid)){
            conditionMap.put("parentClassifyValueOid",parentClassifyValueOid);
        }
        PageHelper pageHelper = new PageHelper(-1);
        pageHelper.addDefaultAsc("ordernum");
        List<CodeClassifyValueDO> valueDOList = codeClassifyValueMapper.selectByCondition(conditionMap, pageHelper);
        return codeClassifyValueDO2VOs(valueDOList);
    }
    /**
     * 根据码段主键删除其存在的码值对象
     * @param codeclassifysecoid 分类码段的主键
     * @return 执行结果
     */
    @Override
    public BaseResult batchDeleteBySecOid(String codeclassifysecoid) {
        VciBaseUtil.alertNotNull(codeclassifysecoid,"分类码段的主键");
        Map<String,String> conditionMap = new HashMap<>();
        conditionMap.put("codeClassifySecOid",codeclassifysecoid);
        VciQueryWrapperForDO wrapper = new VciQueryWrapperForDO(conditionMap,CodeClassifyValueDO.class);
        List<CodeClassifyValueDO> valueDOList = codeClassifyValueMapper.selectByWrapper(wrapper);
        codeClassifyValueMapper.batchDeleteByOids(valueDOList.stream().map(CodeClassifyValueDO::getOid).collect(Collectors.toList()));
        return BaseResult.success();
    }
    /**
     * 批量添加分类码段的码值。主要是保存码值的序号
     * @param dtoList 分类码段的码值列表
     * @param codeclassifysecoid 分类码段的主键
     * @return 执行结果
     */
    @Override
    public BaseResult batchSave4Order(List<CodeClassifyValueDTO> dtoList, String codeclassifysecoid) {
        VciBaseUtil.alertNotNull(codeclassifysecoid,"分类码段主键");
        Map<String,String> conditionMap = new HashMap<>();
        conditionMap.put("codeClassifySecOid",codeclassifysecoid);
        VciQueryWrapperForDO wrapper = new VciQueryWrapperForDO(conditionMap,CodeClassifyValueDO.class);
        List<CodeClassifyValueDO> valueDOList = codeClassifyValueMapper.selectByWrapper(wrapper);
        List<CodeClassifyValueDO> updateList = new ArrayList<>();
        dtoList.forEach(dto -> {
            if( StringUtils.isNotBlank( dto.getOid() )){
                List<CodeClassifyValueDO> 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);
                });
            }
        });
        codeClassifyValueMapper.batchUpdate(updateList);
        return BaseResult.success();
    }
}