ludc
2024-09-14 36c2449aec5b51e5ed4e5c6841154b746060e09a
Source/plt-web/plt-web-parent/plt-web/src/main/java/com/vci/web/service/impl/OsStatusServiceImpl.java
@@ -2,23 +2,30 @@
import com.vci.corba.common.PLException;
import com.vci.corba.omd.stm.StatePool;
import com.vci.po.OsStatusPO;
import com.vci.starter.poi.bo.ReadExcelOption;
import com.vci.starter.poi.bo.WriteExcelData;
import com.vci.starter.poi.bo.WriteExcelOption;
import com.vci.starter.poi.constant.ExcelLangCodeConstant;
import com.vci.starter.poi.util.ExcelUtil;
import com.vci.starter.web.annotation.log.VciUnLog;
import com.vci.starter.web.exception.VciBaseException;
import com.vci.starter.web.pagemodel.BaseQueryObject;
import com.vci.starter.web.pagemodel.BaseResult;
import com.vci.starter.web.pagemodel.DataGrid;
import com.vci.starter.web.pagemodel.PageHelper;
import com.vci.starter.web.util.LangBaseUtil;
import com.vci.starter.web.util.VciBaseUtil;
import com.vci.starter.web.util.VciDateUtil;
import com.vci.web.dto.OsStatusDTO;
import com.vci.web.model.OsStatusDO;
import com.vci.web.pageModel.OsStatusVO;
import com.vci.starter.web.util.*;
import com.vci.dto.OsStatusDTO;
import com.vci.model.OsStatusDO;
import com.vci.pagemodel.OsStatusVO;
import com.vci.web.service.OsLifeCycleServiceI;
import com.vci.web.service.OsStatusServiceI;
import com.vci.web.service.WebBoServiceI;
import com.vci.web.util.Func;
import com.vci.web.util.PlatformClientUtil;
import com.vci.web.util.WebUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.util.HSSFColor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -26,10 +33,13 @@
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.io.File;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import static com.vci.frameworkcore.constant.FrameWorkBusLangCodeConstant.DATA_OID_NOT_EXIST;
import static com.vci.constant.FrameWorkBusLangCodeConstant.DATA_OID_NOT_EXIST;
/**
 * 状态的服务
@@ -64,6 +74,11 @@
    private OsLifeCycleServiceI lifeCycleService;
    /**
     *  必填列
     */
    private List<Integer> ColumnNameisRed = new ArrayList<Integer>();
    /**
     * 加载自身
     */
    @Autowired(required = false)
@@ -77,11 +92,12 @@
     * @return 显示对象
     */
    @Override
    public OsStatusVO statusDO2VO(com.vci.corba.omd.stm.StatePool statePool) {
    public OsStatusVO statusDO2VO(StatePool statePool) {
        OsStatusVO statusVO = new OsStatusVO();
        if(statePool!=null){
            statusVO.setOid(statePool.oid);
            statusVO.setCreator(statePool.creator);
            statusVO.setImagePath(statePool.imagePath);
            statusVO.setLastModifier(statePool.modifier);
            try {
                statusVO.setCreateTime(new Date(statePool.createTime));
@@ -104,7 +120,7 @@
     * @return 显示对象
     */
    @Override
    public List<OsStatusVO> statusDO2VOs(Collection<com.vci.corba.omd.stm.StatePool> statePools) {
    public List<OsStatusVO> statusDO2VOs(Collection<StatePool> statePools) {
        List<OsStatusVO> statusVOS = new ArrayList<>();
        if(!CollectionUtils.isEmpty(statePools)){
            statePools.stream().forEach(statePool -> {
@@ -168,7 +184,7 @@
     * @param statePoolList 状态内容
     */
    @Override
    public void batchAddStatus(List<StatePool> statePoolList) {
    public boolean batchAddStatus(List<StatePool> statePoolList) throws Exception{
        if(!CollectionUtils.isEmpty(statePoolList)){
            for(StatePool statePool : statePoolList) {
                try {
@@ -177,7 +193,9 @@
                    throw WebUtil.getVciBaseException(e);
                }
            }
            return true;
        }
        return false;
    }
    /**
@@ -185,7 +203,7 @@
     * @param statePoolList 状态内容
     */
    @Override
    public void batchEditSave(List<StatePool> statePoolList) {
    public boolean batchEditSave(List<StatePool> statePoolList) {
        if(!CollectionUtils.isEmpty(statePoolList)){
            for(StatePool statePool : statePoolList) {
                try {
@@ -195,6 +213,7 @@
                }
            }
        }
        return true;
    }
    /**
@@ -254,57 +273,99 @@
     * @param statusDTO 状态的数据传输对象
     */
    @Override
    public void addSave(OsStatusDTO statusDTO) {
        VciBaseUtil.alertNotNull(statusDTO,"状态的信息",statusDTO.getId(),"状态的英文名称",statusDTO.getName(),"状态的中文名称");
        statusDTO.setOid(VciBaseUtil.getPk());
        StatePool pool = statusDTO2DO(statusDTO);
        List<StatePool> poolList = new ArrayList<>();
        poolList.add(pool);
        batchAddStatus(poolList);
        clearCache();
        self.selectAllStatusMap();
    public boolean addSave(OsStatusDTO statusDTO) throws Exception {
        VciBaseUtil.alertNotNull(
            statusDTO,"状态的信息",
            statusDTO.getId(),"状态的英文名称"
        );
        if (statusDTO.getId().length()>50) {
            throw new PLException("500",new String[]{"状态英文名称不能超过50个字符!"});
        }
        // 状态池名称只能为英文字母
        String regex = "[a-z A-Z]*";
        if (!statusDTO.getId().matches(regex)) {
            throw new PLException("500",new String[]{"名称只能为英文!"});
        }
        StatePool dbStatePool = platformClientUtil.getStatePoolService().getStatePool(statusDTO.getId());
        if (Func.isNotEmpty(dbStatePool) && Func.isNotBlank(dbStatePool.oid)) {
            throw new PLException("500",new String[]{"名称重复请更换名称!"});
        }
        //虽然会自动生成oid,但是这儿设置主键,避免放入缓存的数据是没有oid的
        statusDTO.setOid(VciBaseUtil.getPk().toUpperCase(Locale.ROOT));
        try {
            boolean res = batchAddStatus(Arrays.asList(statusDTO2DO(statusDTO)));
            self.selectAllStatusMap();
            return res;
        }catch (Exception e){
            e.printStackTrace();
            logger.error(e.getMessage());
            return false;
        }
    }
    /**
     * 编辑状态
     * @param statusDTO 状态的数据传输对象
     */
    @Override
    public void editSave(OsStatusDTO statusDTO){
        VciBaseUtil.alertNotNull(statusDTO,"状态的信息",statusDTO.getId(),"状态的英文名称",statusDTO.getName(),"状态的中文名称",statusDTO.getOid(),"主键");
    public boolean editSave(OsStatusDTO statusDTO) throws Exception {
        VciBaseUtil.alertNotNull(statusDTO,"状态的信息",
                statusDTO.getId(),"状态的英文名称",
                statusDTO.getName(),"状态的中文名称",
                statusDTO.getOid(),"主键");
        OsStatusVO statusVO = getObjectByOid(statusDTO.getOid());
        if(Func.isEmpty(statusVO) || Func.isBlank(statusVO.getOid())){
            throw new PLException("500",new String[]{"修改的状态对象不存在!"});
        }
        StatePool pool = statusDTO2DO(statusDTO);
        pool.creator = statusVO.getCreator();
        pool.createTime = VciDateUtil.getTime(statusVO.getCreateTime());
        List<StatePool> poolList = new ArrayList<>();
        poolList.add(pool);
        batchEditSave(poolList);
        clearCache();
        self.selectAllStatusMap();
        try {
            boolean res = batchEditSave(Arrays.asList(pool));
            self.selectAllStatusMap();
            return res;
        }catch (Exception e){
            e.printStackTrace();
            logger.error(e.getMessage());
            return false;
        }
    }
    /**
     * 删除状态
     * @param oids 主键
     * @param osStatusDTOS
     */
    @Override
    public void delete(String oids){
        VciBaseUtil.alertNotNull(oids,"主键");
        //判断是否被引用
        List<OsStatusVO> statusVOList1 = selectByOidCollection(VciBaseUtil.str2List(oids));
        if(statusVOList1.stream().anyMatch(statusVO -> lifeCycleService.checkStatusUsed(statusVO))){
    public boolean deleteStatus(List<OsStatusDTO> osStatusDTOS) throws PLException {
        VciBaseUtil.alertNotNull(osStatusDTOS,"待删除的属性列表");
        Set<String> oids = osStatusDTOS.stream().map(OsStatusDTO::getOid).collect(Collectors.toSet());
        List<OsStatusVO> osStatusVOList = selectByOidCollection(oids);
        //判断枚举是否有被引用
        if(osStatusVOList.stream().anyMatch(statusVO -> lifeCycleService.checkStatusUsed(statusVO))){
            throw new VciBaseException("状态在生命周期中被使用,不能删除");
        }
        statusVOList1.stream().forEach(statusVO -> {
            try {
                platformClientUtil.getStatePoolService().deleteStatePool(statusVO2DO(statusVO));
            }catch (Throwable e){
                throw new VciBaseException(LangBaseUtil.getErrorMsg(e),new String[]{},e);
        //平台的deleteStatus方法必传三个参数,oid、name和ts
        List<StatePool> statePoolList = new ArrayList<>();
        for(OsStatusDTO statusDTO : osStatusDTOS){
            //oid和ts判空
            String oid = statusDTO.getOid();
            //id主要用来对缓存数据删除
            String id = statusDTO.getId();
            //后台会用ts进行数据一致性校验
            Date ts = statusDTO.getTs();
            if(Func.isBlank(oid) || Func.isBlank(id) || Func.isEmpty(ts)){
                throw new PLException("500",new String[]{"待删除的状态列表中主键【oid】、调整时间【ts】、状态名称【name】不能为空!"});
            }
        });
        clearCache();
            StatePool statePool = new StatePool();
            statePool.oid = oid;
            statePool.name = id;
            statePool.ts = Func.format(ts,VciDateUtil.DateTimeMillFormat);
            statePoolList.add(statePool);
        }
        boolean res = platformClientUtil.getStatePoolService().deleteStatePools(statePoolList.toArray(new StatePool[statePoolList.size()]));
        //clearCache();
        self.selectAllStatusMap();
        return res;
    }
    /**
@@ -318,16 +379,182 @@
        statePool.oid = statusDTO.getOid();
        statePool.id = "";
        statePool.name = statusDTO.getId();
        //statePool.imagePath = statusDTO.getImagePath();
        statePool.description = statusDTO.getDescription()==null?"":statusDTO.getDescription();
        String userId = VciBaseUtil.getCurrentUserId();
        String userId = WebThreadLocalUtil.getCurrentUserSessionInfoInThread().getUserId();
        long now = VciDateUtil.getNowTime();
        statePool.creator = userId;
        statePool.creator = Func.isBlank(statusDTO.getCreator()) ? userId:statusDTO.getCreator();
        statePool.createTime = now;
        statePool.modifier = userId;
        statePool.modifyTime = now;
        statePool.ts = statusDTO.getTs()==null?VciDateUtil.getNowString(VciDateUtil.DateTimeMillFormat):VciDateUtil.date2Str(statusDTO.getTs(),VciDateUtil.DateTimeMillFormat);
        statePool.tag = statusDTO.getName();
        return statePool;
    }
    /**
     * 导出选中的状态
     * @param exportFileName 导出的文件名
     * @param statusOids 需要导出的属性名称
     * @return
     */
    @Override
    public String exportStatus(String exportFileName, String statusOids,boolean flag/*控制导出的列名是否和导入模板一致*/) throws PLException {
        if(Func.isBlank(statusOids)){
            throw new PLException("500",new String[]{"请勾选要导出的属性!"});
        }
        //界面没传名称,使用默认导出名称
        exportFileName = Func.isBlank(exportFileName) ?  "状态池状态导出_" + Func.format(new Date(),"yyyy-MM-dd HHmmss.sss"):exportFileName;
        //设置列名
        List<String> columns = this.getCloumns(flag);
        //写excel
        String excelPath = LocalFileUtil.getDefaultTempFolder() + File.separator + exportFileName +  ".xls";
        try {
            new File(excelPath).createNewFile();
        } catch (Throwable e) {
            throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[]{excelPath}, e);
        }
        //设置列
        List<WriteExcelData> excelDataList = new ArrayList<>();
        //设置列头
        for (int index = 0; index < columns.size(); index++) {
            excelDataList.add(new WriteExcelData(0,index, columns.get(index)));
        }
        //按照属性名查询属性,然后处理属性导出
        List<String> statusOidList = Func.toStrList(statusOids);
        AtomicInteger i = new AtomicInteger(1);
        statusOidList.stream().forEach(oid->{
            OsStatusVO osStatusVO = this.getObjectByOid(oid);
            excelDataList.add(new WriteExcelData(i.get(),0, osStatusVO.getId()));
            excelDataList.add(new WriteExcelData(i.get(),1, osStatusVO.getName()));
            //excelDataList.add(new WriteExcelData(i.get(),2, osStatusVO.getImagePath()));
            excelDataList.add(new WriteExcelData(i.get(),3, osStatusVO.getDescription()));
            i.getAndIncrement();
        });
        WriteExcelOption excelOption = new WriteExcelOption(excelDataList);
        ExcelUtil.writeDataToFile(excelPath, excelOption);
        return excelPath;
    }
    /**
     * 下载状态导入模板
     * @param exportFileName
     * @return
     * @throws PLException
     */
    @Override
    public String downloadStatusTemplate(String exportFileName) throws Exception {
        //界面没传名称,使用默认导出名称
        exportFileName = Func.isBlank(exportFileName) ?  "状态池导入模板_" + Func.format(new Date(),"yyyy-MM-dd HHmmss.sss"):exportFileName;
        //设置列名
        List<String> columns = this.getCloumns(true);
        //设置必填列
        ColumnNameisRed.clear();
        ColumnNameisRed.add(0);
        //写excel
        String excelPath = LocalFileUtil.getDefaultTempFolder() + File.separator + exportFileName +  ".xls";
        try {
            new File(excelPath).createNewFile();
        } catch (Throwable e) {
            throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[]{excelPath}, e);
        }
        //设置列
        List<WriteExcelData> excelDataList = new ArrayList<>();
        //设置列头
        for (int index = 0; index < columns.size(); index++) {
            //判断是否为必填列,给必填列设置颜色
            if(ColumnNameisRed.contains(index)){
                WriteExcelData excelData = new WriteExcelData(0, index, columns.get(index));
                excelData.setFontColor(String.valueOf(HSSFColor.HSSFColorPredefined.RED.getIndex()));
                excelDataList.add(excelData);
            }else{
                excelDataList.add(new WriteExcelData(0,index, columns.get(index)));
            }
        }
        WriteExcelOption excelOption = new WriteExcelOption(excelDataList);
        ExcelUtil.writeDataToFile(excelPath, excelOption);
        return excelPath;
    }
    /**
     * 获取导出或导入模板的列名
     * @param flag 是否获取导入模板列名
     * @return
     */
    private List<String> getCloumns(boolean flag){
        if(flag){
            return new ArrayList<>(
                    Arrays.asList("名称(不能为空)", "标签(对名称的解释)"/*,"图片(路径)"*/, "描述(可以为空)")
            );
        }
        return new ArrayList<>(Arrays.asList("名称", "标签"/*, "图片"*/, "描述"));
    }
    /**
     * 导入状态
     * @param file
     * @return
     */
    @Override
    public BaseResult importStatus(File file) throws Exception {
        VciBaseUtil.alertNotNull(file,"excel文件");
        if(!file.exists()){
            throw new VciBaseException("导入的excel文件不存在,{0}",new String[]{file.getPath()});
        }
        try{
            //1、读取excel中的数据,组成对象
            ReadExcelOption excelOption = new ReadExcelOption();
            List<OsStatusPO> poList = ExcelUtil.readDataObjectFromExcel(file, OsStatusPO.class,excelOption,(value, po, fieldName)->{});
            //去除都是空的情况
            if(CollectionUtils.isEmpty(poList)){
                return BaseResult.fail(ExcelLangCodeConstant.IMPORT_CONTENT_NULL,new String[]{});
            }
            //excel判重,数据校验,dto对象转换,存储对象转换,执行保存
            List<StatePool> statePoolList = new ArrayList<>();
            //当前excel中是否重复用的判重Map:(key:判重属性,value:行号)
            Map<String, String> excelReapeat = new HashMap<>();
            poList.stream().forEach(osStatusPO -> {
                try {
                    StatePool dbStatePool = platformClientUtil.getStatePoolService().getStatePool(osStatusPO.getId());
                    if(Func.isNotEmpty(dbStatePool) && Func.isNotBlank(dbStatePool.oid)){
                        throw new VciBaseException("第【"+osStatusPO.getRowIndex()+"】行,名称在系统中已经存在,请修改!");
                    }
                } catch (PLException e) {
                    e.printStackTrace();
                    logger.error(e.getMessage());
                    throw new VciBaseException(VciBaseUtil.getExceptionMessage(e));
                }
                if(Func.isBlank(osStatusPO.getId())){//状态名判空
                    throw new VciBaseException("第【"+osStatusPO.getRowIndex()+"】行,statusnameerror");
                }else if(!osStatusPO.getId().matches("[a-z A-Z]*")){
                    // 状态池名称只能为英文字母
                    throw new VciBaseException("名称只能为英文!");
                }else if(excelReapeat.containsKey(osStatusPO.getId())){//状态名表格中判重
                    throw new VciBaseException("第【"+excelReapeat.get(osStatusPO.getId())+"】行和第【"+osStatusPO.getRowIndex()+"】行数据,名称重复");
                }
                //状态名excel中判重处理
                excelReapeat.put(osStatusPO.getId(),osStatusPO.getRowIndex());
                OsStatusDTO osStatusDTO = new OsStatusDTO();
                osStatusDTO.setOid(VciBaseUtil.getPk().toUpperCase(Locale.ROOT));
                osStatusDTO.setId(osStatusPO.getId());
                osStatusDTO.setName(osStatusPO.getName());
                //osStatusDTO.setImagePath(osStatusPO.getImagePath());
                osStatusDTO.setDescription(osStatusPO.getDescription());
                statePoolList.add(statusDTO2DO(osStatusDTO));
            });
            //执行保存操作
            batchAddStatus(statePoolList);
        }catch (Exception e){
            if(logger.isErrorEnabled()){
                logger.error("读取excel内容时或保存用户信息时出现了错误,具体原因:",VciBaseUtil.getExceptionMessage(e));
            }
            e.printStackTrace();
            return BaseResult.fail(VciBaseUtil.getExceptionMessage(e),new String[]{},e);
        }
        return BaseResult.success("状态导入成功!");
    }
    /**
@@ -351,7 +578,5 @@
        statePool.tag = statusVO.getName();
        return statePool;
    }
}