From b9a5b68fab3428bb23c05ba3e0cab83afa1a82cb Mon Sep 17 00:00:00 2001
From: “mitao” <“2763622819@qq.com”>
Date: 星期五, 23 一月 2026 16:02:37 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ProjectController.java        |    3 
 ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java   |    9 
 ruoyi-system/src/main/java/com/ruoyi/system/query/DeviceDetailCheckListQuery.java    |    4 
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/EntrustProjectController.java |   83 ------
 ruoyi-system/src/main/java/com/ruoyi/system/enums/BizResultCode.java                 |  227 ++++++++++++++++++++
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProjectInfoServiceImpl.java |   26 -
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ReportServiceImpl.java      |  264 ++++++++++++++++++++++++
 ruoyi-system/src/main/resources/mapper/system/ProjectMapper.xml                      |    4 
 8 files changed, 519 insertions(+), 101 deletions(-)

diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/EntrustProjectController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/EntrustProjectController.java
index 826445a..3de17ea 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/EntrustProjectController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/EntrustProjectController.java
@@ -164,82 +164,13 @@
         recordService.updateById(record);
         return R.ok();
     }
-    @ApiOperation(value = "隐患详情")
-    @GetMapping("/errorDetail")
-    public R errorDetail(Integer id) {
-        Record record = recordService.getById(id);
-
-        return R.ok();
-    }
-    @ApiOperation(value = "获取项目详情", response = Project.class)
-    @GetMapping("/getProjectDetail/{id}")
-    public R<ProjectVo> getStoryDetail(@PathVariable Integer id) {
-        ProjectVo projectVo = new ProjectVo();
-        Project project = projectService.getById(id);
-        BeanUtils.copyProperties(project, projectVo);
-
-        List<String> properties = deviceUsageService.getDeviceUsageList(id);
-        projectVo.setProperties(properties);
-
-        ProjectInfo projectInfo = projectInfoService.getOne(new LambdaUpdateWrapper<ProjectInfo>().eq(ProjectInfo::getProjectId, id));
-        if (projectInfo != null) {
-            projectVo.setProgress(projectInfo.getProgress());
-        }
-        Task task = taskService.getOne(new LambdaUpdateWrapper<Task>().eq(Task::getProjectId, id).orderByDesc(Task::getUpdateTime).last("limit 1"));
-
-        if (task != null) {
-            projectVo.setCheckTime(task.getUpdateTime());
-        }
-        return R.ok(projectVo);
-    }
-
-
-    @ApiOperation(value = "获取项目隐患数量", response = Project.class)
-    @GetMapping("/getProjectHiddenDangerCount/{id}")
-    public R<HiddenDangerVo> getProjectHiddenDangerCount(@PathVariable Integer id) {
-        HiddenDangerVo hiddenDangerVo = new HiddenDangerVo();
-        List<Task> list = taskService.list(new LambdaQueryWrapper<Task>().eq(Task::getProjectId, id));
-        if (!list.isEmpty()) {
-            List<Integer> taskIds = list.stream().map(Task::getId).collect(Collectors.toList());
-            // 0是一级隐患
-            List<Record> records = recordService.list(new LambdaQueryWrapper<Record>().eq(Record::getLevel, 0).eq(Record::getDeleted, 0).in(Record::getCheckTaskId, taskIds));
-            hiddenDangerVo.setSerious(records.size());
-            int rectified = records.stream().filter(Record::getReformed).collect(Collectors.toList()).size();
-            hiddenDangerVo.setRectified(rectified);
-            hiddenDangerVo.setUnRectified(records.size() - rectified);
-        }
-        return R.ok(hiddenDangerVo);
-    }
-
-
-    @ApiOperation(value = "获取隐患列表", response = HiddenDangerListVo.class)
-    @PostMapping("/getHiddenDangerList")
-    public R<Page<HiddenDangerListVo>> getHiddenDangerList(@RequestBody @Valid HiddenDangerListQuery query) {
-        List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>().eq(Task::getProjectId, query.getProjectId()));
-        if (tasks.isEmpty()) {
-            return R.ok(new Page<>());
-        }
-        List<Integer> taskIds = tasks.stream().map(Task::getId).collect(Collectors.toList());
-        Page<HiddenDangerListVo> page = new Page<>(query.getPageNum(), query.getPageSize());
-        List<HiddenDangerListVo> list = recordService.getHiddenDangerList(page, query, taskIds);
-        page.setRecords(list);
-        return R.ok(page);
-
-    }
-
-
-    @ApiOperation(value = "编辑隐患责任人")
-    @PostMapping("/editHiddenDangerResponsiblePerson")
-    public R<Void> editHiddenDangerResponsiblePerson(@RequestBody @Valid EditHiddenDangerResponsiblePersonDto dto) {
-        Record record = recordService.getById(dto.getId());
-        if (record == null) {
-            return R.fail("隐患不存在");
-        }
-        record.setResponsiblePerson(dto.getResponsiblePerson());
-        recordService.updateById(record);
-        return R.ok();
-    }
-
+//    @ApiOperation(value = "隐患详情")
+//    @GetMapping("/errorDetail")
+//    public R errorDetail(Integer id) {
+//        Record record = recordService.getById(id);
+//
+//        return R.ok();
+//    }
 
     @ApiOperation(value = "获取隐患详情")
     @GetMapping("/getHiddenDangerDetail/{problemId}")
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ProjectController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ProjectController.java
index 2c3d23f..463f835 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ProjectController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/ProjectController.java
@@ -212,13 +212,13 @@
         return R.ok(list);
     }
 
+
     @ApiOperation(value = "获取检查资料详情")
     @GetMapping("/getDeviceDetailCheckPlanDetail")
     public R<Check> getDeviceDetailCheckPlanDetail(@RequestParam Integer id) {
         Check check = checkService.getDeviceDetailCheckPlanDetail(id);
         return R.ok(check);
     }
-
 
 
     @ApiOperation(value = "获取大屏人员在岗信息")
@@ -260,6 +260,7 @@
         return R.ok(list);
     }
 
+
     @ApiOperation(value = "获取人员在岗列表",response = ProjectPersonOnDutyListVo.class)
     @PostMapping("/getProjectOnDutyList")
     public R<Page<ProjectPersonOnDutyListVo>> getProjectOnDutyList(@RequestBody @Valid ProjectPersonListQuery query) {
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
index 4c6e46a..629f207 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
@@ -1,6 +1,7 @@
 package com.ruoyi.framework.web.service;
 
 import cn.hutool.core.util.PhoneUtil;
+import cn.hutool.crypto.SecureUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.ruoyi.common.constant.CacheConstants;
 import com.ruoyi.common.constant.Constants;
@@ -15,8 +16,10 @@
 import com.ruoyi.common.exception.user.*;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.common.utils.MessageUtils;
+import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.ip.IpUtils;
+import com.ruoyi.common.utils.sign.Md5Utils;
 import com.ruoyi.framework.manager.AsyncManager;
 import com.ruoyi.framework.manager.factory.AsyncFactory;
 import com.ruoyi.framework.security.context.AuthenticationContextHolder;
@@ -90,8 +93,14 @@
             log.info("登录用户:{} 不存在.", username);
             throw new ServiceException(MessageUtils.message("user.not.exists"));
         }
+        if (!user.getPassword().equals(SecureUtil.md5( password)))
+        {
+            log.info("登录用户:{} 密码错误", username);
+            throw new UserPasswordNotMatchException();
+        }
         if(user.getState()!=1){
             log.info("登录用户:{} 已被停用.", username);
+            throw new ServiceException(MessageUtils.message("user.blocked"));
         }
         LoginUser loginUser = new LoginUser();
         loginUser.setUserId(Long.valueOf(user.getId()));
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/enums/BizResultCode.java b/ruoyi-system/src/main/java/com/ruoyi/system/enums/BizResultCode.java
new file mode 100644
index 0000000..f4831cb
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/enums/BizResultCode.java
@@ -0,0 +1,227 @@
+package com.ruoyi.system.enums;
+
+
+import lombok.Getter;
+
+/**
+ * @description: 弹窗消息的定义
+ * @author: code
+ **/
+@Getter
+public enum BizResultCode implements ApiResultCode {
+
+    INVALID_OPERATION("无效操作"),
+    MOBILE_ALREADY_EXIST("手机号已存在"),
+    USERNAME_ALREADY_EXIST("用户名已存在"),
+    ACCOUNT_NOT_FOUND("帐号不存在"),
+    SYS_VALIDATION_FAILED_ERROR("验证失败,无效请求"),
+    APP_CLIENT_NOT_EXIST("登录客户端不存在"),
+    SESSION_EXPIRED("会话已过期"),
+    SESSION_INVALID("会话无效"),
+    NO_LOGIN_ERROR("未登录"),
+    ACCOUNT_FORBIDDEN("帐号被禁用"),
+
+    H_CAPTCHA_CODE_NULL_ERROR("图形验证码不能为空"),
+    CAPTCHA_CODE_NOT_NULL(""),
+    H_CAPTCHA_CODE_VALIDATE_ERROR("图形验证失败"),
+    VERIFICATION_CODE_INVALID("图形验证码验证失败"),
+    BIZ_PASSWORD_INVALID("密码错误"),
+
+//    BIZ_CLIENT_NOT_FOUND("委托方不存在"),
+//    BIZ_CLIENT_NAME_ALREADY_EXISTS("委托方名称已存在"),
+//    BIZ_CONTRACT_NOT_EXIST("合同不存在"),
+
+    BIZ_CAR_NOT_EXIST("车辆不存在"),
+
+    BIZ_DATE_FORMAT_ERROR("日期格式错误"),
+
+    BIZ_PROJECT_NOT_EXIST("项目不存在"),
+
+    BIZ_DEVICE_NOT_EXIST("设备不存在"),
+
+    BIZ_SCORE_WEIGHT_CAN_NOT_NULL("分数和权重不能为空"),
+
+    BIZ_HIERARCHY_SYSTEM_NOT_EXIST("体系不存在"),
+
+    BIZ_PARENT_HIERARCHY_SYSTEM_NOT_EXIST("父ID体系不存在"),
+
+    BIZ_PLAN_NOT_EXIST("计划不存在"),
+
+    BIZ_PROBLEM_NUM_CANNOT_NULL("问题数量集合不能为空"),
+
+    BIZ_PROBLEM_SCALE_CANNOT_NULL("对应规模集合不能为空"),
+
+    BIZ_REAL_RULE_NOT_EXIST("实测实量规则不存在"),
+
+    BIZ_EXPERT_NOT_EXIST("专家不存在"),
+
+    EXPERT_FUNCTIONS_MUST_ENABLE("专家功能必须启用"),
+
+    BIZ_MODEL_NOT_EXIST("模型不存在"),
+
+    BIZ_PROJECT_STATUS_NOT_MATCH("项目状态不匹配"),
+
+    BIZ_EXPERT_SCORE_SYS_NOT_EXIST("专家评分体系不存在"),
+
+    BIZ_MEMBERSHIP_DEGREE_NOT_EXIST("隐患等级不存在"),
+
+    BIZ_PROJECT_SUPERVISOR_HIS_NOT_EXIST("项目监督历史不存在"),
+
+    BIZ_PROJECT_DEVICE_NOT_EXIST("项目设备不存在"),
+
+    BIZ_REPORT_TEMPLATE_NOT_EXIST("报告模板不存在"),
+
+    BIZ_REPORT_TEMPLATE_TYPE_NOT_EXIST("报告模板类型不存在"),
+
+    BIZ_ARCHIVE_NOT_EXIST("档案不存在"),
+
+    BIZ_PROJECT_NOT_CLOSED("项目未关闭"),
+
+    BIZ_PROJECT_ALREADY_CLOSED("项目已关闭"),
+
+    BIZ_PLAN_CLIENT_EXIST("该委托方对应的计划已存在"),
+
+    BIZ_PLAN_PROJECT_RELATION_NOT_EXIST("计划项目关系不存在"),
+
+    BIZ_PROJECT_NAME_EXIST("同一个委托方下已存在相同名称的项目"),
+    HIERARCHY_PARENT_NOT_FOUND("父级体系不存在"),
+    HIERARCHY_NODE_NOT_FOUND("节点不存在"),
+    HIERARCHY_NODE_NAME_ALREADY_EXISTS("节点名称已存在"),
+    BIZ_MODEL_NOT_FOUND("模型不存在"),
+    DRIVER_CAR_NOT_MATCH("司机和车辆数量不匹配"),
+    PARAM_ERROR("参数错误"),
+    CAR_NOT_EXIST("车辆不存在"),
+    PROBLEM_NOT_EXIST("问题不存在"),
+    ID_CANNOT_NULL("ID不能为空"),
+    MODEL_NOT_FOUND("模型不存在"),
+    PROJECT_INFO_NOT_EXIST("项目信息不存在"),
+    DEVICE_NOT_FOUND("设备不存在"),
+    DEVICE_IS_BUSY("设备正在使用中"),
+    PLAN_NOT_EXIST("计划不存在"),
+    ARCHIVE_NOT_EXIST("档案不存在"),
+    ENTITY_NOT_FOUND("实体不存在"),
+    ENTITY_NAME_ALREADY_EXISTS("实体名称已存在"),
+    ENTITY_CANNOT_NULL("实体不能为空"),
+    MODEL_PUBLISHED_CANNOT_MODIFY("已发布的模型不可修改"),
+    ACCOUNT_ALREADY_EXISTS("登录账号已存在"),
+    //无权修改他人信息
+    NO_PERMISSION_MODIFY_OTHERS_INFO("无权修改他人信息"),
+    DEVICE_USAGE_NOT_FOUND("设备使用记录不存在"),
+    MEMBERSHIP_MATRIX_LOAD_ERROR("隶属度矩阵加载失败"),
+    TASK_NOT_FOUND("任务不存在"),
+    TASK_ALREADY_EXIST("任务已存在"),
+    TASK_STATUS_ERROR("任务状态错误"),
+    NUMBER_FACTOR_NOT_EXIST("问题数量集合不存在"),
+    NUMBER_FACTOR_INDEX_ERROR("问题数量索引错误"),
+    SCALE_FACTOR_NOT_EXIST("对应规模集合不存在"),
+    SCALE_FACTOR_INDEX_ERROR("对应规模索引错误"),
+    INDEX_COLS_EMPTY("索引列为空"),
+    COMPARE_MATRIX_EMPTY("比较矩阵为空"),
+    MATRIX_SIZE_ERROR("矩阵大小错误"),
+    MATRIX_ERROR("所有的数字都应该是正数,且沿着主对角线对称的元素应该是彼此的相反数"),
+    NUMBER_NON_NEGATIVE("所有的数字都应该是非负数"),
+    INDEX_RANGE_ERROR("索引范围错误"),
+    MEMBERSHIP_MATRIX_ERROR("隶属度矩阵每一行的和应该等于1"),
+    SIGN_RECORD_EXIST("重复签到"),
+    PLAN_NAME_EXIST("计划名称已存在"),
+    CAR_LICENSE_NO_EXIST("车牌号已存在"),
+    HIERARCHY_NOT_FOUND("体系数据不存在"),
+    PLAN_NOT_FOUND("计划不存在"),
+    RECORD_NOT_FOUND("问题记录不存在"),
+    RECORD_REVIEW_EXISTED("问题已经复核"),
+    REVIEW_ALREADY_REFORMED("问题已经整改,无须复查"),
+    UPLOAD_FILE_FAILED("上传文件失败"),
+    UPLOAD_FILE_CONTAINS_ILLEGAL_CHARACTERS("上传文件名包含非法字符"),
+    FILE_NOT_FOUND("文件不存在"),
+    EVAL_FUZZY_RESULT_NOT_EXIST("模糊评价结果不存在"),
+    EVAL_SCORE_RESULT_NOT_EXIST("评分评价结果不存在"),
+    USER_IS_DISABLE("用户已被禁用"),
+    EXPERT_MODEL_NOT_EXIST("专家对应的模型不存在"),
+    MEMBERSHIP_MATRIX_NOT_EXIST("隶属度矩阵不存在"),
+    EXPERT_NOT_FOUND("专家不存在"),
+    MOBILE_FORMAT_ERROR("手机号格式错误"),
+    HIERARCHY_NOT_EXIST("体系不存在"),
+    PlAN_MODEL_EXPERT_SHOULD_PAIRED("计划模型和专家模型不匹配"),
+    PLAN_SYSTEM_MODEL_NOT_EXIST("综合体系模型不存在"),
+    PLAN_DEVICE_MODEL_NOT_EXIST("设备体系模型不存在"),
+    REVIEW_TASK_NOT_EXIST("复核任务不存在"),
+    ERROR_RECORD_ALL_REVIEWD("问题已全部复核"),
+    PROJECT_INFO_EXISTS("检查任务对应的项目信息已存在"),
+    IMPORT_DATA_EMPTY("导入数据为空"),
+    IMPORT_DATA_COLUMN_COUNT("导入数据列数不正确"),
+    CLIENT_NOT_FOUND("委托方不存在"),
+    DEVICE_ALREADY_EXISTS("设备名称已存在"),
+    ROLE_NOT_FOUND("角色不存在"),
+    CHECK_TASK_NOT_EXIST("检查任务不存在"),
+    DEVICE_USAGE_NOT_EXISTED("设备使用记录不存在"),
+    PASSWORD_ERROR("密码输入错误"),
+    PASSWORD_FORMAT_ERROR("密码需要6到16位长度"),
+
+    // License相关错误码
+    LICENSE_NOT_CONFIGURED("License密钥未配置"),
+    LICENSE_INVALID_FORMAT("License格式错误"),
+    LICENSE_SIGNATURE_INVALID("License签名验证失败"),
+    LICENSE_EXPIRED("License已过期"),
+    LICENSE_VALIDATION_FAILED("License验证失败"),
+
+    // 报告生成相关错误码
+    BIZ_REPORT_GENERATE_FAILED("报告生成失败");
+
+    private final String errorMsg;
+
+    BizResultCode(String errorMsg) {
+        this.errorMsg = errorMsg;
+    }
+
+    /**
+     * 得到 message 的值.
+     *
+     * @return 属性 message 的值.
+     */
+    @Override
+    public String getErrorMsg() {
+        return errorMsg + "(" + getAppId() + ")";
+    }
+
+    /**
+     * @return 当前服务的AppId
+     */
+    @Override
+    public String getAppId() {
+        return "1001";
+    }
+
+    /**
+     * 校验方法
+     *
+     * @param expect
+     */
+    public void check(boolean expect) {
+        if (expect) {
+            throw new BizException(this.errorMsg);
+        }
+    }
+
+    /**
+     * 校验方法
+     * @param expect
+     * @param code
+     */
+    public void check(boolean expect, String code) {
+        if (expect) {
+            throw new BizException(code);
+        }
+    }
+
+    /**
+     * 校验方法
+     * @param expect
+     * @param code
+     * @param message
+     */
+    public void check(boolean expect, String code, String message) {
+        if (expect) {
+            throw new BizException(message);
+        }
+    }
+}
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/query/DeviceDetailCheckListQuery.java b/ruoyi-system/src/main/java/com/ruoyi/system/query/DeviceDetailCheckListQuery.java
index 8665d5b..fd3d4c4 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/query/DeviceDetailCheckListQuery.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/query/DeviceDetailCheckListQuery.java
@@ -15,8 +15,8 @@
     @NotNull(message = "项目id不能为空")
     private Integer projectId;
 
-    @ApiModelProperty("计划id")
-    private Integer planId;
+    @ApiModelProperty("计划类型")
+    private Integer planType;
 
 
     @ApiModelProperty("开始时间")
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProjectInfoServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProjectInfoServiceImpl.java
index e1db0fa..5b16ef0 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProjectInfoServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ProjectInfoServiceImpl.java
@@ -1,20 +1,16 @@
 package com.ruoyi.system.service.impl;
 
-import cn.hutool.core.date.DateUnit;
-import cn.hutool.core.date.DateUtil;
 import com.alibaba.fastjson2.JSONArray;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.system.mapper.ProjectInfoMapper;
 import com.ruoyi.system.model.Project;
 import com.ruoyi.system.model.ProjectInfo;
-import com.ruoyi.system.mapper.ProjectInfoMapper;
 import com.ruoyi.system.model.Record;
 import com.ruoyi.system.query.ProjectDangerousTrendQuery;
 import com.ruoyi.system.query.ProjectHiddenDangerTrendListQuery;
 import com.ruoyi.system.service.ProjectCategoryCalculator;
 import com.ruoyi.system.service.ProjectInfoService;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.system.service.ProjectService;
-import com.ruoyi.system.service.RecordService;
 import com.ruoyi.system.vo.ProjectDangerousTrendVo;
 import com.ruoyi.system.vo.ProjectHiddenDangerList;
 import com.ruoyi.system.vo.ProjectHiddenDangerNextList;
@@ -30,7 +26,10 @@
 import java.time.YearMonth;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.TemporalAdjusters;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
 
 import static java.util.stream.Collectors.groupingBy;
 
@@ -230,18 +229,5 @@
 
         // 计算月份差 + 1(包含结束月份)
         return (int) ChronoUnit.MONTHS.between(start, end) + 1;
-    }
-    public static void main(String[] args) {
-        LocalDate monthBoundaries = getMonthBoundaries("2025-03", true);
-        System.out.println(monthBoundaries);
-        System.out.println(getMonthBoundaries("2025-02",false));
-
-        System.out.println(calculateMonthsBetween("2025-03", "2026-01"));
-
-        for (int count = 0; count < 11; count++) {
-            // 根据2025-03 根据循环获取下一个月的时间
-            LocalDate monthBoundaries1 = getMonthBoundaries("2025-03", true).plusMonths(count);
-            System.out.println(monthBoundaries1.toString().substring(0,7));
-        }
     }
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ReportServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ReportServiceImpl.java
new file mode 100644
index 0000000..30054c9
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/ReportServiceImpl.java
@@ -0,0 +1,264 @@
+package com.ruoyi.system.service.impl;
+
+
+import com.alibaba.fastjson2.JSONObject;
+import com.ruoyi.system.enums.BizResultCode;
+import com.ruoyi.system.model.ReportTemplate;
+import com.ruoyi.system.service.*;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.io.ByteArrayInputStream;
+import java.io.OutputStream;
+
+/**
+ * 报告数据服务实现类
+ **/
+@Slf4j
+@Service
+public class ReportServiceImpl implements ReportService {
+
+    @Resource
+    private ReportTemplateService reportTemplateService;
+
+    @Resource
+    private ProjectInfoService projectInfoService;
+
+    @Resource
+    private DeviceUsageService deviceUsageService;
+
+    @Resource
+    private EvalFuzzyService evalFuzzyService;
+
+    @Resource
+    private EvalScoreService evalScoreService;
+
+    @Resource
+    private ErrorRecordService errorRecordService;
+
+    @Resource
+    private DeviceService deviceService;
+
+    @Resource
+    private UserFileService userFileService;
+
+    @Override
+    public JSONObject fuzzyReportData(Integer checkTaskId, Integer templateId) {
+        var evalFuzzyResult = evalFuzzyService.getByCheckTaskId(checkTaskId);
+        BizResultCode.EVAL_FUZZY_RESULT_NOT_EXIST.check(evalFuzzyResult == null);
+
+        var evalScoreResult =  evalScoreService.getByCheckTaskId(checkTaskId);
+        BizResultCode.EVAL_SCORE_RESULT_NOT_EXIST.check(evalScoreResult == null);
+
+        var reportTemplate = reportTemplateService.get(templateId);
+        BizResultCode.BIZ_REPORT_TEMPLATE_NOT_EXIST.check(reportTemplate == null);
+
+        switch (reportTemplate.getType()) {
+            case ThirdPartyReport:
+                return buildFuzzySystemReportData(evalFuzzyResult, evalScoreResult, reportTemplate);
+            case DeviceReport:
+                return buildFuzzyDeviceReportData(evalFuzzyResult, evalScoreResult, reportTemplate);
+            default:
+                throw new BizException(BizResultCode.BIZ_REPORT_TEMPLATE_TYPE_NOT_EXIST);
+        }
+    }
+
+    @Override
+    public JSONObject scoreReportData(Integer checkTaskId, Integer templateId) {
+        var evalFuzzyResult = evalFuzzyService.getByCheckTaskId(checkTaskId);
+        BizResultCode.EVAL_FUZZY_RESULT_NOT_EXIST.check(evalFuzzyResult == null);
+
+        var evalScoreResult =  evalScoreService.getByCheckTaskId(checkTaskId);
+        BizResultCode.EVAL_SCORE_RESULT_NOT_EXIST.check(evalScoreResult == null);
+
+        var reportTemplate = reportTemplateService.get(templateId);
+        BizResultCode.BIZ_REPORT_TEMPLATE_NOT_EXIST.check(reportTemplate == null);
+
+        switch (reportTemplate.getType()) {
+            case ThirdPartyReport:
+                return buildScoreSystemReportData(evalFuzzyResult, evalScoreResult, reportTemplate);
+            case DeviceReport:
+                return buildScoreDeviceReportData(evalFuzzyResult, evalScoreResult, reportTemplate);
+            default:
+                throw new BizException(BizResultCode.BIZ_REPORT_TEMPLATE_TYPE_NOT_EXIST);
+        }
+    }
+
+    @Override
+    public XWPFTemplate fuzzyReport(Integer checkTaskId, Integer templateId) {
+        var reportData = fuzzyReportData(checkTaskId, templateId);
+        var builder = getReportBuilder(templateId);
+        var template = reportTemplateService.get(templateId);
+
+        // reportData to JSONObject
+        return builder.buildReport(reportData, template.getConfig());
+    }
+
+    @Override
+    public XWPFTemplate scoreReport(Integer checkTaskId, Integer templateId) {
+        var reportData = scoreReportData(checkTaskId, templateId);
+        var builder = getReportBuilder(templateId);
+        var template = reportTemplateService.get(templateId);
+
+        // reportData to JSONObject
+        return builder.buildReport(reportData, template.getConfig());
+    }
+
+    @Override
+    public void fuzzyReportPdf(Integer checkTaskId, Integer templateId, OutputStream outputStream) {
+        try (var doc = fuzzyReport(checkTaskId, templateId)) {
+            convertToPdf(doc, outputStream);
+        } catch (Exception e) {
+            log.error("生成模糊评价PDF报告失败", e);
+            throw new BizException("生成模糊评价PDF报告失败");
+        }
+    }
+
+    @Override
+    public void scoreReportPdf(Integer checkTaskId, Integer templateId, OutputStream outputStream) {
+        try (var doc = scoreReport(checkTaskId, templateId)) {
+            convertToPdf(doc, outputStream);
+        } catch (Exception e) {
+            log.error("生成打分评价PDF报告失败", e);
+            throw new BizException("生成打分评价PDF报告失败");
+        }
+    }
+
+    /**
+     * 将Word文档转换为PDF
+     * @param template Word模板
+     * @param outputStream 输出流
+     */
+    private void convertToPdf(XWPFTemplate template, OutputStream outputStream) throws Exception {
+        // 先将Word模板写入字节数组
+        ByteArrayOutputStream docOutputStream = new ByteArrayOutputStream();
+        template.write(docOutputStream);
+
+        // 从字节数组读取Word文档
+        ByteArrayInputStream docInputStream = new ByteArrayInputStream(docOutputStream.toByteArray());
+        org.apache.poi.xwpf.usermodel.XWPFDocument document = new org.apache.poi.xwpf.usermodel.XWPFDocument(docInputStream);
+
+        // 转换为PDF
+        PdfOptions options = PdfOptions.create();
+        PdfConverter.getInstance().convert(document, outputStream, options);
+
+        // 关闭资源
+        document.close();
+        docInputStream.close();
+        docOutputStream.close();
+    }
+
+    private ReportBuilderBase getReportBuilder(Integer templateId) {
+        var reportTemplate = reportTemplateService.get(templateId);
+        BizResultCode.BIZ_REPORT_TEMPLATE_NOT_EXIST.check(reportTemplate == null);
+        switch (reportTemplate.getType()) {
+            case ThirdPartyReport:
+                return new SystemReportBuilder(userFileService);
+            case DeviceReport:
+                return new DeviceReportBuilder(userFileService);
+            default:
+                throw new BizException(BizResultCode.BIZ_REPORT_TEMPLATE_TYPE_NOT_EXIST);
+        }
+    }
+
+    private JSONObject buildFuzzySystemReportData(EvalFuzzyResult evalFuzzyResult, EvalScoreResult scoreResult, ReportTemplate reportTemplate) {
+        // 查询必须要的数据
+        var records = errorRecordService.listSystemErrors(evalFuzzyResult.getTask().getId());
+        var project = evalFuzzyResult.getProject();
+        var projectInfo = evalFuzzyResult.getTask().getProjectInfo();
+//        var projectInfo = projectInfoService.getByCheckTaskId(evalFuzzyResult.getTask().getId());
+        var deviceUsages = deviceUsageService.listUsages(project.getId(), null);
+        var devices= deviceUsages.stream().map(DeviceUsage::getDevice).toList();
+        var hierarchy = evalFuzzyResult.getPlan().getSystemScoreExpert().getModel().getHierarchy().getContent();
+
+        // 生成报告数据
+        return SystemFuzzyReportData.builder()
+                .reportId(evalFuzzyResult.getId())
+                .systemHierarchy(hierarchy)
+                .sysResult(evalFuzzyResult.getSystemRes())
+                .scoreResult(scoreResult.getSystemRes())
+                .template(reportTemplate)
+                .project(project)
+                .projectInfo(projectInfo)
+                .devices(devices)
+                .records(records)
+                .build()
+                .generate();
+    }
+
+    private JSONObject buildScoreSystemReportData(EvalFuzzyResult evalFuzzyResult, EvalScoreResult scoreResult, ReportTemplate reportTemplate) {
+        // 查询必须要的数据
+        var records = errorRecordService.listSystemErrors(evalFuzzyResult.getTask().getId());
+        var project = evalFuzzyResult.getProject();
+//        var projectInfo = projectInfoService.latest(evalFuzzyResult.getProject().getId());
+        var projectInfo = evalFuzzyResult.getTask().getProjectInfo();
+        var deviceUsages = deviceUsageService.listUsages(project.getId(), null);
+        var devices= deviceUsages.stream().map(DeviceUsage::getDevice).toList();
+        var hierarchy = evalFuzzyResult.getPlan().getSystemScoreExpert().getModel().getHierarchy().getContent();
+
+        // 生成报告数据
+        return SystemScoreReportData.builder()
+                .reportId(evalFuzzyResult.getId())
+                .systemHierarchy(hierarchy)
+                .sysResult(evalFuzzyResult.getSystemRes())
+                .scoreResult(scoreResult.getSystemRes())
+                .template(reportTemplate)
+                .project(project)
+                .projectInfo(projectInfo)
+                .devices(devices)
+                .records(records)
+                .build()
+                .generate();
+    }
+
+    private JSONObject buildFuzzyDeviceReportData(EvalFuzzyResult evalFuzzyResult, EvalScoreResult scoreResult,  ReportTemplate reportTemplate) {
+        var records = errorRecordService.listDeviceErrors(evalFuzzyResult.getTask().getId());
+        var project = evalFuzzyResult.getProject();
+        var projectInfo = evalFuzzyResult.getTask().getProjectInfo();
+//        var projectInfo = projectInfoService.getByCheckTaskId(evalFuzzyResult.getTask().getId());
+        var deviceIds = evalFuzzyResult.getDeviceResMap().keySet();
+        var devices = deviceService.findAllById(deviceIds);
+        var hierarchy = evalFuzzyResult.getPlan().getDeviceScoreExpert().getModel().getHierarchy().getContent();
+
+        // 生成报告数据
+        return DeviceFuzzyReportData.builder()
+                .reportId(evalFuzzyResult.getId())
+                .deviceResMap(evalFuzzyResult.getDeviceResMap())
+                .deviceHierarchy(hierarchy)
+                .template(reportTemplate)
+                .project(project)
+                .projectInfo(projectInfo)
+                .devices(devices)
+                .records(records)
+                .build()
+                .generate();
+    }
+
+    private JSONObject buildScoreDeviceReportData(EvalFuzzyResult evalFuzzyResult, EvalScoreResult evalScoreResult, ReportTemplate reportTemplate) {
+        var records = errorRecordService.listDeviceErrors(evalFuzzyResult.getTask().getId());
+        var project = evalFuzzyResult.getProject();
+//        var projectInfo = projectInfoService.getByCheckTaskId(evalFuzzyResult.getTask().getId());
+        var projectInfo = evalFuzzyResult.getTask().getProjectInfo();
+        var deviceIds = evalFuzzyResult.getDeviceResMap().keySet();
+        var devices = deviceService.findAllById(deviceIds);
+        var hierarchy = evalFuzzyResult.getPlan().getDeviceScoreExpert().getModel().getHierarchy().getContent();
+
+        // 生成报告数据
+        return DeviceScoreReportData.builder()
+                .reportId(evalFuzzyResult.getId())
+                .deviceResMap(evalFuzzyResult.getDeviceResMap())
+                .deviceScoreResMap(evalScoreResult.getDeviceResMap())
+                .deviceHierarchy(hierarchy)
+                .template(reportTemplate)
+                .project(project)
+                .projectInfo(projectInfo)
+                .devices(devices)
+                .records(records)
+                .build()
+                .generate();
+    }
+
+
+
+}
diff --git a/ruoyi-system/src/main/resources/mapper/system/ProjectMapper.xml b/ruoyi-system/src/main/resources/mapper/system/ProjectMapper.xml
index ac3b4bf..2d04038 100644
--- a/ruoyi-system/src/main/resources/mapper/system/ProjectMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/ProjectMapper.xml
@@ -34,8 +34,8 @@
             <if test="query.planName != null and query.planName != ''">
                 and t2.name like concat('%',#{query.planName},'%')
             </if>
-            <if test="query.planId != null">
-                and t2.id = #{query.planId}
+            <if test="query.planType != null">
+                and t2.type = #{query.planType}
             </if>
             <if test="query.startTime != null and query.startTime != ''">
                 and t1.date >= #{query.startTime}

--
Gitblit v1.7.1