package com.estate.expert.admin.controller.admin; import com.estate.expert.admin.io.processor.impl.matrix.WeightMatrixProcessor; import com.estate.expert.admin.service.expert.DeviceExpertService; import com.estate.expert.admin.service.expert.SysExpertService; import com.estate.expert.common.domain.Session; import com.estate.expert.common.rpc.Result; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Controller; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.io.ByteArrayOutputStream; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; /** * 专家矩阵数据导入导出(JSON格式) */ @Slf4j @CrossOrigin @Api(tags = "管理后台/专家矩阵数据") @RequestMapping("/admin/matrix") @Controller @Validated public class MatrixController { @Resource private SysExpertService sysExpertService; @Resource private DeviceExpertService deviceExpertService; ////// 打分专家 - 权重矩阵导入导出 ////// @ApiOperation("综合体系-打分评价-权重矩阵导出") @PostMapping("/system/score/weightMatrix/export") public void exportSystemScoreWeightMatrix( @ApiParam("专家ID") @RequestParam Integer expertId, HttpServletResponse response) { var expert = sysExpertService.get(expertId); if(expert == null) { throw new RuntimeException("专家不存在"); } var hierarchyTree = sysExpertService.getHierarchyTree(expertId); var weightMap = expert.getWeightMap(); // 如果没有权重数据,生成默认权重(所有节点权重为1.0) if(weightMap == null || weightMap.isEmpty()) { weightMap = generateDefaultWeightMap(hierarchyTree); } try { String filename = "综合体系-" + expert.getName() + "-权重矩阵"; String encodedFilename = URLEncoder.encode(filename, StandardCharsets.UTF_8.toString()).replace("+", "%20"); response.setContentType("application/json;charset=UTF-8"); response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFilename + ".json"); new WeightMatrixProcessor(hierarchyTree).saveToJson(response.getOutputStream(), weightMap); response.getOutputStream().flush(); } catch (Exception e) { log.error("综合体系权重矩阵导出失败", e); throw new RuntimeException("导出失败: " + e.getMessage()); } } @ApiOperation("综合体系-打分评价-权重矩阵导入模版") @PostMapping("/system/score/weightMatrix/template") public void downloadSystemScoreWeightMatrixTemplate( @ApiParam("专家ID") @RequestParam Integer expertId, HttpServletResponse response) { exportSystemScoreWeightMatrix(expertId, response); } @ApiOperation("综合体系-打分评价-权重矩阵导入") @PostMapping("/system/score/weightMatrix/import") @ResponseBody public Result importSystemScoreWeightMatrix( Session session, @ApiParam("专家ID") @RequestParam Integer expertId, @RequestParam("file") MultipartFile file) { try { var hierarchyTree = sysExpertService.getHierarchyTree(expertId); var weightMap = new WeightMatrixProcessor(hierarchyTree).loadFromJson(file.getInputStream()); // 更新专家的权重数据 var expert = sysExpertService.get(expertId); expert.setWeightMap(weightMap); sysExpertService.edit(expert); return Result.success("权重矩阵导入成功,共导入 " + weightMap.size() + " 个节点"); } catch (Exception e) { log.error("综合体系权重矩阵导入失败", e); return Result.error("导入失败: " + e.getMessage()); } } @ApiOperation("设备体系-打分评价-权重矩阵导出") @PostMapping("/device/score/weightMatrix/export") public void exportDeviceScoreWeightMatrix( @ApiParam("专家ID") @RequestParam Integer expertId, HttpServletResponse response) { var expert = deviceExpertService.get(expertId); if(expert == null) { throw new RuntimeException("专家不存在"); } var hierarchyTree = deviceExpertService.getHierarchyTree(expertId); var weightMap = expert.getWeightMap(); // 如果没有权重数据,生成默认权重(所有节点权重为1.0) if(weightMap == null || weightMap.isEmpty()) { weightMap = generateDefaultWeightMap(hierarchyTree); } try { String filename = "设备体系-" + expert.getName() + "-权重矩阵"; String encodedFilename = URLEncoder.encode(filename, StandardCharsets.UTF_8.toString()).replace("+", "%20"); response.setContentType("application/json;charset=UTF-8"); response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFilename + ".json"); new WeightMatrixProcessor(hierarchyTree).saveToJson(response.getOutputStream(), weightMap); response.getOutputStream().flush(); } catch (Exception e) { log.error("设备体系权重矩阵导出失败", e); throw new RuntimeException("导出失败: " + e.getMessage()); } } @ApiOperation("设备体系-打分评价-权重矩阵导入模版") @PostMapping("/device/score/weightMatrix/template") public void downloadDeviceScoreWeightMatrixTemplate( @ApiParam("专家ID") @RequestParam Integer expertId, HttpServletResponse response) { exportDeviceScoreWeightMatrix(expertId, response); } @ApiOperation("设备体系-打分评价-权重矩阵导入") @PostMapping("/device/score/weightMatrix/import") @ResponseBody public Result importDeviceScoreWeightMatrix( Session session, @ApiParam("专家ID") @RequestParam Integer expertId, @RequestParam("file") MultipartFile file) { try { var hierarchyTree = deviceExpertService.getHierarchyTree(expertId); var weightMap = new WeightMatrixProcessor(hierarchyTree).loadFromJson(file.getInputStream()); // 更新专家的权重数据 var expert = deviceExpertService.get(expertId); expert.setWeightMap(weightMap); deviceExpertService.edit(expert); return Result.success("权重矩阵导入成功,共导入 " + weightMap.size() + " 个节点"); } catch (Exception e) { log.error("设备体系权重矩阵导入失败", e); return Result.error("导入失败: " + e.getMessage()); } } /** * 生成默认的权重Map(所有节点权重为1.0) */ private java.util.Map generateDefaultWeightMap( com.estate.expert.admin.utils.tree.TreeRoot hierarchyTree) { java.util.Map weightMap = new java.util.TreeMap<>(); // 递归遍历所有节点,生成默认权重 generateDefaultWeightForNode(hierarchyTree.root(), weightMap); return weightMap; } /** * 递归为节点及其子节点生成默认权重 */ private void generateDefaultWeightForNode( com.estate.expert.admin.utils.tree.TreeNode node, java.util.Map weightMap) { // 跳过根节点 if(!"/".equals(node.getPath()) && node.getPath() != null && node.getPath().length() > 1) { // 设置默认权重为1.0 weightMap.put(node.getPath(), 1.0f); } // 递归处理子节点 if(node.getChildren() != null && !node.getChildren().isEmpty()) { for(var child : node.getChildren().values()) { generateDefaultWeightForNode(child, weightMap); } } } }