ParsingStructThread.java 13 KB
package com.gx.obe.struct.thread;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import org.dom4j.Element;

import com.gx.obe.common.file.utils.BidFileUtils;
import com.gx.obe.common.widget.listener.ProgressMessageAdapter;
import com.gx.obe.common.widget.listener.ProgressMessageListener;
import com.gx.obe.components.core.Constants;
import com.gx.obe.components.core.enumeration.CommonEnum;
import com.gx.obe.struct.beans.ModelData;
import com.gx.obe.struct.beans.StructDateInfo;
import com.gx.obe.struct.enums.DataCategoryEnum;
import com.gx.obe.struct.enums.ModelDataClassEnum;
import com.gx.obe.struct.enums.ModelDataTypeEnum;
import com.gx.obe.struct.handler.RelChapterTypeHandler;
import com.gx.obe.struct.service.EvaluationContentService;
import com.gx.obe.struct.utils.ParsingStructXmlUtils;
import com.gx.obe.util.utils.UuidUtils;
import com.gx.obe.web.entity.Supplier;
import com.gx.obe.web.entity.evaluation.EvaluationContent;
import com.gx.obe.web.entity.tender.TenderProjectEntity;
import com.gx.obe.web.service.SupplierService;

/**
 * @Description: 解析结构化数据线程
 * @author chenxw
 */
public class ParsingStructThread implements Runnable {
	
	private final EvaluationContentService evaluationContentService = new EvaluationContentService();
	private final SupplierService supplierService = new SupplierService();
	private final StructDateInfo structDateInfo = new StructDateInfo();
	private String tenderId;
	private TenderProjectEntity tenderproject;
	private ProgressMessageListener messageProgress;
	/**
	 * @author chenxw
	 * @param tenderproject.getId()
	 * @param callBack
	 */
	public ParsingStructThread(TenderProjectEntity tenderproject, ProgressMessageListener messageProgress) {
		this.tenderproject = tenderproject;
		this.messageProgress = messageProgress;
	}
	
	@Override
	public void run() {
		this.tenderId = tenderproject.getId();
		parsingStruct();
		messageProgress.finish(messageProgress.getErrorMessagesSize() == 0);
	}
	
	/**
	 * @Description: 解析结构化数据
	 * @author chenxw 
	 */
	private void parsingStruct() {
		//--------------------------------获取供应商列表--------------------------------------------------
		
		messageProgress.message("开始获取获取供应商列表...", 0);
		Optional<List<Supplier>> supplierListQptional = Optional.ofNullable(supplierService.getOpenBidSuccessSupplier(tenderId)).filter(t -> !t.isEmpty());
		if (!supplierListQptional.isPresent()) {
			messageProgress.message("供应商列表获取失败!", -1);
			return;
		}
		messageProgress.message("供应商列表获取成功!", 1);
		
		//--------------------------------解析供应商评议表数据--------------------------------------------------
		
		ParsingSupplierSelfOpinionThread parsingSupplierSelfOpinionThread = new ParsingSupplierSelfOpinionThread(tenderproject, supplierListQptional.get(),new ProgressMessageAdapter () {
			@Override
			public void message(String message, int flag) {
				messageProgress.message(message, flag);
			}

			@Override
			public void finish(boolean flag) {
			}
		}) ;
		parsingSupplierSelfOpinionThread.start();
		parsingSupplierSelfOpinionThread.join();
		
		//--------------------------------解析供应商标书定位数据--------------------------------------------------
//		String isIntelligentScore = tenderproject.getEvaluationParamByKey("isIntelligentScore");
//		if(null != isIntelligentScore && CommonEnum.YES.equals(isIntelligentScore)) {		
//		}
		ParsingSupplierRespItemThread parsingSupplierRespItemThread = new ParsingSupplierRespItemThread(tenderproject, supplierListQptional.get(),new ProgressMessageAdapter () {
			@Override
			public void message(String message, int flag) {
				messageProgress.message(message, flag);
			}
			
			@Override
			public void finish(boolean flag) {
			}
		}) ;
		parsingSupplierRespItemThread.start();
		parsingSupplierRespItemThread.join();

		//--------------------------------获取评审内容列表--------------------------------------------------
		
//		messageProgress.message("开始获取评审内容...", 0);
		Optional<Map<String, Set<String>>> relChapterTypeListMapOptional = Optional.ofNullable(evaluationContentService.getEvaluationContentList(tenderId)).filter(t -> !t.isEmpty()).map(l -> {
			return l.stream().collect(Collectors.groupingBy(EvaluationContent::getDataCategory, Collectors.mapping(EvaluationContent::getRelChapterType, Collectors.toSet())));
		});
		
		Consumer<Set<String>> consumer = t -> {
			t.add("CompletedAchievements");
			t.add("OngoingAchievements");
		};
		relChapterTypeListMapOptional.map(t -> t.get(DataCategoryEnum.TDI.getKey())).ifPresent(consumer);
		relChapterTypeListMapOptional.map(t -> t.get(DataCategoryEnum.TT.getKey())).ifPresent(consumer);
		if (!relChapterTypeListMapOptional.isPresent()) {
//			messageProgress.message("未获取到已绑定指标结构化内容!", -1);
			return;
		}
//		messageCallBack.callBackMsg("开始获取评审内容!");
//		messageCallBack.callBackMsg(true, "获取评审内容成功!");
		
		//--------------------------------解析投标结构化数据--------------------------------------------------
		
		messageProgress.message("开始解析结构化标书结构...", 0);
		try {
			relChapterTypeListMapOptional.map(m -> m.get(DataCategoryEnum.TT.getKey())).map(Set::parallelStream).ifPresent(s -> {
				s.forEach(t -> {
					ParsingStructXmlUtils.resolverTemplateTable(tenderId, t).ifPresent(structDateInfo.getTemplateTableList()::addAll);
				});
			});
		} catch (Exception e) {
			messageProgress.message("解析招标结构化数据失败,请检查是否下载招标文件!", -1);
//			System.out.println(e.getMessage());
			return;
		}
		messageProgress.message("结构化标书结构解析成功!", 1);
		
		//--------------------------------解析投标结构化数据--------------------------------------------------
		
		messageProgress.message("开始解析投标结构化数据!", 1);
		try {
//			supplierListQptional.get().parallelStream().forEach(t -> parsingSupplierBidFileStruct(t, relChapterTypeListMapOptional.get(), Constants.getBidFilePath(tenderId, t.getId())));
			supplierListQptional.get().stream().forEach(t -> {
				messageProgress.message("正在解析[" + t.getSupplierName() +"]结构化数据...", 0);
				parsingSupplierBidFileStruct(t, relChapterTypeListMapOptional.get(), Constants.getBidFilePath(tenderId, t.getId()));
			});
		} catch (Exception e) {
			messageProgress.message("解析投标结构化数据失败!", -1);
//			System.out.println(e.getStackTrace());
			return;
		}
		messageProgress.message("解析投标结构化数据成功!", 1);
		
		//--------------------------------保存结构化数据--------------------------------------------------
		
		messageProgress.message("开始保存结构化数据!", 0);
		if (!evaluationContentService.deleteOrSaveStructDateInfo(tenderId, structDateInfo)) {
			messageProgress.message("保存结构化数据失败!", -1);
			return;
		}
		messageProgress.message("保存结构化数据成功!", 1);
		
		//--------------------------------end--------------------------------------------------
		
		messageProgress.message( "解析结构化数据结束!", 0);
		messageProgress.message("---------------------------------", 0);
	}
	
	/**
	 * @Description: 解析对应供应商结构化数据
	 * @author chenxw
	 * @param supplier
	 * @param relChapterTypeSetMap
	 * @param bidFilePath
	 */
	private void parsingSupplierBidFileStruct(Supplier supplier, Map<String, Set<String>> relChapterTypeSetMap, String bidFilePath) {
		//获取BidFileIndexTree.xml中fileItem列表
//		System.out.println(supplier.getSupplierName());
//		System.out.println(relChapterTypeSetMap);
		ParsingStructXmlUtils.resolverBidFileIndexTree(bidFilePath).filter(t -> !t.isEmpty()).ifPresent(el -> {
			//解析小范本表单数据
			Optional.ofNullable(relChapterTypeSetMap.get(DataCategoryEnum.TDI.getKey())).ifPresent(l -> structDateInfo.getTemplateDataItemList().addAll(l.stream().map(t -> {
//				System.out.println("resolverObeTemplateDataItem");
				return ParsingStructXmlUtils.resolverObeTemplateDataItem(tenderId, supplier.getId(), t, el, bidFilePath);
			}).filter(Optional::isPresent).map(Optional::get).flatMap(List::stream).collect(Collectors.toList())));
			//解析小范本表格数据
			Optional.ofNullable(relChapterTypeSetMap.get(DataCategoryEnum.TT.getKey())).ifPresent(l -> structDateInfo.getTemplateTableList().addAll(l.stream().map(t -> {
//				System.out.println(bidFilePath);
				return ParsingStructXmlUtils.resolverTemplateTable(tenderId, supplier.getId(), t, el, bidFilePath);
			}).filter(Optional::isPresent).map(Optional::get).flatMap(List::stream).collect(Collectors.toList())));
			//解析对象结构化数据
			Optional.ofNullable(relChapterTypeSetMap.get(DataCategoryEnum.MD.getKey())).ifPresent(l -> l.stream().forEach(t -> parsingModelData(t, supplier, el, bidFilePath)));
		});
	}
	
	/**
	 * @Description: 解析对应评审内容结构化数据
	 * @author chenxw
	 * @param evaluationContent
	 * @param supplier
	 * @param fileItemElementList
	 * @param bidFilePath
	 */
	private void parsingModelData(String relChapterType, Supplier supplier, List<Element> fileItemElementList, String bidFilePath) {
		//获取结构化数据xml文件地址
		RelChapterTypeHandler handler = new RelChapterTypeHandler(relChapterType);
		Optional<ModelDataTypeEnum> modelDataTypeEnum = Optional.of(handler.getRelChapterType()).map(ModelDataTypeEnum.MAP::get);
		
		fileItemElementList.stream().filter(t -> {
			return handler.getRelChapterType().equals(t.elementTextTrim("chapterType"));
		}).findAny().map(this::getBidFileName).filter(Optional::isPresent).map(Optional::get).map(bidFilePath::concat).ifPresent(xmlFilePath -> {
		
			ModelData modelData = initModelData(supplier.getId(), modelDataTypeEnum.map(ModelDataTypeEnum.EQ_ProjectLeader::equals).orElse(false) ? handler.getRelChapterType() : relChapterType);
			structDateInfo.getModelDataList().add(modelData);
//			System.out.println(handler.getMark());
//			System.out.println(relChapterType);
			modelDataTypeEnum.map(ModelDataTypeEnum::getClassEnum).ifPresent(t -> parsingModelDataDetail(t, modelData.getId(), xmlFilePath, handler.getMark()));
		});
	}
	
	/**
	 * @Description: 获得投标文件文件名
	 * @author chenxw
	 * @param fileItem
	 * @param isEnc
	 * @return
	 */
	public Optional<String> getBidFileName(Element fileItemElement) {
		Optional<Element> fileItem = Optional.ofNullable(fileItemElement);
		return BidFileUtils.getBidFileName(fileItem.map(t -> {
			return t.elementText("fileName");
		}).orElse(null), fileItem.map(t -> {
			return t.elementText("fileId");
		}).orElse(null));
	}
	
	/**
	 * @Description: 解析对象结构化数据明细
	 * @author chenxw
	 * @param modelDataEnum
	 * @param modelDataId
	 * @param xmlFilePath
	 * @param string 
	 */
	private void parsingModelDataDetail(ModelDataClassEnum modelDataEnum, String modelDataId, String xmlFilePath, String mark) {
//		System.out.println("parsingModelDataDetail");
		Consumer<ParsingStructXmlUtils.AttachmentFileOperation> consumer = t -> ParsingStructXmlUtils.resolverAttachmentFile(t).ifPresent(structDateInfo.getAttachmentFileList()::addAll);
		switch (modelDataEnum) {
			case BusinessLicense:
//				System.out.println("BusinessLicense");
				ParsingStructXmlUtils.resolverBusinessLicense(tenderId, modelDataId, xmlFilePath, consumer).ifPresent(structDateInfo.getBusinessLicenseList()::addAll);
				break;
			case BidderInfo:
//				System.out.println("BidderInfo");
				ParsingStructXmlUtils.resolverBidderBasicInfo(tenderId, modelDataId, xmlFilePath, consumer).ifPresent(structDateInfo.getBidderBasicInfoList()::addAll);
				break;
			case Finance:
//				System.out.println("Finance");
				ParsingStructXmlUtils.resolverFinance(tenderId, modelDataId, xmlFilePath, consumer).ifPresent(structDateInfo.getFinanceList()::addAll);
				break;
			case Performance:
//				System.out.println("Performance");
				ParsingStructXmlUtils.resolverPerformance(tenderId, modelDataId, xmlFilePath, consumer, mark).ifPresent(structDateInfo.getPerformanceList()::addAll);
				break;
			case ProjectLeader:
//				System.out.println("ProjectLeader");
				ParsingStructXmlUtils.resolverProjectLeader(tenderId, modelDataId, xmlFilePath, consumer).ifPresent(structDateInfo.getProjectLeaderList()::addAll);
				break;
			case Qualification:
//				System.out.println("Qualification");
				ParsingStructXmlUtils.resolverQualification(tenderId, modelDataId, xmlFilePath, consumer).ifPresent(structDateInfo.getQualificationList()::addAll);
				break;
			default:
				break;
		}
	}
	
	/**
	 * @Description: 初始化对象结构化数据
	 * @author chenxw
	 * @param supplierId
	 * @param evaluationContent
	 * @return
	 */
	private ModelData initModelData(String supplierId, String relChapterType) {
//		System.out.println("initModelData");
		ModelData modelData = new ModelData();
		modelData.setId(UuidUtils.getUUID());
		modelData.setTenderId(tenderId);
		modelData.setSupplierId(supplierId);
		modelData.setRelChapterType(relChapterType);
		modelData.setDataCode(relChapterType);
		return modelData;
	}
	
}