1. 指标子集映射

This commit is contained in:
李玉东 2025-08-13 14:57:20 +08:00
parent f0f305ed23
commit c1a401fcc9
7 changed files with 366 additions and 0 deletions

View File

@ -0,0 +1,43 @@
package com.hshh.evaluation.controller;
import com.hshh.evaluation.entity.EvaluationTemplate;
import com.hshh.evaluation.service.EvaluationTemplateService;
import com.hshh.system.common.bean.BaseController;
import com.hshh.system.common.bean.PaginationBean;
import io.swagger.v3.oas.annotations.Operation;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 评估工程模板表 前端控制器.
*
* @author liDongYu
* @since 2025-08-13
*/
@Controller
@RequestMapping("/evaluation/evaluationTemplate")
public class EvaluationTemplateController extends BaseController {
@Resource
private EvaluationTemplateService evaluationTemplateService;
/**
* 默认页.
*
* @return evaluation/list.html
*/
@GetMapping("/")
@Operation(summary = "评估工程模板首页", description = "导航到评估工程模板首页")
public String list(PaginationBean request, Model model) {
setNavigateTitle(model, "/evaluation/evaluationTemplate/");
List<EvaluationTemplate> list = evaluationTemplateService.list(request);
Long total = evaluationTemplateService.count(request);
//设置分页信息
setPaginationInfo(request, list, total, model);
return "evaluation_template/list";
}
}

View File

@ -0,0 +1,45 @@
package com.hshh.evaluation.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 com.hshh.system.common.bean.BaseBean;
import java.time.LocalDateTime;
import lombok.Data;
/**
* 评估工程模板表.
*
* @author liDongYu
* @since 2025-08-13
*/
@TableName("m_data_evaluation_template")
@Data
public class EvaluationTemplate extends BaseBean {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private String templateName;
private Integer indicatorTopId;
private Integer indicatorWeightId;
private Integer templateStatus;
private String templateMemo;
private LocalDateTime createTime;
@TableField(exist = false)
private String indicatorTopName;
@TableField(exist = false)
private String templateStatusName;
}

View File

@ -0,0 +1,31 @@
package com.hshh.evaluation.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hshh.evaluation.entity.EvaluationTemplate;
import com.hshh.system.common.bean.PaginationBean;
import java.util.List;
/**
* 评估工程模板表 Mapper 接口.
*
* @author liDongYu
* @since 2025-08-13
*/
public interface EvaluationTemplateMapper extends BaseMapper<EvaluationTemplate> {
/**
* 查询模板列表.
*
* @param search 查询条件
* @return 模板列表
*/
List<EvaluationTemplate> list(PaginationBean search);
/**
* 记录总数.
*
* @param search 查询条件
* @return 总数
*/
Long count(PaginationBean search);
}

View File

@ -0,0 +1,31 @@
package com.hshh.evaluation.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.hshh.evaluation.entity.EvaluationTemplate;
import com.hshh.system.common.bean.PaginationBean;
import java.util.List;
/**
* 评估工程模板表 服务类.
*
* @author liDongYu
* @since 2025-08-13
*/
public interface EvaluationTemplateService extends IService<EvaluationTemplate> {
/**
* 查询模板列表.
*
* @param search 查询条件
* @return 模板列表
*/
List<EvaluationTemplate> list(PaginationBean search);
/**
* 记录总数.
*
* @param search 查询条件
* @return 总数
*/
Long count(PaginationBean search);
}

View File

@ -0,0 +1,31 @@
package com.hshh.evaluation.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hshh.evaluation.entity.EvaluationTemplate;
import com.hshh.evaluation.mapper.EvaluationTemplateMapper;
import com.hshh.evaluation.service.EvaluationTemplateService;
import com.hshh.system.common.bean.PaginationBean;
import java.util.List;
import org.springframework.stereotype.Service;
/**
* 评估工程模板表 服务实现类.
*
* @author liDongYu
* @since 2025-08-13
*/
@Service
public class EvaluationTemplateServiceImpl extends
ServiceImpl<EvaluationTemplateMapper, EvaluationTemplate> implements
EvaluationTemplateService {
@Override
public List<EvaluationTemplate> list(PaginationBean search) {
return this.baseMapper.list(search);
}
@Override
public Long count(PaginationBean search) {
return this.baseMapper.count(search);
}
}

View File

@ -0,0 +1,53 @@
<?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.EvaluationTemplateMapper">
<select id="list" resultType="com.hshh.evaluation.entity.EvaluationTemplate"
parameterType="com.hshh.system.common.bean.PaginationBean" databaseId="mysql">
SELECT
@rownum := @rownum + 1 AS seq,
t.*
FROM (
SELECT T1.*,T2.name as indicatorTopName FROM m_data_evaluation_template T1 left join m_data_indicator T2 on T1.indicator_top_id=T2.id
<where>
<if test="search != null and search !='' ">
T1.template_name LIKE CONCAT('%',#{search},'%')
</if>
</where>
order by T1.id asc ) t, ( SELECT @rownum := #{start} ) r limit
#{start},#{pageSize}
</select>
<select id="list" resultType="com.hshh.evaluation.entity.EvaluationTemplate"
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.*,
a1.name as indicatorTopName
FROM m_data_evaluation_template a left join m_data_indicator a1 on a.indicator_top_id=a1.name
<where>
<if test="search != null and search !='' ">
a.template_name LIKE '%'||#{search}||'%'
</if>
</where>
) t
WHERE t.seq > #{start} AND t.seq &lt;= (#{start} + #{pageSize})
</select>
<select id="count" resultType="java.lang.Long" databaseId="dm">
select count(id) from m_data_evaluation_template
<where>
<if test="search != null and search !=''">
(template_name LIKE '%'||#{search}||'%') )
</if>
</where>
</select>
<select id="count" resultType="java.lang.Long" databaseId="mysql">
select count(id) from m_data_evaluation_template
<where>
<if test="search != null and search !=''">
template_name LIKE CONCAT('%',#{search},'%')
</if>
</where>
</select>
</mapper>

View File

@ -0,0 +1,132 @@
package com.hshh.system.common.algorithm;
import java.util.*;
/** 树节点:每个非叶子节点可附带“对子节点的判断矩阵” */
class AhpNode {
final String name;
final List<AhpNode> children = new ArrayList<>();
// 对子节点的两两比较矩阵仅在 children.size()>1 时需要
double[][] localMatrix;
// 计算得到
double[] localWeights; // 本节点的子节点局部权重=1
double lambdaMax = Double.NaN, ci = Double.NaN, cr = Double.NaN;
double globalWeight = Double.NaN; // 本节点的全局权重根设为1叶子递推得到
AhpNode(String name) { this.name = name; }
AhpNode setLocalMatrix(double[][] m) { this.localMatrix = m; return this; }
AhpNode add(AhpNode... nodes) { this.children.addAll(Arrays.asList(nodes)); return this; }
}
public class AhpTreeDemo {
/** 递归计算:从 root 开始,将局部权重通过父节点全局权重向下传播 */
static void computeTree(AhpNode root) {
if (Double.isNaN(root.globalWeight)) root.globalWeight = 1.0; // 根默认 1
int k = root.children.size();
if (k == 0) return; // 叶子
if (k == 1) {
// 单子节点不需要矩阵权重=1直接传播
root.localWeights = new double[]{1.0};
AhpNode c = root.children.get(0);
c.globalWeight = root.globalWeight; // 乘1
computeTree(c);
root.lambdaMax = 1; root.ci = 0; root.cr = 0;
return;
}
if (root.localMatrix == null || root.localMatrix.length != k || root.localMatrix[0].length != k) {
throw new IllegalStateException("Node '"+root.name+"' needs a "+k+"x"+k+" localMatrix.");
}
// AHP对子节点判断矩阵 -> 局部权重 + 一致性
Ahp.EigenResult er = Ahp.principalEigen(root.localMatrix, 1e-12, 10000);
root.localWeights = er.w;
root.lambdaMax = er.lambdaMax;
root.ci = Ahp.consistencyIndex(er.lambdaMax, k);
root.cr = Ahp.consistencyRatio(er.lambdaMax, k);
// 传播子全局 = 父全局 × 局部权重
for (int i = 0; i < k; i++) {
AhpNode child = root.children.get(i);
child.globalWeight = root.globalWeight * root.localWeights[i];
computeTree(child);
}
}
/** 打印树(缩进展示),显示局部/全局权重与一致性 */
static void printTree(AhpNode node, int depth) {
String indent = " ".repeat(depth);
String info = String.format("%s- %s (global=%.4f)", indent, node.name,
Double.isNaN(node.globalWeight) ? 0.0 : node.globalWeight);
System.out.println(info);
if (node.children.size() > 1) {
System.out.printf("%s local weights = %s | λmax=%.6f CI=%.6f CR=%.6f%n",
indent, Ahp.fmt(node.localWeights), node.lambdaMax, node.ci, node.cr);
}
for (AhpNode c : node.children) printTree(c, depth+1);
}
// ---------------- 完整示例 ----------------
// public static void main(String[] args) {
// // 层次H -> A,B ; A -> A1,A2,A3 ; B -> B1,B2
// AhpNode H = new AhpNode("H"); // 目标
// AhpNode A = new AhpNode("A"); // 准则组 A
// AhpNode B = new AhpNode("B"); // 准则组 B
// AhpNode A1 = new AhpNode("A1");
// AhpNode A2 = new AhpNode("A2");
// AhpNode A3 = new AhpNode("A3");
// AhpNode B1 = new AhpNode("B1");
// AhpNode B2 = new AhpNode("B2");
//
// // 组装树
// H.add(A, B);
// A.add(A1, A2, A3);
// B.add(B1, B2);
//
// // 顶层 H 的判断矩阵A vs B
// H.setLocalMatrix(new double[][]{
// {1, 3},
// {1.0/3, 1}
// });
//
// // A 组内A1,A2,A3
// A.setLocalMatrix(new double[][]{
// {1, 2, 4},
// {0.5, 1, 3},
// {0.25, 1.0/3, 1}
// });
//
// // B 组内B1,B2
// B.setLocalMatrix(new double[][]{
// {1, 0.5},
// {2, 1}
// });
//
// // 计算
// H.globalWeight = 1.0; // 根节点全局权重=1
// computeTree(H);
//
// // 打印结果
// printTree(H, 0);
//
// // 校验所有叶子全局之和应为 1
// double sumLeaves = sumLeaves(H);
// System.out.printf("%nSum of leaf global weights = %.6f%n", sumLeaves);
// }
static double sumLeaves(AhpNode n) {
if (n.children.isEmpty()) return n.globalWeight;
double s = 0.0;
for (AhpNode c : n.children) s += sumLeaves(c);
return s;
}
}