package com.estate.expert.admin.service.impl; import com.estate.expert.admin.domain.common.IDtoBase; import com.estate.expert.admin.domain.standard.expert.Expert; import com.estate.expert.admin.domain.standard.expert.matrix.CompareMatrix; import com.estate.expert.admin.domain.standard.expert.matrix.MembershipMatrix; import com.estate.expert.admin.domain.standard.expert.matrix.MembershipMatrixRowDto; import com.estate.expert.admin.domain.standard.expert.matrix.WeightMatrixRow; import com.estate.expert.admin.domain.standard.hierachy.HierarchyData; import com.estate.expert.admin.domain.user.User; import com.estate.expert.admin.enums.BizResultCode; import com.estate.expert.admin.io.processor.impl.matrix.CompareMatrixProcessor; import com.estate.expert.admin.io.processor.impl.matrix.MembershipMatrixProcessor; import com.estate.expert.admin.service.common.CrudServiceBaseImpl; import com.estate.expert.admin.service.expert.ExpertService; import com.estate.expert.admin.utils.Tuple; import com.estate.expert.admin.utils.tree.TreeNode; import com.estate.expert.admin.utils.tree.TreeRoot; import com.estate.expert.admin.utils.tree.helper.TreeHelper; import org.springframework.core.io.ClassPathResource; import org.springframework.util.CollectionUtils; import javax.lang.model.type.NullType; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.TreeMap; /** * 专家服务实现 */ public abstract class ExpertServiceImpl extends CrudServiceBaseImpl implements ExpertService { @Override public void editWeightMap(Integer expertId, String hierarchyPath, Float weight) { var expert = get(expertId); BizResultCode.BIZ_EXPERT_NOT_EXIST.check(expert == null); if(expert.getWeightMap() == null) expert.setWeightMap(new TreeMap<>()); expert.getWeightMap().put(hierarchyPath, weight); save(expert); } @Override public void editWeightMatrixRow(Integer expertId, WeightMatrixRow row) { var expert = get(expertId); BizResultCode.BIZ_EXPERT_NOT_EXIST.check(expert == null); if(expert.getWeightMap() == null) expert.setWeightMap(new TreeMap<>()); expert.getWeightMap().put(row.getHierarchyPath(), row.getWeight()); save(expert); } @Override public void editWeightMatrixRows(Integer expertId, List rows) { var expert = get(expertId); BizResultCode.BIZ_EXPERT_NOT_EXIST.check(expert == null); if(expert.getWeightMap() == null) expert.setWeightMap(new TreeMap<>()); rows.forEach(row -> expert.getWeightMap().put(row.getHierarchyPath(), row.getWeight())); save(expert); } @Override public Map> weightMap(Integer expertId, String hierarchyPath) { var res = new TreeMap>(); var expert = get(expertId); BizResultCode.BIZ_EXPERT_NOT_EXIST.check(expert == null); var hierarchyTree = getHierarchyTree(expertId); var weightMap = expert.getWeightMap(); var node = hierarchyTree.get(hierarchyPath); BizResultCode.HIERARCHY_NODE_NOT_FOUND.check(node == null); node.getChildren().forEach((key, value) -> { Float weight = value.getData().getWeight(); if(weightMap != null && weightMap.containsKey(value.getPath())) { weight = weightMap.get(value.getPath()); } res.put(value.getPath(), new Tuple<>(value.getName(), weight)); }); return res; } @Override public List weightMatrix(Integer expertId, String hierarchyPath) { var expert = get(expertId); BizResultCode.BIZ_EXPERT_NOT_EXIST.check(expert == null); var weightMatrix = new ArrayList(); var hierarchyTree = getHierarchyTree(expertId); var weightMap = expert.getWeightMap(); var node = hierarchyTree.get(hierarchyPath); BizResultCode.HIERARCHY_NODE_NOT_FOUND.check(node == null); node.getChildren().forEach((key, value) -> { Float weight = value.getData().getWeight(); if(weightMap != null && weightMap.containsKey(value.getPath())) { weight = weightMap.get(value.getPath()); } weightMatrix.add(WeightMatrixRow.builder() .name(value.getName()) .hierarchyPath(value.getPath()) .weight(weight) .build()); }); return weightMatrix; } @Override public MembershipMatrix getMembershipMatrix(Integer expertId) { var expert = get(expertId); BizResultCode.BIZ_EXPERT_NOT_EXIST.check(expert == null); return expert.getMembershipMatrix(); } @Override public void editMembershipMatrix(Integer expertId, float[][][][][] data) { MembershipMatrixProcessor.validate(data); var expert = get(expertId); BizResultCode.BIZ_EXPERT_NOT_EXIST.check(expert == null); var oldMatrix = expert.getMembershipMatrix(); if(oldMatrix != null) oldMatrix.setData(data); else expert.setMembershipMatrix(new MembershipMatrix(null, data)); save(expert); } @Override public void editMembershipMatrixRow(Integer expertId, MembershipMatrixRowDto row) { MembershipMatrixProcessor.validateRow(row); var expert = get(expertId); BizResultCode.BIZ_EXPERT_NOT_EXIST.check(expert == null); var matrix = expert.getMembershipMatrix(); BizResultCode.MEMBERSHIP_MATRIX_NOT_EXIST.check(matrix == null); var data = matrix.getData(); data[row.getP1()][row.getP2()][row.getP3()][row.getP4()] = new float[]{row.getV0(), row.getV1(), row.getV2(), row.getV3(), row.getV4()}; save(expert); } @Override public List listMembershipMatrixRows(Integer expertId, Integer p1, Integer p2, Integer p3, Integer p4) { var matrix = getMembershipMatrix(expertId); return matrix.listRows(p1, p2, p3, p4); } @Override public void importMembershipMatrix(Integer expertId, InputStream inputStream) { MembershipMatrix matrix = null; try { matrix = new MembershipMatrixProcessor().loadFromWorkbook(inputStream); editMembershipMatrix(expertId, matrix.getData()); } catch (IOException e) { e.printStackTrace(); BizResultCode.MEMBERSHIP_MATRIX_LOAD_ERROR.check(true); } BizResultCode.MEMBERSHIP_MATRIX_LOAD_ERROR.check(matrix == null); } @Override public CompareMatrix getFuzzyMatrix(Integer expertId, String hierarchyPath) { var hierarchyTree = getHierarchyTree(expertId); var node = hierarchyTree.get(hierarchyPath); BizResultCode.HIERARCHY_NODE_NOT_FOUND.check(node == null); var children = node.getChildren(); BizResultCode.COMPARE_MATRIX_EMPTY.check(children == null || children.isEmpty()); var indexCols = children.values().stream().map(TreeNode::getName).toArray(String[]::new); return getFuzzyMatrix(expertId, hierarchyPath, indexCols); } @Override public CompareMatrix getFuzzyMatrix(Integer expertId, String hierarchyPath, String[] indexCols) { var expert = get(expertId); BizResultCode.BIZ_EXPERT_NOT_EXIST.check(expert == null); BizResultCode.INDEX_COLS_EMPTY.check(indexCols == null || indexCols.length == 0); if(expert.getCompareMatrixMap() == null) return new CompareMatrix(indexCols); var compareMatrix = expert.getCompareMatrixMap().get(hierarchyPath); if(compareMatrix == null) return new CompareMatrix(indexCols); return compareMatrix.subMatrix(indexCols); } @Override public void editFuzzyMatrix(Integer expertId, String hierarchyPath, CompareMatrix matrix) { // 校验矩阵 CompareMatrixProcessor.validate(matrix); var expert = get(expertId); BizResultCode.BIZ_EXPERT_NOT_EXIST.check(expert == null); var compareMatrixMap = expert.getCompareMatrixMap(); if(compareMatrixMap == null) { compareMatrixMap = new TreeMap<>(); expert.setCompareMatrixMap(compareMatrixMap); } compareMatrixMap.put(hierarchyPath, matrix); save(expert); } @Override public TreeNode getNullModelTree(Integer expertId) { var expert = get(expertId); BizResultCode.BIZ_EXPERT_NOT_EXIST.check(expert == null); var modelTree = getModelTree(expert.getModel()); return TreeHelper. convertTree(modelTree.root(), (node, newNode) -> null); } // public abstract TreeRoot getModelTree(Model model); @Override public TreeRoot getHierarchyTree(Integer expertId) { var expert = get(expertId); BizResultCode.BIZ_EXPERT_NOT_EXIST.check(expert == null); // 首先获得模型中的树结构 var modelTree = getModelTree(expert.getModel()); var scoreMatrix = expert.getWeightMap(); // 然后根据专家的评分表,更新树的评分 if(scoreMatrix != null) { TreeHelper.travel(modelTree.root(), (node) -> { var score = scoreMatrix.get(node.getPath()); if (score != null) { node.getData().setScore(score); } }); } return modelTree; } ////// 初始化专家 ////// @Override public T add(User creator, T entity) { BizResultCode.EXPERT_FUNCTIONS_MUST_ENABLE.check(CollectionUtils.isEmpty(entity.getExpertFuncs())); BizResultCode.EXPERT_MODEL_NOT_EXIST.check(entity.getModel() == null || !existModel(entity.getModel().getId())); if(entity.getMembershipMatrix() == null) entity.setMembershipMatrix(loadDefaultMembershipMatrix()); return super.add(creator, entity); } @Override public T edit(T entity) { BizResultCode.EXPERT_FUNCTIONS_MUST_ENABLE.check(CollectionUtils.isEmpty(entity.getExpertFuncs())); return super.edit(entity); } private MembershipMatrix loadDefaultMembershipMatrix() { try { var res = new ClassPathResource("data/membership_matrix.xlsx"); return new MembershipMatrixProcessor().loadFromWorkbook(res.getInputStream()); } catch (IOException e) { throw new RuntimeException(e); } } protected abstract boolean existModel(Integer modelId); }