1. 指标子集映射
This commit is contained in:
parent
e7974f15cb
commit
e0bc36ae0e
|
|
@ -1,39 +0,0 @@
|
||||||
package com.hshh.evaluation.bean;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 模板权重暂存数据.
|
|
||||||
*
|
|
||||||
* @author LiDongYU
|
|
||||||
* @since 2025/7/22
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class DraftWeightData {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 页面定义的临时key.
|
|
||||||
*/
|
|
||||||
private String key;
|
|
||||||
/**
|
|
||||||
* 父指标ID.
|
|
||||||
*/
|
|
||||||
private Integer parentIndicationId;
|
|
||||||
/**
|
|
||||||
* 模板ID.
|
|
||||||
*/
|
|
||||||
private Integer templateId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 表头map linkedMap. key是指标id,value是 {id,name}
|
|
||||||
*/
|
|
||||||
private Map<Integer, MetricTableHeaderBean> headerMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 页面中指标表的权重信息设置.key 为fromIndicatorId+"_"+toIndicatorId.
|
|
||||||
*/
|
|
||||||
private List<List<MetricMapperWeightBean>> weight;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
package com.hshh.evaluation.controller;
|
package com.hshh.evaluation.controller;
|
||||||
|
|
||||||
import com.hshh.evaluation.bean.DraftWeightData;
|
import com.hshh.evaluation.bean.DynamicTable;
|
||||||
import com.hshh.evaluation.bean.MetricMapperWeightBean;
|
import com.hshh.evaluation.bean.MetricMapperWeightBean;
|
||||||
import com.hshh.evaluation.entity.EvaluationTemplate;
|
import com.hshh.evaluation.bean.MetricTableHeaderBean;
|
||||||
import com.hshh.evaluation.entity.EvaluationTemplateWeight;
|
import com.hshh.evaluation.entity.EvaluationTemplateWeight;
|
||||||
import com.hshh.indicator.entity.Indicator;
|
import com.hshh.indicator.entity.Indicator;
|
||||||
|
import com.hshh.indicator.service.IndicatorService;
|
||||||
|
import com.hshh.indicator.service.impl.IndicatorServiceImpl;
|
||||||
import com.hshh.system.common.bean.BaseController;
|
import com.hshh.system.common.bean.BaseController;
|
||||||
import com.hshh.system.common.util.DraftStore;
|
import com.hshh.system.common.bean.SpringContextHolder;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -41,84 +43,100 @@ public class AssistantTemplateController extends BaseController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 组装历史权重数据.
|
* 把数据库中的明细数据转化为页面约定的数据类型.
|
||||||
*
|
*
|
||||||
* @param evaluationTemplate 当前模板数据
|
* @param detailList 数据库数据
|
||||||
* @return 评估数据列表
|
* @return 页面约定的权重列表
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
protected List<MetricMapperWeightBean> convertEvaluationTemplateWeightList(
|
||||||
protected Map<Integer, DraftWeightData> unitWeightMap(
|
List<EvaluationTemplateWeight> detailList) {
|
||||||
EvaluationTemplate evaluationTemplate) {
|
List<MetricMapperWeightBean> list = new ArrayList<>();
|
||||||
|
detailList.forEach(detail -> {
|
||||||
// 获取缓存中的数据
|
MetricMapperWeightBean weightBean = new MetricMapperWeightBean();
|
||||||
Map<Integer, DraftWeightData> cacheData = DraftStore.get(evaluationTemplate.getDraftKey(),
|
weightBean.setRowNum(detail.getRowNum());
|
||||||
Map.class);
|
weightBean.setValue(detail.getWeight());
|
||||||
if (cacheData == null) {
|
weightBean.setRowId(detail.getFromIndicatorId());
|
||||||
if (evaluationTemplate.getCurrentPagePartData() != null) {
|
weightBean.setColId(detail.getToIndicatorId());
|
||||||
|
weightBean.setParentId(detail.getIndicatorParentId());
|
||||||
Map<Integer, DraftWeightData> defaultMap = new LinkedHashMap<>();
|
list.add(weightBean);
|
||||||
DraftWeightData weightData = createDefaultDraftWeightData(evaluationTemplate);
|
});
|
||||||
defaultMap.put(weightData.getParentIndicationId(), weightData);
|
return list;
|
||||||
return defaultMap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//cacheData数据结构 父ID-->当前id下子指标的权重信息
|
|
||||||
//查看当前页面上传的最后一次指标权重信息;用当前页面的数据更新缓存或者增加缓存
|
|
||||||
if (evaluationTemplate.getCurrentPagePartData() != null) {
|
|
||||||
|
|
||||||
int parentId = evaluationTemplate.getCurrentPagePartData().get(0).get(0).getParentId();
|
|
||||||
cacheData.remove(parentId);
|
|
||||||
//构建一个简易的只包含实际当前表格中的数据的暂存对象类,供后面合并
|
|
||||||
DraftWeightData draftWeightData = createDefaultDraftWeightData(evaluationTemplate);
|
|
||||||
|
|
||||||
cacheData.put(parentId, draftWeightData);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cacheData;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DraftWeightData createDefaultDraftWeightData(EvaluationTemplate evaluationTemplate) {
|
|
||||||
int pid = evaluationTemplate.getCurrentPagePartData().get(0).get(0).getParentId();
|
|
||||||
DraftWeightData draftWeightData = new DraftWeightData();
|
|
||||||
draftWeightData.setTemplateId(evaluationTemplate.getId());
|
|
||||||
draftWeightData.setWeight(evaluationTemplate.getCurrentPagePartData());
|
|
||||||
draftWeightData.setParentIndicationId(pid);
|
|
||||||
draftWeightData.setKey(evaluationTemplate.getDraftKey());
|
|
||||||
return draftWeightData;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当一个指标下面只有一个孩子时,填充默认权重1.
|
* 创建表格头.
|
||||||
*
|
*
|
||||||
* @param lonelyChild 只有自己,没有其他节点和他同级
|
* @param children 子指标
|
||||||
* @param unitWeightDataMap 当前已经设置的权重信息.
|
* @return 表格头信息
|
||||||
*/
|
*/
|
||||||
|
protected Map<Integer, MetricTableHeaderBean> createTableHeaderMap(List<Indicator> children) {
|
||||||
|
List<MetricTableHeaderBean> headerBeans = new ArrayList<>();
|
||||||
|
children.forEach(a -> {
|
||||||
|
MetricTableHeaderBean bean = new MetricTableHeaderBean();
|
||||||
|
bean.setId(a.getId());
|
||||||
|
bean.setName(a.getName());
|
||||||
|
headerBeans.add(bean);
|
||||||
|
});
|
||||||
|
Map<Integer, MetricTableHeaderBean> headerMap = new LinkedHashMap<>();
|
||||||
|
headerBeans.forEach(header -> {
|
||||||
|
headerMap.put(header.getId(), header);
|
||||||
|
});
|
||||||
|
return headerMap;
|
||||||
|
}
|
||||||
|
|
||||||
protected void paddingDefaultValueWhenParentHasOnlyLonelyChild(List<Indicator> lonelyChild,
|
/**
|
||||||
Map<Integer, DraftWeightData> unitWeightDataMap) {
|
* 从数据库创建一个空的默认映射列表.
|
||||||
for (Indicator indicator : lonelyChild) {
|
*
|
||||||
if (!unitWeightDataMap.containsKey(indicator.getParentId())) {
|
* @param parentIndicatorId 父指标
|
||||||
List<List<MetricMapperWeightBean>> singleRowList = new ArrayList<>();
|
* @param children 子指标
|
||||||
List<MetricMapperWeightBean> list = new ArrayList<>();
|
* @param i 行号
|
||||||
|
* @return 默认映射列表
|
||||||
|
*/
|
||||||
|
protected List<MetricMapperWeightBean> createEmptyMapperList(Integer parentIndicatorId,
|
||||||
|
List<Indicator> children, int i) {
|
||||||
|
List<MetricMapperWeightBean> innerList = new ArrayList<>();
|
||||||
|
for (Indicator child : children) {
|
||||||
MetricMapperWeightBean weightBean = new MetricMapperWeightBean();
|
MetricMapperWeightBean weightBean = new MetricMapperWeightBean();
|
||||||
list.add(weightBean);
|
//行ID
|
||||||
singleRowList.add(list);
|
weightBean.setRowId(children.get(i).getId());
|
||||||
weightBean.setParentId(indicator.getParentId());
|
//列Id
|
||||||
weightBean.setValue("1");
|
weightBean.setColId(child.getId());
|
||||||
weightBean.setRowId(indicator.getId());
|
|
||||||
weightBean.setColId(indicator.getId());
|
//初始默认为1
|
||||||
weightBean.setRowNum(1);
|
weightBean.setValue("1")
|
||||||
DraftWeightData draftWeightData = new DraftWeightData();
|
|
||||||
draftWeightData.setParentIndicationId(indicator.getParentId());
|
|
||||||
draftWeightData.setWeight(singleRowList);
|
|
||||||
;
|
;
|
||||||
unitWeightDataMap.put(indicator.getParentId(), draftWeightData);
|
|
||||||
}
|
weightBean.setRowNum(i + 1);
|
||||||
|
weightBean.setParentId(parentIndicatorId);
|
||||||
|
innerList.add(weightBean);
|
||||||
}
|
}
|
||||||
|
return innerList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从数据库创建动态表.
|
||||||
|
*
|
||||||
|
* @param indicatePid 父节点指标
|
||||||
|
* @return 动态表
|
||||||
|
*/
|
||||||
|
protected DynamicTable createNewDynamicFromDatabase(Integer indicatePid) {
|
||||||
|
DynamicTable dynamicTable = new DynamicTable();
|
||||||
|
//查询当前指标的子指标
|
||||||
|
IndicatorService indicatorService = SpringContextHolder.getBean(IndicatorServiceImpl.class);
|
||||||
|
List<Indicator> children = indicatorService.queryChildren(indicatePid);
|
||||||
|
|
||||||
|
//设置头信息
|
||||||
|
dynamicTable.setHeaderMap(createTableHeaderMap(children));
|
||||||
|
|
||||||
|
//设置权重信息
|
||||||
|
List<List<MetricMapperWeightBean>> weight = new ArrayList<>();
|
||||||
|
for (int i = 0; i < children.size(); i++) {
|
||||||
|
List<MetricMapperWeightBean> innerList = createEmptyMapperList(indicatePid, children, i
|
||||||
|
);
|
||||||
|
weight.add(innerList);
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamicTable.setWeight(weight);
|
||||||
|
return dynamicTable;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package com.hshh.evaluation.controller;
|
package com.hshh.evaluation.controller;
|
||||||
|
|
||||||
import com.hshh.evaluation.bean.DraftWeightData;
|
|
||||||
import com.hshh.evaluation.bean.DynamicTable;
|
import com.hshh.evaluation.bean.DynamicTable;
|
||||||
import com.hshh.evaluation.bean.MetricComputeRequest;
|
import com.hshh.evaluation.bean.MetricComputeRequest;
|
||||||
import com.hshh.evaluation.bean.MetricComputerResponse;
|
import com.hshh.evaluation.bean.MetricComputerResponse;
|
||||||
|
|
@ -23,15 +22,12 @@ import com.hshh.system.common.bean.OperateResult;
|
||||||
import com.hshh.system.common.bean.PaginationBean;
|
import com.hshh.system.common.bean.PaginationBean;
|
||||||
import com.hshh.system.common.enums.ErrorCode;
|
import com.hshh.system.common.enums.ErrorCode;
|
||||||
import com.hshh.system.common.enums.ErrorMessage;
|
import com.hshh.system.common.enums.ErrorMessage;
|
||||||
import com.hshh.system.common.util.DraftStore;
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
@ -103,6 +99,7 @@ public class EvaluationTemplateController extends AssistantTemplateController {
|
||||||
return "project_template/list";
|
return "project_template/list";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导航到增加页面.
|
* 导航到增加页面.
|
||||||
*
|
*
|
||||||
|
|
@ -115,43 +112,6 @@ public class EvaluationTemplateController extends AssistantTemplateController {
|
||||||
return "project_template/add";
|
return "project_template/add";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取指标树.
|
|
||||||
*
|
|
||||||
* @param id 指标ID
|
|
||||||
* @return 指标树
|
|
||||||
*/
|
|
||||||
@GetMapping("/metricTree/{id}/{templateId}")
|
|
||||||
@ResponseBody
|
|
||||||
public OperateResult<List<JsTree>> metricTree(@PathVariable("id") Integer id,
|
|
||||||
@PathVariable("templateId") Integer templateId) {
|
|
||||||
if (id == null) {
|
|
||||||
return OperateResult.success(new ArrayList<>());
|
|
||||||
}
|
|
||||||
//查询指标权重树
|
|
||||||
Map<Integer, Double> weightMap = evaluationTemplateIndicatorWeightService.getEvaluationTemplateIndicatorWeightMap(
|
|
||||||
id, templateId);
|
|
||||||
Map<Integer, List<EvaluationTemplateWeight>> weightDetailMap = evaluationTemplateDetailWeightService.groupByParentIndicatorId(
|
|
||||||
id, templateId);
|
|
||||||
List<JsTree> jsTreeList = indicatorService.metricTree(id);
|
|
||||||
//开始给指标设置权重,指标名称后挂在权重信息;并在data属性中,增加子节点-子节点的权重信息
|
|
||||||
setWeightToTree(jsTreeList, weightMap, weightDetailMap);
|
|
||||||
return OperateResult.success(jsTreeList);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setWeightToTree(List<JsTree> jsTreeList, Map<Integer, Double> weightMap,
|
|
||||||
Map<Integer, List<EvaluationTemplateWeight>> weightDetailMap) {
|
|
||||||
jsTreeList.forEach(tree -> {
|
|
||||||
if (weightMap.containsKey((int) tree.getOriginalId())) {
|
|
||||||
tree.getData().put("weight", weightMap.get((int) tree.getOriginalId()));
|
|
||||||
|
|
||||||
}
|
|
||||||
if(weightDetailMap.containsKey((int) tree.getOriginalId())) {
|
|
||||||
tree.getData().put("weightDetail", weightDetailMap.get((int) tree.getOriginalId()));
|
|
||||||
}
|
|
||||||
setWeightToTree(tree.getChildren(), weightMap, weightDetailMap);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存模板. 必须设置指标;设置完成权重,才成成功提交
|
* 保存模板. 必须设置指标;设置完成权重,才成成功提交
|
||||||
|
|
@ -182,23 +142,17 @@ public class EvaluationTemplateController extends AssistantTemplateController {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//1.合并权重数据
|
// //1.合并权重数据
|
||||||
Map<Integer, DraftWeightData> unitWeightDataMap = unitWeightMap(evaluationTemplate);
|
// Map<Integer, DraftWeightData> unitWeightDataMap = unitWeightMap(evaluationTemplate);
|
||||||
|
//
|
||||||
|
// //2.填充数据;如果一个指标下面只有一个孩子,则默认填充为1
|
||||||
|
// List<Indicator> lonelyChild = indicatorService.queryLonelyChild(
|
||||||
|
// evaluationTemplate.getIndicatorTopId());
|
||||||
|
//
|
||||||
|
// paddingDefaultValueWhenParentHasOnlyLonelyChild(lonelyChild, unitWeightDataMap);
|
||||||
|
|
||||||
//2.填充数据;如果一个指标下面只有一个孩子,则默认填充为1
|
// //4. 提交
|
||||||
List<Indicator> lonelyChild = indicatorService.queryLonelyChild(
|
// evaluationTemplateService.saveWhole(evaluationTemplate, unitWeightDataMap);
|
||||||
evaluationTemplate.getIndicatorTopId());
|
|
||||||
|
|
||||||
paddingDefaultValueWhenParentHasOnlyLonelyChild(lonelyChild, unitWeightDataMap);
|
|
||||||
|
|
||||||
//3.开始验证完整性/一致性
|
|
||||||
String validateWholeMessage = validate(evaluationTemplate.getIndicatorTopId(),
|
|
||||||
unitWeightDataMap);
|
|
||||||
if (!validateWholeMessage.isEmpty()) {
|
|
||||||
return OperateResult.error(null, validateWholeMessage, ErrorCode.BUSINESS_ERROR.getCode());
|
|
||||||
}
|
|
||||||
//4. 提交
|
|
||||||
evaluationTemplateService.saveWhole(evaluationTemplate, unitWeightDataMap);
|
|
||||||
return OperateResult.success();
|
return OperateResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -238,7 +192,67 @@ public class EvaluationTemplateController extends AssistantTemplateController {
|
||||||
return OperateResult.success(template);
|
return OperateResult.success(template);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指标树.
|
||||||
|
*
|
||||||
|
* @param id 指标ID
|
||||||
|
* @return 指标树
|
||||||
|
*/
|
||||||
|
@GetMapping("/metricTree/{id}/{templateId}")
|
||||||
|
@ResponseBody
|
||||||
|
public OperateResult<List<JsTree>> metricTree(@PathVariable("id") Integer id,
|
||||||
|
@PathVariable("templateId") Integer templateId) {
|
||||||
|
if (id == null) {
|
||||||
|
return OperateResult.success(new ArrayList<>());
|
||||||
|
}
|
||||||
|
//查询指标权重树
|
||||||
|
Map<Integer, Double> weightMap = evaluationTemplateIndicatorWeightService.getEvaluationTemplateIndicatorWeightMap(
|
||||||
|
id, templateId);
|
||||||
|
Map<Integer, List<EvaluationTemplateWeight>> weightDetailMap = evaluationTemplateDetailWeightService.groupByParentIndicatorId(
|
||||||
|
id, templateId);
|
||||||
|
List<JsTree> jsTreeList = indicatorService.metricTree(id);
|
||||||
|
//开始给指标设置权重,指标名称后挂在权重信息;并在data属性中,增加子节点-子节点的权重信息
|
||||||
|
setWeightToTree(jsTreeList, weightMap, weightDetailMap);
|
||||||
|
return OperateResult.success(jsTreeList);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setWeightToTree(List<JsTree> jsTreeList, Map<Integer, Double> weightMap,
|
||||||
|
Map<Integer, List<EvaluationTemplateWeight>> weightDetailMap) {
|
||||||
|
if (jsTreeList == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
jsTreeList.forEach(tree -> {
|
||||||
|
if (weightMap.containsKey((int) tree.getOriginalId())) {
|
||||||
|
tree.getData().put("weight", weightMap.get((int) tree.getOriginalId()));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
tree.getData().put("weight", 1);
|
||||||
|
}
|
||||||
|
if (weightDetailMap.containsKey((int) tree.getOriginalId())) {
|
||||||
|
tree.getData().put("weightDetail",
|
||||||
|
convertEvaluationTemplateWeightList(weightDetailMap.get((int) tree.getOriginalId())));
|
||||||
|
}
|
||||||
|
setWeightToTree(tree.getChildren(), weightMap, weightDetailMap);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指标编辑/新增时的table表格.
|
||||||
|
*
|
||||||
|
* @param indicateId 指标ID
|
||||||
|
* @param model session容器
|
||||||
|
* @return table.html
|
||||||
|
*/
|
||||||
|
@GetMapping("/tablePage")
|
||||||
|
public String tablePage(Integer indicateId, Model model) {
|
||||||
|
model.addAttribute("data", createNewDynamicFromDatabase(indicateId));
|
||||||
|
model.addAttribute("indicateId", indicateId);
|
||||||
|
return "project_template/table";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算指标,当设置变化时触发.
|
* 计算指标,当设置变化时触发.
|
||||||
|
|
@ -272,91 +286,11 @@ public class EvaluationTemplateController extends AssistantTemplateController {
|
||||||
H.children.forEach(child -> {
|
H.children.forEach(child -> {
|
||||||
MetricComputerResponse response = new MetricComputerResponse();
|
MetricComputerResponse response = new MetricComputerResponse();
|
||||||
response.setId(child.name);
|
response.setId(child.name);
|
||||||
response.setWeight(String.format("%.2f", child.globalWeight));
|
response.setWeight(String.format("%.4f", child.globalWeight));
|
||||||
responseList.add(response);
|
responseList.add(response);
|
||||||
});
|
});
|
||||||
return OperateResult.success(responseList);
|
return OperateResult.success(responseList);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 验证指标权重完整性/一致性.
|
|
||||||
*
|
|
||||||
* @param indicatorTopId 指标顶级ID
|
|
||||||
* @param weightByParentIdMap 已经设置的权重Map
|
|
||||||
* @return 验证提示结果
|
|
||||||
*/
|
|
||||||
private String validate(Integer indicatorTopId,
|
|
||||||
Map<Integer, DraftWeightData> weightByParentIdMap) {
|
|
||||||
//所有topId=indicatorTopId列表
|
|
||||||
List<Indicator> list = indicatorService.queryByTopId(indicatorTopId);
|
|
||||||
// key=指标ID value=指标数据
|
|
||||||
Map<Integer, Indicator> indicatorMap = list.stream()
|
|
||||||
.collect(Collectors.toMap(Indicator::getId, a -> a));
|
|
||||||
Map<Integer, List<Indicator>> parentMap = list.stream().filter(a -> a.getParentId() != null)
|
|
||||||
.collect(Collectors.groupingBy(Indicator::getParentId));
|
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
parentMap.forEach((indicatorId, children) -> {
|
|
||||||
//完整性
|
|
||||||
if (!weightByParentIdMap.containsKey(indicatorId)) {
|
|
||||||
String indicatorName =
|
|
||||||
indicatorMap.get(indicatorId) == null ? "" : indicatorMap.get(indicatorId).getName();
|
|
||||||
sb.append(indicatorName).append("没有设置权重<br>\n");
|
|
||||||
}
|
|
||||||
if (weightByParentIdMap.get(indicatorId) != null) {
|
|
||||||
//一致性
|
|
||||||
List<List<MetricMapperWeightBean>> childWeightList = weightByParentIdMap.get(indicatorId)
|
|
||||||
.getWeight();
|
|
||||||
consistencyValidate(sb, childWeightList, indicatorMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 验证一致性. 假设有三个指标 A,B,C A--AA AB,AC |B--BB BA BC| C--CC CA CB.
|
|
||||||
*
|
|
||||||
* @param sb 提示消息
|
|
||||||
* @param childWeightList 要验证的数据
|
|
||||||
* @param indicatorMap 指标map key=id value=指标
|
|
||||||
*/
|
|
||||||
private void consistencyValidate(StringBuffer sb,
|
|
||||||
List<List<MetricMapperWeightBean>> childWeightList, Map<Integer, Indicator> indicatorMap) {
|
|
||||||
if (childWeightList != null && childWeightList.size() > 1) {
|
|
||||||
//获取第一行记录作为标准
|
|
||||||
List<MetricMapperWeightBean> firstRow = childWeightList.get(0);
|
|
||||||
//获取A指标ID
|
|
||||||
Integer firstFormIndicatorId = firstRow.get(0).getRowId();
|
|
||||||
//把第一行的数据,用rowId+"_+colId作为键,value为值
|
|
||||||
Map<String, Double> firstRowMap = new HashMap<>();
|
|
||||||
|
|
||||||
firstRow.forEach(child -> {
|
|
||||||
firstRowMap.put(child.getRowId() + "_" + child.getColId(),
|
|
||||||
Double.parseDouble(child.getValue()));
|
|
||||||
});
|
|
||||||
for (int i = 1; i < childWeightList.size(); i++) {
|
|
||||||
List<MetricMapperWeightBean> weightBeanList = childWeightList.get(i);
|
|
||||||
for (int j = 1; j < weightBeanList.size(); j++) {
|
|
||||||
//获取第一行她的from指标值 AB
|
|
||||||
Double abValue = firstRowMap.get(
|
|
||||||
firstFormIndicatorId + "_" + weightBeanList.get(j).getRowId());
|
|
||||||
//获取AC
|
|
||||||
Double acValue = firstRowMap.get(
|
|
||||||
firstFormIndicatorId + "_" + weightBeanList.get(j).getColId());
|
|
||||||
//获取BC
|
|
||||||
double bcValue = Double.parseDouble(weightBeanList.get(j).getValue());
|
|
||||||
if (bcValue > 1 && acValue.compareTo(abValue) > 0) {
|
|
||||||
sb.append(indicatorMap.get(weightBeanList.get(j).getRowId())).append("必须小于1")
|
|
||||||
.append("<br>\n");
|
|
||||||
}
|
|
||||||
if (bcValue < 1 && acValue.compareTo(abValue) < 0) {
|
|
||||||
sb.append(indicatorMap.get(weightBeanList.get(j).getRowId())).append("必须大于1")
|
|
||||||
.append("<br>\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ public class EvaluationTemplateIndicatorWeight implements Serializable {
|
||||||
|
|
||||||
private Integer indicatorId;
|
private Integer indicatorId;
|
||||||
|
|
||||||
private Double weight;
|
private String weight;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ public class EvaluationTemplateWeight implements Serializable {
|
||||||
/**
|
/**
|
||||||
* 权重.
|
* 权重.
|
||||||
*/
|
*/
|
||||||
private Double weight;
|
private String weight;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 父指标ID.
|
* 父指标ID.
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package com.hshh.evaluation.service;
|
package com.hshh.evaluation.service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.hshh.evaluation.bean.DraftWeightData;
|
|
||||||
import com.hshh.evaluation.entity.EvaluationTemplate;
|
import com.hshh.evaluation.entity.EvaluationTemplate;
|
||||||
import com.hshh.system.common.bean.PaginationBean;
|
import com.hshh.system.common.bean.PaginationBean;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package com.hshh.evaluation.service.impl;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.hshh.evaluation.bean.DraftWeightData;
|
|
||||||
import com.hshh.evaluation.entity.EvaluationTemplate;
|
import com.hshh.evaluation.entity.EvaluationTemplate;
|
||||||
import com.hshh.evaluation.entity.EvaluationTemplateWeight;
|
import com.hshh.evaluation.entity.EvaluationTemplateWeight;
|
||||||
import com.hshh.evaluation.mapper.EvaluationTemplateMapper;
|
import com.hshh.evaluation.mapper.EvaluationTemplateMapper;
|
||||||
|
|
|
||||||
|
|
@ -314,6 +314,7 @@
|
||||||
//获取选中的根节点
|
//获取选中的根节点
|
||||||
let id = $(
|
let id = $(
|
||||||
'input[name="radio_names"]:checked').val();
|
'input[name="radio_names"]:checked').val();
|
||||||
|
if(id){
|
||||||
let url = document.getElementById("_rootPath").value + "indicator/" + id;
|
let url = document.getElementById("_rootPath").value + "indicator/" + id;
|
||||||
let http = new HttpClient();
|
let http = new HttpClient();
|
||||||
http.get(url, function (error, res, xhr) {
|
http.get(url, function (error, res, xhr) {
|
||||||
|
|
@ -323,6 +324,8 @@
|
||||||
}, "indicatorForm")
|
}, "indicatorForm")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// 递归加 parent 属性
|
// 递归加 parent 属性
|
||||||
function setParentRefs(node, parent) {
|
function setParentRefs(node, parent) {
|
||||||
node.parent = parent;
|
node.parent = parent;
|
||||||
|
|
|
||||||
|
|
@ -147,30 +147,23 @@
|
||||||
obj.templateName = document.getElementById("templateForm")["templateName"].value;
|
obj.templateName = document.getElementById("templateForm")["templateName"].value;
|
||||||
obj.templateMemo = document.getElementById("templateForm")["templateMemo"].value;
|
obj.templateMemo = document.getElementById("templateForm")["templateMemo"].value;
|
||||||
obj.indicatorTopId = document.getElementById("templateForm")["indicatorTopId"].value;
|
obj.indicatorTopId = document.getElementById("templateForm")["indicatorTopId"].value;
|
||||||
obj.draftKey = document.getElementById("templateForm")["draftKey"].value;
|
const inst = $('#metric_tree').jstree(true);
|
||||||
let pageMapData = getRowsTableData();
|
|
||||||
|
|
||||||
if (pageMapData && pageMapData.length > 0) {
|
const flat = inst.get_json('#', { flat: true, no_data: false });
|
||||||
|
flat.forEach(n => {
|
||||||
|
console.log(`[id=${n.id}] parent=${n.parent} text="${n.text}"`, n.data || {});
|
||||||
|
});
|
||||||
|
|
||||||
obj.currentPagePartData = pageMapData;
|
|
||||||
}
|
|
||||||
let url = document.getElementById("_rootPath").value + "evaluation/evaluationTemplate/save";
|
|
||||||
let http = new HttpClient();
|
|
||||||
http.post(url, obj, function (error, res, xhr) {
|
|
||||||
closeDialog("modal-full-width");
|
|
||||||
document.getElementById("_evaluation_evaluationTemplate_").click();
|
|
||||||
|
|
||||||
}, "templateForm", null)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据指标ID获取指标树
|
// 根据指标ID获取指标树
|
||||||
function metricTree(id) {
|
function metricTree(id) {
|
||||||
let templateId = document.getElementById("templateForm")["id"].value;
|
let templateId = document.getElementById("templateForm")["id"].value;
|
||||||
if(!templateId||templateId===""){
|
if (!templateId || templateId === "") {
|
||||||
templateId="0"
|
templateId = "0"
|
||||||
}
|
}
|
||||||
const url = document.getElementById("_rootPath").value
|
const url = document.getElementById("_rootPath").value
|
||||||
+ "evaluation/evaluationTemplate/metricTree/" + id+"/" + templateId;
|
+ "evaluation/evaluationTemplate/metricTree/" + id + "/" + templateId;
|
||||||
const http = new HttpClient();
|
const http = new HttpClient();
|
||||||
|
|
||||||
http.get(url, function (error, res, xhr) {
|
http.get(url, function (error, res, xhr) {
|
||||||
|
|
@ -202,89 +195,32 @@
|
||||||
|
|
||||||
let id = data.node.id || "";
|
let id = data.node.id || "";
|
||||||
id = id.replace(/^tree_/, "");
|
id = id.replace(/^tree_/, "");
|
||||||
draftDataAddAndGetData(id);
|
getTablePage(id);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}, "templateForm");
|
}, "templateForm");
|
||||||
}
|
}
|
||||||
|
|
||||||
//暂存旧数据+获取表数据
|
|
||||||
function draftDataAddAndGetData(id) {
|
|
||||||
|
|
||||||
//首先判断是否存在历史表格.
|
|
||||||
let headerData = getTableHeadData();
|
|
||||||
|
|
||||||
if (!headerData || headerData.size === 0) {
|
|
||||||
|
|
||||||
//去数据
|
|
||||||
getTablePage(id);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
let obj = {};
|
|
||||||
obj.templateId = document.getElementById("templateForm")["id"].value;
|
|
||||||
obj.key = document.getElementById("templateForm")["draftKey"].value;
|
|
||||||
obj.headerMap = mapToObject(headerData);
|
|
||||||
|
|
||||||
obj.weight = getRowsTableData();
|
|
||||||
|
|
||||||
if (obj.weight.length > 0) {
|
|
||||||
|
|
||||||
//获取父ID
|
|
||||||
obj.parentIndicationId = obj.weight[0][0].parentId;
|
|
||||||
let url = document.getElementById("_rootPath").value
|
|
||||||
+ "evaluation/evaluationTemplate/receiveDraft";
|
|
||||||
let http = new HttpClient();
|
|
||||||
//暂存数据
|
|
||||||
http.post(url, obj, function (error, res, xhr) {
|
|
||||||
getTablePage(id);
|
|
||||||
|
|
||||||
}, null, null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//获取表头元素
|
|
||||||
function getTableHeadData() {
|
|
||||||
let tr = document.getElementById("dynamic_header_tr");
|
|
||||||
if (!tr) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
let thList = tr.querySelectorAll('th');
|
|
||||||
|
|
||||||
let map = new Map();
|
|
||||||
for (let i = 1; i < thList.length; i++) {
|
|
||||||
let th = thList[i];
|
|
||||||
|
|
||||||
let obj = {};
|
|
||||||
obj.id = parseInt(th.getAttribute('data-value'));
|
|
||||||
obj.name = th.getAttribute('data-name');
|
|
||||||
map.set(obj.id, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
//绘制表格
|
//绘制表格
|
||||||
function getTablePage(indicatorId) {
|
function getTablePage(indicatorId) {
|
||||||
const templateId = document.getElementById("templateForm")["id"].value;
|
|
||||||
const url = document.getElementById("_rootPath").value
|
const url = document.getElementById("_rootPath").value
|
||||||
+ "evaluation/evaluationTemplate/getDraftData";
|
+ "evaluation/evaluationTemplate/tablePage?indicateId=" + indicatorId;
|
||||||
let obj = {};
|
|
||||||
//页面key
|
|
||||||
obj.key = document.getElementById("templateForm")["draftKey"].value;
|
|
||||||
//父ID
|
|
||||||
obj.parentIndicationId = indicatorId;
|
|
||||||
//模板ID
|
|
||||||
obj.templateId = templateId;
|
|
||||||
|
|
||||||
let http = new HttpClient();
|
let http = new HttpClient();
|
||||||
http.post(url, obj, function (error, res, xhr) {
|
http.get(url, function (error, res, xhr) {
|
||||||
|
|
||||||
document.getElementById("table_area").innerHTML = res;
|
document.getElementById("table_area").innerHTML = res;
|
||||||
}, null, null)
|
//绘制当前选中的指标下的children值
|
||||||
|
const inst = $('#metric_tree').jstree(true);
|
||||||
|
|
||||||
|
const node =inst.get_selected(true)[0];
|
||||||
|
if(node.data.children){
|
||||||
|
console.log(node.data.children);
|
||||||
|
}
|
||||||
|
|
||||||
|
}, null)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -316,14 +252,18 @@
|
||||||
postObj.metric = metric;
|
postObj.metric = metric;
|
||||||
postObj.weightList = getRowsTableData();
|
postObj.weightList = getRowsTableData();
|
||||||
http.post(url, postObj, function (error, res, xhr) {
|
http.post(url, postObj, function (error, res, xhr) {
|
||||||
const $tree = $('#metric_tree');
|
const inst = $('#metric_tree').jstree(true);
|
||||||
|
const selected = inst.get_selected(); // 返回选中节点 id 数组
|
||||||
|
const selectTreeId = selected[0];
|
||||||
|
const parentNode = inst.get_node(selectTreeId);
|
||||||
|
parentNode.data.children = postObj.weightList;
|
||||||
res.result.forEach(element => {
|
res.result.forEach(element => {
|
||||||
let id = "tree_" + element.id;
|
let id = "tree_" + element.id;
|
||||||
let node = $tree.jstree(true).get_node(id, false);
|
let node = inst.get_node(id, false);
|
||||||
let name = node.text.replace(/\([^)]*\)/g, "");
|
let name = node.text.replace(/\([^)]*\)/g, "");
|
||||||
name = name + "(" + element.weight + ")";
|
name = name + "(" + element.weight + ")";
|
||||||
|
node.data.weight = element.weight;
|
||||||
$tree.jstree(true).rename_node(node, name);
|
inst.rename_node(node, name);
|
||||||
})
|
})
|
||||||
}, null, null)
|
}, null, null)
|
||||||
}
|
}
|
||||||
|
|
@ -416,4 +356,24 @@
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
//获取表头元素
|
||||||
|
function getTableHeadData() {
|
||||||
|
let tr = document.getElementById("dynamic_header_tr");
|
||||||
|
if (!tr) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
let thList = tr.querySelectorAll('th');
|
||||||
|
|
||||||
|
let map = new Map();
|
||||||
|
for (let i = 1; i < thList.length; i++) {
|
||||||
|
let th = thList[i];
|
||||||
|
|
||||||
|
let obj = {};
|
||||||
|
obj.id = parseInt(th.getAttribute('data-value'));
|
||||||
|
obj.name = th.getAttribute('data-name');
|
||||||
|
map.set(obj.id, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -7,31 +7,29 @@
|
||||||
<th th:each="item:${data.headerMap}" th:text="${item.value.name}" th:data-value="${item.value.id}" th:data-name="${item.value.name}"></th>
|
<th th:each="item:${data.headerMap}" th:text="${item.value.name}" th:data-value="${item.value.id}" th:data-name="${item.value.name}"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
|
|
||||||
<tbody class="autonum" id="dynamic_tbody_tr">
|
<tbody class="autonum" id="dynamic_tbody_tr">
|
||||||
<tr th:each="item,stat:${data.headerMap}">
|
<tr th:each="item,stat:${data.headerMap}">
|
||||||
<td th:text="${item.value.name}"></td>
|
<td th:text="${item.value.name}"></td>
|
||||||
<td th:each="listItem:${data.weight.get(stat.index)}">
|
<td th:each="listItem:${data.weight.get(stat.index)}">
|
||||||
<label>
|
<label>
|
||||||
<select onchange="mapperChange(this)" class="form-select" th:id="${listItem.rowId+'_'+listItem.colId}" name="mapper-select" th:data-pid="${listItem.parentId}" th:disabled="${listItem.rowId == listItem.colId}" >
|
<select onchange="mapperChange(this)" class="form-select" th:id="${listItem.rowId+'_'+listItem.colId}" name="mapper-select" th:data-pid="${listItem.parentId}" th:disabled="${listItem.rowId == listItem.colId}" >
|
||||||
<option value="1" th:selected="${listItem.value=='1'}">同样重要(1)</option>
|
<option value="1" >同样重要(1)</option>
|
||||||
<option value="2" th:selected="${listItem.value=='2'}">微小重要(2)</option>
|
<option value="2" >微小重要(2)</option>
|
||||||
<option value="3" th:selected="${listItem.value=='3'}">稍微重要(3)</option>
|
<option value="3" >稍微重要(3)</option>
|
||||||
<option value="4" th:selected="${listItem.value=='4'}">更为重要(4)</option>
|
<option value="4">更为重要(4)</option>
|
||||||
<option value="5" th:selected="${listItem.value=='5'}">明显重要(5)</option>
|
<option value="5" >明显重要(5)</option>
|
||||||
<option value="6" th:selected="${listItem.value=='6'}">十分重要(6)</option>
|
<option value="6">十分重要(6)</option>
|
||||||
<option value="7" th:selected="${listItem.value=='7'}">强烈重要(7)</option>
|
<option value="7" >强烈重要(7)</option>
|
||||||
<option value="8" th:selected="${listItem.value=='8'}">更强烈重要(8)</option>
|
<option value="8" >更强烈重要(8)</option>
|
||||||
<option value="9" th:selected="${listItem.value=='9'}">极端重要(9)</option>
|
<option value="9" >极端重要(9)</option>
|
||||||
<option value="0.5" th:selected="${listItem.value=='0.5'}">微小次要(0.5)</option>
|
<option value="0.5" >微小次要(0.5)</option>
|
||||||
<option value="0.3333" th:selected="${listItem.value=='0.3333'}">稍微次要(0.3333)</option>
|
<option value="0.3333" >稍微次要(0.3333)</option>
|
||||||
<option value="0.25" th:selected="${listItem.value=='0.25'}">更为次要(0.25)</option>
|
<option value="0.25" >更为次要(0.25)</option>
|
||||||
<option value="0.2" th:selected="${listItem.value=='0.2'}">明显次要(0.2)</option>
|
<option value="0.2" >明显次要(0.2)</option>
|
||||||
<option value="0.16667" th:selected="${listItem.value=='0.16667'}">十分次要(0.16667)</option>
|
<option value="0.16667" >十分次要(0.16667)</option>
|
||||||
<option value="0.14286" th:selected="${listItem.value=='0.14286'}">强烈次要(0.14286)</option>
|
<option value="0.14286" >强烈次要(0.14286)</option>
|
||||||
<option value="0.125" th:selected="${listItem.value=='0.125'}">更强烈次要(0.125)</option>
|
<option value="0.125" >更强烈次要(0.125)</option>
|
||||||
<option value="0.11111" th:selected="${listItem.value=='0.11111'}">极端次要(0.11111)</option>
|
<option value="0.11111" >极端次要(0.11111)</option>
|
||||||
</select>
|
</select>
|
||||||
<div class="invalid-feedback" th:id="${listItem.rowId+'_'+listItem.colId+'_error_tip'}" ></div>
|
<div class="invalid-feedback" th:id="${listItem.rowId+'_'+listItem.colId+'_error_tip'}" ></div>
|
||||||
</label>
|
</label>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user