Compare commits
4 Commits
e2d86ae384
...
92f28962ef
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
92f28962ef | ||
|
|
e0bc36ae0e | ||
|
|
e7974f15cb | ||
|
|
ba1a3bcae4 |
|
|
@ -1,14 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<component name="Encoding" defaultCharsetForPropertiesFiles="UTF-8">
|
||||
<file url="file://$PROJECT_DIR$/manager-admin/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/manager-admin/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/manager-common/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/manager-common/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/manager-system/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/manager-system/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/manager-z-generation/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/manager-z-generation/src/main/resources" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||
</component>
|
||||
|
|
|
|||
10
.idea/inspectionProfiles/Project_Default.xml
Normal file
10
.idea/inspectionProfiles/Project_Default.xml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||
<Languages>
|
||||
<language minSize="65" name="Java" />
|
||||
</Languages>
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
||||
|
|
@ -25,6 +25,11 @@
|
|||
<artifactId>system</artifactId>
|
||||
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
|
|
@ -34,6 +39,15 @@
|
|||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.11.0</version>
|
||||
<configuration>
|
||||
<source>11</source>
|
||||
<target>11</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
|
|
|
|||
|
|
@ -1,206 +1,140 @@
|
|||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<title>指标设置 Demo</title>
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8" />
|
||||
<title>替换雷达为横向条形图 · 最小示例</title>
|
||||
<style>
|
||||
body { font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial; background:#f8fafc; }
|
||||
.chart-card { width: 900px; margin: 40px auto; background: #f3f6fb; border-radius: 12px; padding: 24px; }
|
||||
.chart-title { margin: 0 0 8px; text-align: center; color:#0f172a; }
|
||||
.chart-container {
|
||||
position: relative;
|
||||
height: 300px; /* 你提供的高度 */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Tabler 样式(也可换成你项目内置的 tabler.min.css) -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@tabler/core@1.0.0-beta20/dist/css/tabler.min.css"/>
|
||||
|
||||
<style>
|
||||
:root{
|
||||
/* 你的主题主色,可按项目实际调整 */
|
||||
--accent: #206bc4;
|
||||
}
|
||||
|
||||
/* 强调卡片 */
|
||||
.card-priority{
|
||||
border: 2px solid var(--accent);
|
||||
box-shadow: 0 10px 30px rgba(32,107,196,.16);
|
||||
background: linear-gradient(180deg, rgba(32,107,196,.04), rgba(32,107,196,.02));
|
||||
position: sticky; /* 吸顶 */
|
||||
top: 12px;
|
||||
z-index: 3;
|
||||
transition: box-shadow .18s ease, transform .18s ease;
|
||||
}
|
||||
.card-priority .card-header{
|
||||
background: linear-gradient(90deg, rgba(32,107,196,.10), rgba(32,107,196,0));
|
||||
border-bottom: 1px solid rgba(32,107,196,.2);
|
||||
}
|
||||
.priority-dot{
|
||||
width: 10px; height: 10px; border-radius: 999px;
|
||||
background: var(--accent);
|
||||
box-shadow: 0 0 0 4px rgba(32,107,196,.15);
|
||||
margin-right: .5rem;
|
||||
}
|
||||
.card-priority:hover,
|
||||
.card-priority:focus-within{
|
||||
box-shadow: 0 14px 40px rgba(32,107,196,.24);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
/* 切换时的短暂高亮 */
|
||||
@keyframes flashHighlight{
|
||||
0% { box-shadow: 0 0 0 0 rgba(32,107,196,0); }
|
||||
20% { box-shadow: 0 0 0 6px rgba(32,107,196,.25); }
|
||||
100% { box-shadow: 0 10px 30px rgba(32,107,196,.16); }
|
||||
}
|
||||
.card-priority.flash{ animation: flashHighlight .9s ease-out; }
|
||||
|
||||
/* 次级卡片更弱一些,拉开层级 */
|
||||
.card-secondary{
|
||||
border: 1px solid rgba(0,0,0,.06);
|
||||
box-shadow: 0 4px 14px rgba(0,0,0,.06);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="theme-light">
|
||||
<div class="page">
|
||||
<header class="navbar navbar-expand-md navbar-light d-print-none" style="border-bottom:1px solid rgba(0,0,0,.06);">
|
||||
<div class="container-xl">
|
||||
<h2 class="navbar-brand">海上评估系统</h2>
|
||||
<div class="ms-auto text-muted">管理员</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="page-body">
|
||||
<div class="container-xl">
|
||||
|
||||
<!-- 重点卡片:选择指标 -->
|
||||
<div class="card card-priority mb-3" id="cardPriority">
|
||||
<div class="card-header d-flex align-items-center">
|
||||
<span class="priority-dot"></span>
|
||||
<h3 class="card-title mb-0">选择指标
|
||||
<span class="badge bg-primary ms-2">必填</span>
|
||||
</h3>
|
||||
<div class="ms-auto">
|
||||
<button class="btn btn-primary" id="btnNext">下一步</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3 align-items-center">
|
||||
<div class="col-auto">
|
||||
<label for="metricSelect" class="col-form-label">指标列表</label>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-lg-4">
|
||||
<select id="metricSelect" class="form-select">
|
||||
<option value="" selected disabled>请选择一个指标</option>
|
||||
<option value="aaa">AAA</option>
|
||||
<option value="bbb">BBB</option>
|
||||
<option value="ccc">CCC</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-12 col-lg-auto">
|
||||
<span class="form-hint">选择后将影响下方所有设置。</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 次级卡片:评价集设置 -->
|
||||
<div class="card card-secondary">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title mb-0">评价集设置</h3>
|
||||
<div class="ms-auto">
|
||||
<button class="btn btn-outline-primary" id="btnAdd">增加评价</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<!-- 左侧:子集列表 -->
|
||||
<div class="col-12 col-md-3">
|
||||
<div class="list-group">
|
||||
<label class="list-group-item">
|
||||
<input class="form-check-input me-2" type="radio" name="subset" value="x1"> x1
|
||||
</label>
|
||||
<label class="list-group-item">
|
||||
<input class="form-check-input me-2" type="radio" name="subset" value="c2" checked> c2
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右侧:表格占位 -->
|
||||
<div class="col-12 col-md-9">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-vcenter">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>序号</th>
|
||||
<th>名称</th>
|
||||
<th>符号</th>
|
||||
<th>下限值</th>
|
||||
<th>符号</th>
|
||||
<th>上限值</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="rulesBody">
|
||||
<tr class="text-muted">
|
||||
<td colspan="6">尚未添加评价规则,点击右上角“增加评价”。</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- row -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 占位内容,方便滚动测试吸顶 -->
|
||||
<div style="height: 40vh;"></div>
|
||||
|
||||
</div>
|
||||
<div class="chart-card">
|
||||
<h3 class="chart-title">一级维度得分对比</h3>
|
||||
<div class="chart-container">
|
||||
<svg id="radarChart"></svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/d3@7"></script>
|
||||
<script>
|
||||
// 切换指标时,给重点卡片一个轻微高亮动画
|
||||
const card = document.getElementById('cardPriority');
|
||||
const select = document.getElementById('metricSelect');
|
||||
select.addEventListener('change', () => {
|
||||
card.classList.add('flash');
|
||||
setTimeout(() => card.classList.remove('flash'), 900);
|
||||
});
|
||||
/**
|
||||
* 横向条形图(替换 #radarChart)
|
||||
* @param {string|SVGElement} svgSel - 目标 SVG 选择器/元素
|
||||
* @param {{name:string,score:number}[]} data - 数据;score 建议 0~100
|
||||
* @param {{domainMax?:number, sortAsc?:boolean, target?:number, margin?:object}} opts
|
||||
*/
|
||||
function renderBarChart(svgSel, data, opts = {}) {
|
||||
const cfg = Object.assign({
|
||||
sortAsc: true,
|
||||
domainMax: 100, // 轴与条统一最大值,确保与刻度对齐
|
||||
target: 80,
|
||||
margin: { top: 24, right: 120, bottom: 28, left: 200 }
|
||||
}, opts);
|
||||
|
||||
// 下一步按钮:如果未选择则聚焦并闪烁
|
||||
document.getElementById('btnNext').addEventListener('click', () => {
|
||||
if (!select.value) {
|
||||
select.focus();
|
||||
card.classList.add('flash');
|
||||
setTimeout(() => card.classList.remove('flash'), 900);
|
||||
} else {
|
||||
// 这里写你的跳转或展开逻辑
|
||||
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
|
||||
}
|
||||
});
|
||||
const src = (data||[]).map(d=>({...d}));
|
||||
if (cfg.sortAsc) src.sort((a,b)=>d3.ascending(a.score,b.score));
|
||||
|
||||
// 增加评价:简单追加一行示例
|
||||
document.getElementById('btnAdd').addEventListener('click', () => {
|
||||
const body = document.getElementById('rulesBody');
|
||||
if (body.firstElementChild && body.firstElementChild.classList.contains('text-muted')) {
|
||||
body.innerHTML = '';
|
||||
const svg = d3.select(svgSel);
|
||||
const parent = svg.node().parentNode;
|
||||
const W = parent.clientWidth || 800;
|
||||
const H = parent.clientHeight || Math.max(240, src.length*40 + cfg.margin.top + cfg.margin.bottom);
|
||||
|
||||
svg.attr("width", W).attr("height", H)
|
||||
.attr("viewBox", `0 0 ${W} ${H}`)
|
||||
.attr("preserveAspectRatio","xMidYMid meet")
|
||||
.selectAll("*").remove();
|
||||
|
||||
const {top,right,bottom,left} = cfg.margin;
|
||||
const width = Math.max(50, W - left - right);
|
||||
const innerH = Math.max(20, H - top - bottom);
|
||||
const gap = 10;
|
||||
const barH = Math.max(16, Math.min(32, (innerH - (src.length-1)*gap) / Math.max(1,src.length)));
|
||||
|
||||
const g = svg.append("g").attr("transform", `translate(${left},${top})`);
|
||||
|
||||
// ★ 唯一的 x 比例尺(条/轴/目标线共用)
|
||||
const x = d3.scaleLinear()
|
||||
.domain([0, cfg.domainMax])
|
||||
.nice()
|
||||
.range([0, width]);
|
||||
|
||||
const y = d3.scaleBand()
|
||||
.domain(src.map(d=>d.name))
|
||||
.range([0, src.length*(barH+gap)-gap])
|
||||
.paddingInner(gap/(barH+gap));
|
||||
|
||||
const color = d3.scaleLinear()
|
||||
.domain([0.5*cfg.domainMax, 0.75*cfg.domainMax, 0.9*cfg.domainMax])
|
||||
.range (["#ef4444", "#f59e0b", "#10b981"])
|
||||
.clamp(true);
|
||||
|
||||
// X 轴
|
||||
g.append("g")
|
||||
.attr("transform", `translate(0,${y.range()[1]})`)
|
||||
.call(d3.axisBottom(x).ticks(6).tickSizeOuter(0))
|
||||
.selectAll("path,line").attr("stroke", "#e5e7eb");
|
||||
|
||||
// 行
|
||||
const row = g.selectAll(".row").data(src).enter().append("g")
|
||||
.attr("class","row")
|
||||
.attr("transform", d=>`translate(0,${y(d.name)})`);
|
||||
|
||||
// 条形
|
||||
row.append("rect")
|
||||
.attr("height", barH)
|
||||
.attr("width", d=>x(d.score)) // 与轴同一比例尺
|
||||
.attr("fill", d=>color(d.score))
|
||||
.attr("rx", 8).attr("ry", 8);
|
||||
|
||||
// 左侧分类名
|
||||
row.append("text")
|
||||
.attr("x", -10).attr("y", barH/2).attr("dy",".35em")
|
||||
.attr("text-anchor","end").attr("fill","#0f172a").attr("font-weight",700)
|
||||
.text(d=>d.name);
|
||||
|
||||
// 右侧分数
|
||||
row.append("text")
|
||||
.attr("x", d=>x(d.score)+8).attr("y", barH/2).attr("dy",".35em")
|
||||
.attr("fill","#0f172a").attr("font-weight",800).attr("font-size",18)
|
||||
.text(d=>d.score.toFixed(1));
|
||||
|
||||
// 最低分标注
|
||||
const minScore = d3.min(src, d=>d.score);
|
||||
row.filter(d=>d.score===minScore).append("text")
|
||||
.attr("x", d=>x(d.score)+8).attr("y", barH/2+16)
|
||||
.attr("fill","#ef4444").attr("font-weight",800).attr("font-size",12)
|
||||
.text("LOWEST");
|
||||
|
||||
// 目标线(可选)
|
||||
if (typeof cfg.target === "number") {
|
||||
g.append("line")
|
||||
.attr("x1", x(cfg.target)).attr("x2", x(cfg.target))
|
||||
.attr("y1", 0).attr("y2", y.range()[1])
|
||||
.attr("stroke", "#94a3b8").attr("stroke-dasharray", "4,4");
|
||||
g.append("text")
|
||||
.attr("x", x(cfg.target)+6).attr("y", -6)
|
||||
.attr("fill","#64748b").attr("font-size",12)
|
||||
.text(`目标 ${cfg.target}`);
|
||||
}
|
||||
const idx = body.children.length + 1;
|
||||
const tr = document.createElement('tr');
|
||||
tr.innerHTML = `
|
||||
<td>${idx}</td>
|
||||
<td><input class="form-control form-control-sm" placeholder="名称"/></td>
|
||||
<td>
|
||||
<select class="form-select form-select-sm">
|
||||
<option>>=</option><option>></option><option>=</option>
|
||||
<option><=</option><option><</option>
|
||||
</select>
|
||||
</td>
|
||||
<td><input class="form-control form-control-sm" placeholder="下限"/></td>
|
||||
<td>
|
||||
<select class="form-select form-select-sm">
|
||||
<option><=</option><option><</option><option>=</option>
|
||||
<option>>=</option><option>></option>
|
||||
</select>
|
||||
</td>
|
||||
<td><input class="form-control form-control-sm" placeholder="上限"/></td>
|
||||
`;
|
||||
body.appendChild(tr);
|
||||
});
|
||||
}
|
||||
|
||||
// ====== 最小示例数据(可替换为你的实时数据)======
|
||||
const level1 = [
|
||||
{ name:"港口安全管理", score: 90 },
|
||||
{ name:"港口环境与资源利用", score: 90 },
|
||||
{ name:"港口运行效率", score:90 }
|
||||
];
|
||||
|
||||
// 渲染 & 自适应
|
||||
renderBarChart('#radarChart', level1, { domainMax: 100, target: 80 });
|
||||
window.addEventListener('resize', () =>
|
||||
renderBarChart('#radarChart', level1, { domainMax: 100, target: 80 })
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
52
manager-admin/src/main/java/com/hshh/AdminInit.java
Normal file
52
manager-admin/src/main/java/com/hshh/AdminInit.java
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
package com.hshh;
|
||||
|
||||
import com.hshh.system.base.service.LogsService;
|
||||
import com.hshh.system.common.threadpool.ThreadPools;
|
||||
import com.hshh.system.logs.LogRecorderThread;
|
||||
import com.hshh.thread.HandleEvaluationCmdThread;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 系统初始化类.
|
||||
*
|
||||
* @author LiDongYU
|
||||
* @since 2025/7/22
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class AdminInit {
|
||||
|
||||
@Resource
|
||||
private LogsService logsService;
|
||||
private static final ExecutorService cpu = ThreadPools.newCpuBoundPool("cpu-pool");
|
||||
private static final int evaluationThreadNum = 5;
|
||||
|
||||
/**
|
||||
* 初始化系统相关函数.
|
||||
*/
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
//评估线程
|
||||
startEvaluationThread();
|
||||
//日志记录线程
|
||||
startRecordLogs();
|
||||
}
|
||||
|
||||
private void startEvaluationThread() {
|
||||
try {
|
||||
for (int i = 0; i < evaluationThreadNum; i++) {
|
||||
cpu.execute(new Thread(new HandleEvaluationCmdThread()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("error::", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void startRecordLogs() {
|
||||
new Thread(new LogRecorderThread(logsService)).start();
|
||||
}
|
||||
}
|
||||
|
|
@ -24,4 +24,5 @@ public class Application {
|
|||
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import com.hshh.model.entity.ModelDefine;
|
|||
import com.hshh.model.service.FormFieldConfigService;
|
||||
import com.hshh.model.service.FormValueService;
|
||||
import com.hshh.model.service.ModelDefineService;
|
||||
import com.hshh.system.annotation.LogOperation;
|
||||
import com.hshh.system.common.bean.BaseController;
|
||||
import com.hshh.system.common.bean.ErrorField;
|
||||
import com.hshh.system.common.bean.OperateResult;
|
||||
|
|
@ -70,6 +71,7 @@ public class DataController extends BaseController {
|
|||
* @param model session容器
|
||||
* @return /data/list.html
|
||||
*/
|
||||
@LogOperation("进入数据管理")
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "导航到数据管理页面", description = "导航到数据管理页面")
|
||||
public String index(PaginationBean request, Model model) {
|
||||
|
|
@ -81,12 +83,12 @@ public class DataController extends BaseController {
|
|||
|
||||
model.addAttribute("modelDefineList", modelDefineList); //设置到session中
|
||||
|
||||
if (!modelDefineList.isEmpty()) {
|
||||
if (!modelDefineList.isEmpty() && request.getBusinessKey() != null) {
|
||||
|
||||
List<FormFieldConfig> formConfigList = formFieldConfigService.getFormFieldConfigByModelId(
|
||||
modelDefineList.get(0).getId()); //查询模型表头
|
||||
request.getBusinessKey()); //查询模型表头
|
||||
sortFieldList(formConfigList); //排序
|
||||
Map<String, String> headerMap = new LinkedHashMap<>(); //定义表头兑现
|
||||
Map<String, String> headerMap = new LinkedHashMap<>(); //定义表头
|
||||
formConfigList.forEach(formFieldConfig -> {
|
||||
headerMap.put(formFieldConfig.getFieldName(), formFieldConfig.getFieldLabel());
|
||||
});
|
||||
|
|
@ -114,10 +116,10 @@ public class DataController extends BaseController {
|
|||
*/
|
||||
private void setCurrentActiveModelDefine(Model model, PaginationBean request,
|
||||
List<ModelDefine> modelDefineList) {
|
||||
AtomicReference<ModelDefine> activeModelDefine = new AtomicReference<>(); //当前激活的数据模型;tab页
|
||||
AtomicReference<ModelDefine> activeModelDefine = new AtomicReference<>();
|
||||
|
||||
modelDefineList.forEach(a -> {
|
||||
if (request.getId() != null && request.getId().equals(a.getId())) {
|
||||
if (request.getBusinessKey() != null && request.getBusinessKey().equals(a.getId())) {
|
||||
a.setChecked(true);
|
||||
activeModelDefine.set(a);
|
||||
|
||||
|
|
@ -129,12 +131,6 @@ public class DataController extends BaseController {
|
|||
});
|
||||
if (activeModelDefine.get() != null) {
|
||||
model.addAttribute("currentModelDefine", activeModelDefine.get());
|
||||
} else {
|
||||
//设置默认第一个选中
|
||||
modelDefineList.get(0).setChecked(true);
|
||||
//设置查询参数为第一个
|
||||
request.setId(modelDefineList.get(0).getId());
|
||||
model.addAttribute("currentModelDefine", modelDefineList.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -154,6 +150,7 @@ public class DataController extends BaseController {
|
|||
* @param id 模型id
|
||||
* @return form表单内容 div...
|
||||
*/
|
||||
@LogOperation("获取form输入窗体")
|
||||
@GetMapping("/getForm/{id}")
|
||||
@Operation(summary = "获取form输入窗体", description = "根据模型ID获取form窗体")
|
||||
@ResponseBody
|
||||
|
|
@ -168,6 +165,7 @@ public class DataController extends BaseController {
|
|||
* @param formValue 表单值
|
||||
* @return 操作结果
|
||||
*/
|
||||
@LogOperation("保存对应模型ID对应的form表单记录")
|
||||
@PostMapping("/form/save")
|
||||
@ResponseBody
|
||||
@Operation(summary = "保存记录", description = "保存对应模型ID对应的form表单记录")
|
||||
|
|
@ -191,6 +189,7 @@ public class DataController extends BaseController {
|
|||
* @param id 记录ID
|
||||
* @return 操作结果
|
||||
*/
|
||||
@LogOperation("根据ID删除记录")
|
||||
@ResponseBody
|
||||
@GetMapping("/remove/{id}")
|
||||
@Operation(summary = "删除记录", description = "根据ID删除记录")
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
package com.hshh.data.controller;
|
||||
|
||||
/**
|
||||
* [类的简要说明]
|
||||
* <p>
|
||||
* [详细描述,可选]
|
||||
* <p>
|
||||
*
|
||||
* @author LiDongYU
|
||||
* @since 2025/7/22
|
||||
*/
|
||||
public class TestController {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.hshh.evaluation.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* [类的简要说明]
|
||||
* <p>
|
||||
* [详细描述,可选]
|
||||
* <p>
|
||||
*
|
||||
* @author LiDongYU
|
||||
* @since 2025/7/22
|
||||
*/
|
||||
@Data
|
||||
public class BarData {
|
||||
|
||||
private String name;
|
||||
private double score;
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.hshh.evaluation.bean;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* csv上传文件描述类.
|
||||
*
|
||||
* @author LiDongYU
|
||||
* @since 2025/7/22
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class CsvUploadBean extends PageEvaluationRequest {
|
||||
|
||||
private MultipartFile file;
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package com.hshh.evaluation.bean;
|
||||
|
||||
import com.hshh.indicator.entity.IndicatorEvalItem;
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 描述评估字段对应的信息,包含权重和评价集.
|
||||
*
|
||||
* @author LiDongYU
|
||||
* @since 2025/7/22
|
||||
*/
|
||||
@Data
|
||||
public class EvalItemToFieldInfo {
|
||||
|
||||
/**
|
||||
* 字段名称.
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 权重.
|
||||
*/
|
||||
private double weight;
|
||||
/**
|
||||
* 评价集列表.
|
||||
*/
|
||||
private List<IndicatorEvalItem> evalItemList;
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.hshh.evaluation.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 描述请求数据到类型类.
|
||||
*
|
||||
* @author LiDongYU
|
||||
* @since 2025/7/22
|
||||
*/
|
||||
@Data
|
||||
public class PageDatasourceRequest implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
//数据源类型 数据库||Csv文件
|
||||
private String datasourceType;
|
||||
//工程ID
|
||||
private Integer projectId;
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package com.hshh.evaluation.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 描述评估请求对象.
|
||||
*
|
||||
* @author LiDongYU
|
||||
* @since 2025/7/22
|
||||
*/
|
||||
@Data
|
||||
public class PageEvaluationRequest {
|
||||
|
||||
/**
|
||||
* database | csv.
|
||||
*/
|
||||
private String datasourceType;
|
||||
/**
|
||||
* 基础设施ID.
|
||||
*/
|
||||
private Integer modelId;
|
||||
/**
|
||||
* 工程ID.
|
||||
*/
|
||||
private Integer projectId;
|
||||
/**
|
||||
* 查询关键子.
|
||||
*/
|
||||
private String search;
|
||||
/**
|
||||
* 模板ID.
|
||||
*/
|
||||
private Integer templateId;
|
||||
/**
|
||||
* 随机字符.
|
||||
*/
|
||||
private String randomKey;
|
||||
/**
|
||||
* 计算方式.
|
||||
*/
|
||||
private String method;
|
||||
private Integer indicatorTopId;
|
||||
/**
|
||||
* 用户ID.
|
||||
*/
|
||||
private Integer userId;
|
||||
private String membership;
|
||||
private int[] ids;
|
||||
//csv数据标识字段
|
||||
private String identifier;
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.hshh.evaluation.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 页面指标权重.
|
||||
*
|
||||
* @author LiDongYU
|
||||
* @since 2025/7/22
|
||||
*/
|
||||
@Data
|
||||
public class PageIndicatorWeight {
|
||||
|
||||
/**
|
||||
* 指标ID.
|
||||
*/
|
||||
private int indicatorId;
|
||||
/**
|
||||
* 权重.
|
||||
*/
|
||||
private String weight;
|
||||
}
|
||||
|
|
@ -10,9 +10,9 @@ import lombok.Data;
|
|||
* @since 2025/7/22
|
||||
*/
|
||||
@Data
|
||||
public class MetricComputeRequest {
|
||||
public class PageMetricComputeRequest {
|
||||
|
||||
private List<String> metric;
|
||||
private List<List<MetricMapperWeightBean>> weightList;
|
||||
private List<List<PageMetricMapperWeightBean>> weightList;
|
||||
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ import lombok.Data;
|
|||
* @since 2025/7/22
|
||||
*/
|
||||
@Data
|
||||
public class MetricComputerResponse {
|
||||
public class PageMetricComputerResponse {
|
||||
|
||||
private String id;
|
||||
private String weight;
|
||||
|
|
@ -9,7 +9,7 @@ import lombok.Data;
|
|||
* @since 2025/7/22
|
||||
*/
|
||||
@Data
|
||||
public class MetricMapperWeightBean {
|
||||
public class PageMetricMapperWeightBean {
|
||||
|
||||
/**
|
||||
* 从那个指标开始.
|
||||
|
|
@ -31,4 +31,5 @@ public class MetricMapperWeightBean {
|
|||
* 行号.
|
||||
*/
|
||||
private int rowNum;
|
||||
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ import lombok.Data;
|
|||
* @since 2025/7/22
|
||||
*/
|
||||
@Data
|
||||
public class MetricTableHeaderBean {
|
||||
public class PageMetricTableHeaderBean {
|
||||
|
||||
private int id;
|
||||
private String name;
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.hshh.evaluation.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* [类的简要说明]
|
||||
* <p>
|
||||
* [详细描述,可选]
|
||||
* <p>
|
||||
*
|
||||
* @author LiDongYU
|
||||
* @since 2025/7/22
|
||||
*/
|
||||
@Data
|
||||
public class PieData implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private String label;
|
||||
private double value;
|
||||
private String color;
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package com.hshh.evaluation.bean;
|
||||
|
||||
import com.hshh.evaluation.entity.EvaluationRootResult;
|
||||
import com.hshh.indicator.entity.IndicatorTopLevel;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 报告模板类.
|
||||
*
|
||||
* @author LiDongYU
|
||||
* @since 2025/7/22
|
||||
*/
|
||||
@Data
|
||||
public class ReportBean implements Serializable {
|
||||
|
||||
private EvaluationRootResult result;
|
||||
private List<IndicatorTopLevel> levelList;
|
||||
private String highRate;
|
||||
private Integer bottomNum;
|
||||
|
||||
private List<PieData> pieDataList;
|
||||
|
||||
private List<ReportIndicatorNodeData> dataNodeList;
|
||||
private List<BarData> barDataList;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package com.hshh.evaluation.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* [类的简要说明]
|
||||
* <p>
|
||||
* [详细描述,可选]
|
||||
* <p>
|
||||
*
|
||||
* @author LiDongYU
|
||||
* @since 2025/7/22
|
||||
*/
|
||||
@Data
|
||||
public class ReportIndicatorNodeData implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private String id;
|
||||
private String name;
|
||||
private Integer level;
|
||||
private double score;
|
||||
private Map<String, Double> membershipDist;
|
||||
private double weight;
|
||||
private String parent;
|
||||
private String evaluation;
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.hshh.evaluation.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 评估数据描述.原始数据id,实际数据data,type=csv or database.
|
||||
*
|
||||
* @author LiDongYU
|
||||
* @since 2025/7/22
|
||||
*/
|
||||
@Data
|
||||
public class SingleEvaluationData {
|
||||
|
||||
private int id;
|
||||
private String data;
|
||||
private String type;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -11,14 +11,14 @@ import lombok.Data;
|
|||
* @since 2025/7/22
|
||||
*/
|
||||
@Data
|
||||
public class DynamicTable {
|
||||
public class pageDynamicTable {
|
||||
|
||||
|
||||
/**
|
||||
* 表头map linkedMap.
|
||||
*/
|
||||
private Map<Integer, MetricTableHeaderBean> headerMap;
|
||||
private Map<Integer, PageMetricTableHeaderBean> headerMap;
|
||||
|
||||
|
||||
private List<List<MetricMapperWeightBean>> weight;
|
||||
private List<List<PageMetricMapperWeightBean>> weight;
|
||||
}
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
package com.hshh.evaluation.controller;
|
||||
|
||||
import com.hshh.evaluation.bean.BarData;
|
||||
import com.hshh.evaluation.bean.PieData;
|
||||
import com.hshh.evaluation.bean.ReportIndicatorNodeData;
|
||||
import com.hshh.evaluation.entity.EvaluationIndicatorResult;
|
||||
import com.hshh.evaluation.entity.EvaluationRootResult;
|
||||
import com.hshh.indicator.entity.IndicatorTopLevel;
|
||||
import com.hshh.system.common.bean.BaseController;
|
||||
import com.hshh.system.common.enums.LevelEnum;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* [类的简要说明]
|
||||
* <p>
|
||||
* [详细描述,可选]
|
||||
* <p>
|
||||
*
|
||||
* @author LiDongYU
|
||||
* @since 2025/7/22
|
||||
*/
|
||||
public class AssistantEvaluationProjectController extends BaseController {
|
||||
|
||||
protected Map<String, Double> membershipScoreMap(String input) {
|
||||
Map<String, Double> map = new LinkedHashMap<>(); // 保证顺序和输入一致
|
||||
|
||||
for (String pair : input.split(";")) {
|
||||
if (pair.trim().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
String[] kv = pair.split(":");
|
||||
if (kv.length == 2) {
|
||||
String key = kv[0].trim();
|
||||
double value = Double.parseDouble(kv[1].trim());
|
||||
map.put(key, value);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
protected String getClosestLevel(List<IndicatorTopLevel> levelList, int targetScore) {
|
||||
IndicatorTopLevel closest = null;
|
||||
int minDiff = Integer.MAX_VALUE;
|
||||
for (IndicatorTopLevel item : levelList) {
|
||||
int diff = Math.abs(targetScore - (int) Double.parseDouble(item.getGrade()));
|
||||
if (diff < minDiff) {
|
||||
minDiff = diff;
|
||||
closest = item;
|
||||
}
|
||||
}
|
||||
return closest != null ? closest.getLevelName() : null;
|
||||
}
|
||||
|
||||
//获取优良率
|
||||
protected String highRate(Map<String, Double> membershipMap) {
|
||||
AtomicReference<Double> highRate = new AtomicReference<>((double) 0);
|
||||
membershipMap.forEach((k, v) -> {
|
||||
if (k.equals(LevelEnum.Excellent.getLevel())) {
|
||||
highRate.set(highRate.get() + v);
|
||||
}
|
||||
if (k.equals(LevelEnum.Good.getLevel())) {
|
||||
highRate.set(highRate.get() + v);
|
||||
}
|
||||
});
|
||||
return String.format("%.2f", highRate.get() * 100);
|
||||
}
|
||||
|
||||
protected void setLevelName(List<IndicatorTopLevel> levelList, EvaluationRootResult rootResult) {
|
||||
if (levelList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
rootResult.setLevelName(levelList.get(levelList.size() - 1).getLevelName());
|
||||
for (IndicatorTopLevel indicatorTopLevel : levelList) {
|
||||
if (Double.parseDouble(rootResult.getFinalScore()) >= Double.parseDouble(
|
||||
indicatorTopLevel.getGrade())) {
|
||||
rootResult.setLevelName(indicatorTopLevel.getLevelName());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected List<PieData> pieDataList(Map<String, Double> membershipMap) {
|
||||
List<PieData> list = new ArrayList<>();
|
||||
membershipMap.forEach((k, v) -> {
|
||||
PieData pieData = new PieData();
|
||||
pieData.setLabel(k);
|
||||
pieData.setValue(v * 100);
|
||||
pieData.setColor(LevelEnum.getColor(k));
|
||||
list.add(pieData);
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
protected List<ReportIndicatorNodeData> covertIndicatorResultToReportIndicatorNodeData(
|
||||
List<EvaluationIndicatorResult> list, List<IndicatorTopLevel> levelList) {
|
||||
List<ReportIndicatorNodeData> resultList = new ArrayList<>();
|
||||
list.forEach(indicatorResult -> {
|
||||
ReportIndicatorNodeData reportIndicatorNodeData = new ReportIndicatorNodeData();
|
||||
resultList.add(reportIndicatorNodeData);
|
||||
|
||||
reportIndicatorNodeData.setId("node_" + indicatorResult.getIndicatorId());
|
||||
reportIndicatorNodeData.setName(indicatorResult.getIndicatorName());
|
||||
reportIndicatorNodeData.setLevel(indicatorResult.getLevel());
|
||||
reportIndicatorNodeData.setScore(
|
||||
new BigDecimal(indicatorResult.getFinalScore()).setScale(2, RoundingMode.HALF_UP)
|
||||
.doubleValue());
|
||||
Map<String, Double> membershipScoreMap = new HashMap<>();
|
||||
Map<String, Double> originalMap = membershipScoreMap(indicatorResult.getMemberShipScore());
|
||||
|
||||
originalMap.forEach((k, v) -> {
|
||||
membershipScoreMap.put(LevelEnum.getCode(k),
|
||||
BigDecimal.valueOf(v * 100).setScale(2, RoundingMode.HALF_UP).doubleValue());
|
||||
});
|
||||
reportIndicatorNodeData.setMembershipDist(membershipScoreMap);
|
||||
reportIndicatorNodeData.setEvaluation(
|
||||
getClosestLevel(levelList, (int) reportIndicatorNodeData.getScore()));
|
||||
reportIndicatorNodeData.setWeight(indicatorResult.getWeight());
|
||||
if (indicatorResult.getIndicatorParentId() != null) {
|
||||
reportIndicatorNodeData.setParent("node_" + indicatorResult.getIndicatorParentId());
|
||||
}
|
||||
});
|
||||
return resultList;
|
||||
}
|
||||
|
||||
protected List<BarData> covertIndicatorResultToBarData(List<EvaluationIndicatorResult> list) {
|
||||
List<BarData> resultList = new ArrayList<>();
|
||||
list.forEach(indicatorResult -> {
|
||||
BarData barData = new BarData();
|
||||
barData.setName(indicatorResult.getIndicatorName());
|
||||
barData.setScore(
|
||||
new BigDecimal(indicatorResult.getFinalScore()).setScale(2, RoundingMode.HALF_UP)
|
||||
.doubleValue());
|
||||
resultList.add(barData);
|
||||
});
|
||||
return resultList;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +1,19 @@
|
|||
package com.hshh.evaluation.controller;
|
||||
|
||||
import com.hshh.evaluation.bean.DraftWeightData;
|
||||
import com.hshh.evaluation.bean.MetricMapperWeightBean;
|
||||
import com.hshh.evaluation.entity.EvaluationTemplate;
|
||||
import com.hshh.evaluation.bean.PageMetricMapperWeightBean;
|
||||
import com.hshh.evaluation.bean.PageMetricTableHeaderBean;
|
||||
import com.hshh.evaluation.bean.pageDynamicTable;
|
||||
import com.hshh.evaluation.entity.EvaluationTemplateWeight;
|
||||
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.util.DraftStore;
|
||||
import com.hshh.system.common.bean.SpringContextHolder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 评估模板类辅助方法.
|
||||
|
|
@ -27,7 +30,7 @@ public class AssistantTemplateController extends BaseController {
|
|||
* @return list string数组
|
||||
*/
|
||||
protected List<String[]> convertMetricMapperWeightBeanListToStrArray(
|
||||
List<List<MetricMapperWeightBean>> weightList) {
|
||||
List<List<PageMetricMapperWeightBean>> weightList) {
|
||||
|
||||
List<String[]> data = new ArrayList<>();
|
||||
weightList.forEach(weight -> {
|
||||
|
|
@ -41,84 +44,108 @@ public class AssistantTemplateController extends BaseController {
|
|||
}
|
||||
|
||||
/**
|
||||
* 组装历史权重数据.
|
||||
* 把数据库中的明细数据转化为页面约定的数据类型.
|
||||
*
|
||||
* @param evaluationTemplate 当前模板数据
|
||||
* @return 评估数据列表
|
||||
* @param detailList 数据库数据
|
||||
* @return 页面约定的权重列表
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Map<Integer, DraftWeightData> unitWeightMap(
|
||||
EvaluationTemplate evaluationTemplate) {
|
||||
protected List<List<PageMetricMapperWeightBean>> convertEvaluationTemplateWeightList(
|
||||
List<EvaluationTemplateWeight> detailList) {
|
||||
List<List<PageMetricMapperWeightBean>> finalList = new ArrayList<>();
|
||||
Map<Integer, List<EvaluationTemplateWeight>> groupByFromIndicatorMap = detailList.stream()
|
||||
.collect(Collectors.groupingBy(EvaluationTemplateWeight::getFromIndicatorId));
|
||||
|
||||
// 获取缓存中的数据
|
||||
Map<Integer, DraftWeightData> cacheData = DraftStore.get(evaluationTemplate.getDraftKey(),
|
||||
Map.class);
|
||||
if (cacheData == null) {
|
||||
if (evaluationTemplate.getCurrentPagePartData() != null) {
|
||||
groupByFromIndicatorMap.forEach((key, value) -> {
|
||||
List<PageMetricMapperWeightBean> list = new ArrayList<>();
|
||||
finalList.add(list);
|
||||
value.forEach(detail -> {
|
||||
PageMetricMapperWeightBean weightBean = new PageMetricMapperWeightBean();
|
||||
weightBean.setRowNum(detail.getRowNum());
|
||||
weightBean.setValue(detail.getWeight());
|
||||
weightBean.setRowId(detail.getFromIndicatorId());
|
||||
weightBean.setColId(detail.getToIndicatorId());
|
||||
weightBean.setParentId(detail.getIndicatorParentId());
|
||||
list.add(weightBean);
|
||||
});
|
||||
});
|
||||
|
||||
Map<Integer, DraftWeightData> defaultMap = new LinkedHashMap<>();
|
||||
DraftWeightData weightData = createDefaultDraftWeightData(evaluationTemplate);
|
||||
defaultMap.put(weightData.getParentIndicationId(), weightData);
|
||||
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;
|
||||
return finalList;
|
||||
}
|
||||
|
||||
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 unitWeightDataMap 当前已经设置的权重信息.
|
||||
* @param children 子指标
|
||||
* @return 表格头信息
|
||||
*/
|
||||
|
||||
protected void paddingDefaultValueWhenParentHasOnlyLonelyChild(List<Indicator> lonelyChild,
|
||||
Map<Integer, DraftWeightData> unitWeightDataMap) {
|
||||
for (Indicator indicator : lonelyChild) {
|
||||
if (!unitWeightDataMap.containsKey(indicator.getParentId())) {
|
||||
List<List<MetricMapperWeightBean>> singleRowList = new ArrayList<>();
|
||||
List<MetricMapperWeightBean> list = new ArrayList<>();
|
||||
MetricMapperWeightBean weightBean = new MetricMapperWeightBean();
|
||||
list.add(weightBean);
|
||||
singleRowList.add(list);
|
||||
weightBean.setParentId(indicator.getParentId());
|
||||
weightBean.setValue("1");
|
||||
weightBean.setRowId(indicator.getId());
|
||||
weightBean.setColId(indicator.getId());
|
||||
weightBean.setRowNum(1);
|
||||
DraftWeightData draftWeightData = new DraftWeightData();
|
||||
draftWeightData.setParentIndicationId(indicator.getParentId());
|
||||
draftWeightData.setWeight(singleRowList);
|
||||
;
|
||||
unitWeightDataMap.put(indicator.getParentId(), draftWeightData);
|
||||
}
|
||||
}
|
||||
protected Map<Integer, PageMetricTableHeaderBean> createTableHeaderMap(List<Indicator> children) {
|
||||
List<PageMetricTableHeaderBean> headerBeans = new ArrayList<>();
|
||||
children.forEach(a -> {
|
||||
PageMetricTableHeaderBean bean = new PageMetricTableHeaderBean();
|
||||
bean.setId(a.getId());
|
||||
bean.setName(a.getName());
|
||||
headerBeans.add(bean);
|
||||
});
|
||||
Map<Integer, PageMetricTableHeaderBean> headerMap = new LinkedHashMap<>();
|
||||
headerBeans.forEach(header -> {
|
||||
headerMap.put(header.getId(), header);
|
||||
});
|
||||
return headerMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从数据库创建一个空的默认映射列表.
|
||||
*
|
||||
* @param parentIndicatorId 父指标
|
||||
* @param children 子指标
|
||||
* @param i 行号
|
||||
* @return 默认映射列表
|
||||
*/
|
||||
protected List<PageMetricMapperWeightBean> createEmptyMapperList(Integer parentIndicatorId,
|
||||
List<Indicator> children, int i) {
|
||||
List<PageMetricMapperWeightBean> innerList = new ArrayList<>();
|
||||
for (Indicator child : children) {
|
||||
PageMetricMapperWeightBean weightBean = new PageMetricMapperWeightBean();
|
||||
//行ID
|
||||
weightBean.setRowId(children.get(i).getId());
|
||||
//列Id
|
||||
weightBean.setColId(child.getId());
|
||||
|
||||
//初始默认为1
|
||||
weightBean.setValue("1")
|
||||
;
|
||||
|
||||
weightBean.setRowNum(i + 1);
|
||||
weightBean.setParentId(parentIndicatorId);
|
||||
innerList.add(weightBean);
|
||||
}
|
||||
return innerList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从数据库创建动态表.
|
||||
*
|
||||
* @param indicatePid 父节点指标
|
||||
* @return 动态表
|
||||
*/
|
||||
protected pageDynamicTable createNewDynamicFromDatabase(Integer indicatePid) {
|
||||
pageDynamicTable dynamicTable = new pageDynamicTable();
|
||||
//查询当前指标的子指标
|
||||
IndicatorService indicatorService = SpringContextHolder.getBean(IndicatorServiceImpl.class);
|
||||
List<Indicator> children = indicatorService.queryChildren(indicatePid);
|
||||
|
||||
//设置头信息
|
||||
dynamicTable.setHeaderMap(createTableHeaderMap(children));
|
||||
|
||||
//设置权重信息
|
||||
List<List<PageMetricMapperWeightBean>> weight = new ArrayList<>();
|
||||
for (int i = 0; i < children.size(); i++) {
|
||||
List<PageMetricMapperWeightBean> innerList = createEmptyMapperList(indicatePid, children, i
|
||||
);
|
||||
weight.add(innerList);
|
||||
}
|
||||
|
||||
dynamicTable.setWeight(weight);
|
||||
return dynamicTable;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,30 +1,58 @@
|
|||
package com.hshh.evaluation.controller;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.hshh.evaluation.bean.CsvUploadBean;
|
||||
import com.hshh.evaluation.bean.PageEvaluationRequest;
|
||||
import com.hshh.evaluation.bean.ReportBean;
|
||||
import com.hshh.evaluation.entity.EvaluationCsvData;
|
||||
import com.hshh.evaluation.entity.EvaluationHistory;
|
||||
import com.hshh.evaluation.entity.EvaluationIndicatorResult;
|
||||
import com.hshh.evaluation.entity.EvaluationProject;
|
||||
import com.hshh.evaluation.entity.EvaluationRootResult;
|
||||
import com.hshh.evaluation.entity.EvaluationTemplate;
|
||||
import com.hshh.evaluation.service.EvaluationCsvDataService;
|
||||
import com.hshh.evaluation.service.EvaluationHistoryService;
|
||||
import com.hshh.evaluation.service.EvaluationIndicatorResultService;
|
||||
import com.hshh.evaluation.service.EvaluationProjectService;
|
||||
import com.hshh.evaluation.service.EvaluationRootResultService;
|
||||
import com.hshh.evaluation.service.EvaluationTemplateService;
|
||||
import com.hshh.indicator.entity.Indicator;
|
||||
import com.hshh.indicator.entity.IndicatorTopLevel;
|
||||
import com.hshh.indicator.service.IndicatorService;
|
||||
import com.hshh.indicator.service.IndicatorTopLevelService;
|
||||
import com.hshh.model.entity.FormValue;
|
||||
import com.hshh.model.service.FormFieldConfigService;
|
||||
import com.hshh.model.service.FormValueService;
|
||||
import com.hshh.system.annotation.LogOperation;
|
||||
import com.hshh.system.base.entity.TableRelations;
|
||||
import com.hshh.system.base.service.TableRelationsService;
|
||||
import com.hshh.system.common.bean.BaseController;
|
||||
import com.hshh.system.common.bean.OperateResult;
|
||||
import com.hshh.system.common.bean.PaginationBean;
|
||||
import com.hshh.system.common.enums.ErrorCode;
|
||||
import com.hshh.system.common.enums.ErrorMessage;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
|
||||
/**
|
||||
* 评估工程.
|
||||
|
|
@ -34,21 +62,62 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
|||
*/
|
||||
@Controller
|
||||
@RequestMapping("/evaluation/project")
|
||||
public class EvaluationProjectController extends BaseController {
|
||||
public class EvaluationProjectController extends AssistantEvaluationProjectController {
|
||||
|
||||
@Resource
|
||||
private EvaluationProjectService evaluationProjectService;
|
||||
|
||||
/**
|
||||
* 模板服务类.
|
||||
*/
|
||||
@Resource
|
||||
private EvaluationTemplateService evaluationTemplateService;
|
||||
|
||||
/**
|
||||
* 数据库引用关系记录服务类.
|
||||
*/
|
||||
@Resource
|
||||
private TableRelationsService tableRelationsService;
|
||||
|
||||
/**
|
||||
* 基础设施服务类.
|
||||
*/
|
||||
@Resource
|
||||
private FormFieldConfigService formFieldConfigService;
|
||||
/**
|
||||
* 数据查询服务类.
|
||||
*/
|
||||
@Resource
|
||||
private FormValueService formValueService;
|
||||
/**
|
||||
* 指标服务类.
|
||||
*/
|
||||
@Resource
|
||||
private IndicatorService indicatorService;
|
||||
|
||||
|
||||
/**
|
||||
* 上传的csv文件数据记录服务类.
|
||||
*/
|
||||
@Resource
|
||||
private EvaluationCsvDataService evaluationCsvDataService;
|
||||
|
||||
/**
|
||||
* 评估历史服务类.
|
||||
*/
|
||||
@Resource
|
||||
private EvaluationHistoryService evaluationHistoryService;
|
||||
|
||||
/**
|
||||
* 根指标评估历史记录服务类.
|
||||
*/
|
||||
@Resource
|
||||
private EvaluationRootResultService rootResultService;
|
||||
@Resource
|
||||
private IndicatorTopLevelService topLevelService;
|
||||
@Resource
|
||||
private EvaluationIndicatorResultService evaluationIndicatorResultService;
|
||||
|
||||
/**
|
||||
* 默认页.
|
||||
*
|
||||
|
|
@ -87,6 +156,7 @@ public class EvaluationProjectController extends BaseController {
|
|||
*/
|
||||
@ResponseBody
|
||||
@PostMapping("/save")
|
||||
@LogOperation("保存评估工程")
|
||||
public OperateResult<Object> save(@Valid @RequestBody EvaluationProject project,
|
||||
BindingResult bindingResult) {
|
||||
if (bindingResult.hasErrors()) {
|
||||
|
|
@ -119,9 +189,9 @@ public class EvaluationProjectController extends BaseController {
|
|||
*/
|
||||
@ResponseBody
|
||||
@GetMapping("/remove/{id}")
|
||||
@LogOperation("删除工程")
|
||||
public OperateResult<Void> remove(@PathVariable("id") Integer id) {
|
||||
List<TableRelations> reList = tableRelationsService.queryRel(id,
|
||||
"m_data_evaluation_project");
|
||||
List<TableRelations> reList = tableRelationsService.queryRel(id, "m_data_evaluation_project");
|
||||
if (!reList.isEmpty()) {
|
||||
return OperateResult.error(null, ErrorMessage.OBJ_ALREADY_TAKEN.getMessage(),
|
||||
ErrorCode.BUSINESS_ERROR.getCode());
|
||||
|
|
@ -130,4 +200,307 @@ public class EvaluationProjectController extends BaseController {
|
|||
return OperateResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择数据源类型.
|
||||
*
|
||||
* @param params 请求参数
|
||||
* @param model session容器
|
||||
* @return project/datasource_select.html
|
||||
*/
|
||||
@GetMapping("/selectDatasourceType")
|
||||
public String selectDatasourceType(@RequestParam Map<String, String> params, Model model) {
|
||||
setAttribute(model, params);
|
||||
|
||||
return "project/datasource_select";
|
||||
}
|
||||
|
||||
/**
|
||||
* 导航到数据库记录展现界面.
|
||||
*
|
||||
* @param request 查询请求
|
||||
* @param model session容器
|
||||
* @return project/datasource_db.html
|
||||
*/
|
||||
@GetMapping("/database")
|
||||
public String databasePage(PaginationBean request, Model model,
|
||||
@RequestParam Map<String, String> params) {
|
||||
|
||||
//获取基础设施ID
|
||||
Long modelId = evaluationProjectService.selectModelIdByProjectId(
|
||||
params.get("projectId") == null ? 0 : Integer.parseInt(params.get("projectId")));
|
||||
if (modelId == null) {
|
||||
throw new RuntimeException("没有设置基础设施");
|
||||
}
|
||||
params.put("modelId", modelId.toString());
|
||||
|
||||
//设置数据源页面中的隐藏属性
|
||||
addDatasourceModelAttribute(request, model, params);
|
||||
|
||||
//获取表头
|
||||
Map<String, String> headerMap = formFieldConfigService.getHeaderMap(modelId.intValue());
|
||||
model.addAttribute("headerMap", headerMap);
|
||||
//查询数据
|
||||
//替换为modelId查询
|
||||
request.setBusinessKey(modelId.intValue());
|
||||
|
||||
List<FormValue> formDataList = formValueService.list(request);
|
||||
List<Map<String, Object>> listMap = new ArrayList<>();
|
||||
formDataList.forEach(formData -> {
|
||||
|
||||
listMap.add(formData.toMap()); //转为map对象放入listMap中
|
||||
});
|
||||
|
||||
Long total = formValueService.count(request);
|
||||
setPaginationInfo(request, listMap, total, model);
|
||||
return "project/datasource_db";
|
||||
}
|
||||
|
||||
private void addDatasourceModelAttribute(PaginationBean request, Model model,
|
||||
@RequestParam Map<String, String> params) {
|
||||
EvaluationProject project = evaluationProjectService.getById(
|
||||
params.get("projectId") == null ? 0 : Integer.parseInt(params.get("projectId")));
|
||||
if (project != null) {
|
||||
model.addAttribute("templateId", project.getTemplateId());
|
||||
params.put("templateId", project.getTemplateId() + "");
|
||||
}
|
||||
setAttribute(model, params);
|
||||
|
||||
}
|
||||
|
||||
private void setAttribute(Model model, @RequestParam Map<String, String> params) {
|
||||
if (params.get("projectId") != null) {
|
||||
model.addAttribute("projectId", params.get("projectId"));
|
||||
}
|
||||
if (params.get("templateId") != null) {
|
||||
model.addAttribute("templateId", params.get("templateId"));
|
||||
}
|
||||
if (params.get("method") != null) {
|
||||
model.addAttribute("method", params.get("method"));
|
||||
}
|
||||
if (params.get("search") != null) {
|
||||
model.addAttribute("search", params.get("search"));
|
||||
}
|
||||
if (params.get("randomKey") != null) {
|
||||
model.addAttribute("randomKey", params.get("randomKey"));
|
||||
}
|
||||
if (params.get("modelId") != null) {
|
||||
model.addAttribute("modelId", params.get("modelId"));
|
||||
}
|
||||
if (params.get("membership") != null) {
|
||||
model.addAttribute("membership", params.get("membership"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 导航到csv记录呈现界面.
|
||||
*
|
||||
* @param request 查询请求
|
||||
* @param model session容器
|
||||
* @return project/datasource_csv.html
|
||||
*/
|
||||
|
||||
@GetMapping("/csv")
|
||||
public String csvPage(PaginationBean request, Model model,
|
||||
@RequestParam Map<String, String> params) {
|
||||
|
||||
if (params.get("projectId") != null && params.get("templateId") == null) {
|
||||
EvaluationProject project = evaluationProjectService.getById(
|
||||
Integer.parseInt(params.get("projectId")));
|
||||
if (project != null) {
|
||||
model.addAttribute("templateId", project.getTemplateId());
|
||||
}
|
||||
}
|
||||
|
||||
setAttribute(model, params);
|
||||
|
||||
//分页查询randomKey
|
||||
List<EvaluationCsvData> list = evaluationCsvDataService.list(request);
|
||||
if (!list.isEmpty()) {
|
||||
//取出csvHeader
|
||||
JSONArray first = JSON.parseArray(list.get(0).getCsvHeader());
|
||||
|
||||
Map<String, String> headerMap = new LinkedHashMap<>();
|
||||
first.forEach(item -> {
|
||||
headerMap.put(item.toString(), item.toString());
|
||||
});
|
||||
|
||||
model.addAttribute("headerMap", headerMap);
|
||||
List<Map<String, Object>> listMap = new ArrayList<>();
|
||||
list.forEach(formData -> {
|
||||
|
||||
listMap.add(formData.toMap()); //转为map对象放入listMap中
|
||||
});
|
||||
Long total = evaluationCsvDataService.count(request);
|
||||
setPaginationInfo(request, listMap, total, model);
|
||||
}
|
||||
|
||||
return "project/datasource_csv";
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传csv文件.
|
||||
*
|
||||
* @param uploadInfo 上传的信息
|
||||
* @return project/datasource_csv.html
|
||||
*/
|
||||
|
||||
@PostMapping("/uploadCsv")
|
||||
public String uploadCsv(@ModelAttribute CsvUploadBean uploadInfo,
|
||||
RedirectAttributes ra, @RequestParam Map<String, String> params) throws IOException {
|
||||
|
||||
//上传文件信息放入数据库
|
||||
evaluationProjectService.uploadCsv(uploadInfo);
|
||||
|
||||
//设置工程ID
|
||||
ra.addAttribute("id", uploadInfo.getProjectId());
|
||||
ra.addAttribute("search", uploadInfo.getSearch());
|
||||
ra.addAttribute("randomKey", uploadInfo.getRandomKey());
|
||||
ra.addAttribute("method", uploadInfo.getMethod());
|
||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||
ra.addAttribute(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return "redirect:/evaluation/project/csv";
|
||||
}
|
||||
|
||||
/**
|
||||
* 导航的数据评估执行页面.
|
||||
*
|
||||
* @param request 评估请求
|
||||
* @param model session容器
|
||||
* @return 评估处理页面
|
||||
*/
|
||||
@LogOperation("评估执行页面")
|
||||
@PostMapping("/processEvaluation")
|
||||
public String processEvaluationPage(@RequestBody PageEvaluationRequest request, Model model) {
|
||||
|
||||
addProcessEvaluationModelAttribute(request, model);
|
||||
return "project/project_evaluation_process";
|
||||
}
|
||||
|
||||
private void addProcessEvaluationModelAttribute(PageEvaluationRequest request, Model model) {
|
||||
//获取工程名称
|
||||
EvaluationProject project = evaluationProjectService.getById(request.getProjectId());
|
||||
if (project != null) {
|
||||
model.addAttribute("projectName", project.getProjectName());
|
||||
}
|
||||
Indicator indicator = indicatorService.selectByTemplateId(request.getTemplateId());
|
||||
//获取指标名称
|
||||
if (indicator != null) {
|
||||
model.addAttribute("indicatorName", indicator.getName());
|
||||
}
|
||||
//设置数据源类型
|
||||
model.addAttribute("datasourceName",
|
||||
(request.getDatasourceType().equals("database") ? "数据库" : "CSV文件"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看根指标评估历史.
|
||||
*
|
||||
* @param projectId 工程ID
|
||||
* @return project/evaluation_root_history.html
|
||||
*/
|
||||
@GetMapping("/root_history")
|
||||
public String rootHistory(Integer projectId) {
|
||||
EvaluationHistory recentHistory = evaluationHistoryService.queryRecentByProjectId(projectId);
|
||||
if (recentHistory == null) {
|
||||
throw new RuntimeException("请先开始评估");
|
||||
}
|
||||
String randomKey = recentHistory.getRandomKey();
|
||||
// 重定向到另一个接口,带上参数
|
||||
return "redirect:root_history_by_randomKey?randomKey=" + randomKey + "&projectId=" + projectId;
|
||||
}
|
||||
|
||||
@GetMapping("/root_history_by_randomKey")
|
||||
public String rootHistoryByRandomKey(String randomKey, Integer projectId, Model model) {
|
||||
List<EvaluationRootResult> rootList = rootResultService.queryListByRandomKey(
|
||||
randomKey);
|
||||
model.addAttribute("projectId", projectId);
|
||||
model.addAttribute("rootList", rootList);
|
||||
return "project/evaluation_root_history";
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看报告.
|
||||
*
|
||||
* @param id 根历史记录ID
|
||||
*/
|
||||
@GetMapping("/reportData")
|
||||
@ResponseBody
|
||||
@LogOperation("查看报告")
|
||||
public OperateResult<ReportBean> report(Integer id) {
|
||||
final ReportBean reportBean = new ReportBean();
|
||||
//设置摘要信息
|
||||
EvaluationRootResult rootResult = rootResultService.getById(id);
|
||||
reportBean.setResult(rootResult);
|
||||
//规范化时间
|
||||
rootResult.setCreateTimeStr(
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").format(rootResult.getCreateTime()));
|
||||
|
||||
//获取底层指标数量
|
||||
int bottomNum = indicatorService.selectNoChildByTopId(rootResult.getIndicatorTopId()).size();
|
||||
reportBean.setBottomNum(bottomNum);
|
||||
|
||||
//设置所在评价集区间名称
|
||||
List<IndicatorTopLevel> levelList = topLevelService.getTopLevel(rootResult.getIndicatorTopId());
|
||||
levelList.sort((a, b) -> Double.compare(Double.parseDouble(b.getGrade()),
|
||||
Double.parseDouble(a.getGrade())));
|
||||
setLevelName(levelList, rootResult);
|
||||
reportBean.setLevelList(levelList);
|
||||
|
||||
//各维度得分对比
|
||||
String membership = rootResult.getMembershipScore();
|
||||
Map<String, Double> membershipMap = membershipScoreMap(membership);
|
||||
StringBuilder replaceMemberShipBuilder = new StringBuilder();
|
||||
levelList.forEach(level -> {
|
||||
if (membershipMap.get(level.getLevelName()) != null) {
|
||||
replaceMemberShipBuilder.append(level.getLevelName()).append(":")
|
||||
.append(membershipMap.get(level.getLevelName())).append(";");
|
||||
level.setActualValue(
|
||||
Double.parseDouble(level.getGrade()) * membershipMap.get(level.getLevelName()));
|
||||
}
|
||||
});
|
||||
//按照优先级重新覆盖隶属函数对应的值
|
||||
rootResult.setMembershipScore(replaceMemberShipBuilder.toString());
|
||||
//设置指标表格
|
||||
List<EvaluationIndicatorResult> indicatorResultList = evaluationIndicatorResultService.selectByRootId(
|
||||
id);
|
||||
reportBean.setDataNodeList(
|
||||
covertIndicatorResultToReportIndicatorNodeData(indicatorResultList, levelList));
|
||||
|
||||
//设置优和良综合
|
||||
reportBean.setHighRate(highRate(membershipMap));
|
||||
//设置隶属度pie数据
|
||||
reportBean.setPieDataList(pieDataList(membershipMap));
|
||||
//查询一级指标的名称和得分
|
||||
List<EvaluationIndicatorResult> firstLevelList = evaluationIndicatorResultService.queryListByParentIdAndRandomKey(
|
||||
rootResult.getIndicatorTopId(),
|
||||
|
||||
rootResult.getRandomKey(), rootResult.getId());
|
||||
|
||||
//设置柱状图数据
|
||||
reportBean.setBarDataList(covertIndicatorResultToBarData(firstLevelList));
|
||||
return OperateResult.success(reportBean);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导航到报告页面.
|
||||
*/
|
||||
@GetMapping("/report")
|
||||
public String reportPage() {
|
||||
return "project/evaluation_report";
|
||||
}
|
||||
|
||||
/**
|
||||
* 导航到历史页面.
|
||||
*/
|
||||
@GetMapping("/history")
|
||||
public String history(Integer projectId, Model model) {
|
||||
List<EvaluationHistory> list = evaluationHistoryService.queryListByProjectId(
|
||||
projectId);
|
||||
model.addAttribute("list", list);
|
||||
return "project/evaluation_history";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,36 +1,31 @@
|
|||
package com.hshh.evaluation.controller;
|
||||
|
||||
import com.hshh.evaluation.bean.DraftWeightData;
|
||||
import com.hshh.evaluation.bean.DynamicTable;
|
||||
import com.hshh.evaluation.bean.MetricComputeRequest;
|
||||
import com.hshh.evaluation.bean.MetricComputerResponse;
|
||||
import com.hshh.evaluation.bean.MetricMapperWeightBean;
|
||||
import com.hshh.evaluation.bean.MetricTableHeaderBean;
|
||||
import com.hshh.evaluation.bean.PageMetricComputeRequest;
|
||||
import com.hshh.evaluation.bean.PageMetricComputerResponse;
|
||||
import com.hshh.evaluation.bean.PageMetricMapperWeightBean;
|
||||
import com.hshh.evaluation.entity.EvaluationTemplate;
|
||||
import com.hshh.evaluation.entity.EvaluationTemplateWeight;
|
||||
import com.hshh.evaluation.service.EvaluationTemplateIndicatorWeightService;
|
||||
import com.hshh.evaluation.service.EvaluationTemplateService;
|
||||
import com.hshh.evaluation.service.EvaluationTemplateWeightService;
|
||||
import com.hshh.indicator.entity.Indicator;
|
||||
import com.hshh.indicator.service.IndicatorService;
|
||||
import com.hshh.system.annotation.LogOperation;
|
||||
import com.hshh.system.base.entity.TableRelations;
|
||||
import com.hshh.system.base.service.TableRelationsService;
|
||||
import com.hshh.system.common.Strings.StringOperationUtil;
|
||||
import com.hshh.system.common.algorithm.AhpNode;
|
||||
import com.hshh.system.common.algorithm.AhpTreeCompute;
|
||||
import com.hshh.system.common.Strings.StringUtil;
|
||||
import com.hshh.system.algorithm.ahp.AhpNode;
|
||||
import com.hshh.system.algorithm.ahp.AhpTreeCompute;
|
||||
import com.hshh.system.common.bean.JsTree;
|
||||
import com.hshh.system.common.bean.OperateResult;
|
||||
import com.hshh.system.common.bean.PaginationBean;
|
||||
import com.hshh.system.common.enums.ErrorCode;
|
||||
import com.hshh.system.common.enums.ErrorMessage;
|
||||
import com.hshh.system.common.util.DraftStore;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
|
@ -74,10 +69,16 @@ public class EvaluationTemplateController extends AssistantTemplateController {
|
|||
private TableRelationsService tableRelationsService;
|
||||
|
||||
/**
|
||||
* 权重服务类.
|
||||
* 权重服务详情类.
|
||||
*/
|
||||
@Resource
|
||||
private EvaluationTemplateWeightService evaluationTemplateWeightService;
|
||||
private EvaluationTemplateWeightService evaluationTemplateDetailWeightService;
|
||||
/**
|
||||
* 指标权重类.
|
||||
*/
|
||||
@Resource
|
||||
private EvaluationTemplateIndicatorWeightService evaluationTemplateIndicatorWeightService;
|
||||
|
||||
|
||||
/**
|
||||
* 默认页.
|
||||
|
|
@ -96,6 +97,7 @@ public class EvaluationTemplateController extends AssistantTemplateController {
|
|||
return "project_template/list";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 导航到增加页面.
|
||||
*
|
||||
|
|
@ -108,19 +110,6 @@ public class EvaluationTemplateController extends AssistantTemplateController {
|
|||
return "project_template/add";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指标树.
|
||||
*
|
||||
* @param id 项目ID
|
||||
* @return 指标树
|
||||
*/
|
||||
@GetMapping("/metricTree/{id}")
|
||||
@ResponseBody
|
||||
public OperateResult<List<JsTree>> metricTree(@PathVariable("id") Integer id, Model model) {
|
||||
|
||||
return OperateResult.success(indicatorService.metricTree(id));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 保存模板. 必须设置指标;设置完成权重,才成成功提交
|
||||
|
|
@ -131,6 +120,7 @@ public class EvaluationTemplateController extends AssistantTemplateController {
|
|||
*/
|
||||
@ResponseBody
|
||||
@PostMapping("/save")
|
||||
@LogOperation("保存模板")
|
||||
public OperateResult<Object> save(@Valid @RequestBody EvaluationTemplate evaluationTemplate,
|
||||
BindingResult bindingResult) {
|
||||
if (bindingResult.hasErrors()) {
|
||||
|
|
@ -150,35 +140,19 @@ public class EvaluationTemplateController extends AssistantTemplateController {
|
|||
evaluationTemplate.setCreateTime(LocalDateTime.now());
|
||||
|
||||
}
|
||||
|
||||
//1.合并权重数据
|
||||
Map<Integer, DraftWeightData> unitWeightDataMap = unitWeightMap(evaluationTemplate);
|
||||
|
||||
//2.填充数据;如果一个指标下面只有一个孩子,则默认填充为1
|
||||
List<Indicator> lonelyChild = indicatorService.queryLonelyChild(
|
||||
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);
|
||||
evaluationTemplateService.saveWhole(evaluationTemplate);
|
||||
return OperateResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id删除指标.
|
||||
* 根据id删除模板.
|
||||
*
|
||||
* @param id 要删除的ID
|
||||
* @return 操作结果
|
||||
*/
|
||||
@GetMapping("/remove/{id}")
|
||||
@ResponseBody
|
||||
@LogOperation("删除模板")
|
||||
public OperateResult<Object> remove(@PathVariable("id") Integer id) {
|
||||
List<TableRelations> reledList = tableRelationsService.queryRel(id,
|
||||
"m_data_evaluation_template");
|
||||
|
|
@ -208,157 +182,68 @@ public class EvaluationTemplateController extends AssistantTemplateController {
|
|||
}
|
||||
|
||||
/**
|
||||
* 暂存权重数据.
|
||||
* 获取指标树.
|
||||
*
|
||||
* @param data 权重数据 页面传入的权重map数据key为rowId_colId(from指标id_to指标ID)
|
||||
* value为{rowId:a,colId:b,value:0.1}类似
|
||||
* @return 操作结果
|
||||
* @param id 指标ID
|
||||
* @return 指标树
|
||||
*/
|
||||
@PostMapping("/receiveDraft")
|
||||
@GetMapping("/metricTree/{id}/{templateId}")
|
||||
@ResponseBody
|
||||
@SuppressWarnings("unchecked")
|
||||
public synchronized OperateResult<Void> receiveDraft(@RequestBody DraftWeightData data) {
|
||||
log.info("receive draft data: pId= {}", data.getParentIndicationId());
|
||||
//根据key获取已经缓存的信息
|
||||
Map<Integer, DraftWeightData> dataMap = DraftStore.get(data.getKey(), Map.class);
|
||||
//如果缓存不存在
|
||||
if (dataMap == null) {
|
||||
dataMap = new HashMap<>();
|
||||
public OperateResult<List<JsTree>> metricTree(@PathVariable("id") Integer id,
|
||||
@PathVariable("templateId") Integer templateId) {
|
||||
if (id == null) {
|
||||
return OperateResult.success(new ArrayList<>());
|
||||
}
|
||||
//key为上级指标
|
||||
dataMap.put(data.getParentIndicationId(), data);
|
||||
//更新缓存
|
||||
DraftStore.put(data.getKey(), dataMap);
|
||||
return OperateResult.success();
|
||||
//查询指标权重树
|
||||
Map<Integer, String> 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取暂存数据.
|
||||
*
|
||||
* @param requestData 请求数据.
|
||||
* @return 表格和数据
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@PostMapping("/getDraftData")
|
||||
public synchronized String getDraftData(@RequestBody DraftWeightData requestData, Model model) {
|
||||
//查看key 是否有缓存记录
|
||||
Map<Integer, Object> cacheData = DraftStore.get(requestData.getKey(), Map.class);
|
||||
//如果没有记录
|
||||
if (cacheData == null) { //从数据库中获取
|
||||
model.addAttribute("data", createNewDynamicFromDatabase(requestData));
|
||||
return "project_template/table";
|
||||
private void setWeightToTree(List<JsTree> jsTreeList, Map<Integer, String> weightMap,
|
||||
Map<Integer, List<EvaluationTemplateWeight>> weightDetailMap) {
|
||||
if (jsTreeList == null) {
|
||||
return;
|
||||
}
|
||||
//如果有记录查看对应的指标是否有记录
|
||||
Object cacheWeightObj = cacheData.get(requestData.getParentIndicationId());
|
||||
//如果对应指标没有记录
|
||||
if (cacheWeightObj == null) { //从数据库读取
|
||||
model.addAttribute("data", createNewDynamicFromDatabase(requestData));
|
||||
return "project_template/table";
|
||||
}
|
||||
DraftWeightData data = (DraftWeightData) cacheWeightObj;
|
||||
jsTreeList.forEach(tree -> {
|
||||
if (weightMap.containsKey((int) tree.getOriginalId())) {
|
||||
|
||||
model.addAttribute("data", createDynamicFromCache(data));
|
||||
tree.getData().put("weight", weightMap.get((int) tree.getOriginalId()));
|
||||
tree.setText(tree.getText() + "(" + weightMap.get((int) tree.getOriginalId()) + ")");
|
||||
} else {
|
||||
tree.setText(tree.getText() + "(1)");
|
||||
tree.getData().put("weight", 1);
|
||||
}
|
||||
if (weightDetailMap.containsKey((int) tree.getOriginalId())) {
|
||||
tree.getData().put("children",
|
||||
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";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 从数据库创建动态表.
|
||||
*
|
||||
* @param requestData 用户请求数据
|
||||
* @return 动态表
|
||||
*/
|
||||
private DynamicTable createNewDynamicFromDatabase(DraftWeightData requestData) {
|
||||
DynamicTable dynamicTable = new DynamicTable();
|
||||
//查询当前指标的子指标
|
||||
List<Indicator> children = indicatorService.queryChildren(requestData.getParentIndicationId());
|
||||
//获取指标权重信息
|
||||
List<EvaluationTemplateWeight> weightInDbList = evaluationTemplateWeightService.queryListByIndicatorParentIdAndTemplateId(
|
||||
requestData.getParentIndicationId(), requestData.getTemplateId());
|
||||
//转化为key=fromId+"_"+toId,value=self
|
||||
Map<String, EvaluationTemplateWeight> weightInMap = weightInDbList.stream()
|
||||
.collect(
|
||||
Collectors.toMap(a -> a.getFromIndicatorId() + "_" + a.getToIndicatorId(), a -> a));
|
||||
//设置头信息
|
||||
dynamicTable.setHeaderMap(createTableHeaderMap(children));
|
||||
|
||||
//设置权重信息
|
||||
List<List<MetricMapperWeightBean>> weight = new ArrayList<>();
|
||||
for (int i = 0; i < children.size(); i++) {
|
||||
List<MetricMapperWeightBean> innerList = createEmptyMapperList(requestData, children, i,
|
||||
weightInMap);
|
||||
weight.add(innerList);
|
||||
}
|
||||
|
||||
dynamicTable.setWeight(weight);
|
||||
return dynamicTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建表格头.
|
||||
*
|
||||
* @param children 子指标
|
||||
* @return 表格头信息
|
||||
*/
|
||||
private 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从数据库创建一个空的默认映射列表.
|
||||
*
|
||||
* @param requestData 请求数据
|
||||
* @param children 子指标
|
||||
* @param i 行号
|
||||
* @return 默认映射列表
|
||||
*/
|
||||
private static List<MetricMapperWeightBean> createEmptyMapperList(DraftWeightData requestData,
|
||||
List<Indicator> children, int i, Map<String, EvaluationTemplateWeight> weightInMap) {
|
||||
List<MetricMapperWeightBean> innerList = new ArrayList<>();
|
||||
for (Indicator child : children) {
|
||||
MetricMapperWeightBean weightBean = new MetricMapperWeightBean();
|
||||
//行ID
|
||||
weightBean.setRowId(children.get(i).getId());
|
||||
//列Id
|
||||
weightBean.setColId(child.getId());
|
||||
EvaluationTemplateWeight evaluationTemplateWeight = weightInMap.get(
|
||||
weightBean.getRowId() + "_" + weightBean.getColId());
|
||||
//初始默认为1
|
||||
weightBean.setValue(
|
||||
evaluationTemplateWeight == null ? "1" : evaluationTemplateWeight.getWeight() + "");
|
||||
|
||||
weightBean.setRowNum(evaluationTemplateWeight == null ? (i + 1)
|
||||
: evaluationTemplateWeight.getRowNum());
|
||||
weightBean.setParentId(requestData.getParentIndicationId());
|
||||
innerList.add(weightBean);
|
||||
}
|
||||
return innerList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从缓存中创建动态表.
|
||||
*
|
||||
* @param data 缓存数据
|
||||
* @return 动态表
|
||||
*/
|
||||
protected DynamicTable createDynamicFromCache(DraftWeightData data) {
|
||||
DynamicTable dynamicTable = new DynamicTable();
|
||||
dynamicTable.setHeaderMap(data.getHeaderMap());
|
||||
dynamicTable.setWeight(data.getWeight());
|
||||
return dynamicTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算指标,当设置变化时触发.
|
||||
*
|
||||
|
|
@ -367,13 +252,13 @@ public class EvaluationTemplateController extends AssistantTemplateController {
|
|||
*/
|
||||
@PostMapping("/computer")
|
||||
@ResponseBody
|
||||
public synchronized OperateResult<List<MetricComputerResponse>> computerWeight(
|
||||
@RequestBody MetricComputeRequest requests) {
|
||||
public synchronized OperateResult<List<PageMetricComputerResponse>> computerWeight(
|
||||
@RequestBody PageMetricComputeRequest requests) {
|
||||
//如果没有值,直接静默返回
|
||||
if (requests.getWeightList() == null || requests.getWeightList().isEmpty()) {
|
||||
return OperateResult.success();
|
||||
}
|
||||
final List<MetricComputerResponse> responseList = new ArrayList<>();
|
||||
final List<PageMetricComputerResponse> responseList = new ArrayList<>();
|
||||
|
||||
List<String> metricList = requests.getMetric();
|
||||
final AhpNode H = new AhpNode("H");
|
||||
|
|
@ -381,101 +266,21 @@ public class EvaluationTemplateController extends AssistantTemplateController {
|
|||
AhpNode m = new AhpNode(metric);
|
||||
H.add(m);
|
||||
});
|
||||
List<List<MetricMapperWeightBean>> weightList = requests.getWeightList();
|
||||
List<List<PageMetricMapperWeightBean>> weightList = requests.getWeightList();
|
||||
|
||||
double[][] data = StringOperationUtil.toDoubleArray(
|
||||
double[][] data = StringUtil.toDoubleArray(
|
||||
convertMetricMapperWeightBeanListToStrArray(weightList));
|
||||
H.setLocalMatrix(data);
|
||||
H.globalWeight = 1; // 根节点全局权重=1
|
||||
AhpTreeCompute.computeTree(H);
|
||||
H.children.forEach(child -> {
|
||||
MetricComputerResponse response = new MetricComputerResponse();
|
||||
PageMetricComputerResponse response = new PageMetricComputerResponse();
|
||||
response.setId(child.name);
|
||||
response.setWeight(String.format("%.2f", child.globalWeight));
|
||||
response.setWeight(String.format("%.4f", child.globalWeight));
|
||||
responseList.add(response);
|
||||
});
|
||||
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");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
package com.hshh.evaluation.entity;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.hshh.system.common.bean.BaseBean;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* csv数据.
|
||||
*
|
||||
* @author liDongYu
|
||||
* @since 2025-08-21
|
||||
*/
|
||||
@TableName("m_data_evaluation_csv_data")
|
||||
@Data
|
||||
public class EvaluationCsvData extends BaseBean {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
|
||||
private Integer projectId;
|
||||
|
||||
|
||||
private String randomKey;
|
||||
|
||||
|
||||
private String rawData;
|
||||
|
||||
private LocalDateTime createTime;
|
||||
|
||||
|
||||
private Integer userId;
|
||||
|
||||
public Map<String, Object> toMap() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("id", id);
|
||||
map.put("seq", getSeq());
|
||||
JSONObject jsonObj = JSON.parseObject(rawData, JSONObject.class);
|
||||
map.putAll(jsonObj);
|
||||
return map;
|
||||
|
||||
}
|
||||
|
||||
private String csvHeader;
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package com.hshh.evaluation.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 评估记录表.
|
||||
*
|
||||
* @author liDongYu
|
||||
* @since 2025-08-21
|
||||
*/
|
||||
@TableName("m_data_evaluation_history")
|
||||
@Data
|
||||
public class EvaluationHistory implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
|
||||
private LocalDateTime createTime;
|
||||
|
||||
|
||||
private Integer projectId;
|
||||
|
||||
|
||||
private Integer userId;
|
||||
|
||||
private String randomKey;
|
||||
private String datasourceType;
|
||||
private String membershipFunc;
|
||||
private String fuzzyOperator;
|
||||
|
||||
}
|
||||
|
|
@ -4,7 +4,8 @@ import com.baomidou.mybatisplus.annotation.IdType;
|
|||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.hshh.evaluation.bean.MetricMapperWeightBean;
|
||||
import com.hshh.evaluation.bean.PageIndicatorWeight;
|
||||
import com.hshh.evaluation.bean.PageMetricMapperWeightBean;
|
||||
import com.hshh.system.common.bean.BaseBean;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
|
@ -47,12 +48,16 @@ public class EvaluationTemplate extends BaseBean {
|
|||
private String indicatorTopName;
|
||||
@TableField(exist = false)
|
||||
private String templateStatusName;
|
||||
//提交时,当前页面对应的指标id,其余指标从缓存取
|
||||
@TableField(exist = false)
|
||||
private List<List<MetricMapperWeightBean>> currentPagePartData;
|
||||
//暂存指标权重的key
|
||||
@TableField(exist = false)
|
||||
private String draftKey;
|
||||
|
||||
/**
|
||||
* 前端传递的各个指标的权重.
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private List<PageIndicatorWeight> indicatorWeightList;
|
||||
/**
|
||||
* 前端传递的各个指标之间对比权重信息.
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private List<PageMetricMapperWeightBean> templateDetailWeightList;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
package com.hshh.evaluation.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import java.io.Serializable;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 模板指标权重表.
|
||||
*
|
||||
* @author liDongYu
|
||||
* @since 2025-08-21
|
||||
*/
|
||||
@TableName("m_data_evaluation_template_indicator_weight")
|
||||
@Data
|
||||
public class EvaluationTemplateIndicatorWeight implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
private Integer templateId;
|
||||
|
||||
private Integer indicatorTopId;
|
||||
|
||||
private Integer indicatorId;
|
||||
|
||||
private String weight;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -8,13 +8,13 @@ import lombok.Data;
|
|||
|
||||
/**
|
||||
* <p>
|
||||
* 模板指标权重表
|
||||
* 模板指标权重详情表.
|
||||
* </p>
|
||||
*
|
||||
* @author liDongYu
|
||||
* @since 2025-08-14
|
||||
*/
|
||||
@TableName("m_data_evaluation_template_weight")
|
||||
@TableName("m_data_evaluation_template_weight_detail")
|
||||
@Data
|
||||
public class EvaluationTemplateWeight implements Serializable {
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ public class EvaluationTemplateWeight implements Serializable {
|
|||
/**
|
||||
* 权重.
|
||||
*/
|
||||
private Double weight;
|
||||
private String weight;
|
||||
|
||||
/**
|
||||
* 父指标ID.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
package com.hshh.evaluation.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.hshh.evaluation.entity.EvaluationCsvData;
|
||||
import com.hshh.system.common.bean.PaginationBean;
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* 上传的评估数据csv原始数据记录.
|
||||
*
|
||||
* @author liDongYu
|
||||
* @since 2025-08-21
|
||||
*/
|
||||
public interface EvaluationCsvDataMapper extends BaseMapper<EvaluationCsvData> {
|
||||
|
||||
/**
|
||||
* 列表信息.
|
||||
*
|
||||
* @param paginationBean 请求参数
|
||||
* @return 结果列表
|
||||
*/
|
||||
List<EvaluationCsvData> list(PaginationBean paginationBean);
|
||||
|
||||
/**
|
||||
* 总条数.
|
||||
*
|
||||
* @param paginationBean 请求参数
|
||||
* @return 总条目
|
||||
*/
|
||||
Long count(PaginationBean paginationBean);
|
||||
|
||||
/**
|
||||
* 根据id集合查找记录.
|
||||
*
|
||||
* @param ids id集合
|
||||
* @return 结果列表
|
||||
*/
|
||||
List<EvaluationCsvData> selectByIds(@Param("ids") List<Integer> ids);
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.hshh.evaluation.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.hshh.evaluation.entity.EvaluationHistory;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 评估记录表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author liDongYu
|
||||
* @since 2025-08-21
|
||||
*/
|
||||
public interface EvaluationHistoryMapper extends BaseMapper<EvaluationHistory> {
|
||||
|
||||
/**
|
||||
* 根据项目查询最新的历史记录.
|
||||
*
|
||||
* @param projectId 工程ID
|
||||
* @return 最新的历史记录
|
||||
*/
|
||||
List<EvaluationHistory> queryRecentByProjectId(Integer projectId);
|
||||
}
|
||||
|
|
@ -28,4 +28,12 @@ public interface EvaluationProjectMapper extends BaseMapper<EvaluationProject> {
|
|||
* @return 总条数
|
||||
*/
|
||||
Long count(PaginationBean paginationBean);
|
||||
|
||||
/**
|
||||
* 根据工程ID获取到对应的基础设施ID.
|
||||
*
|
||||
* @param projectId 工程ID
|
||||
* @return 基础设施ID
|
||||
*/
|
||||
Long selectModelIdByProjectId(Integer projectId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
package com.hshh.evaluation.mapper;
|
||||
|
||||
import com.hshh.evaluation.entity.EvaluationTemplateIndicatorWeight;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author liDongYu
|
||||
* @since 2025-08-21
|
||||
*/
|
||||
public interface EvaluationTemplateIndicatorWeightMapper extends BaseMapper<EvaluationTemplateIndicatorWeight> {
|
||||
|
||||
}
|
||||
|
|
@ -28,4 +28,6 @@ public interface EvaluationTemplateMapper extends BaseMapper<EvaluationTemplate>
|
|||
* @return 总数
|
||||
*/
|
||||
Long count(PaginationBean search);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
package com.hshh.evaluation.service;
|
||||
|
||||
import com.hshh.evaluation.bean.PageEvaluationRequest;
|
||||
|
||||
|
||||
/**
|
||||
* 核心评估服务.
|
||||
*
|
||||
* @author LiDongYU
|
||||
* @since 2025/7/22
|
||||
*/
|
||||
public interface CoreEvaluationService {
|
||||
|
||||
/**
|
||||
* 核心评估算法.
|
||||
*
|
||||
* @param request 评估请求
|
||||
* @param userId 用户 ID
|
||||
*/
|
||||
void evaluation(PageEvaluationRequest request, Integer userId);
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package com.hshh.evaluation.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.hshh.evaluation.bean.CsvUploadBean;
|
||||
import com.hshh.evaluation.entity.EvaluationCsvData;
|
||||
import com.hshh.system.common.bean.PaginationBean;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* 保存每次评估时上传的csv数据.
|
||||
*
|
||||
* @author liDongYu
|
||||
* @since 2025-08-21
|
||||
*/
|
||||
public interface EvaluationCsvDataService extends IService<EvaluationCsvData> {
|
||||
|
||||
/**
|
||||
* 保存用户上传的csv文件记录.
|
||||
*
|
||||
* @param dataList csv解析后的数据
|
||||
* @param uploadInfo 附加表单信息
|
||||
*/
|
||||
void saveWhole(List<Map<String, String>> dataList, CsvUploadBean uploadInfo);
|
||||
|
||||
/**
|
||||
* 列表信息.
|
||||
*
|
||||
* @param paginationBean 请求参数
|
||||
* @return 结果列表
|
||||
*/
|
||||
List<EvaluationCsvData> list(PaginationBean paginationBean);
|
||||
|
||||
/**
|
||||
* 总条数.
|
||||
*
|
||||
* @param paginationBean 请求参数
|
||||
* @return 总条目
|
||||
*/
|
||||
Long count(PaginationBean paginationBean);
|
||||
|
||||
/**
|
||||
* 根据id集合查找记录.
|
||||
*
|
||||
* @param ids id集合
|
||||
* @return 结果列表
|
||||
*/
|
||||
List<EvaluationCsvData> selectByIds(@Param("ids") List<Integer> ids);
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.hshh.evaluation.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.hshh.evaluation.bean.PageEvaluationRequest;
|
||||
import com.hshh.evaluation.entity.EvaluationHistory;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 评估记录表 服务类.
|
||||
*
|
||||
* @author liDongYu
|
||||
* @since 2025-08-21
|
||||
*/
|
||||
public interface EvaluationHistoryService extends IService<EvaluationHistory> {
|
||||
|
||||
/**
|
||||
* 保存评估历史.
|
||||
*
|
||||
* @param request 评估请求
|
||||
*/
|
||||
void saveWhole(PageEvaluationRequest request);
|
||||
|
||||
/**
|
||||
* 根据项目查询最新的历史记录.
|
||||
*
|
||||
* @param projectId 工程ID
|
||||
* @return 最新的历史记录
|
||||
*/
|
||||
EvaluationHistory queryRecentByProjectId(Integer projectId);
|
||||
|
||||
/**
|
||||
* 查询工程评估的历史记录.
|
||||
*
|
||||
* @param projectId 工程ID
|
||||
* @return 历史记录
|
||||
*/
|
||||
List<EvaluationHistory> queryListByProjectId(Integer projectId);
|
||||
}
|
||||
|
|
@ -1,8 +1,11 @@
|
|||
package com.hshh.evaluation.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.hshh.evaluation.bean.CsvUploadBean;
|
||||
import com.hshh.evaluation.bean.PageEvaluationRequest;
|
||||
import com.hshh.evaluation.entity.EvaluationProject;
|
||||
import com.hshh.system.common.bean.PaginationBean;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
|
@ -43,4 +46,27 @@ public interface EvaluationProjectService extends IService<EvaluationProject> {
|
|||
* @param evaluationProject 工程数据
|
||||
*/
|
||||
void saveWhole(EvaluationProject evaluationProject);
|
||||
|
||||
/**
|
||||
* 根据工程ID获取到对应的基础设施ID.
|
||||
*
|
||||
* @param projectId 工程ID
|
||||
* @return 基础设施ID
|
||||
*/
|
||||
Long selectModelIdByProjectId(Integer projectId);
|
||||
|
||||
/**
|
||||
* 评估动作.
|
||||
*
|
||||
* @param request 评估请求
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
void evaluate(PageEvaluationRequest request, Integer userId);
|
||||
|
||||
/**
|
||||
* 上传csv文件.
|
||||
*
|
||||
* @param uploadInfo csv文件信息
|
||||
*/
|
||||
void uploadCsv(CsvUploadBean uploadInfo) throws IOException;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
package com.hshh.evaluation.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.hshh.evaluation.entity.EvaluationTemplateIndicatorWeight;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 指标权重服务类.
|
||||
*
|
||||
* @author liDongYu
|
||||
* @since 2025-08-21
|
||||
*/
|
||||
public interface EvaluationTemplateIndicatorWeightService extends
|
||||
IService<EvaluationTemplateIndicatorWeight> {
|
||||
|
||||
/**
|
||||
* 获取指标对应的权重.
|
||||
*
|
||||
* @param indicatorTopId 指标ID
|
||||
* @param templateId 模板 ID
|
||||
* @return 权重信息
|
||||
*/
|
||||
Map<Integer, String> getEvaluationTemplateIndicatorWeightMap(Integer indicatorTopId,
|
||||
Integer templateId);
|
||||
|
||||
/**
|
||||
* 保存指标权重信息.
|
||||
*
|
||||
* @param templateId 模板ID
|
||||
* @param indicatorTopId 顶级指标ID
|
||||
* @param list 指标权重集合
|
||||
*/
|
||||
void saveEvaluationTemplateIndicatorWeight(Integer templateId, Integer indicatorTopId,
|
||||
List<EvaluationTemplateIndicatorWeight> list);
|
||||
|
||||
/**
|
||||
* 删除指标权重信息.
|
||||
*
|
||||
* @param templateId 模板 ID
|
||||
* @param indicatorTopId 顶级指标ID
|
||||
*/
|
||||
void deleteByTemplateIdAndIndicatorTopId(Integer templateId, Integer indicatorTopId);
|
||||
}
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
package com.hshh.evaluation.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.hshh.evaluation.bean.DraftWeightData;
|
||||
import com.hshh.evaluation.bean.MetricMapperWeightBean;
|
||||
import com.hshh.evaluation.entity.EvaluationTemplate;
|
||||
import com.hshh.system.common.bean.PaginationBean;
|
||||
import java.util.List;
|
||||
|
|
@ -36,10 +34,10 @@ public interface EvaluationTemplateService extends IService<EvaluationTemplate>
|
|||
* 保存评估模板数据.
|
||||
*
|
||||
* @param evaluationTemplate 评估模板
|
||||
* @param weightData 权重
|
||||
|
||||
*/
|
||||
void saveWhole(EvaluationTemplate evaluationTemplate,
|
||||
Map<Integer, DraftWeightData> weightData);
|
||||
void saveWhole(EvaluationTemplate evaluationTemplate
|
||||
);
|
||||
|
||||
/**
|
||||
* 根据名称查询列表.
|
||||
|
|
@ -48,5 +46,13 @@ public interface EvaluationTemplateService extends IService<EvaluationTemplate>
|
|||
* @return 模板列表
|
||||
*/
|
||||
List<EvaluationTemplate> queryByName(String name);
|
||||
|
||||
/**
|
||||
* 删除模板(事务删除).
|
||||
*
|
||||
* @param evaluationTemplate 模板数据
|
||||
*/
|
||||
void deleteTemplate(EvaluationTemplate evaluationTemplate);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.hshh.evaluation.service;
|
|||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.hshh.evaluation.entity.EvaluationTemplateWeight;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 模板指标权重表 服务类.
|
||||
|
|
@ -13,24 +14,6 @@ import java.util.List;
|
|||
public interface EvaluationTemplateWeightService extends IService<EvaluationTemplateWeight> {
|
||||
|
||||
|
||||
/**
|
||||
* 根据模板id+指标id删除.
|
||||
*
|
||||
* @param templateId 模板ID
|
||||
* @param indicatorTopId 顶级指标ID
|
||||
* @param parentId 上级指标ID
|
||||
*/
|
||||
void deleteEvaluationTemplateWeightWithTemplateIdAndIndicatorId(Integer templateId,
|
||||
Integer indicatorTopId,
|
||||
Integer parentId);
|
||||
|
||||
/**
|
||||
* 根据模板ID删除权重信息.
|
||||
*
|
||||
* @param templateId 模板ID
|
||||
*/
|
||||
void deleteEvaluationTemplateWeightWithTemplateId(Integer templateId);
|
||||
|
||||
/**
|
||||
* 根据指标父ID和模板id获取权重列表.
|
||||
*
|
||||
|
|
@ -40,4 +23,43 @@ public interface EvaluationTemplateWeightService extends IService<EvaluationTemp
|
|||
*/
|
||||
List<EvaluationTemplateWeight> queryListByIndicatorParentIdAndTemplateId(
|
||||
Integer indicatorParentId, Integer templateId);
|
||||
|
||||
/**
|
||||
* 根据顶级ID和模板id获取权重列表.
|
||||
*
|
||||
* @param indicatorTopId 指标顶级ID
|
||||
* @param templateId 模板ID
|
||||
* @return 权重列表
|
||||
*/
|
||||
List<EvaluationTemplateWeight> queryListByIndicatorTopIdAndTemplateId(
|
||||
Integer indicatorTopId, Integer templateId);
|
||||
|
||||
/**
|
||||
* 指标对应的权重详情,按照父指标ID分类.
|
||||
*
|
||||
* @param indicatorParentId 父指标ID
|
||||
* @param templateId 模板ID
|
||||
* @return 权重map信息
|
||||
*/
|
||||
Map<Integer, List<EvaluationTemplateWeight>> groupByParentIndicatorId(Integer indicatorParentId,
|
||||
Integer templateId);
|
||||
|
||||
/**
|
||||
* 保存指标和指标之间的矩阵信息.
|
||||
*
|
||||
* @param templateId 模板ID
|
||||
* @param indicatorTopId 指标ID
|
||||
* @param weightList 互比矩阵列表
|
||||
*/
|
||||
void saveIndicatorMatrix(Integer templateId, Integer indicatorTopId,
|
||||
List<EvaluationTemplateWeight> weightList);
|
||||
|
||||
/**
|
||||
* 删除互比信息.
|
||||
*
|
||||
* @param templateId 模板ID
|
||||
* @param indicatorTopId 顶级指标ID
|
||||
*/
|
||||
void deleteByTemplateIdAndIndicatorTopId(Integer templateId, Integer indicatorTopId);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,514 @@
|
|||
package com.hshh.evaluation.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.hshh.evaluation.bean.PageEvaluationRequest;
|
||||
import com.hshh.evaluation.bean.SingleEvaluationData;
|
||||
import com.hshh.evaluation.entity.EvaluationCsvData;
|
||||
import com.hshh.evaluation.entity.EvaluationTemplate;
|
||||
import com.hshh.evaluation.service.CoreEvaluationService;
|
||||
import com.hshh.evaluation.service.EvaluationCsvDataService;
|
||||
import com.hshh.evaluation.service.EvaluationHistoryService;
|
||||
import com.hshh.evaluation.service.EvaluationRootResultService;
|
||||
import com.hshh.evaluation.service.EvaluationTemplateIndicatorWeightService;
|
||||
import com.hshh.evaluation.service.EvaluationTemplateService;
|
||||
import com.hshh.indicator.entity.Indicator;
|
||||
import com.hshh.indicator.entity.IndicatorBottomCsvMapper;
|
||||
import com.hshh.indicator.entity.IndicatorBottomFormMapper;
|
||||
import com.hshh.indicator.entity.IndicatorEvalItem;
|
||||
import com.hshh.indicator.entity.IndicatorTopLevel;
|
||||
import com.hshh.indicator.entity.IndicatorTopSet;
|
||||
import com.hshh.indicator.service.IndicatorBottomCsvMapperService;
|
||||
import com.hshh.indicator.service.IndicatorBottomFormMapperService;
|
||||
import com.hshh.indicator.service.IndicatorEvalItemService;
|
||||
import com.hshh.indicator.service.IndicatorService;
|
||||
import com.hshh.indicator.service.IndicatorTopLevelService;
|
||||
import com.hshh.indicator.service.IndicatorTopSetService;
|
||||
import com.hshh.model.entity.FormValue;
|
||||
import com.hshh.model.service.FormValueService;
|
||||
import com.hshh.system.algorithm.fuzzy.EvaluationLevel;
|
||||
import com.hshh.system.algorithm.fuzzy.FuzzyEvaluationService;
|
||||
import com.hshh.system.algorithm.fuzzy.FuzzyOperator;
|
||||
import com.hshh.system.algorithm.fuzzy.GlobalEvaluationConfig;
|
||||
import com.hshh.system.algorithm.fuzzy.GlobalMembershipFunction;
|
||||
import com.hshh.system.algorithm.fuzzy.GradeRange;
|
||||
import com.hshh.system.algorithm.fuzzy.IndicatorNode;
|
||||
import com.hshh.system.algorithm.fuzzy.LeafFullTriangularMembershipFunction;
|
||||
import com.hshh.system.algorithm.fuzzy.LeafHybridMembershipFunction;
|
||||
import com.hshh.system.common.bean.PaginationBean;
|
||||
import com.hshh.system.ws.WsEvaluationServer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* 模糊综合评估服务类 (重构后).
|
||||
*
|
||||
* @author LiDongYU
|
||||
* @since 2025/7/22
|
||||
*/
|
||||
@Service
|
||||
public class CoreEvaluationServiceImpl implements CoreEvaluationService {
|
||||
|
||||
|
||||
@Resource
|
||||
private EvaluationTemplateService evaluationTemplateService;
|
||||
@Resource
|
||||
private IndicatorTopSetService indicatorTopSetService;
|
||||
@Resource
|
||||
private IndicatorService indicatorService;
|
||||
@Resource
|
||||
private IndicatorTopLevelService indicatorTopLevelService;
|
||||
@Resource
|
||||
private IndicatorBottomFormMapperService indicatorBottomFormMapperService;
|
||||
@Resource
|
||||
private IndicatorBottomCsvMapperService indicatorBottomCsvMapperService;
|
||||
@Resource
|
||||
private FormValueService formValueService;
|
||||
@Resource
|
||||
private EvaluationCsvDataService evaluationCsvDataService;
|
||||
@Resource
|
||||
private EvaluationTemplateIndicatorWeightService evaluationTemplateIndicatorWeightService;
|
||||
@Resource
|
||||
private IndicatorEvalItemService indicatorEvalItemService; //底部指标评价集区间
|
||||
@Resource
|
||||
private EvaluationHistoryService evaluationHistoryService; //评估历史批次记录
|
||||
@Resource
|
||||
private EvaluationRootResultService evaluationRootResultService; //评估详情及概况记录
|
||||
|
||||
// 定义分页大小常量,便于管理
|
||||
private static final int DEFAULT_PAGE_SIZE = 100;
|
||||
|
||||
/**
|
||||
* 评估主入口方法。 通过策略模式分发到不同的数据源处理器.
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void evaluation(PageEvaluationRequest request, Integer userId) {
|
||||
long now = System.currentTimeMillis();
|
||||
try {
|
||||
|
||||
// 1. 获取评估所需的通用前置数据(模板、隶属度、评价集、指标树)
|
||||
EvaluationTemplate template = getTemplateOrThrow(request.getTemplateId());
|
||||
Integer indicatorTopId = template.getIndicatorTopId();
|
||||
request.setIndicatorTopId(indicatorTopId);
|
||||
IndicatorTopSet membershipFuncSet = getMembershipFuncSetOrThrow(indicatorTopId); //隶属函数设置
|
||||
List<IndicatorTopLevel> topLevelList = getTopLevelListOrThrow(indicatorTopId); //评价集区间
|
||||
Indicator indicator = indicatorService.getIndicator(indicatorTopId); //获取指标
|
||||
|
||||
Map<Integer, String> indicatorWeightMap = evaluationTemplateIndicatorWeightService.getEvaluationTemplateIndicatorWeightMap(
|
||||
indicatorTopId, template.getId()); //指标权重map
|
||||
Map<Integer, List<IndicatorEvalItem>> indicatorEvalItemMap = indicatorEvalItemService.getIndicatorEvalItemMapByIndicatorTopId(
|
||||
indicatorTopId); //底部指标评价范围
|
||||
// 2. 根据数据源类型,选择并执行相应的策略
|
||||
String dataSourceType = request.getDatasourceType();
|
||||
if ("database".equals(dataSourceType)) {
|
||||
// 获取数据库数据源的特定映射关系
|
||||
List<IndicatorBottomFormMapper> mapperList = indicatorBottomFormMapperService.selectIndicatorToFieldNameListByIndicatorTopId(
|
||||
indicatorTopId);
|
||||
if (mapperList == null || mapperList.isEmpty()) {
|
||||
throw new EvaluationException("设施字段和指标没有设置映射关系");
|
||||
}
|
||||
Map<Integer, String> mappingMap = mapperList.stream().collect(
|
||||
Collectors.toMap(IndicatorBottomFormMapper::getIndicatorId,
|
||||
IndicatorBottomFormMapper::getFiledName));
|
||||
|
||||
// 创建数据库策略并执行
|
||||
DataSourceStrategy<FormValue> dbStrategy = new DatabaseSourceStrategy(formValueService,
|
||||
FormValue::getModelData);
|
||||
processEvaluation(request, userId, membershipFuncSet, topLevelList, indicator, mappingMap,
|
||||
dbStrategy, indicatorWeightMap, indicatorEvalItemMap);
|
||||
|
||||
} else if ("csv".equals(dataSourceType)) {
|
||||
// 获取CSV数据源的特定映射关系
|
||||
List<IndicatorBottomCsvMapper> mapperList = indicatorBottomCsvMapperService.selectIndicatorToFieldNameListByIndicatorTopId(
|
||||
indicatorTopId);
|
||||
if (mapperList == null || mapperList.isEmpty()) {
|
||||
throw new EvaluationException("CSV列和指标没有设置映射关系");
|
||||
}
|
||||
Map<Integer, String> mappingMap = mapperList.stream().collect(
|
||||
Collectors.toMap(IndicatorBottomCsvMapper::getIndicatorId,
|
||||
IndicatorBottomCsvMapper::getCsvColumnName));
|
||||
|
||||
// 创建CSV策略并执行
|
||||
DataSourceStrategy<EvaluationCsvData> csvStrategy = new CsvSourceStrategy(
|
||||
evaluationCsvDataService, EvaluationCsvData::getRawData);
|
||||
processEvaluation(request, userId, membershipFuncSet, topLevelList, indicator, mappingMap,
|
||||
csvStrategy, indicatorWeightMap, indicatorEvalItemMap);
|
||||
|
||||
} else {
|
||||
throw new EvaluationException("不支持的数据源类型: " + dataSourceType);
|
||||
}
|
||||
|
||||
} catch (EvaluationException e) {
|
||||
WsEvaluationServer.sendTips(e.getMessage(), request.getRandomKey());
|
||||
}
|
||||
long end = System.currentTimeMillis();
|
||||
long diff = (end - now) / 1000;
|
||||
WsEvaluationServer.sendTips("整体评估完成,总耗时" + diff + "秒", request.getRandomKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一的评估处理流程,与具体数据源解耦.
|
||||
*
|
||||
* @param strategy 数据源策略,封装了如何获取数据的具体实现
|
||||
*/
|
||||
private <T> void processEvaluation(PageEvaluationRequest request, Integer userId,
|
||||
IndicatorTopSet membershipFuncSet, List<IndicatorTopLevel> topLevelList,
|
||||
Indicator indicator, Map<Integer, String> mappingMap,
|
||||
DataSourceStrategy<T> strategy, Map<Integer, String> indicatorWeightMap,
|
||||
Map<Integer, List<IndicatorEvalItem>> indicatorEvalItemMap) {
|
||||
|
||||
//首先记录本次评估
|
||||
request.setMembership(membershipFuncSet.getMembershipFunc());
|
||||
evaluationHistoryService.saveWhole(request);
|
||||
|
||||
boolean hasSpecificIds = request.getIds() != null && request.getIds().length > 0;
|
||||
|
||||
if (hasSpecificIds) {
|
||||
// --- 按指定ID列表进行评估 ---
|
||||
List<Integer> idList = Arrays.stream(request.getIds()).boxed().collect(Collectors.toList());
|
||||
List<T> dataList = strategy.fetchByIds(idList);
|
||||
|
||||
if (dataList != null && !dataList.isEmpty()) {
|
||||
List<SingleEvaluationData> evaluationData = strategy.extractData(dataList);
|
||||
startEvaluation(request, userId, membershipFuncSet, topLevelList, indicator, evaluationData,
|
||||
mappingMap, indicatorWeightMap, indicatorEvalItemMap);
|
||||
}
|
||||
} else {
|
||||
// --- 分页处理所有数据进行评估 ---
|
||||
PaginationBean paginationBean = new PaginationBean();
|
||||
paginationBean.setSearch(request.getSearch());
|
||||
paginationBean.setPageSize(DEFAULT_PAGE_SIZE);
|
||||
|
||||
paginationBean.setRandomKey(request.getRandomKey());
|
||||
paginationBean.setBusinessKey(request.getModelId());
|
||||
Long totalRecords = strategy.count(paginationBean);
|
||||
if (totalRecords == null || totalRecords == 0) {
|
||||
return; // 没有数据,直接返回
|
||||
}
|
||||
|
||||
int totalPages = (int) ((totalRecords + DEFAULT_PAGE_SIZE - 1) / DEFAULT_PAGE_SIZE);
|
||||
|
||||
for (int currentPage = 1; currentPage <= totalPages; currentPage++) {
|
||||
paginationBean.setCurrentPage(currentPage);
|
||||
List<T> currentPageData = strategy.fetchByPage(paginationBean);
|
||||
|
||||
if (currentPageData != null && !currentPageData.isEmpty()) {
|
||||
List<SingleEvaluationData> evaluationData = strategy.extractData(currentPageData);
|
||||
startEvaluation(request, userId, membershipFuncSet, topLevelList, indicator,
|
||||
evaluationData, mappingMap, indicatorWeightMap, indicatorEvalItemMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 数据源策略接口。 定义了数据访问的统一契约,将数据获取的算法从主流程中分离出来.
|
||||
*
|
||||
* @param <T> 数据源对应的实体类型 (如 FormValue, EvaluationCsvData)
|
||||
*/
|
||||
private interface DataSourceStrategy<T> {
|
||||
|
||||
List<T> fetchByIds(List<Integer> ids);
|
||||
|
||||
List<T> fetchByPage(PaginationBean paginationBean);
|
||||
|
||||
Long count(PaginationBean paginationBean);
|
||||
|
||||
List<SingleEvaluationData> extractData(List<T> dataList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据库数据源的具体实现策略.
|
||||
*/
|
||||
private static class DatabaseSourceStrategy implements DataSourceStrategy<FormValue> {
|
||||
|
||||
private final FormValueService service;
|
||||
private final Function<FormValue, String> dataExtractor;
|
||||
|
||||
public DatabaseSourceStrategy(FormValueService service,
|
||||
Function<FormValue, String> dataExtractor) {
|
||||
this.service = service;
|
||||
this.dataExtractor = dataExtractor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FormValue> fetchByIds(List<Integer> ids) {
|
||||
return service.selectByIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FormValue> fetchByPage(PaginationBean paginationBean) {
|
||||
return service.list(paginationBean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long count(PaginationBean paginationBean) {
|
||||
return service.count(paginationBean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SingleEvaluationData> extractData(List<FormValue> dataList) {
|
||||
List<SingleEvaluationData> list = new ArrayList<>();
|
||||
dataList.forEach(value -> {
|
||||
SingleEvaluationData singleEvaluationData = new SingleEvaluationData();
|
||||
singleEvaluationData.setData(value.getModelData());
|
||||
singleEvaluationData.setId(value.getId());
|
||||
singleEvaluationData.setType("database");
|
||||
list.add(singleEvaluationData);
|
||||
});
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CSV文件数据源的具体实现策略.
|
||||
*/
|
||||
private static class CsvSourceStrategy implements DataSourceStrategy<EvaluationCsvData> {
|
||||
|
||||
private final EvaluationCsvDataService service;
|
||||
private final Function<EvaluationCsvData, String> dataExtractor;
|
||||
|
||||
public CsvSourceStrategy(EvaluationCsvDataService service,
|
||||
Function<EvaluationCsvData, String> dataExtractor) {
|
||||
this.service = service;
|
||||
this.dataExtractor = dataExtractor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EvaluationCsvData> fetchByIds(List<Integer> ids) {
|
||||
|
||||
return service.selectByIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EvaluationCsvData> fetchByPage(PaginationBean paginationBean) {
|
||||
return service.list(paginationBean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long count(PaginationBean paginationBean) {
|
||||
return service.count(paginationBean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SingleEvaluationData> extractData(List<EvaluationCsvData> dataList) {
|
||||
List<SingleEvaluationData> list = new ArrayList<>();
|
||||
dataList.forEach(value -> {
|
||||
SingleEvaluationData singleEvaluationData = new SingleEvaluationData();
|
||||
singleEvaluationData.setId(value.getId());
|
||||
singleEvaluationData.setType("csv");
|
||||
singleEvaluationData.setData(value.getRawData());
|
||||
list.add(singleEvaluationData);
|
||||
});
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
private EvaluationTemplate getTemplateOrThrow(Integer templateId) {
|
||||
EvaluationTemplate template = evaluationTemplateService.getById(templateId);
|
||||
if (template == null) {
|
||||
throw new EvaluationException("没有找到对应的指标信息");
|
||||
}
|
||||
return template;
|
||||
}
|
||||
|
||||
private IndicatorTopSet getMembershipFuncSetOrThrow(Integer indicatorTopId) {
|
||||
IndicatorTopSet set = indicatorTopSetService.getIndicatorTopSet(indicatorTopId);
|
||||
if (set == null) {
|
||||
throw new EvaluationException("没有找到对应的隶属度函数");
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
private List<IndicatorTopLevel> getTopLevelListOrThrow(Integer indicatorTopId) {
|
||||
List<IndicatorTopLevel> list = indicatorTopLevelService.getTopLevel(indicatorTopId);
|
||||
if (list == null || list.isEmpty()) {
|
||||
throw new EvaluationException("没有找到全局指标集区间和分值");
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
private static class EvaluationException extends RuntimeException {
|
||||
|
||||
public EvaluationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
private GlobalEvaluationConfig globalEvaluationConfig(List<IndicatorTopLevel> topLevelList) {
|
||||
|
||||
topLevelList.sort((a, b) -> Integer.compare(b.getLevelOrder(), a.getLevelOrder()));
|
||||
List<EvaluationLevel> evaluationLevels = new ArrayList<>();
|
||||
|
||||
topLevelList.forEach(topLevel -> {
|
||||
EvaluationLevel evaluationLevel = new EvaluationLevel(topLevel.getLevelName(),
|
||||
Double.parseDouble(topLevel.getGrade()));
|
||||
evaluationLevels.add(evaluationLevel);
|
||||
});
|
||||
return new GlobalEvaluationConfig(evaluationLevels);
|
||||
}
|
||||
|
||||
/**
|
||||
* 核心评估触发点(此方法保持不变).
|
||||
*/
|
||||
private void startEvaluation(PageEvaluationRequest request, Integer userId,
|
||||
IndicatorTopSet membershipFuncSet, List<IndicatorTopLevel> topLevelList,
|
||||
Indicator indicator, List<SingleEvaluationData> originalList, Map<Integer, String> mappingMap,
|
||||
Map<Integer, String> indicatorWeightMap,
|
||||
Map<Integer, List<IndicatorEvalItem>> indicatorEvalItemMap) {
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
WsEvaluationServer.sendTips("分批次评估" + originalList.size() + "条记录",
|
||||
request.getRandomKey());
|
||||
|
||||
List<IndicatorNode> resultList = new ArrayList<>();
|
||||
//全局level等级及代表分
|
||||
GlobalEvaluationConfig globalEvaluationConfig = globalEvaluationConfig(topLevelList);
|
||||
//遍历数据
|
||||
for (SingleEvaluationData singleEvaluationData : originalList) {
|
||||
JSONObject jsonObject = JSON.parseObject(singleEvaluationData.getData());
|
||||
Map<String, Object> valueMap = new HashMap<>(jsonObject);
|
||||
IndicatorNode root = new IndicatorNode(indicator.getId() + "", indicator.getName());
|
||||
//工程ID
|
||||
root.setProjectId(request.getProjectId());
|
||||
//记录原始数据ID
|
||||
root.setOriginalId(indicator.getId());
|
||||
//记录数据来源
|
||||
root.setType(request.getDatasourceType());
|
||||
//本批次唯一标识
|
||||
root.setRandomKey(request.getRandomKey());
|
||||
//用户id
|
||||
root.setUserId(userId);
|
||||
//设置标识
|
||||
root.setLogicName(jsonObject.getString(request.getIdentifier()) == null ? ""
|
||||
: jsonObject.getString(request.getIdentifier()));
|
||||
root.setLevel(0);
|
||||
//设置隶属函数
|
||||
root.setMembershipFunction(new GlobalMembershipFunction(membershipFuncSet.getMembershipFunc(),
|
||||
Double.parseDouble(membershipFuncSet.getTriangleOverlapRatio()),
|
||||
|
||||
Double.parseDouble(membershipFuncSet.getTrianglePeakRatio()),
|
||||
Double.parseDouble(membershipFuncSet.getSoftEdgeS()),
|
||||
globalEvaluationConfig));
|
||||
//设置权重
|
||||
root.setWeight(indicatorWeightMap.get(indicator.getId()) == null ? 1
|
||||
: Double.parseDouble(indicatorWeightMap.get(indicator.getId())));
|
||||
recursionBuild(valueMap, indicatorWeightMap, indicator, root, mappingMap,
|
||||
globalEvaluationConfig, membershipFuncSet, indicatorEvalItemMap);
|
||||
|
||||
FuzzyEvaluationService service = new FuzzyEvaluationService(globalEvaluationConfig);
|
||||
service.performFuzzyEvaluation(root, FuzzyOperator.valueOf(request.getMethod()));
|
||||
resultList.add(root);
|
||||
}
|
||||
saveResult(resultList);
|
||||
|
||||
long end = System.currentTimeMillis();
|
||||
long diff = (end - now) / 1000;
|
||||
WsEvaluationServer.sendTips(
|
||||
"分批次结束评估" + originalList.size() + "条记录,耗时:" + diff + "秒",
|
||||
request.getRandomKey());
|
||||
}
|
||||
|
||||
private void saveResult(List<IndicatorNode> resultList) {
|
||||
resultList.forEach(indicatorNode -> {
|
||||
evaluationRootResultService.saveWhole(indicatorNode);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归一个根指标,设置实际值,隶属度,权重.
|
||||
*
|
||||
* @param valueMap 实际值map key=字段名称
|
||||
* @param indicatorWeightMap 权重map key=指标ID
|
||||
* @param indicator 当前指标
|
||||
* @param node 当前节点
|
||||
* @param mappingMap 指标id对应字段名称
|
||||
* @param globalEvaluationConfig 全局评价集集合
|
||||
* @param membershipFuncSet 全局隶属函数设置,告知采用那个函数
|
||||
* @param indicatorEvalItemMap 底部指标评价集区间
|
||||
*/
|
||||
private void recursionBuild(Map<String, Object> valueMap,
|
||||
Map<Integer, String> indicatorWeightMap,
|
||||
Indicator indicator, IndicatorNode node, Map<Integer, String> mappingMap,
|
||||
GlobalEvaluationConfig globalEvaluationConfig, IndicatorTopSet membershipFuncSet,
|
||||
Map<Integer, List<IndicatorEvalItem>> indicatorEvalItemMap) {
|
||||
if (indicator.getChildren() != null && !indicator.getChildren().isEmpty()) {
|
||||
node.setChildren(new ArrayList<>());
|
||||
indicator.getChildren().forEach(child -> {
|
||||
IndicatorNode childNode = new IndicatorNode(child.getId() + "", child.getName());
|
||||
childNode.setLevel(node.getLevel() + 1);
|
||||
//设置隶属函数
|
||||
childNode.setMembershipFunction(
|
||||
new GlobalMembershipFunction(membershipFuncSet.getMembershipFunc(),
|
||||
Double.parseDouble(membershipFuncSet.getTriangleOverlapRatio()),
|
||||
|
||||
Double.parseDouble(membershipFuncSet.getTrianglePeakRatio()),
|
||||
Double.parseDouble(membershipFuncSet.getSoftEdgeS()),
|
||||
globalEvaluationConfig));
|
||||
//设置权重
|
||||
childNode.setWeight(indicatorWeightMap.get(child.getId()) == null ? 1
|
||||
: Double.parseDouble(indicatorWeightMap.get(child.getId())));
|
||||
childNode.setOriginalId(child.getId());
|
||||
childNode.setRandomKey(node.getRandomKey());
|
||||
node.getChildren().add(childNode);
|
||||
|
||||
recursionBuild(valueMap, indicatorWeightMap, child, childNode, mappingMap,
|
||||
globalEvaluationConfig, membershipFuncSet, indicatorEvalItemMap);
|
||||
});
|
||||
} else { //是叶子节点,设置值,设置
|
||||
//根据mappingMap获取这个指标对应的输入字段
|
||||
String fieldName = mappingMap.get(indicator.getId());
|
||||
if (fieldName != null) {
|
||||
Object currentValue = valueMap.get(fieldName);
|
||||
if (currentValue != null) {
|
||||
node.setActualValue(Double.parseDouble(currentValue.toString()));
|
||||
}
|
||||
|
||||
}
|
||||
if (indicatorEvalItemMap.get(indicator.getId()) != null) {
|
||||
List<IndicatorEvalItem> indicatorEvalItemList = indicatorEvalItemMap.get(indicator.getId());
|
||||
List<GradeRange> gradeRanges = getGradeRange(indicatorEvalItemList);
|
||||
if (membershipFuncSet.getMembershipFunc().equals("TRAP_TRI")) {
|
||||
node.setMembershipFunction(new LeafHybridMembershipFunction(gradeRanges,
|
||||
Double.parseDouble(membershipFuncSet.getTriangleOverlapRatio()),
|
||||
|
||||
Double.parseDouble(membershipFuncSet.getTrianglePeakRatio()),
|
||||
Double.parseDouble(membershipFuncSet.getSoftEdgeS()),
|
||||
globalEvaluationConfig));
|
||||
} else {
|
||||
node.setMembershipFunction(new LeafFullTriangularMembershipFunction(gradeRanges,
|
||||
Double.parseDouble(membershipFuncSet.getTriangleOverlapRatio()),
|
||||
|
||||
Double.parseDouble(membershipFuncSet.getTrianglePeakRatio()),
|
||||
Double.parseDouble(membershipFuncSet.getSoftEdgeS()),
|
||||
globalEvaluationConfig));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<GradeRange> getGradeRange(List<IndicatorEvalItem> indicatorEvalItemList) {
|
||||
List<GradeRange> list = new ArrayList<>();
|
||||
indicatorEvalItemList.sort(
|
||||
Comparator.comparingDouble(a -> Double.parseDouble(a.getBottomValue())));
|
||||
indicatorEvalItemList.forEach(indicatorEvalItem -> {
|
||||
GradeRange gradeRange = new GradeRange(indicatorEvalItem.getEvaluationName(),
|
||||
Double.parseDouble(indicatorEvalItem.getBottomValue()),
|
||||
Double.parseDouble(indicatorEvalItem.getTopValue()));
|
||||
list.add(gradeRange);
|
||||
});
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
package com.hshh.evaluation.service.impl;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.hshh.evaluation.bean.CsvUploadBean;
|
||||
import com.hshh.evaluation.entity.EvaluationCsvData;
|
||||
import com.hshh.evaluation.mapper.EvaluationCsvDataMapper;
|
||||
import com.hshh.evaluation.service.EvaluationCsvDataService;
|
||||
import com.hshh.system.common.bean.PaginationBean;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* 服务实现类.
|
||||
*
|
||||
* @author liDongYu
|
||||
* @since 2025-08-21
|
||||
*/
|
||||
@Service
|
||||
public class EvaluationCsvDataServiceImpl extends
|
||||
ServiceImpl<EvaluationCsvDataMapper, EvaluationCsvData> implements
|
||||
EvaluationCsvDataService {
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void saveWhole(List<Map<String, String>> dataList, CsvUploadBean uploadInfo) {
|
||||
dataList.forEach(map -> {
|
||||
StringBuilder header = new StringBuilder();
|
||||
EvaluationCsvData evaluationCsvData = new EvaluationCsvData();
|
||||
//设置原始数据
|
||||
evaluationCsvData.setRawData(JSON.toJSONString(map));
|
||||
//设置随机key
|
||||
evaluationCsvData.setRandomKey(uploadInfo.getRandomKey());
|
||||
//时间
|
||||
evaluationCsvData.setCreateTime(LocalDateTime.now());
|
||||
//工程
|
||||
evaluationCsvData.setProjectId(uploadInfo.getProjectId());
|
||||
//设置表头
|
||||
evaluationCsvData.setCsvHeader(JSON.toJSONString(map.keySet()));
|
||||
save(evaluationCsvData);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EvaluationCsvData> list(PaginationBean paginationBean) {
|
||||
return this.baseMapper.list(paginationBean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long count(PaginationBean paginationBean) {
|
||||
return this.baseMapper.count(paginationBean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EvaluationCsvData> selectByIds(List<Integer> ids) {
|
||||
return this.baseMapper.selectByIds(ids);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package com.hshh.evaluation.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.hshh.evaluation.bean.PageEvaluationRequest;
|
||||
import com.hshh.evaluation.entity.EvaluationHistory;
|
||||
import com.hshh.evaluation.mapper.EvaluationHistoryMapper;
|
||||
import com.hshh.evaluation.service.EvaluationHistoryService;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 评估记录表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author liDongYu
|
||||
* @since 2025-08-21
|
||||
*/
|
||||
@Service
|
||||
public class EvaluationHistoryServiceImpl extends
|
||||
ServiceImpl<EvaluationHistoryMapper, EvaluationHistory> implements
|
||||
EvaluationHistoryService {
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void saveWhole(PageEvaluationRequest request) {
|
||||
EvaluationHistory history = new EvaluationHistory();
|
||||
history.setCreateTime(LocalDateTime.now());
|
||||
history.setUserId(request.getUserId());
|
||||
history.setRandomKey(request.getRandomKey());
|
||||
history.setProjectId(request.getProjectId());
|
||||
history.setDatasourceType(request.getDatasourceType());
|
||||
history.setMembershipFunc(request.getMembership());
|
||||
history.setFuzzyOperator(request.getMethod());
|
||||
save(history);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EvaluationHistory queryRecentByProjectId(Integer projectId) {
|
||||
List<EvaluationHistory> list = this.baseMapper.queryRecentByProjectId(projectId);
|
||||
if (!list.isEmpty()) {
|
||||
return list.get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EvaluationHistory> queryListByProjectId(Integer projectId) {
|
||||
QueryWrapper<EvaluationHistory> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("project_id", projectId);
|
||||
queryWrapper.orderByDesc("id");
|
||||
return this.baseMapper.selectList(queryWrapper);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,14 +2,30 @@ package com.hshh.evaluation.service.impl;
|
|||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.hshh.evaluation.bean.CsvUploadBean;
|
||||
import com.hshh.evaluation.bean.PageEvaluationRequest;
|
||||
import com.hshh.evaluation.entity.EvaluationProject;
|
||||
import com.hshh.evaluation.mapper.EvaluationProjectMapper;
|
||||
import com.hshh.evaluation.service.CoreEvaluationService;
|
||||
import com.hshh.evaluation.service.EvaluationCsvDataService;
|
||||
import com.hshh.evaluation.service.EvaluationProjectService;
|
||||
import com.hshh.system.base.service.TableRelationsService;
|
||||
import com.hshh.system.common.bean.PaginationBean;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.csv.CSVFormat;
|
||||
import org.apache.commons.csv.CSVParser;
|
||||
import org.apache.commons.csv.CSVRecord;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
|
|
@ -20,9 +36,10 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
* @since 2025-08-11
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class EvaluationProjectServiceImpl extends
|
||||
ServiceImpl<EvaluationProjectMapper, EvaluationProject> implements
|
||||
EvaluationProjectService {
|
||||
ServiceImpl<EvaluationProjectMapper, EvaluationProject> implements EvaluationProjectService {
|
||||
|
||||
|
||||
/**
|
||||
* 数据库引用关系记录服务类.
|
||||
|
|
@ -30,6 +47,19 @@ public class EvaluationProjectServiceImpl extends
|
|||
@Resource
|
||||
private TableRelationsService tableRelationsService;
|
||||
|
||||
|
||||
/**
|
||||
* 上传的csv文件数据记录服务类.
|
||||
*/
|
||||
@Resource
|
||||
private EvaluationCsvDataService evaluationCsvDataService;
|
||||
/**
|
||||
* 数据库记录评估服务.
|
||||
*/
|
||||
@Resource
|
||||
private CoreEvaluationService coreEvaluationService;
|
||||
|
||||
|
||||
@Override
|
||||
public List<EvaluationProject> list(PaginationBean paginationBean) {
|
||||
return this.baseMapper.list(paginationBean);
|
||||
|
|
@ -58,4 +88,61 @@ public class EvaluationProjectServiceImpl extends
|
|||
tableRelationsService.addRel(evaluationProject.getId(), "m_data_evaluation_project", relList,
|
||||
"m_data_evaluation_template");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long selectModelIdByProjectId(Integer projectId) {
|
||||
return this.baseMapper.selectModelIdByProjectId(projectId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 评估操作.
|
||||
*
|
||||
* @param request 评估请求
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void evaluate(PageEvaluationRequest request, Integer userId) {
|
||||
//评估接口单列
|
||||
coreEvaluationService.evaluation(request, userId);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uploadCsv(CsvUploadBean uploadInfo) throws IOException {
|
||||
CSVFormat format = CSVFormat.DEFAULT
|
||||
.builder()
|
||||
.setHeader() // 表示第一行就是表头
|
||||
.setSkipHeaderRecord(true) // 跳过第一行数据,不把它算到记录里
|
||||
.setIgnoreEmptyLines(true)
|
||||
.setTrim(true)
|
||||
.build();
|
||||
//获取表头信息
|
||||
List<Map<String, String>> rows = new ArrayList<>();
|
||||
try (Reader reader = new InputStreamReader(uploadInfo.getFile().getInputStream(),
|
||||
StandardCharsets.UTF_8);
|
||||
CSVParser parser = new CSVParser(reader, format)) {
|
||||
|
||||
// 取有序表头:Apache 返回 Map<列名, 索引>,按索引排序得到原始顺序
|
||||
List<String> headers = parser.getHeaderMap()
|
||||
.entrySet()
|
||||
.stream()
|
||||
.sorted(Comparator.comparingInt(Map.Entry::getValue))
|
||||
.map(Map.Entry::getKey)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (CSVRecord rec : parser) {
|
||||
Map<String, String> obj = new LinkedHashMap<>();
|
||||
for (String h : headers) {
|
||||
// get(h):按列名取值,可能为 null
|
||||
obj.put(h, rec.isMapped(h) ? rec.get(h) : null);
|
||||
}
|
||||
rows.add(obj);
|
||||
|
||||
|
||||
}
|
||||
evaluationCsvDataService.saveWhole(rows, uploadInfo);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
package com.hshh.evaluation.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.hshh.evaluation.entity.EvaluationTemplateIndicatorWeight;
|
||||
import com.hshh.evaluation.mapper.EvaluationTemplateIndicatorWeightMapper;
|
||||
import com.hshh.evaluation.service.EvaluationTemplateIndicatorWeightService;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author liDongYu
|
||||
* @since 2025-08-21
|
||||
*/
|
||||
@Service
|
||||
public class EvaluationTemplateIndicatorWeightServiceImpl extends
|
||||
ServiceImpl<EvaluationTemplateIndicatorWeightMapper, EvaluationTemplateIndicatorWeight> implements
|
||||
EvaluationTemplateIndicatorWeightService {
|
||||
|
||||
@Override
|
||||
public Map<Integer, String> getEvaluationTemplateIndicatorWeightMap(Integer indicatorTopId,
|
||||
Integer templateId) {
|
||||
QueryWrapper<EvaluationTemplateIndicatorWeight> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("indicator_top_id", indicatorTopId);
|
||||
wrapper.eq("template_id", templateId);
|
||||
List<EvaluationTemplateIndicatorWeight> list = this.list(wrapper);
|
||||
if (list != null && !list.isEmpty()) {
|
||||
return list.stream().collect(
|
||||
Collectors.toMap(EvaluationTemplateIndicatorWeight::getIndicatorId,
|
||||
EvaluationTemplateIndicatorWeight::getWeight));
|
||||
}
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void saveEvaluationTemplateIndicatorWeight(Integer templateId, Integer indicatorTopId,
|
||||
List<EvaluationTemplateIndicatorWeight> list) {
|
||||
//先删除旧信息
|
||||
QueryWrapper<EvaluationTemplateIndicatorWeight> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("template_id", templateId);
|
||||
wrapper.eq("indicator_top_id", indicatorTopId);
|
||||
this.remove(wrapper);
|
||||
if (list != null && !list.isEmpty()) {
|
||||
list.forEach(this::save);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTemplateIdAndIndicatorTopId(Integer templateId, Integer indicatorTopId) {
|
||||
QueryWrapper<EvaluationTemplateIndicatorWeight> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("template_id", templateId);
|
||||
wrapper.eq("indicator_top_id", indicatorTopId);
|
||||
this.remove(wrapper);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,15 +2,16 @@ package com.hshh.evaluation.service.impl;
|
|||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
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.EvaluationTemplateIndicatorWeight;
|
||||
import com.hshh.evaluation.entity.EvaluationTemplateWeight;
|
||||
import com.hshh.evaluation.mapper.EvaluationTemplateMapper;
|
||||
import com.hshh.evaluation.service.EvaluationTemplateIndicatorWeightService;
|
||||
import com.hshh.evaluation.service.EvaluationTemplateService;
|
||||
import com.hshh.evaluation.service.EvaluationTemplateWeightService;
|
||||
import com.hshh.system.common.bean.PaginationBean;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
|
@ -25,8 +26,16 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
public class EvaluationTemplateServiceImpl extends
|
||||
ServiceImpl<EvaluationTemplateMapper, EvaluationTemplate> implements EvaluationTemplateService {
|
||||
|
||||
/**
|
||||
* 指标互比详情服务类.
|
||||
*/
|
||||
@Resource
|
||||
private EvaluationTemplateWeightService evaluationTemplateWeightService;
|
||||
private EvaluationTemplateWeightService evaluationTemplateDetailWeightService;
|
||||
/**
|
||||
* 指标权重服务类.
|
||||
*/
|
||||
@Resource
|
||||
private EvaluationTemplateIndicatorWeightService evaluationTemplateIndicatorWeightService;
|
||||
|
||||
@Override
|
||||
public List<EvaluationTemplate> list(PaginationBean search) {
|
||||
|
|
@ -40,42 +49,52 @@ public class EvaluationTemplateServiceImpl extends
|
|||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void saveWhole(EvaluationTemplate evaluationTemplate,
|
||||
Map<Integer, DraftWeightData> weightDataMap) {
|
||||
public void saveWhole(EvaluationTemplate evaluationTemplate
|
||||
) {
|
||||
//保存或者更新模板信息
|
||||
saveOrUpdate(evaluationTemplate);
|
||||
if (weightDataMap != null && !weightDataMap.isEmpty()) {
|
||||
|
||||
weightDataMap.forEach((k, v) -> {
|
||||
//先按模板ID+上级指标ID
|
||||
evaluationTemplateWeightService.deleteEvaluationTemplateWeightWithTemplateIdAndIndicatorId(
|
||||
evaluationTemplate.getId(), evaluationTemplate.getIndicatorTopId(), k);
|
||||
v.getWeight().forEach(weightBeanList -> {
|
||||
weightBeanList.forEach(weightBean -> {
|
||||
EvaluationTemplateWeight evaluationTemplateWeight = new EvaluationTemplateWeight();
|
||||
//设置模板ID
|
||||
evaluationTemplateWeight.setTemplateId(evaluationTemplate.getId());
|
||||
//设置权重
|
||||
evaluationTemplateWeight.setWeight(Double.valueOf(weightBean.getValue()));
|
||||
//设置顶级指标ID
|
||||
evaluationTemplateWeight.setIndicatorTopId(evaluationTemplate.getIndicatorTopId());
|
||||
//fromIndicatorId
|
||||
evaluationTemplateWeight.setFromIndicatorId(weightBean.getRowId());
|
||||
//toIndicatorId
|
||||
evaluationTemplateWeight.setToIndicatorId(weightBean.getColId());
|
||||
//设置上级指标ID
|
||||
evaluationTemplateWeight.setIndicatorParentId(weightBean.getParentId());
|
||||
//设置行号
|
||||
evaluationTemplateWeight.setRowNum(weightBean.getRowNum());
|
||||
//保存
|
||||
evaluationTemplateWeightService.save(evaluationTemplateWeight);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
//保存指标权重信息
|
||||
List<EvaluationTemplateIndicatorWeight> indicatorWeightList = new ArrayList<>();
|
||||
if (evaluationTemplate.getIndicatorWeightList() != null
|
||||
&& !evaluationTemplate.getIndicatorWeightList()
|
||||
.isEmpty()) {
|
||||
evaluationTemplate.getIndicatorWeightList().forEach(a -> {
|
||||
EvaluationTemplateIndicatorWeight indicatorWeight = new EvaluationTemplateIndicatorWeight();
|
||||
indicatorWeight.setWeight(a.getWeight());
|
||||
//设置模板ID
|
||||
indicatorWeight.setTemplateId(evaluationTemplate.getId());
|
||||
//设置顶级指标ID
|
||||
indicatorWeight.setIndicatorTopId(evaluationTemplate.getIndicatorTopId());
|
||||
//设置指标ID
|
||||
indicatorWeight.setIndicatorId(a.getIndicatorId());
|
||||
indicatorWeightList.add(indicatorWeight);
|
||||
});
|
||||
|
||||
evaluationTemplateIndicatorWeightService.saveEvaluationTemplateIndicatorWeight(
|
||||
evaluationTemplate.getId(), evaluationTemplate.getIndicatorTopId(), indicatorWeightList);
|
||||
}
|
||||
|
||||
//保存各个指标之间互相比较的权重信息
|
||||
if (evaluationTemplate.getTemplateDetailWeightList() != null
|
||||
&& !evaluationTemplate.getTemplateDetailWeightList()
|
||||
.isEmpty()) {
|
||||
List<EvaluationTemplateWeight> detailList = new ArrayList<>();
|
||||
evaluationTemplate.getTemplateDetailWeightList().forEach(a -> {
|
||||
EvaluationTemplateWeight detailWeight = new EvaluationTemplateWeight();
|
||||
//设置模板ID
|
||||
detailWeight.setTemplateId(evaluationTemplate.getId());
|
||||
//设置顶级指标ID
|
||||
detailWeight.setIndicatorTopId(evaluationTemplate.getIndicatorTopId());
|
||||
detailWeight.setFromIndicatorId(a.getRowId());
|
||||
detailWeight.setToIndicatorId(a.getColId());
|
||||
detailWeight.setWeight(a.getValue());
|
||||
detailWeight.setIndicatorParentId(a.getParentId());
|
||||
detailWeight.setRowNum(a.getRowNum());
|
||||
detailList.add(detailWeight);
|
||||
});
|
||||
evaluationTemplateDetailWeightService.saveIndicatorMatrix(evaluationTemplate.getId(),
|
||||
evaluationTemplate.getIndicatorTopId(), detailList);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -88,8 +107,16 @@ public class EvaluationTemplateServiceImpl extends
|
|||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void deleteTemplate(EvaluationTemplate evaluationTemplate) {
|
||||
evaluationTemplateWeightService.deleteEvaluationTemplateWeightWithTemplateId(
|
||||
evaluationTemplate.getId());
|
||||
|
||||
//删除互比信息
|
||||
evaluationTemplateDetailWeightService.deleteByTemplateIdAndIndicatorTopId(
|
||||
evaluationTemplate.getId(), evaluationTemplate.getIndicatorTopId());
|
||||
//删除指标权重信息
|
||||
evaluationTemplateIndicatorWeightService.deleteByTemplateIdAndIndicatorTopId(
|
||||
evaluationTemplate.getId(), evaluationTemplate.getIndicatorTopId());
|
||||
//删除模板
|
||||
this.removeById(evaluationTemplate.getId());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,9 @@ import com.hshh.evaluation.entity.EvaluationTemplateWeight;
|
|||
import com.hshh.evaluation.mapper.EvaluationTemplateWeightMapper;
|
||||
import com.hshh.evaluation.service.EvaluationTemplateWeightService;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
|
@ -23,25 +24,6 @@ public class EvaluationTemplateWeightServiceImpl extends
|
|||
EvaluationTemplateWeightService {
|
||||
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void deleteEvaluationTemplateWeightWithTemplateIdAndIndicatorId(Integer templateId,
|
||||
Integer indicatorTopId, Integer parentId) {
|
||||
QueryWrapper<EvaluationTemplateWeight> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("template_id", templateId);
|
||||
queryWrapper.eq("indicator_top_id", indicatorTopId);
|
||||
queryWrapper.eq("indicator_parent_id", parentId);
|
||||
this.remove(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteEvaluationTemplateWeightWithTemplateId(Integer templateId) {
|
||||
QueryWrapper<EvaluationTemplateWeight> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("template_id", templateId);
|
||||
|
||||
this.remove(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EvaluationTemplateWeight> queryListByIndicatorParentIdAndTemplateId(
|
||||
Integer indicatorParentId, Integer templateId) {
|
||||
|
|
@ -51,4 +33,45 @@ public class EvaluationTemplateWeightServiceImpl extends
|
|||
queryWrapper.eq("indicator_parent_id", indicatorParentId);
|
||||
return this.list(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Integer, List<EvaluationTemplateWeight>> groupByParentIndicatorId(
|
||||
Integer indicatorParentId, Integer templateId) {
|
||||
List<EvaluationTemplateWeight> list = this.queryListByIndicatorTopIdAndTemplateId(
|
||||
indicatorParentId, templateId);
|
||||
if (!list.isEmpty()) {
|
||||
return list.stream()
|
||||
.collect(Collectors.groupingBy(EvaluationTemplateWeight::getIndicatorParentId));
|
||||
}
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveIndicatorMatrix(Integer templateId, Integer indicatorTopId,
|
||||
List<EvaluationTemplateWeight> weightList) {
|
||||
QueryWrapper<EvaluationTemplateWeight> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("template_id", templateId);
|
||||
queryWrapper.eq("indicator_top_id", indicatorTopId);
|
||||
this.remove(queryWrapper);
|
||||
if (weightList != null && !weightList.isEmpty()) {
|
||||
weightList.forEach(this::save);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByTemplateIdAndIndicatorTopId(Integer templateId, Integer indicatorTopId) {
|
||||
QueryWrapper<EvaluationTemplateWeight> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("template_id", templateId);
|
||||
queryWrapper.eq("indicator_top_id", indicatorTopId);
|
||||
this.remove(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EvaluationTemplateWeight> queryListByIndicatorTopIdAndTemplateId(
|
||||
Integer indicatorTopId, Integer templateId) {
|
||||
QueryWrapper<EvaluationTemplateWeight> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("template_id", templateId);
|
||||
queryWrapper.eq("indicator_top_id", indicatorTopId);
|
||||
return this.list(queryWrapper);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
package com.hshh.indicator.bean;
|
||||
|
||||
import com.hshh.indicator.entity.IndicatorEvalItem;
|
||||
import com.hshh.system.common.bean.JsTree;
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
/**
|
||||
* [类的简要说明]
|
||||
* <p>
|
||||
* [详细描述,可选]
|
||||
* <p>
|
||||
*
|
||||
* @author LiDongYU
|
||||
* @since 2025/7/22
|
||||
*/
|
||||
@Data
|
||||
public class IndicatorEvalBean {
|
||||
|
||||
private List<JsTree> jsTreeList;
|
||||
//评价集范围
|
||||
private List<IndicatorEvalItem> evalItemList;
|
||||
//顶级指标ID
|
||||
private Integer indicatorTopId;
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.hshh.indicator.bean;
|
||||
|
||||
import com.hshh.indicator.entity.IndicatorTopLevel;
|
||||
import com.hshh.indicator.entity.IndicatorTopSet;
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 接收全局指标level,隶属函数bean.
|
||||
*
|
||||
* @author LiDongYU
|
||||
* @since 2025/7/22
|
||||
*/
|
||||
@Data
|
||||
public class IndicatorSetBean {
|
||||
|
||||
private List<IndicatorTopLevel> levels;
|
||||
private IndicatorTopSet topSet;
|
||||
}
|
||||
|
|
@ -1,20 +1,23 @@
|
|||
package com.hshh.indicator.controller;
|
||||
|
||||
import com.hshh.indicator.bean.IndicatorEvalBean;
|
||||
import com.hshh.indicator.entity.Indicator;
|
||||
import com.hshh.indicator.entity.IndicatorEvalItem;
|
||||
import com.hshh.indicator.service.IndicatorEvalItemService;
|
||||
import com.hshh.indicator.service.IndicatorService;
|
||||
import com.hshh.indicator.service.IndicatorTopLevelService;
|
||||
import com.hshh.indicator.service.IndicatorTopSetService;
|
||||
import com.hshh.system.annotation.LogOperation;
|
||||
import com.hshh.system.common.bean.BaseController;
|
||||
import com.hshh.system.common.bean.JsTree;
|
||||
import com.hshh.system.common.bean.OperateResult;
|
||||
import com.hshh.system.common.enums.ErrorCode;
|
||||
import com.hshh.system.common.enums.ErrorMessage;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
|
@ -32,13 +35,14 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
|||
@RequestMapping("/evaluation")
|
||||
public class EvaluationController extends BaseController {
|
||||
|
||||
|
||||
/**
|
||||
* 指标服务类. 查询所有指标列表
|
||||
* 指标服务类.
|
||||
*/
|
||||
@Resource
|
||||
private IndicatorService indicatorService;
|
||||
/**
|
||||
* 评价服务类.
|
||||
* 指标评价集范围服务类.
|
||||
*/
|
||||
@Resource
|
||||
private IndicatorEvalItemService indicatorEvalItemService;
|
||||
|
|
@ -49,109 +53,87 @@ public class EvaluationController extends BaseController {
|
|||
* @return indicator/evaluation_list.html
|
||||
*/
|
||||
@GetMapping("/evaluationList")
|
||||
public String evaluationList(Integer topIndicatorId, Integer indicatorId, Model model) {
|
||||
public String evaluationList(Model model) {
|
||||
setNavigateTitle(model, "/evaluation/evaluationList");
|
||||
List<Indicator> rootList = indicatorService.queryRootList();
|
||||
if (rootList != null && !rootList.isEmpty()) {
|
||||
if (topIndicatorId != null) {
|
||||
for (Indicator indicator : rootList) {
|
||||
if (indicator.getId().equals(topIndicatorId)) {
|
||||
indicator.setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
topIndicatorId = rootList.get(0).getId();
|
||||
rootList.get(0).setChecked(true);
|
||||
|
||||
}
|
||||
}
|
||||
//查询所有没有孩子的子节点
|
||||
List<Indicator> indicatorListWithoutChildren = indicatorService.selectNoChildByTopId(
|
||||
topIndicatorId);
|
||||
if (!indicatorListWithoutChildren.isEmpty()) {
|
||||
if (indicatorId != null) {
|
||||
for (Indicator indicator : indicatorListWithoutChildren) {
|
||||
if (indicator.getId().equals(indicatorId)) {
|
||||
indicator.setChecked(true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
indicatorListWithoutChildren.get(0).setChecked(true);
|
||||
|
||||
}
|
||||
}
|
||||
//查询子指标的评价集
|
||||
List<IndicatorEvalItem> evaluationList = indicatorEvalItemService.queryListByIndicatorId(
|
||||
indicatorId == null ? (indicatorListWithoutChildren.isEmpty() ? 0
|
||||
: indicatorListWithoutChildren.get(0).getId()) : indicatorId);
|
||||
model.addAttribute("evaluationList", evaluationList);
|
||||
model.addAttribute("rootList", rootList);
|
||||
model.addAttribute("indicatorListWithoutChildren", indicatorListWithoutChildren);
|
||||
List<Indicator> bottomList = indicatorService.queryRootList();
|
||||
model.addAttribute("rootList", bottomList);
|
||||
return "indicator/evaluation_list";
|
||||
}
|
||||
|
||||
/**
|
||||
* 导航到评价集增加页面.
|
||||
* 获取当前指标的评价信息.
|
||||
*
|
||||
* @return indicator/add_evaluation.html
|
||||
* @param id 指标ID
|
||||
* @return 评价详细信息
|
||||
*/
|
||||
@RequestMapping("/evaluationAdd")
|
||||
@Operation(summary = "导航到评价集增加页面", description = "导航到评价集增加页面")
|
||||
public String evaluationAdd() {
|
||||
return "indicator/add_evaluation";
|
||||
@GetMapping("/{id}")
|
||||
@ResponseBody
|
||||
|
||||
public OperateResult<IndicatorEvalBean> metricIdChange(@PathVariable("id") Integer id) {
|
||||
IndicatorEvalBean indicatorEvalBean = new IndicatorEvalBean();
|
||||
|
||||
//查询底部评价集
|
||||
indicatorEvalBean.setJsTreeList(evalItemTree(id));
|
||||
return OperateResult.success(indicatorEvalBean);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存评价集.
|
||||
* 建立底部指标树.
|
||||
*
|
||||
* @param item 评价集数据
|
||||
* @param bindingResult 字段错误信息
|
||||
* @param id 根指标
|
||||
* @return 包含底部指标的树
|
||||
*/
|
||||
private List<JsTree> evalItemTree(Integer id) {
|
||||
List<JsTree> jsTreeList = new ArrayList<>();
|
||||
JsTree jsTree = new JsTree();
|
||||
jsTree.setText("根指标");
|
||||
jsTree.setId("0");
|
||||
jsTreeList.add(jsTree);
|
||||
jsTree.setChildren(new ArrayList<>());
|
||||
//查询根部指标所有底部指标
|
||||
List<Indicator> bottomList = indicatorService.selectNoChildByTopId(
|
||||
id);
|
||||
//查询底部指标的评价集范围
|
||||
Map<Integer, List<IndicatorEvalItem>> evalMap = indicatorEvalItemService.getIndicatorEvalItemMapByIndicatorTopId(
|
||||
id);
|
||||
bottomList.forEach(a -> {
|
||||
JsTree child = new JsTree();
|
||||
jsTree.getChildren().add(child);
|
||||
child.setId("tree_" + a.getId());
|
||||
child.setOriginalId(a.getId());
|
||||
child.setText(a.getName());
|
||||
if (evalMap.containsKey(a.getId())) {
|
||||
List<IndicatorEvalItem> evalItemList = evalMap.get(a.getId());
|
||||
evalItemList = evalItemList.stream().peek(aa -> {
|
||||
if (aa.getEqualValue() == null) {
|
||||
aa.setEqualValue("");
|
||||
}
|
||||
}).collect(Collectors.toList());
|
||||
StringBuilder tipBuilder = new StringBuilder();
|
||||
evalItemList.forEach(evalItem -> {
|
||||
tipBuilder.append(evalItem.getEvaluationName()).append(":")
|
||||
.append(evalItem.getBottomValue())
|
||||
.append(",").append(evalItem.getTopValue());
|
||||
child.setText(a.getName() + "(" + tipBuilder + ")");
|
||||
});
|
||||
child.getData().put("range", evalItemList);
|
||||
}
|
||||
|
||||
});
|
||||
return jsTreeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存评价集,隶属函数设置,评级集枚举和分值.
|
||||
*
|
||||
* @param data 前端数据
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PostMapping("/save")
|
||||
@ResponseBody
|
||||
public OperateResult<Object> save(@Valid @RequestBody IndicatorEvalItem item,
|
||||
BindingResult bindingResult) {
|
||||
if (bindingResult.hasErrors()) {
|
||||
return errorsInputHandle(bindingResult);
|
||||
}
|
||||
indicatorEvalItemService.saveOrUpdate(item);
|
||||
@LogOperation("保存评价集")
|
||||
public OperateResult<Void> save(@RequestBody IndicatorEvalBean data) {
|
||||
indicatorEvalItemService.saveWhole(data);
|
||||
return OperateResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id删除评价.
|
||||
*
|
||||
* @param id 要删除的id
|
||||
* @return 操作结果
|
||||
*/
|
||||
@GetMapping("/remove/{id}")
|
||||
@ResponseBody
|
||||
public OperateResult<Void> remove(@PathVariable("id") Integer id) {
|
||||
IndicatorEvalItem evaluation = indicatorEvalItemService.getById(id);
|
||||
if (evaluation == null) {
|
||||
return OperateResult.error(null, ErrorMessage.ID_NOT_EXIT.getMessage(),
|
||||
ErrorCode.BUSINESS_ERROR.getCode());
|
||||
}
|
||||
indicatorEvalItemService.removeById(id);
|
||||
return OperateResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ID查询评价信息.
|
||||
*
|
||||
* @param id 评价ID
|
||||
* @return id对应的评价
|
||||
*/
|
||||
@GetMapping("/{id}")
|
||||
@ResponseBody
|
||||
public OperateResult<IndicatorEvalItem> view(@PathVariable("id") Integer id) {
|
||||
IndicatorEvalItem evaluation = indicatorEvalItemService.getById(id);
|
||||
if (evaluation == null) {
|
||||
return OperateResult.error(null, ErrorMessage.ID_NOT_EXIT.getMessage(),
|
||||
ErrorCode.BUSINESS_ERROR.getCode());
|
||||
}
|
||||
return OperateResult.success(evaluation, ErrorMessage.SUCCESS.getMessage());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import com.hshh.model.entity.FormFieldConfig;
|
|||
import com.hshh.model.entity.ModelDefine;
|
||||
import com.hshh.model.service.FormFieldConfigService;
|
||||
import com.hshh.model.service.ModelDefineService;
|
||||
import com.hshh.system.annotation.LogOperation;
|
||||
import com.hshh.system.common.bean.BaseController;
|
||||
import com.hshh.system.common.bean.CheckedBean;
|
||||
import com.hshh.system.common.bean.OperateResult;
|
||||
|
|
@ -121,7 +122,7 @@ public class IndicatorController extends BaseController {
|
|||
}
|
||||
}
|
||||
model.addAttribute("rootList", rootList);
|
||||
return "/indicator/list";
|
||||
return "indicator/list";
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -138,7 +139,7 @@ public class IndicatorController extends BaseController {
|
|||
List<ModelDefine> modelDefineList = modelDefineService.list();
|
||||
model.addAttribute("modelDefineList", modelDefineList);
|
||||
}
|
||||
return "/indicator/add_indicator";
|
||||
return "indicator/add_indicator";
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -165,6 +166,7 @@ public class IndicatorController extends BaseController {
|
|||
* @param bindingResult 字段验证信息
|
||||
* @return 保存结果
|
||||
*/
|
||||
@LogOperation("保存指标")
|
||||
@PostMapping("/save")
|
||||
@ResponseBody
|
||||
@Operation(summary = "保存指标", description = "验证后保存指标")
|
||||
|
|
@ -202,6 +204,7 @@ public class IndicatorController extends BaseController {
|
|||
*/
|
||||
@GetMapping("/remove/{id}")
|
||||
@ResponseBody
|
||||
@LogOperation("删除指标")
|
||||
@Operation(summary = "删除指标", description = "根据ID删除指定指标")
|
||||
public OperateResult<Void> remove(@PathVariable("id") Integer id) {
|
||||
if (id == null) {
|
||||
|
|
@ -236,14 +239,15 @@ public class IndicatorController extends BaseController {
|
|||
List<Indicator> rootList = indicatorService.queryRootList();
|
||||
|
||||
//设置根指标的选中状态
|
||||
setChecked(rootList, indicatorTopId, true);
|
||||
setChecked(rootList, indicatorTopId, false);
|
||||
|
||||
// 顶级指标放入session容器
|
||||
model.addAttribute("rootList", rootList);
|
||||
// 底层指标放入session容器
|
||||
model.addAttribute("childrenIndicator", indicatorService.selectNoChildByTopId(
|
||||
indicatorTopId == null ? (rootList.isEmpty() ? 0 : rootList.get(0).getId())
|
||||
: indicatorTopId));
|
||||
if (indicatorTopId != null) {
|
||||
model.addAttribute("childrenIndicator", indicatorService.selectNoChildByTopId(
|
||||
indicatorTopId));
|
||||
}
|
||||
|
||||
// form表单和顶级指标对应列表放入session容器
|
||||
modelForm(model, (indicatorTopId == null ? (rootList.isEmpty() ? 0 : rootList.get(0).getId())
|
||||
|
|
@ -336,6 +340,7 @@ public class IndicatorController extends BaseController {
|
|||
*/
|
||||
@PostMapping("/uploadCsv")
|
||||
@ResponseBody
|
||||
@LogOperation("上传csv文件")
|
||||
public OperateResult<List<IndicatorCsvColumn>> uploadCsv(@RequestParam("file") MultipartFile file,
|
||||
Integer indicatorTopId) throws IOException {
|
||||
List<IndicatorCsvColumn> list = indicatorService.saveIndicatorTopCsvMapper(indicatorTopId,
|
||||
|
|
@ -355,6 +360,7 @@ public class IndicatorController extends BaseController {
|
|||
*/
|
||||
@PostMapping("/indicatorFormMapper")
|
||||
@ResponseBody
|
||||
@LogOperation("保存指标和form表单ID的映射关系")
|
||||
public OperateResult<List<FormFieldConfig>> saveIndicatorFormMapper(
|
||||
@RequestBody IndicatorFormMapper formMapper) {
|
||||
indicatorTopMapperService.saveFormMapper(formMapper);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
package com.hshh.indicator.controller;
|
||||
|
||||
import com.hshh.indicator.bean.IndicatorSetBean;
|
||||
import com.hshh.system.common.bean.BaseController;
|
||||
import com.hshh.system.common.bean.OperateResult;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
/**
|
||||
* 指标全局函数设置.
|
||||
*
|
||||
* @author LiDongYU
|
||||
* @since 2025/7/22
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/indicatorSet")
|
||||
@Tag(name = "指标全局函数设置", description = "指标全局函数设置")
|
||||
public class IndicatorSetController extends BaseController {
|
||||
|
||||
/**
|
||||
* 指标全局函数默认设置页面.
|
||||
*
|
||||
* @param model 数据容器
|
||||
* @param request 页面请求
|
||||
* @return indicator_set.html
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public String list(Model model, HttpServletRequest request) {
|
||||
setNavigateTitle(model, "/indicatorSet/list");
|
||||
return "system/indicator/indicator_set";
|
||||
}
|
||||
@PostMapping("/save")
|
||||
public OperateResult<Void> save(@RequestBody IndicatorSetBean indicatorSetBean) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableId;
|
|||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.hshh.system.common.bean.CheckedBean;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
|
@ -45,5 +46,17 @@ public class Indicator extends CheckedBean {
|
|||
return this.name;
|
||||
}
|
||||
|
||||
@TableField(exist = false)
|
||||
private double weight;
|
||||
//当前值
|
||||
@TableField(exist = false)
|
||||
private String value;
|
||||
|
||||
//隶属度描述
|
||||
@TableField(exist = false)
|
||||
private Map<String, String> membership;
|
||||
|
||||
//得分
|
||||
@TableField(exist = false)
|
||||
private String score;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.hshh.indicator.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import java.io.Serializable;
|
||||
|
|
@ -17,58 +18,69 @@ import java.io.Serializable;
|
|||
|
||||
public class IndicatorBottomCsvMapper implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Integer id;
|
||||
private static final long serialVersionUID = 1L;
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
|
||||
private Integer indicatorTopId;
|
||||
private Integer indicatorTopId;
|
||||
|
||||
|
||||
private Integer indicatorId;
|
||||
private Integer indicatorId;
|
||||
|
||||
|
||||
private Integer csvColumnId;
|
||||
private Integer csvColumnId;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getIndicatorTopId() {
|
||||
return indicatorTopId;
|
||||
}
|
||||
public Integer getIndicatorTopId() {
|
||||
return indicatorTopId;
|
||||
}
|
||||
|
||||
public void setIndicatorTopId(Integer indicatorTopId) {
|
||||
this.indicatorTopId = indicatorTopId;
|
||||
}
|
||||
public void setIndicatorTopId(Integer indicatorTopId) {
|
||||
this.indicatorTopId = indicatorTopId;
|
||||
}
|
||||
|
||||
public Integer getIndicatorId() {
|
||||
return indicatorId;
|
||||
}
|
||||
public Integer getIndicatorId() {
|
||||
return indicatorId;
|
||||
}
|
||||
|
||||
public void setIndicatorId(Integer indicatorId) {
|
||||
this.indicatorId = indicatorId;
|
||||
}
|
||||
public void setIndicatorId(Integer indicatorId) {
|
||||
this.indicatorId = indicatorId;
|
||||
}
|
||||
|
||||
public Integer getCsvColumnId() {
|
||||
return csvColumnId;
|
||||
}
|
||||
public Integer getCsvColumnId() {
|
||||
return csvColumnId;
|
||||
}
|
||||
|
||||
public void setCsvColumnId(Integer csvColumnId) {
|
||||
this.csvColumnId = csvColumnId;
|
||||
}
|
||||
public void setCsvColumnId(Integer csvColumnId) {
|
||||
this.csvColumnId = csvColumnId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IndicatorBottomCsvMapper{" +
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IndicatorBottomCsvMapper{" +
|
||||
"id = " + id +
|
||||
", indicatorTopId = " + indicatorTopId +
|
||||
", indicatorId = " + indicatorId +
|
||||
", csvColumnId = " + csvColumnId +
|
||||
"}";
|
||||
}
|
||||
}
|
||||
|
||||
@TableField(exist = false)
|
||||
private String csvColumnName;
|
||||
|
||||
public String getCsvColumnName() {
|
||||
return csvColumnName;
|
||||
}
|
||||
|
||||
public void setCsvColumnName(String csvColumnName) {
|
||||
this.csvColumnName = csvColumnName;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.hshh.indicator.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import java.io.Serializable;
|
||||
|
|
@ -28,10 +29,7 @@ public class IndicatorBottomFormMapper implements Serializable {
|
|||
private Integer formFieldId;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private Integer indicatorTopId;
|
||||
|
||||
|
||||
@TableField(exist = false)
|
||||
private String filedName;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.hshh.indicator.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import java.io.Serializable;
|
||||
|
|
@ -32,26 +33,13 @@ public class IndicatorEvalItem implements Serializable {
|
|||
private Integer indicatorId;
|
||||
|
||||
private Integer sortOrder;
|
||||
|
||||
@NotNull(message = "名称不能为空")
|
||||
@Size(max = 50, message = "名称不能超过50字符")
|
||||
private String evaluationName;
|
||||
private String topValue;
|
||||
|
||||
@NotNull(message = "符号不能为空")
|
||||
@Size(max = 5, message = "名称不能超过5字符")
|
||||
private String minSymbol;
|
||||
|
||||
@NotNull(message = "值不能为空")
|
||||
@Size(max = 10, message = "值不能超过10字符")
|
||||
private String minValue;
|
||||
|
||||
@NotNull(message = "符号不能为空")
|
||||
@Size(max = 5, message = "名称不能超过5字符")
|
||||
private String maxSymbol;
|
||||
|
||||
@NotNull(message = "值不能为空")
|
||||
@Size(max = 10, message = "值不能超过10字符")
|
||||
private String maxValue;
|
||||
|
||||
private String bottomValue;
|
||||
//除去范围外,等于某个字符串值
|
||||
private String equalValue;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.hshh.indicator.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import java.io.Serializable;
|
||||
|
|
@ -27,4 +28,5 @@ public class IndicatorFormMapper implements Serializable {
|
|||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
package com.hshh.indicator.mapper;
|
||||
|
||||
import com.hshh.indicator.entity.IndicatorBottomCsvMapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.hshh.indicator.entity.IndicatorBottomCsvMapper;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
|
@ -13,4 +14,11 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|||
*/
|
||||
public interface IndicatorBottomCsvMapperMapper extends BaseMapper<IndicatorBottomCsvMapper> {
|
||||
|
||||
/**
|
||||
* 根据根指标查找对应关系.
|
||||
*
|
||||
* @param indicatorTopId 根指标
|
||||
* @return 对应关系列表
|
||||
*/
|
||||
List<IndicatorBottomCsvMapper> selectByIndicatorTopId(Integer indicatorTopId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
package com.hshh.indicator.mapper;
|
||||
|
||||
import com.hshh.indicator.entity.IndicatorBottomFormMapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.hshh.indicator.entity.IndicatorBottomFormMapper;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author liDongYu
|
||||
|
|
@ -13,5 +14,12 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|||
*/
|
||||
public interface IndicatorBottomMapperMapper extends BaseMapper<IndicatorBottomFormMapper> {
|
||||
|
||||
/**
|
||||
* 查找指标ID和字段名称的对应关系.
|
||||
*
|
||||
* @param topId 根指标ID
|
||||
* @return 对应关系列表
|
||||
*/
|
||||
List<IndicatorBottomFormMapper> selectByIndicatorTopId(Integer topId);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,5 +19,13 @@ public interface IndicatorMapper extends BaseMapper<Indicator> {
|
|||
* @param topId 祖先指标ID
|
||||
* @return 指标集
|
||||
*/
|
||||
public List<Indicator> selectNoChildByTopId(@Param("topId") Integer topId);
|
||||
List<Indicator> selectNoChildByTopId(@Param("topId") Integer topId);
|
||||
|
||||
/**
|
||||
* 根据评估模板获取指标.
|
||||
*
|
||||
* @param templateId 模板 ID
|
||||
* @return 指标列表
|
||||
*/
|
||||
List<Indicator> selectByTemplateId(@Param("templateId") Integer templateId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,4 +27,12 @@ public interface IndicatorBottomCsvMapperService extends IService<IndicatorBotto
|
|||
* @param indicatorTopId 顶部指标ID
|
||||
*/
|
||||
void deleteByIndicatorTopId(Integer indicatorTopId);
|
||||
|
||||
/**
|
||||
* 根据指标ID获取对应关系.
|
||||
*
|
||||
* @param topId 根指标ID
|
||||
* @return 对应关系列表
|
||||
*/
|
||||
List<IndicatorBottomCsvMapper> selectIndicatorToFieldNameListByIndicatorTopId(Integer topId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,4 +34,11 @@ public interface IndicatorBottomFormMapperService extends IService<IndicatorBott
|
|||
*/
|
||||
void saveMapper(List<IndicatorBottomFormMapper> indicatorBottomFormMapperList);
|
||||
|
||||
/**
|
||||
* 查找指标ID和字段名称的对应关系.
|
||||
*
|
||||
* @param topId 根指标ID
|
||||
* @return 对应关系列表
|
||||
*/
|
||||
List<IndicatorBottomFormMapper> selectIndicatorToFieldNameListByIndicatorTopId(Integer topId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
package com.hshh.indicator.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.hshh.indicator.bean.IndicatorEvalBean;
|
||||
import com.hshh.indicator.entity.IndicatorEvalItem;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 指标规则表 服务类.
|
||||
|
|
@ -13,19 +15,18 @@ import java.util.List;
|
|||
public interface IndicatorEvalItemService extends IService<IndicatorEvalItem> {
|
||||
|
||||
/**
|
||||
* 根据指标ID和名称查询记录.
|
||||
* 根据顶级指标查询返回以子指标为key,value为子指标评价范围集合.
|
||||
*
|
||||
* @param indicatorId 指标ID
|
||||
* @param name 名称
|
||||
* @return 记录
|
||||
* @param indicatorTopId 顶级指标
|
||||
* @return 以子指标分类的评价集范围
|
||||
*/
|
||||
List<IndicatorEvalItem> queryListByNameAndIndicatorId(Integer indicatorId, String name);
|
||||
Map<Integer, List<IndicatorEvalItem>> getIndicatorEvalItemMapByIndicatorTopId(
|
||||
Integer indicatorTopId);
|
||||
|
||||
/**
|
||||
* 根据子指标查询他的评价集.
|
||||
* 保存评价集
|
||||
*
|
||||
* @param indicatorId 子指标
|
||||
* @return 评价集
|
||||
* @param data 前端数据
|
||||
*/
|
||||
List<IndicatorEvalItem> queryListByIndicatorId(Integer indicatorId);
|
||||
void saveWhole(IndicatorEvalBean data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import com.hshh.indicator.entity.IndicatorCsvColumn;
|
|||
import com.hshh.system.common.bean.JsTree;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
|
|
@ -99,4 +100,14 @@ public interface IndicatorService extends IService<Indicator> {
|
|||
* @return 指标列表,topId一致
|
||||
*/
|
||||
List<Indicator> queryByTopId(Integer topId);
|
||||
|
||||
/**
|
||||
* 根据评估模板获取指标.
|
||||
*
|
||||
* @param templateId 模板 ID
|
||||
* @return 指标列表
|
||||
*/
|
||||
Indicator selectByTemplateId(@Param("templateId") Integer templateId);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,4 +39,10 @@ public class IndicatorBottomCsvMapperServiceImpl extends
|
|||
queryWrapper.eq("indicator_top_id", indicatorTopId);
|
||||
remove(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IndicatorBottomCsvMapper> selectIndicatorToFieldNameListByIndicatorTopId(
|
||||
Integer topId) {
|
||||
return this.baseMapper.selectByIndicatorTopId(topId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,4 +41,9 @@ public class IndicatorBottomMapperServiceImpl extends
|
|||
public void saveMapper(List<IndicatorBottomFormMapper> indicatorBottomFormMapperList) {
|
||||
indicatorBottomFormMapperList.forEach(this::save);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IndicatorBottomFormMapper> selectIndicatorToFieldNameListByIndicatorTopId(Integer topId) {
|
||||
return this.baseMapper.selectByIndicatorTopId(topId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,11 +2,18 @@ package com.hshh.indicator.service.impl;
|
|||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.hshh.indicator.bean.IndicatorEvalBean;
|
||||
import com.hshh.indicator.entity.IndicatorEvalItem;
|
||||
import com.hshh.indicator.mapper.IndicatorEvalItemMapper;
|
||||
import com.hshh.indicator.service.IndicatorEvalItemService;
|
||||
import com.hshh.indicator.service.IndicatorTopLevelService;
|
||||
import com.hshh.indicator.service.IndicatorTopSetService;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* 指标规则表 服务实现类.
|
||||
|
|
@ -18,21 +25,31 @@ import org.springframework.stereotype.Service;
|
|||
public class IndicatorEvalItemServiceImpl extends
|
||||
ServiceImpl<IndicatorEvalItemMapper, IndicatorEvalItem> implements IndicatorEvalItemService {
|
||||
|
||||
@Override
|
||||
public List<IndicatorEvalItem> queryListByNameAndIndicatorId(Integer indicatorId, String name) {
|
||||
QueryWrapper<IndicatorEvalItem> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("indicator_id", indicatorId);
|
||||
queryWrapper.eq("evaluation_name", name);
|
||||
|
||||
return this.list(queryWrapper);
|
||||
|
||||
@Override
|
||||
public Map<Integer, List<IndicatorEvalItem>> getIndicatorEvalItemMapByIndicatorTopId(
|
||||
Integer indicatorTopId) {
|
||||
QueryWrapper<IndicatorEvalItem> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("indicator_top_id", indicatorTopId);
|
||||
queryWrapper.orderByAsc("id");
|
||||
List<IndicatorEvalItem> indicatorEvalItemList = this.list(queryWrapper);
|
||||
|
||||
return indicatorEvalItemList.stream()
|
||||
.collect(Collectors.groupingBy(IndicatorEvalItem::getIndicatorId));
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public List<IndicatorEvalItem> queryListByIndicatorId(Integer indicatorId) {
|
||||
public void saveWhole(IndicatorEvalBean data) {
|
||||
//保存评价集
|
||||
QueryWrapper<IndicatorEvalItem> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("indicator_id", indicatorId);
|
||||
queryWrapper.orderByAsc("sort_order", "id");
|
||||
queryWrapper.eq("indicator_top_id", data.getIndicatorTopId());
|
||||
remove(queryWrapper);
|
||||
data.getEvalItemList().forEach(item -> {
|
||||
item.setIndicatorTopId(data.getIndicatorTopId());
|
||||
save(item);
|
||||
});
|
||||
|
||||
return this.list(queryWrapper);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -187,4 +187,15 @@ public class IndicatorServiceImpl extends ServiceImpl<IndicatorMapper, Indicator
|
|||
|
||||
return this.list(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Indicator selectByTemplateId(Integer templateId) {
|
||||
List<Indicator> list = this.baseMapper.selectByTemplateId(templateId);
|
||||
if (list.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return list.get(0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,10 +99,13 @@ public class ModelDefineController extends BaseController {
|
|||
modelDefine.getId()));
|
||||
|
||||
} else {
|
||||
fieldList.addAll(formFieldConfigService.getFormFieldConfigByModelId(
|
||||
modelList.get(0).getId()));
|
||||
if (!modelList.isEmpty()) {
|
||||
fieldList.addAll(formFieldConfigService.getFormFieldConfigByModelId(
|
||||
modelList.get(0).getId()));
|
||||
|
||||
modelList.get(0).setChecked(true);
|
||||
}
|
||||
|
||||
modelList.get(0).setChecked(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,12 +34,10 @@ public class FormFieldConfig implements Serializable {
|
|||
|
||||
@NotBlank(message = "字段名称不能为空")
|
||||
@Size(max = 50, message = "字段名称不能超过50字符")
|
||||
@Pattern(regexp = "^[A-Za-z_]+$", message = "字段ID只能包含英文字符")
|
||||
@Pattern(regexp = "^[A-Za-z_0-9]+$", message = "字段ID只能包含英文和数字字符")
|
||||
private String fieldName;
|
||||
|
||||
@NotBlank(message = "字段ID不能为空")
|
||||
@Size(max = 50, message = "字段ID不能超过50字符")
|
||||
@Pattern(regexp = "^[A-Za-z_]+$", message = "字段ID只能包含英文字符")
|
||||
|
||||
private String fieldId;
|
||||
@NotBlank(message = "字段标签不能为空")
|
||||
@Size(max = 50, message = "字段标签不能超过50字符")
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|||
import com.hshh.model.entity.FormValue;
|
||||
import com.hshh.system.common.bean.PaginationBean;
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* 动态表单实际对象记录表 Mapper 接口.
|
||||
|
|
@ -28,4 +29,12 @@ public interface FormValueMapper extends BaseMapper<FormValue> {
|
|||
* @return 查询结果
|
||||
*/
|
||||
Long count(PaginationBean request);
|
||||
|
||||
/**
|
||||
* 查询指定id的记录.
|
||||
*
|
||||
* @param ids id集合
|
||||
* @return 结果列表
|
||||
*/
|
||||
List<FormValue> selectByIds(@Param("ids") List<Integer> ids);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.hshh.model.service;
|
|||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.hshh.model.entity.FormFieldConfig;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
|
|
@ -19,7 +20,7 @@ public interface FormFieldConfigService extends IService<FormFieldConfig> {
|
|||
* @param modelId 模型ID
|
||||
* @return 字段列表
|
||||
*/
|
||||
public List<FormFieldConfig> getFormFieldConfigByModelId(Integer modelId);
|
||||
List<FormFieldConfig> getFormFieldConfigByModelId(Integer modelId);
|
||||
|
||||
/**
|
||||
* 查询符合条件的字段列表.
|
||||
|
|
@ -30,6 +31,14 @@ public interface FormFieldConfigService extends IService<FormFieldConfig> {
|
|||
* @param id id
|
||||
* @return 结果列表
|
||||
*/
|
||||
public List<FormFieldConfig> getFormFieldConfigByLabelOrNameOrId(@NotNull Integer modelId,
|
||||
List<FormFieldConfig> getFormFieldConfigByLabelOrNameOrId(@NotNull Integer modelId,
|
||||
@NotNull String label, @NotNull String name, @NotNull String id);
|
||||
|
||||
/**
|
||||
* 获取基础设施的字段信息,按照map返回,linkedHashMap key=fieldName,value=fieldLabel.
|
||||
*
|
||||
* @param modelId 基础设施ID
|
||||
* @return 字段map
|
||||
*/
|
||||
Map<String, String> getHeaderMap(Integer modelId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import java.util.List;
|
|||
* @since 2025-08-01
|
||||
*/
|
||||
public interface FormValueService extends IService<FormValue> {
|
||||
|
||||
/**
|
||||
* 查询列表.
|
||||
*
|
||||
|
|
@ -27,4 +28,12 @@ public interface FormValueService extends IService<FormValue> {
|
|||
* @return 查询结果
|
||||
*/
|
||||
Long count(PaginationBean request);
|
||||
|
||||
/**
|
||||
* 查询指定id的记录.
|
||||
*
|
||||
* @param ids id集合
|
||||
* @return 结果列表
|
||||
*/
|
||||
List<FormValue> selectByIds(List<Integer> ids);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|||
import com.hshh.model.entity.FormFieldConfig;
|
||||
import com.hshh.model.mapper.FormFieldConfigMapper;
|
||||
import com.hshh.model.service.FormFieldConfigService;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
|
|
@ -36,4 +38,14 @@ public class FormFieldConfigServiceImpl extends
|
|||
.eq("field_id", id));
|
||||
return this.list(queryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getHeaderMap(Integer modelId) {
|
||||
Map<String, String> headerMap = new HashMap<>();
|
||||
List<FormFieldConfig> list = getFormFieldConfigByModelId(modelId);
|
||||
list.forEach(formFieldConfig -> {
|
||||
headerMap.put(formFieldConfig.getFieldName(), formFieldConfig.getFieldLabel());
|
||||
});
|
||||
return headerMap;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,4 +27,9 @@ public class FormValueServiceImpl extends ServiceImpl<FormValueMapper, FormValue
|
|||
public Long count(PaginationBean request) {
|
||||
return this.baseMapper.count(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FormValue> selectByIds(List<Integer> ids) {
|
||||
return this.baseMapper.selectByIds(ids);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
package com.hshh.thread;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.hshh.evaluation.bean.PageEvaluationRequest;
|
||||
import com.hshh.evaluation.service.impl.EvaluationProjectServiceImpl;
|
||||
import com.hshh.system.Global;
|
||||
import com.hshh.system.common.bean.SpringContextHolder;
|
||||
import com.hshh.system.common.cmd.CmdEnum;
|
||||
import com.hshh.system.common.cmd.CmdInfo;
|
||||
import java.util.Objects;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 处理系统中的任务线程.
|
||||
*
|
||||
* @author LiDongYU
|
||||
* @since 2025/7/22
|
||||
*/
|
||||
@Slf4j
|
||||
public class HandleEvaluationCmdThread implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (!Thread.interrupted()) {
|
||||
try {
|
||||
CmdInfo cmd = Global.cmdQueue.take();
|
||||
if (Objects.requireNonNull(cmd.getType()) == CmdEnum.EVALUATION) {
|
||||
evaluation(cmd);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("error:", e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//评估
|
||||
private void evaluation(CmdInfo cmd) {
|
||||
|
||||
SpringContextHolder.getBean(EvaluationProjectServiceImpl.class)
|
||||
.evaluate(JSON.parseObject(cmd.getCmd(),
|
||||
PageEvaluationRequest.class), cmd.getUserId());
|
||||
}
|
||||
}
|
||||
|
|
@ -22,15 +22,17 @@ spring:
|
|||
max-request-size: 20MB
|
||||
|
||||
|
||||
|
||||
mybatis-plus:
|
||||
|
||||
mapper-locations: classpath*:/mapper/**/*.xml
|
||||
configuration:
|
||||
database-id: mysql
|
||||
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
database-id: mysql
|
||||
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
|
||||
|
||||
global-config:
|
||||
db-config:
|
||||
id-type: auto
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.hshh.evaluation.mapper.EvaluationCsvDataMapper">
|
||||
<select id="list" resultType="com.hshh.evaluation.entity.EvaluationCsvData"
|
||||
parameterType="com.hshh.system.common.bean.PaginationBean" databaseId="mysql">
|
||||
SELECT
|
||||
@rownum := @rownum + 1 AS seq,
|
||||
t.*
|
||||
FROM (
|
||||
SELECT * FROM m_data_evaluation_csv_data
|
||||
<where>
|
||||
<if test="randomKey!=null">
|
||||
and random_key = #{randomKey}
|
||||
</if>
|
||||
<if test="search != null and search !='' ">
|
||||
and raw_data LIKE CONCAT('%',#{search},'%')
|
||||
</if>
|
||||
</where>
|
||||
order by id asc ) t, ( SELECT @rownum := #{start} ) r limit
|
||||
#{start},#{pageSize}
|
||||
</select>
|
||||
<select id="list" resultType="com.hshh.evaluation.entity.EvaluationCsvData"
|
||||
parameterType="com.hshh.system.common.bean.PaginationBean" databaseId="dm">SELECT
|
||||
t.seq,
|
||||
t.*
|
||||
FROM (
|
||||
SELECT
|
||||
ROW_NUMBER() OVER (ORDER BY id ASC) AS seq,
|
||||
a.*
|
||||
FROM m_data_evaluation_csv_data a
|
||||
<where>
|
||||
<if test="randomKey!=null">
|
||||
and random_key = #{randomKey}
|
||||
</if>
|
||||
<if test="search != null and search !='' ">
|
||||
and raw_data LIKE '%'||#{search}||'%'
|
||||
</if>
|
||||
</where>
|
||||
) t
|
||||
WHERE t.seq > #{start} AND t.seq <= (#{start} + #{pageSize})
|
||||
</select>
|
||||
<select id="count" resultType="java.lang.Long" databaseId="dm">
|
||||
select count(id) from m_data_evaluation_csv_data
|
||||
<where>
|
||||
<if test="randomKey!=null">
|
||||
and random_key = #{randomKey}
|
||||
</if>
|
||||
<if test="search != null and search !=''">
|
||||
and (raw_data LIKE '%'||#{search}||'%')
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
<select id="count" resultType="java.lang.Long" databaseId="mysql">
|
||||
select count(id) from m_data_evaluation_csv_data
|
||||
<where>
|
||||
<if test="randomKey!=null">
|
||||
and random_key = #{randomKey}
|
||||
</if>
|
||||
<if test="search != null and search !=''">
|
||||
and (raw_data LIKE CONCAT('%',#{search},'%'))
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
<select id="selectByIds" resultType="com.hshh.evaluation.entity.EvaluationCsvData">
|
||||
SELECT * FROM m_data_evaluation_csv_data
|
||||
WHERE id IN
|
||||
<foreach collection="ids" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.hshh.evaluation.mapper.EvaluationHistoryMapper">
|
||||
<select id="queryRecentByProjectId" resultType="com.hshh.evaluation.entity.EvaluationHistory">
|
||||
SELECT *
|
||||
FROM m_data_evaluation_history
|
||||
where project_id = #{projectId}
|
||||
ORDER BY id DESC
|
||||
LIMIT 1;
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
@ -50,4 +50,12 @@
|
|||
</if>
|
||||
</where>
|
||||
</select>
|
||||
<select id="selectModelIdByProjectId" resultType="java.lang.Long">
|
||||
SELECT t3.indicator_model_id
|
||||
FROM m_data_evaluation_project t1
|
||||
LEFT JOIN m_data_evaluation_template t2 ON t1.template_id = t2.id
|
||||
LEFT JOIN m_data_indicator_form t3 ON t2.indicator_top_id = t3.indicator_top_id
|
||||
where t1.id = #{projectId}
|
||||
and t3.indicator_model_id is not null
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.hshh.evaluation.mapper.EvaluationTemplateIndicatorWeightMapper">
|
||||
|
||||
</mapper>
|
||||
|
|
@ -50,4 +50,5 @@
|
|||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@
|
|||
FROM (
|
||||
SELECT * FROM m_data_model_field_value
|
||||
<where>
|
||||
<if test="id!=null">
|
||||
and model_define_id = #{id}
|
||||
<if test="businessKey!=null">
|
||||
and model_define_id = #{businessKey}
|
||||
</if>
|
||||
<if test="search != null and search !='' ">
|
||||
and model_data LIKE CONCAT('%',#{search},'%')
|
||||
|
|
@ -29,8 +29,8 @@
|
|||
a.*
|
||||
FROM m_data_model_field_value a
|
||||
<where>
|
||||
<if test="id!=null">
|
||||
and model_define_id = #{id}
|
||||
<if test="businessKey!=null">
|
||||
and model_define_id = #{businessKey}
|
||||
</if>
|
||||
<if test="search != null and search !='' ">
|
||||
and model_data LIKE '%'||#{search}||'%'
|
||||
|
|
@ -42,8 +42,8 @@
|
|||
<select id="count" resultType="java.lang.Long" databaseId="dm">
|
||||
select count(id) from m_data_model_field_value
|
||||
<where>
|
||||
<if test="id!=null">
|
||||
and model_define_id = #{id}
|
||||
<if test="businessKey!=null">
|
||||
and model_define_id = #{businessKey}
|
||||
</if>
|
||||
<if test="search != null and search !=''">
|
||||
and (model_data LIKE '%'||#{search}||'%')
|
||||
|
|
@ -53,12 +53,19 @@
|
|||
<select id="count" resultType="java.lang.Long" databaseId="mysql">
|
||||
select count(id) from m_data_model_field_value
|
||||
<where>
|
||||
<if test="id!=null">
|
||||
and model_define_id = #{id}
|
||||
<if test="businessKey!=null">
|
||||
and model_define_id = #{businessKey}
|
||||
</if>
|
||||
<if test="search != null and search !=''">
|
||||
and (model_data LIKE CONCAT('%',#{search},'%'))
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
<select id="selectByIds" resultType="com.hshh.model.entity.FormValue">
|
||||
SELECT * FROM m_data_model_field_value
|
||||
WHERE id IN
|
||||
<foreach collection="ids" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.hshh.indicator.mapper.IndicatorBottomCsvMapperMapper">
|
||||
<select id="selectByIndicatorTopId" resultType="com.hshh.indicator.entity.IndicatorBottomCsvMapper">
|
||||
|
||||
SELECT
|
||||
t1.indicator_id,
|
||||
t2.csv_column_name
|
||||
FROM
|
||||
m_data_indicator_bottom_csv_mapper t1
|
||||
LEFT JOIN m_data_indicator_csv_column t2 on t1.csv_column_id=t2.id
|
||||
where t1.indicator_top_id=#{id}
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
|
|||
|
|
@ -2,5 +2,13 @@
|
|||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.hshh.indicator.mapper.IndicatorBottomMapperMapper">
|
||||
|
||||
<select id="selectByIndicatorTopId" resultType="com.hshh.indicator.entity.IndicatorBottomFormMapper">
|
||||
SELECT
|
||||
t1.indicator_id,
|
||||
t2.field_id as filedName
|
||||
FROM
|
||||
m_data_indicator_bottom_form_mapper t1
|
||||
LEFT JOIN m_data_model_field_config t2 on t1.form_field_id=t2.id
|
||||
where t1.indicator_top_id=#{indicatorTopId}
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
|
|||
|
|
@ -5,4 +5,5 @@
|
|||
select t.indicator_model_id
|
||||
from m_data_indicator_form t where t.indicator_top_id=#{topId}
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
|
|
|||
|
|
@ -10,4 +10,12 @@
|
|||
WHERE t2.top_id = #{topId} and t2.parent_id IS NOT NULL)
|
||||
order by sort_order
|
||||
</select>
|
||||
<select id="selectByTemplateId" resultType="com.hshh.indicator.entity.Indicator">
|
||||
SELECT
|
||||
t1.*
|
||||
FROM
|
||||
m_data_indicator t1
|
||||
inner join m_data_evaluation_template t2 ON t1.id = t2.indicator_top_id
|
||||
where t2.id=#{templateId}
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
*/
|
||||
function removeValidCss(formId) {
|
||||
|
||||
|
||||
let form = document.getElementById(formId);
|
||||
let elements = form.elements;
|
||||
for (const element of elements) {
|
||||
|
|
@ -63,17 +62,19 @@ function openDialog(id) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function disabledForm(formId) {
|
||||
let form = document.getElementById(formId);
|
||||
// 只读 input 和 textarea
|
||||
form.querySelectorAll('input, textarea').forEach(function(el) {
|
||||
form.querySelectorAll('input, textarea').forEach(function (el) {
|
||||
el.readOnly = true;
|
||||
});
|
||||
// 禁用 select 和 button
|
||||
form.querySelectorAll('select').forEach(function(el) {
|
||||
form.querySelectorAll('select').forEach(function (el) {
|
||||
el.disabled = true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动填充表单,根据 JSON 数据中的 key 和嵌套对象自动拼接 name 属性进行匹配
|
||||
* @param {string} formId - 表单的 ID,例如 "myForm"
|
||||
|
|
@ -88,8 +89,6 @@ function fillForm(formId, data) {
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 递归处理 JSON 对象, 将嵌套对象的 key 拼接为点连接的形式
|
||||
* @param {Object} obj - 当前处理的 JSON 对象
|
||||
|
|
@ -102,7 +101,6 @@ function fillForm(formId, data) {
|
|||
var fullKey = prefix ? prefix + "." + key : key;
|
||||
var value = obj[key];
|
||||
|
||||
|
||||
// 如果值为对象,但不为数组,则递归处理
|
||||
if (value && typeof value === "object" && !Array.isArray(value)) {
|
||||
|
||||
|
|
@ -130,7 +128,7 @@ function fillForm(formId, data) {
|
|||
|
||||
field.value = value;
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -220,7 +218,7 @@ function common_batchRemove() {
|
|||
|
||||
}
|
||||
|
||||
//分页相关
|
||||
//普通静态数据分页相关
|
||||
function _next() {
|
||||
let currentPageNum = document.getElementById("_currentPage").value;
|
||||
_setPage(parseInt(currentPageNum) + 1);
|
||||
|
|
@ -246,6 +244,23 @@ function _resetPageNoSearch() {
|
|||
_search();
|
||||
}
|
||||
|
||||
//动态数据,动态表头,动态表格 header=map record=list(map)
|
||||
function _dynamic_next(form) {
|
||||
let pageNum = document.forms[form]["currentPage"].value;
|
||||
document.forms[form]["currentPage"].value = parseInt(pageNum)+1;
|
||||
dynamic_search();
|
||||
}
|
||||
function _dynamic_pre(form) {
|
||||
let pageNum = document.forms[form]["currentPage"].value;
|
||||
document.forms[form]["currentPage"].value = parseInt(pageNum)-1;
|
||||
dynamic_search();
|
||||
}
|
||||
function _dynamic_resetPageNoSearch(form){
|
||||
document.forms[form]["currentPage"].value = 1;
|
||||
dynamic_search();
|
||||
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
if (document.getElementById('uploadIcon') && document.getElementById(
|
||||
'fileInput')) {
|
||||
|
|
@ -352,13 +367,15 @@ function hideContextMenu() {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
function generateDraftKey() {
|
||||
// 优先用 crypto.randomUUID 生成
|
||||
if (window.crypto && window.crypto.randomUUID) {
|
||||
return 'tpl:new:' + window.crypto.randomUUID();
|
||||
}
|
||||
// 兼容老浏览器
|
||||
return 'tpl:new:' + Date.now().toString(36) + Math.random().toString(36).substring(2, 10);
|
||||
return 'tpl:new:' + Date.now().toString(36) + Math.random().toString(
|
||||
36).substring(2, 10);
|
||||
}
|
||||
|
||||
function mapToObject(map) {
|
||||
|
|
@ -368,10 +385,54 @@ function mapToObject(map) {
|
|||
}
|
||||
return obj;
|
||||
}
|
||||
function showFieldErrorTip(formId,fieldId,message){
|
||||
|
||||
function showFieldErrorTip(formId, fieldId, message) {
|
||||
let formElement = document.getElementById(formId);
|
||||
formElement.elements[fieldId].classList.add(
|
||||
"is-invalid");
|
||||
document.getElementById(
|
||||
fieldId + "_error_tip").innerHTML =message;
|
||||
fieldId + "_error_tip").innerHTML = message;
|
||||
}
|
||||
|
||||
function connectWs(url, {
|
||||
onOpen = () => {},
|
||||
onClose = () => {},
|
||||
onMessage = (msg) => {},
|
||||
onError = (err) => {}
|
||||
} = {}) {
|
||||
url = wsUrl(url);
|
||||
const ws = new WebSocket(url);
|
||||
|
||||
ws.onopen = (ev) => { onOpen(ev, ws); };
|
||||
ws.onclose = (ev) => { onClose(ev, ws); };
|
||||
ws.onmessage = (ev) => { onMessage(ev.data, ws); };
|
||||
ws.onerror = (err) => { onError(err, ws); };
|
||||
|
||||
return ws;
|
||||
}
|
||||
function wsUrl(path) {
|
||||
const loc = window.location; // 当前页面的地址
|
||||
const scheme = loc.protocol === "https:" ? "wss:" : "ws:";
|
||||
return scheme + "//" + loc.host + path;
|
||||
}
|
||||
function formToQueryString(formId) {
|
||||
const form = document.getElementById(formId);
|
||||
const formData = new FormData(form);
|
||||
const params = new URLSearchParams();
|
||||
|
||||
for (let [key, value] of formData.entries()) {
|
||||
// 排除文件输入
|
||||
const field = form.elements[key];
|
||||
if (field && field.type === "file") continue;
|
||||
|
||||
params.append(key, value);
|
||||
}
|
||||
|
||||
return params.toString(); // "key1=val1&key2=val2"
|
||||
}
|
||||
function encryptPassword(password, aesKeyFromBackend,aesIVFromBackend) {
|
||||
var key = CryptoJS.enc.Hex.parse(aesKeyFromBackend); // 32字节
|
||||
var iv = CryptoJS.enc.Hex.parse(aesIVFromBackend); // 16字节
|
||||
|
||||
return CryptoJS.AES.encrypt(password, key, { iv: iv, mode: CryptoJS.mode.CBC }).toString();
|
||||
}
|
||||
1
manager-admin/src/main/resources/static/js/crypto-js.min.js
vendored
Normal file
1
manager-admin/src/main/resources/static/js/crypto-js.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
20
manager-admin/src/main/resources/static/js/html2canvas.min.js
vendored
Normal file
20
manager-admin/src/main/resources/static/js/html2canvas.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
398
manager-admin/src/main/resources/static/js/jspdf.umd.min.js
vendored
Normal file
398
manager-admin/src/main/resources/static/js/jspdf.umd.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -3,83 +3,82 @@
|
|||
<div class="container-xl">
|
||||
<!-- 面包屑导航 -->
|
||||
<div th:replace="fragments/dialog::navigateDialog(${chainMenuList})"></div>
|
||||
<div class="row">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<ul class="nav nav-tabs card-header-tabs" data-bs-toggle="tabs" role="tablist">
|
||||
<li class="nav-item" role="presentation" th:each="item ,stat: ${modelDefineList}">
|
||||
<a
|
||||
href="javascript:void(0)"
|
||||
th:class="'nav-link '+${item.checked?'active':''}"
|
||||
data-bs-toggle="tab"
|
||||
th:text="${item.getModelName()}"
|
||||
th:onclick="|_tabChange('${item.id}')|"></a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="tab-content" id="tab-Content">
|
||||
<div class="tab-pane active show" role="tabpanel">
|
||||
<div class="row">
|
||||
<div class="ms-auto text-end">
|
||||
<a href="javascript:void(0)" class="btn btn-primary"
|
||||
th:onclick="|addModeDataRecord('${currentModelDefine?.id}')|">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/plus -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24"
|
||||
viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M12 5l0 14"></path>
|
||||
<path d="M5 12l14 0"></path>
|
||||
</svg>
|
||||
新增
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div th:replace="fragments/dialog::searchConditionDialog(${condition})"></div>
|
||||
<div class="table-responsive">
|
||||
<table class="table card-table table-vcenter text-nowrap datatable">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th class="w-1">No.
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/chevron-up -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-sm icon-thick"
|
||||
width="24" height="24" viewBox="0 0 24 24" stroke-width="2"
|
||||
stroke="currentColor" fill="none" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M6 15l6 -6l6 6"></path>
|
||||
</svg>
|
||||
</th>
|
||||
<th th:each="item:${headerMap}" th:text="${item.value}"></th>
|
||||
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="item : ${result.getList()}">
|
||||
<td th:text="${item['seq']}"></td>
|
||||
<td th:each="entry : ${headerMap}" th:text="${item[entry.key]}"></td>
|
||||
<td>
|
||||
<a href="javascript:void(0)"
|
||||
th:onclick="|editModelFieldRecord('${item['id']}')|">编辑</a>
|
||||
<a href="javascript:void(0)"
|
||||
th:onclick="|removeModelFieldRecord('${item['id']}')|">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div th:replace="fragments/dialog::paginationDialog(${result})"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row g-4 mb-4">
|
||||
<div class="col-8">
|
||||
|
||||
|
||||
<div class="mb-3 row">
|
||||
<label class="col-2 col-form-label">基础设施</label>
|
||||
<div class="col-6">
|
||||
<label>
|
||||
<select class="form-select" id="modelId" onchange="_tabChange(this)">
|
||||
<option>--请选择基础设施--</option>
|
||||
<option th:each="item ,stat: ${modelDefineList}" th:text="${item.getModelName()}"
|
||||
th:value="${item.id}" th:selected="${item.checked}"></option>
|
||||
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
|
||||
<div class="card-actions">
|
||||
<a href="javascript:void(0)" class="btn btn-primary" onclick="addModeDataRecord()">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/plus -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24"
|
||||
viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M12 5l0 14"></path>
|
||||
<path d="M5 12l14 0"></path>
|
||||
</svg>
|
||||
新增
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div th:replace="fragments/dialog::searchConditionDialog(${condition})"></div>
|
||||
<div class="table-responsive">
|
||||
<table class="table card-table table-vcenter text-nowrap datatable">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th class="w-1">No.
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/chevron-up -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-sm icon-thick"
|
||||
width="24" height="24" viewBox="0 0 24 24" stroke-width="2"
|
||||
stroke="currentColor" fill="none" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M6 15l6 -6l6 6"></path>
|
||||
</svg>
|
||||
</th>
|
||||
<th th:each="item:${headerMap}" th:text="${item.value}"></th>
|
||||
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="item : ${result?.getList()}">
|
||||
<td th:text="${item['seq']}"></td>
|
||||
<td th:each="entry : ${headerMap}" th:text="${item[entry.key]}"></td>
|
||||
<td>
|
||||
<a href="javascript:void(0)"
|
||||
th:onclick="|editModelFieldRecord('${item['id']}')|">编辑</a>
|
||||
<a href="javascript:void(0)"
|
||||
th:onclick="|removeModelFieldRecord('${item['id']}')|">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div th:if="${result!=null}" th:replace="fragments/dialog::paginationDialog(${result})"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -91,12 +90,12 @@
|
|||
</form>
|
||||
<form id="dataExtendForm">
|
||||
<input type="hidden" name="id" id="id">
|
||||
<input type="hidden" name="modelDefineId" id="modelDefineId" th:value="${currentModelDefine.id}">
|
||||
<input type="hidden" name="modelDefineId" id="modelDefineId" th:value="${currentModelDefine?.id}">
|
||||
</form>
|
||||
<script>
|
||||
//增加模型数据的实际表单记录
|
||||
function addModeDataRecord(modelId, data) {
|
||||
|
||||
function addModeDataRecord( data) {
|
||||
let modelId = document.getElementById( "modelId" ).value;
|
||||
let url = document.getElementById("_rootPath").value + "data/getForm/" + modelId;
|
||||
let http = new HttpClient();
|
||||
http.get(url, function (error, res, xhr) {
|
||||
|
|
@ -130,14 +129,15 @@
|
|||
http.post(url, postObj, function (error, res, xhr) {
|
||||
closeDialog("modal-full-width");
|
||||
document.getElementById("_data_list").setAttribute("hx-vals",
|
||||
JSON.stringify({id: postObj.modelDefineId}))
|
||||
JSON.stringify({businessKey: postObj.modelDefineId}))
|
||||
document.getElementById("_data_list").click();
|
||||
}, "dataRecordForm", "modal-full-width")
|
||||
}
|
||||
|
||||
function _tabChange(id) {
|
||||
function _tabChange(obj) {
|
||||
|
||||
document.getElementById("_data_list").setAttribute("hx-vals",
|
||||
JSON.stringify({id: id}));
|
||||
JSON.stringify({businessKey: obj.value}));
|
||||
document.getElementById("_data_list").click();
|
||||
}
|
||||
|
||||
|
|
@ -174,7 +174,7 @@
|
|||
|
||||
if (!error) {
|
||||
document.getElementById("dataExtendForm")['id'].value = res.result.id;
|
||||
addModeDataRecord(res.result.modelDefineId, res.result);
|
||||
addModeDataRecord( res.result);
|
||||
}
|
||||
}, "dataRecordForm")
|
||||
}
|
||||
|
|
|
|||
12
manager-admin/src/main/resources/templates/error/404.html
Normal file
12
manager-admin/src/main/resources/templates/error/404.html
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
|
||||
<div class="page page-center">
|
||||
<div class="container-tight py-4">
|
||||
<div class="empty">
|
||||
<div class="empty-header">404</div>
|
||||
<p class="empty-title">页面不存在</p>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
13
manager-admin/src/main/resources/templates/error/500.html
Normal file
13
manager-admin/src/main/resources/templates/error/500.html
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
|
||||
|
||||
<div class="page page-center">
|
||||
<div class="container-tight py-4">
|
||||
<div class="empty">
|
||||
<div class="empty-header">500</div>
|
||||
<p class="empty-title" th:text="${errorMessage}"></p>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -92,17 +92,40 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div th:fragment="addFullScreenFormDialogNoBtn" id="addFormDialog-no-btn">
|
||||
|
||||
<div class="modal modal-blur fade" id="modal-full-width-no-btn" tabindex="-1" role="dialog"
|
||||
aria-hidden="true" >
|
||||
<div class="modal-dialog modal-full-width modal-dialog-centered modal-dialog-scrollable"
|
||||
role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="addFormDialog-model-title-no-btn"></h5>
|
||||
<button type="button" class="btn-close"
|
||||
onclick="closeDialog('modal-full-width-no-btn')"></button>
|
||||
</div>
|
||||
|
||||
<div class="modal-body" id="add-full-screen-form-modal-body-no-btn" >
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- form add对话框 简单form操作,居中对话框-->
|
||||
<div th:fragment="addSimpleFormDialog" id="addSimpleFormDialog">
|
||||
<div class="modal modal-blur fade" id="simple-form-model" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||
<div class="modal modal-blur fade" id="simple-form-model" tabindex="-1" role="dialog" aria-hidden="true" >
|
||||
<div class="modal-dialog modal-dialog-centered" role="document" style="min-width: 50em;">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="SimpleFormDialog_title"></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" onclick="closeDialog('simple-form-model')"></button>
|
||||
</div>
|
||||
<div class="modal-body" id="simpleFormBody">
|
||||
<div class="modal-body" id="simpleFormBody" >
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
|
@ -113,12 +136,12 @@
|
|||
</div>
|
||||
</div>
|
||||
<div th:fragment="paginationDialog(data)" id="paginationDialog">
|
||||
<div class="card-footer d-flex align-items-center" th:if="${data.total>0}">
|
||||
<div class="card-footer d-flex align-items-center" th:if="${data?.total>0}">
|
||||
<p class="m-0 text-muted"> 共 <span
|
||||
th:text="${data.total}"></span>条
|
||||
th:text="${data?.total}"></span>条
|
||||
记录</p>
|
||||
<ul class="pagination m-0 ms-auto">
|
||||
<li th:class="${data.isHasPrevious()}?'page-item':'page-item disabled'">
|
||||
<li th:class="${data?.isHasPrevious()}?'page-item':'page-item disabled'">
|
||||
<a class="page-link" href="#" tabindex="-1" aria-disabled="true"
|
||||
onclick="_pre()">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/chevron-left -->
|
||||
|
|
@ -158,7 +181,7 @@
|
|||
<div class="card-body border-bottom py-3">
|
||||
<form id="searchForm">
|
||||
<input type="hidden" id="_currentPage" name="currentPage"
|
||||
th:value="${condition.currentPage}"/>
|
||||
th:value="${condition?.currentPage}"/>
|
||||
<div class="card-body border-bottom py-3">
|
||||
|
||||
<div class="d-flex">
|
||||
|
|
@ -166,16 +189,16 @@
|
|||
显示
|
||||
<div class="mx-2 d-inline-block">
|
||||
<input type="text" class="form-control form-control-sm"
|
||||
th:value="${condition.pageSize}" size="3"
|
||||
th:value="${condition?.pageSize}" size="3"
|
||||
name="pageSize">
|
||||
</div>
|
||||
对象
|
||||
记录/每页
|
||||
</div>
|
||||
<div class="ms-auto text-muted">
|
||||
|
||||
<div class="input-group mb-2">
|
||||
<input type="text" class="form-control" placeholder="名称/编码" id="search"
|
||||
name="search" th:value="${condition.search}">
|
||||
name="search" th:value="${condition?.search}">
|
||||
<button class="btn" type="button" onclick="_resetPageNoSearch()">查询</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -196,4 +219,84 @@
|
|||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
<div th:fragment="datasetForListMap(formId,headerMap,result,condition)" id="dataset_list_map_table_page" style="min-height: 50em;max-height: 50em;overflow-y: scroll;">
|
||||
|
||||
<input type="hidden" name="currentPage"
|
||||
th:value="${condition?.currentPage}"/>
|
||||
<div class="card-body border-bottom py-3">
|
||||
<div class="d-flex">
|
||||
<div class="text-muted">
|
||||
显示
|
||||
<div class="mx-2 d-inline-block">
|
||||
<input type="text" class="form-control form-control-sm" name="pageSize" th:value="${condition?.pageSize}" size="3" aria-label="Invoices count">
|
||||
</div>
|
||||
记录/每页
|
||||
</div>
|
||||
<div class="ms-auto text-muted">
|
||||
|
||||
<div class="input-group mb-2">
|
||||
<label>
|
||||
<input type="text" class="form-control" placeholder="名称/编码"
|
||||
name="search" th:value="${condition?.search}">
|
||||
</label>
|
||||
<button class="btn" type="button" th:attr="data-form-id=${#strings.escapeJavaScript(formId)}" onclick="_dynamic_resetPageNoSearch(this.dataset.formId)">查询</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive" style="min-height: 20em;">
|
||||
<table class="table card-table table-vcenter text-nowrap datatable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
|
||||
<th th:each="item:${headerMap}" th:text="${item.value}"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="item : ${result?.getList()}">
|
||||
<td><label>
|
||||
<input type="checkbox" th:value="${item['id']}" name="list_map_table_checkbox">
|
||||
</label></td>
|
||||
|
||||
<td th:each="entry : ${headerMap}" th:text="${item[entry.key]}"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="card-footer d-flex align-items-center">
|
||||
|
||||
<ul class="pagination m-0 ms-auto">
|
||||
<li th:class="${result?.isHasPrevious()}?'page-item':'page-item disabled'">
|
||||
|
||||
<a class="page-link" href="#" tabindex="-1" aria-disabled="true" th:attr="data-form-id=${#strings.escapeJavaScript(formId)}"
|
||||
onclick="_dynamic_pre(this.dataset.formId)">
|
||||
<!-- Download SVG icon from http://tabler-icons.io/i/chevron-left -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"
|
||||
fill="none"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M15 6l-6 6l6 6"/>
|
||||
</svg>
|
||||
|
||||
</a>
|
||||
</li>
|
||||
<li th:class="${result?.isHasNext()}?'page-item':'page-item disabled'" >
|
||||
<a class="page-link" href="#" onclick="_dynamic_next(this.dataset.formId)" th:attr="data-form-id=${#strings.escapeJavaScript(formId)}">
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"
|
||||
fill="none"
|
||||
stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M9 6l6 6l-6 6"/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user