Commit 8db6dcd55b67fcc974afc8818484b2772ee5d664

Authored by 颜惠青
2 parents 6d08c226 61400ba4

Merge branch 'master' of http://gitlab1.renniting.cn/JCSS/urbanops

Showing 25 changed files with 963 additions and 62 deletions
.gitignore
@@ -53,3 +53,15 @@ application-my.yaml @@ -53,3 +53,15 @@ application-my.yaml
53 /urbanops-ui-app/unpackage/ 53 /urbanops-ui-app/unpackage/
54 **/.DS_Store 54 **/.DS_Store
55 old/ 55 old/
  56 +/.claudeignore
  57 +/docs/all_test.html
  58 +/docs/ppt-assets/animations.css
  59 +/docs/ppt-assets/base.css
  60 +/CLAUDE.md
  61 +/urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/enums/ErrorCodeConstants_手动操作.java
  62 +/docs/ppt-assets/fonts.css
  63 +/docs/ppt-assets/runtime.js
  64 +/.claude/settings.local.json
  65 +/docs/ppt-assets/style.css
  66 +/docs/urbanops-architecture-ppt.html
  67 +/docs/urbanops-tech-sharing.html
sql/mysql/garden_problem_type-fix.sql 0 → 100644
  1 +-- =================================================
  2 +-- garden_problem_type 表结构补全
  3 +-- 原因:BaseDO 包含 create_time/update_time/creator/updater/deleted
  4 +-- MyBatis Plus @TableLogic 自动 WHERE deleted=0
  5 +-- 缺少这些列会导致 SQL 报错或无数据返回
  6 +-- =================================================
  7 +
  8 +-- 如果表已存在数据,先备份
  9 +-- CREATE TABLE garden_problem_type_bak AS SELECT * FROM garden_problem_type;
  10 +
  11 +-- 方案1:删表重建(无重要数据时)
  12 +DROP TABLE IF EXISTS `garden_problem_type`;
  13 +CREATE TABLE `garden_problem_type` (
  14 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  15 + `type_code` varchar(32) NOT NULL COMMENT '问题类型编码',
  16 + `type_name` varchar(64) NOT NULL COMMENT '问题类型名称',
  17 + `level` tinyint NOT NULL COMMENT '层级:1一级 2二级 3三级',
  18 + `parent_code` varchar(32) DEFAULT NULL COMMENT '父级类型编码',
  19 + `sort` int DEFAULT 0 COMMENT '排序序号',
  20 + `status` tinyint DEFAULT 1 COMMENT '状态 1启用 0禁用',
  21 + `creator` varchar(64) DEFAULT '' COMMENT '创建者',
  22 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  23 + `updater` varchar(64) DEFAULT '' COMMENT '更新者',
  24 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  25 + `deleted` tinyint NOT NULL DEFAULT 0 COMMENT '逻辑删除 0正常 1删除',
  26 + PRIMARY KEY (`id`),
  27 + UNIQUE KEY `uk_type_code` (`type_code`)
  28 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='问题类型三级分类表';
  29 +
  30 +-- 方案2:已有数据时,用 ALTER 补齐缺失列(按需执行)
  31 +-- ALTER TABLE garden_problem_type ADD COLUMN `creator` varchar(64) DEFAULT '' COMMENT '创建者' AFTER `status`;
  32 +-- ALTER TABLE garden_problem_type ADD COLUMN `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间' AFTER `creator`;
  33 +-- ALTER TABLE garden_problem_type ADD COLUMN `updater` varchar(64) DEFAULT '' COMMENT '更新者' AFTER `create_time`;
  34 +-- ALTER TABLE garden_problem_type ADD COLUMN `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' AFTER `updater`;
  35 +-- ALTER TABLE garden_problem_type ADD COLUMN `deleted` tinyint NOT NULL DEFAULT 0 COMMENT '逻辑删除' AFTER `update_time`;
sql/mysql/problem-type-menu-auto.sql 0 → 100644
  1 +-- =================================================
  2 +-- 问题类型配置 - 菜单与权限 SQL(自动查找父菜单ID)
  3 +-- 直接执行即可,自动从「工单管理」下挂载菜单
  4 +-- =================================================
  5 +
  6 +-- 查询当前最大 ID 作为起始值
  7 +SET @maxId = (SELECT IFNULL(MAX(id), 5000) FROM system_menu);
  8 +
  9 +-- 查询工单管理 菜单ID
  10 +SET @parentId = (SELECT id FROM system_menu WHERE name = '工单管理' AND type = 1 LIMIT 1);
  11 +
  12 +-- 如果找不到工单管理,尝试匹配 workorder 关键字
  13 +-- SET @parentId = (SELECT id FROM system_menu WHERE (name LIKE '%工单%' OR path LIKE '%workorder%') AND type = 1 LIMIT 1);
  14 +
  15 +-- 1. 二级菜单:问题类型
  16 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`)
  17 +VALUES (@maxId + 1, '问题类型', '', 2, 10, @parentId, 'problem-type', 'ep:list', 'garden/problemType/index', 'ProblemType', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0');
  18 +
  19 +-- 2. 按钮:查询
  20 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`)
  21 +VALUES (@maxId + 2, '问题类型查询', 'garden:problem-type:query', 3, 1, @maxId + 1, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0');
  22 +
  23 +-- 3. 按钮:创建
  24 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`)
  25 +VALUES (@maxId + 3, '问题类型创建', 'garden:problem-type:create', 3, 2, @maxId + 1, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0');
  26 +
  27 +-- 4. 按钮:更新
  28 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`)
  29 +VALUES (@maxId + 4, '问题类型更新', 'garden:problem-type:update', 3, 3, @maxId + 1, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0');
  30 +
  31 +-- 5. 按钮:删除
  32 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`)
  33 +VALUES (@maxId + 5, '问题类型删除', 'garden:problem-type:delete', 3, 4, @maxId + 1, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0');
sql/mysql/problem-type-menu.sql 0 → 100644
  1 +-- =================================================
  2 +-- 问题类型配置 - 菜单与权限 SQL
  3 +-- 说明:
  4 +-- 1. 请先查询「工单管理」的菜单 ID,替换下面 @parentId 为实际值
  5 +-- 查询语句:SELECT id FROM system_menu WHERE name = '工单管理' AND type = 1;
  6 +-- 2. 修改下面 @menuId 为可用的起始 ID(确保不与已有菜单 ID 冲突)
  7 +-- 查询最大ID:SELECT MAX(id) FROM system_menu;
  8 +-- 3. 执行前请备份 system_menu 表
  9 +-- =================================================
  10 +
  11 +-- 请根据实际情况替换以下变量值:
  12 +-- SET @parentId = (SELECT id FROM system_menu WHERE name = '工单管理' AND type = 1);
  13 +-- SET @menuId = (SELECT IFNULL(MAX(id), 0) + 1 FROM system_menu);
  14 +
  15 +-- 示例:假设工单管理 parent_id = 2000,起始 menu_id = 5100
  16 +
  17 +-- 1. 二级菜单:问题类型
  18 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`)
  19 +VALUES (@menuId, '问题类型', '', 2, 10, @parentId, 'problem-type', 'ep:list', 'garden/problemType/index', 'ProblemType', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0');
  20 +
  21 +-- 2. 按钮权限:查询
  22 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`)
  23 +VALUES (@menuId + 1, '问题类型查询', 'garden:problem-type:query', 3, 1, @menuId, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0');
  24 +
  25 +-- 3. 按钮权限:创建
  26 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`)
  27 +VALUES (@menuId + 2, '问题类型创建', 'garden:problem-type:create', 3, 2, @menuId, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0');
  28 +
  29 +-- 4. 按钮权限:更新
  30 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`)
  31 +VALUES (@menuId + 3, '问题类型更新', 'garden:problem-type:update', 3, 3, @menuId, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0');
  32 +
  33 +-- 5. 按钮权限:删除
  34 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`)
  35 +VALUES (@menuId + 4, '问题类型删除', 'garden:problem-type:delete', 3, 4, @menuId, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0');
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/costfee/CostFeeController.java
@@ -5,16 +5,24 @@ import com.zteits.urbanops.framework.excel.core.util.ExcelUtils; @@ -5,16 +5,24 @@ import com.zteits.urbanops.framework.excel.core.util.ExcelUtils;
5 import com.zteits.urbanops.module.garden.controller.admin.costfee.vo.WaterFeeImport; 5 import com.zteits.urbanops.module.garden.controller.admin.costfee.vo.WaterFeeImport;
6 import com.zteits.urbanops.module.garden.enums.TemplateEnum; 6 import com.zteits.urbanops.module.garden.enums.TemplateEnum;
7 import com.zteits.urbanops.module.garden.service.costfee.CostFeeService; 7 import com.zteits.urbanops.module.garden.service.costfee.CostFeeService;
  8 +import com.zteits.urbanops.module.system.api.dept.DeptApi;
  9 +import com.zteits.urbanops.module.system.api.dept.dto.DeptRespDTO;
8 import io.swagger.v3.oas.annotations.Operation; 10 import io.swagger.v3.oas.annotations.Operation;
9 import io.swagger.v3.oas.annotations.tags.Tag; 11 import io.swagger.v3.oas.annotations.tags.Tag;
  12 +import jakarta.annotation.security.PermitAll;
10 import jakarta.servlet.http.HttpServletResponse; 13 import jakarta.servlet.http.HttpServletResponse;
11 import lombok.AllArgsConstructor; 14 import lombok.AllArgsConstructor;
12 import lombok.Data; 15 import lombok.Data;
13 import lombok.extern.slf4j.Slf4j; 16 import lombok.extern.slf4j.Slf4j;
  17 +import org.apache.poi.ss.usermodel.*;
  18 +import org.apache.poi.ss.util.CellRangeAddressList;
  19 +import org.apache.poi.xssf.usermodel.XSSFWorkbook;
14 import org.springframework.beans.factory.annotation.Autowired; 20 import org.springframework.beans.factory.annotation.Autowired;
15 import org.springframework.beans.factory.annotation.Value; 21 import org.springframework.beans.factory.annotation.Value;
16 -import org.springframework.core.io.ClassPathResource; 22 +import org.springframework.core.io.Resource;
  23 +import org.springframework.core.io.ResourceLoader;
17 import org.springframework.util.CollectionUtils; 24 import org.springframework.util.CollectionUtils;
  25 +import org.springframework.util.StringUtils;
18 import org.springframework.web.bind.annotation.*; 26 import org.springframework.web.bind.annotation.*;
19 import org.springframework.web.multipart.MultipartFile; 27 import org.springframework.web.multipart.MultipartFile;
20 28
@@ -23,7 +31,6 @@ import java.io.InputStream; @@ -23,7 +31,6 @@ import java.io.InputStream;
23 import java.io.OutputStream; 31 import java.io.OutputStream;
24 import java.lang.reflect.Method; 32 import java.lang.reflect.Method;
25 import java.net.URLEncoder; 33 import java.net.URLEncoder;
26 -import java.nio.charset.StandardCharsets;  
27 import java.util.*; 34 import java.util.*;
28 35
29 import static com.zteits.urbanops.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST; 36 import static com.zteits.urbanops.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
@@ -49,6 +56,12 @@ public class CostFeeController{ @@ -49,6 +56,12 @@ public class CostFeeController{
49 @Value("${static.resource.server.enable}") 56 @Value("${static.resource.server.enable}")
50 private Boolean staticResourceServerenable; 57 private Boolean staticResourceServerenable;
51 58
  59 + @Autowired
  60 + private ResourceLoader resourceLoader;
  61 +
  62 + @jakarta.annotation.Resource
  63 + private DeptApi deptApi;
  64 +
52 // Excel文件校验相关 65 // Excel文件校验相关
53 private static final List<String> ALLOWED_EXCEL_SUFFIX = Arrays.asList(".xlsx", ".xlsm"); 66 private static final List<String> ALLOWED_EXCEL_SUFFIX = Arrays.asList(".xlsx", ".xlsm");
54 private static final String EXCEL_MIME_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; 67 private static final String EXCEL_MIME_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
@@ -59,6 +72,7 @@ public class CostFeeController{ @@ -59,6 +72,7 @@ public class CostFeeController{
59 */ 72 */
60 @GetMapping("/get-import-template") 73 @GetMapping("/get-import-template")
61 @Operation(summary = "获得导入用户模板") 74 @Operation(summary = "获得导入用户模板")
  75 + @PermitAll
62 public void importTemplate(HttpServletResponse response, 76 public void importTemplate(HttpServletResponse response,
63 @RequestParam("templateName") String templateName) throws IOException { 77 @RequestParam("templateName") String templateName) throws IOException {
64 // 参数校验 78 // 参数校验
@@ -74,29 +88,150 @@ public class CostFeeController{ @@ -74,29 +88,150 @@ public class CostFeeController{
74 return; 88 return;
75 } 89 }
76 90
77 - if (staticResourceServerenable) {  
78 - // 构建完整的静态服务器URL(确保路径正确)  
79 - String serverUrl = staticResourceServerUrl;  
80 - if (serverUrl != null && !serverUrl.endsWith("/")) {  
81 - serverUrl += "/"; // 确保URL以/结尾,避免拼接错误  
82 - } 91 + writeAndModifyTemplate(response, template.getName(), template.getStartIndex());
  92 + }
  93 +
  94 + private void writeAndModifyTemplate(HttpServletResponse response,
  95 + String downloadFileName,
  96 + int startIndexRow) throws IOException {
  97 +
  98 + // 拼接模板路径
  99 + String serverUrl = staticResourceServerUrl;
  100 + if (serverUrl != null && !serverUrl.endsWith("/")) {
  101 + serverUrl += "/";
  102 + }
  103 + String fullPath = serverUrl + downloadFileName;
  104 + fullPath = fullPath.replace("\\", "/");
  105 +
  106 + Resource resource = resourceLoader.getResource(fullPath);
  107 +
  108 + // 检查文件是否存在
  109 + if (!resource.exists()) {
  110 + response.sendError(HttpServletResponse.SC_NOT_FOUND, "模板文件不存在");
  111 + return;
  112 + }
  113 +
  114 + // 设置下载响应头
  115 + response.reset();
  116 + response.setContentType(EXCEL_MIME_TYPE);
  117 + // response.setCharacterEncoding("UTF-8");
  118 + String encodedName = URLEncoder.encode(downloadFileName, "UTF-8");
  119 + // 标准文件名编码(Chrome / Edge / Firefox 全兼容)
  120 + response.setHeader("Content-Disposition", "attachment;filename*=UTF-8''" + encodedName);
  121 + // 浏览器缓存配置(必须)
  122 + response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
  123 + response.setHeader("Pragma", "no-cache");
  124 + response.setHeader("Expires", "0");
  125 +
  126 +
  127 + try (InputStream in = resource.getInputStream();
  128 + XSSFWorkbook workbook = new XSSFWorkbook(in);
  129 + OutputStream out = response.getOutputStream()) {
83 130
84 - String encodedFileName = URLEncoder.encode(template.getName().split("\\.")[0], StandardCharsets.UTF_8.name()); 131 + Sheet sheet = workbook.getSheetAt(0);
85 132
86 - String templateFileName = encodedFileName + "." + template.getName().split("\\.")[1]; 133 + // ==============================================
  134 + // 获取最新单位列表
  135 + // ==============================================
  136 + List<DeptRespDTO> companyList = deptApi.getSubDeptList();
  137 + List<String> newUnits = companyList.stream()
  138 + .map(DeptRespDTO::getName)
  139 + .filter(Objects::nonNull)
  140 + .toList();
87 141
88 - String templateUrl = serverUrl + templateFileName; // 包含templates目录 142 + log.info("加载到单位列表:{},共{}条", newUnits, newUnits.size());
89 143
90 - // 方式1:重定向到静态资源服务器  
91 - response.sendRedirect(templateUrl);  
92 - } else {  
93 - String templateFileName = templateName + "." + template.getName().split("\\.")[1]; 144 + // ==============================================
  145 + // 生成新下拉 + 自动赋值
  146 + // ==============================================
  147 + createDropdownAndSetValue(sheet, newUnits, startIndexRow);
  148 +
  149 + // 写入并强制刷新
  150 + workbook.write(out);
  151 + out.flush();
94 152
95 - // 写入模板文件到响应  
96 - writeTemplateToResponse(response, template.getName(), templateFileName); 153 + } catch (Exception e) {
  154 + log.error("模板处理失败", e);
  155 + throw new IOException("文件处理失败", e);
97 } 156 }
98 } 157 }
99 158
  159 + /**
  160 + * 创建下拉框 + 给单元格赋值
  161 + */
  162 + private void createDropdownAndSetValue(Sheet sheet, List<String> options, int startRow) {
  163 + if (options.isEmpty()) {
  164 + log.error("下拉选项为空,不创建");
  165 + return;
  166 + }
  167 +
  168 + // 获取表头行
  169 + Row headerRow = sheet.getRow(startRow - 1);
  170 + if (headerRow == null) {
  171 + log.error("表头行不存在:{}", startRow - 1);
  172 + return;
  173 + }
  174 +
  175 + // 查找“所属单位”列
  176 + int targetCol = -1;
  177 + for (Cell cell : headerRow) {
  178 + if (cell != null && cell.getCellType() == CellType.STRING) {
  179 + String val = cell.getStringCellValue().trim();
  180 + if (val.contains("所属单位") || val.contains("所属公司") ) {
  181 + targetCol = cell.getColumnIndex();
  182 + break;
  183 + }
  184 + }
  185 + }
  186 +
  187 + if (targetCol == -1) {
  188 + log.error("未找到【所属单位】列表头");
  189 + return;
  190 + }
  191 +
  192 + // 取消列隐藏
  193 + sheet.setColumnHidden(targetCol, false);
  194 +
  195 + // ==============================================
  196 + // 遍历行:清空原有内容 + 设置默认值
  197 + // ==============================================
  198 + int endRow = 100;
  199 + for (int r = startRow; r <= endRow; r++) {
  200 + Row row = sheet.getRow(r);
  201 + if (row == null) {
  202 + row = sheet.createRow(r);
  203 + }
  204 +
  205 + Cell cell = row.getCell(targetCol);
  206 + if (cell == null) {
  207 + cell = row.createCell(targetCol);
  208 + }
  209 + String unit = cell.getStringCellValue();
  210 + // 默认赋值【第一个单位】,你可以根据业务改成其他值
  211 + if (!StringUtils.isEmpty(unit)) {
  212 + cell.setCellValue(options.get(0));
  213 + }
  214 + }
  215 +
  216 + // ==============================================
  217 + // 创建下拉框(作用范围:startRow ~ 1000行)
  218 + // ==============================================
  219 + CellRangeAddressList regions = new CellRangeAddressList(startRow, endRow, targetCol, targetCol);
  220 + DataValidationHelper helper = sheet.getDataValidationHelper();
  221 + DataValidationConstraint constraint = helper.createExplicitListConstraint(
  222 + options.toArray(new String[0])
  223 + );
  224 + DataValidation validation = helper.createValidation(constraint, regions);
  225 + // 下拉框基础配置
  226 + validation.setEmptyCellAllowed(true);
  227 + validation.setSuppressDropDownArrow(true); // 显示箭头
  228 + validation.setShowErrorBox(true);
  229 + validation.setShowPromptBox(true); // 启用点击弹出提示
  230 + sheet.addValidationData(validation);
  231 +
  232 + log.info("【成功】为列{}添加下拉并赋值,行{}~{},选项数:{}",
  233 + targetCol, startRow, endRow, options.size());
  234 + }
100 235
101 /** 236 /**
102 * Excel文件上传预览 237 * Excel文件上传预览
@@ -214,31 +349,6 @@ public class CostFeeController{ @@ -214,31 +349,6 @@ public class CostFeeController{
214 } 349 }
215 350
216 /** 351 /**
217 - * 写入模板文件到响应流  
218 - */  
219 - private void writeTemplateToResponse(HttpServletResponse response, String filename, String templatePath) throws IOException {  
220 - // 设置响应头  
221 - response.setContentType(EXCEL_MIME_TYPE);  
222 - response.setCharacterEncoding("UTF-8");  
223 - String encodedFileName = URLEncoder.encode(filename, "UTF-8").replaceAll("\\+", "%20");  
224 - response.setHeader("Content-Disposition", "attachment;filename=" + encodedFileName);  
225 - response.setHeader("Cache-Control", "no-store"); // 禁止缓存  
226 -  
227 - // 读取模板文件并写入响应  
228 - try (InputStream in = new ClassPathResource("template/" + templatePath).getInputStream();  
229 - OutputStream out = response.getOutputStream()) {  
230 -  
231 - byte[] buffer = new byte[4096];  
232 - int bytesRead;  
233 - while ((bytesRead = in.read(buffer)) != -1) {  
234 - out.write(buffer, 0, bytesRead);  
235 - }  
236 - out.flush();  
237 - }  
238 - }  
239 -  
240 -  
241 - /**  
242 * 校验Excel文件有效性(后缀+MIME类型) 352 * 校验Excel文件有效性(后缀+MIME类型)
243 */ 353 */
244 private boolean isValidExcelFile(MultipartFile file) { 354 private boolean isValidExcelFile(MultipartFile file) {
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/problemtype/GardenProblemTypeController.java 0 → 100644
  1 +package com.zteits.urbanops.module.garden.controller.admin.problemtype;
  2 +
  3 +import com.zteits.urbanops.module.garden.controller.admin.problemtype.vo.ProblemTypePageReqVO;
  4 +import com.zteits.urbanops.module.garden.controller.admin.problemtype.vo.ProblemTypeRespVO;
  5 +import com.zteits.urbanops.module.garden.controller.admin.problemtype.vo.ProblemTypeSaveReqVO;
  6 +import org.springframework.web.bind.annotation.*;
  7 +import jakarta.annotation.Resource;
  8 +import org.springframework.validation.annotation.Validated;
  9 +import org.springframework.security.access.prepost.PreAuthorize;
  10 +import io.swagger.v3.oas.annotations.tags.Tag;
  11 +import io.swagger.v3.oas.annotations.Parameter;
  12 +import io.swagger.v3.oas.annotations.Operation;
  13 +
  14 +import jakarta.validation.*;
  15 +import java.util.*;
  16 +
  17 +import com.zteits.urbanops.framework.common.pojo.CommonResult;
  18 +import com.zteits.urbanops.framework.common.pojo.PageResult;
  19 +import com.zteits.urbanops.framework.common.util.object.BeanUtils;
  20 +import static com.zteits.urbanops.framework.common.pojo.CommonResult.success;
  21 +
  22 +import com.zteits.urbanops.module.garden.dal.dataobject.problemtype.GardenProblemTypeDO;
  23 +import com.zteits.urbanops.module.garden.dal.mysql.problemtype.GardenProblemTypeMapper;
  24 +import com.zteits.urbanops.module.garden.service.problemtype.GardenProblemTypeService;
  25 +
  26 +@Tag(name = "管理后台 - 问题类型配置")
  27 +@RestController
  28 +@RequestMapping("/garden/problem-type")
  29 +@Validated
  30 +public class GardenProblemTypeController {
  31 +
  32 + @Resource
  33 + private GardenProblemTypeService gardenProblemTypeService;
  34 +
  35 + @Resource
  36 + private GardenProblemTypeMapper gardenProblemTypeMapper;
  37 +
  38 + @PostMapping("/create")
  39 + @Operation(summary = "创建问题类型(二级/三级)")
  40 + @PreAuthorize("@ss.hasPermission('garden:problem-type:create')")
  41 + public CommonResult<Long> createProblemType(@Valid @RequestBody ProblemTypeSaveReqVO createReqVO) {
  42 + return success(gardenProblemTypeService.createProblemType(createReqVO));
  43 + }
  44 +
  45 + @PutMapping("/update")
  46 + @Operation(summary = "更新问题类型(二级/三级)")
  47 + @PreAuthorize("@ss.hasPermission('garden:problem-type:update')")
  48 + public CommonResult<Boolean> updateProblemType(@Valid @RequestBody ProblemTypeSaveReqVO updateReqVO) {
  49 + gardenProblemTypeService.updateProblemType(updateReqVO);
  50 + return success(true);
  51 + }
  52 +
  53 + @DeleteMapping("/delete")
  54 + @Operation(summary = "删除问题类型")
  55 + @Parameter(name = "id", description = "编号", required = true)
  56 + @PreAuthorize("@ss.hasPermission('garden:problem-type:delete')")
  57 + public CommonResult<Boolean> deleteProblemType(@RequestParam("id") Long id) {
  58 + gardenProblemTypeService.deleteProblemType(id);
  59 + return success(true);
  60 + }
  61 +
  62 + @GetMapping("/get")
  63 + @Operation(summary = "获得问题类型")
  64 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  65 + @PreAuthorize("@ss.hasPermission('garden:problem-type:query')")
  66 + public CommonResult<ProblemTypeRespVO> getProblemType(@RequestParam("id") Long id) {
  67 + GardenProblemTypeDO problemType = gardenProblemTypeService.getProblemType(id);
  68 + ProblemTypeRespVO respVO = BeanUtils.toBean(problemType, ProblemTypeRespVO.class);
  69 + fillParentNames(Arrays.asList(respVO));
  70 + return success(respVO);
  71 + }
  72 +
  73 + @GetMapping("/page")
  74 + @Operation(summary = "获得问题类型分页")
  75 + @PreAuthorize("@ss.hasPermission('garden:problem-type:query')")
  76 + public CommonResult<PageResult<ProblemTypeRespVO>> getProblemTypePage(@Valid ProblemTypePageReqVO pageReqVO) {
  77 + PageResult<GardenProblemTypeDO> pageResult = gardenProblemTypeService.getProblemTypePage(pageReqVO);
  78 + PageResult<ProblemTypeRespVO> voPageResult = BeanUtils.toBean(pageResult, ProblemTypeRespVO.class);
  79 + fillParentNames(voPageResult.getList());
  80 + return success(voPageResult);
  81 + }
  82 +
  83 + @GetMapping("/list-by-parent")
  84 + @Operation(summary = "根据父级编码和层级查询子类型列表(级联下拉用)")
  85 + @PreAuthorize("@ss.hasPermission('garden:problem-type:query')")
  86 + public CommonResult<List<ProblemTypeRespVO>> getProblemTypeListByParent(
  87 + @RequestParam(value = "parentCode", required = false) String parentCode,
  88 + @RequestParam("level") Integer level) {
  89 + List<GardenProblemTypeDO> list = gardenProblemTypeService.getProblemTypeByParentCode(parentCode, level);
  90 + return success(BeanUtils.toBean(list, ProblemTypeRespVO.class));
  91 + }
  92 +
  93 + @GetMapping("/generate-next-code")
  94 + @Operation(summary = "根据父级编码生成下一个类型编码")
  95 + @PreAuthorize("@ss.hasPermission('garden:problem-type:create')")
  96 + public CommonResult<String> generateNextCode(@RequestParam("parentCode") String parentCode) {
  97 + return success(gardenProblemTypeService.generateNextCode(parentCode));
  98 + }
  99 +
  100 + @PostMapping("/sync-level-one")
  101 + @Operation(summary = "从字典表同步一级类型")
  102 + @PreAuthorize("@ss.hasPermission('garden:problem-type:create')")
  103 + public CommonResult<Integer> syncLevelOne() {
  104 + return success(gardenProblemTypeService.syncLevelOneFromDict());
  105 + }
  106 +
  107 + /**
  108 + * 填充每个记录的层级名称:
  109 + * level 1 → levelOneName = 自身 typeName
  110 + * level 2 → levelTwoName = 自身 typeName, levelOneName = 父级 typeName
  111 + * level 3 → levelOneName = 祖父 typeName, levelTwoName = 父级 typeName
  112 + */
  113 + private void fillParentNames(List<ProblemTypeRespVO> list) {
  114 + if (list == null || list.isEmpty()) {
  115 + return;
  116 + }
  117 + for (ProblemTypeRespVO vo : list) {
  118 + if (vo.getLevel() == null) continue;
  119 + if (vo.getLevel() == 1) {
  120 + vo.setLevelOneName(vo.getTypeName());
  121 + } else if (vo.getLevel() == 2) {
  122 + vo.setLevelTwoName(vo.getTypeName());
  123 + if (vo.getParentCode() != null) {
  124 + GardenProblemTypeDO parent = gardenProblemTypeMapper.selectByTypeCode(vo.getParentCode());
  125 + if (parent != null) {
  126 + vo.setLevelOneName(parent.getTypeName());
  127 + }
  128 + }
  129 + } else if (vo.getLevel() == 3) {
  130 + if (vo.getParentCode() != null) {
  131 + GardenProblemTypeDO parent = gardenProblemTypeMapper.selectByTypeCode(vo.getParentCode());
  132 + if (parent != null) {
  133 + vo.setLevelTwoName(parent.getTypeName());
  134 + if (parent.getParentCode() != null) {
  135 + GardenProblemTypeDO grandParent = gardenProblemTypeMapper
  136 + .selectByTypeCode(parent.getParentCode());
  137 + if (grandParent != null) {
  138 + vo.setLevelOneName(grandParent.getTypeName());
  139 + }
  140 + }
  141 + }
  142 + }
  143 + }
  144 + }
  145 + }
  146 +
  147 +}
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/problemtype/vo/ProblemTypePageReqVO.java 0 → 100644
  1 +package com.zteits.urbanops.module.garden.controller.admin.problemtype.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import com.zteits.urbanops.framework.common.pojo.PageParam;
  6 +
  7 +@Schema(description = "管理后台 - 问题类型分页 Request VO")
  8 +@Data
  9 +public class ProblemTypePageReqVO extends PageParam {
  10 +
  11 + @Schema(description = "问题类型编码", example = "PT001")
  12 + private String typeCode;
  13 +
  14 + @Schema(description = "问题类型名称", example = "树木倒伏")
  15 + private String typeName;
  16 +
  17 + @Schema(description = "层级:1一级 2二级 3三级", example = "2")
  18 + private Integer level;
  19 +
  20 + @Schema(description = "父级类型编码", example = "BIZ_GARDEN")
  21 + private String parentCode;
  22 +
  23 + @Schema(description = "一级类型编码(级联筛选)", example = "yl")
  24 + private String levelOneCode;
  25 +
  26 + @Schema(description = "状态 1启用 0禁用", example = "1")
  27 + private Integer status;
  28 +
  29 +}
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/problemtype/vo/ProblemTypeRespVO.java 0 → 100644
  1 +package com.zteits.urbanops.module.garden.controller.admin.problemtype.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import cn.idev.excel.annotation.*;
  6 +
  7 +@Schema(description = "管理后台 - 问题类型 Response VO")
  8 +@Data
  9 +@ExcelIgnoreUnannotated
  10 +public class ProblemTypeRespVO {
  11 +
  12 + @Schema(description = "主键ID", example = "1")
  13 + @ExcelProperty("主键ID")
  14 + private Long id;
  15 +
  16 + @Schema(description = "问题类型编码", example = "PT001")
  17 + @ExcelProperty("问题类型编码")
  18 + private String typeCode;
  19 +
  20 + @Schema(description = "问题类型名称", example = "树木倒伏")
  21 + @ExcelProperty("问题类型名称")
  22 + private String typeName;
  23 +
  24 + @Schema(description = "层级:1一级 2二级 3三级", example = "2")
  25 + @ExcelProperty("层级")
  26 + private Integer level;
  27 +
  28 + @Schema(description = "父级类型编码", example = "BIZ_GARDEN")
  29 + @ExcelProperty("父级类型编码")
  30 + private String parentCode;
  31 +
  32 + @Schema(description = "排序序号", example = "1")
  33 + @ExcelProperty("排序序号")
  34 + private Integer sort;
  35 +
  36 + @Schema(description = "状态 1启用 0禁用", example = "1")
  37 + @ExcelProperty("状态")
  38 + private Integer status;
  39 +
  40 + @Schema(description = "一级类型名称")
  41 + private String levelOneName;
  42 +
  43 + @Schema(description = "二级类型名称")
  44 + private String levelTwoName;
  45 +
  46 + @Schema(description = "创建者")
  47 + @ExcelProperty("创建者")
  48 + private String creator;
  49 +
  50 + @Schema(description = "创建时间")
  51 + @ExcelProperty("创建时间")
  52 + private String createTime;
  53 +
  54 +}
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/problemtype/vo/ProblemTypeSaveReqVO.java 0 → 100644
  1 +package com.zteits.urbanops.module.garden.controller.admin.problemtype.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import jakarta.validation.constraints.*;
  6 +
  7 +@Schema(description = "管理后台 - 问题类型新增/修改 Request VO")
  8 +@Data
  9 +public class ProblemTypeSaveReqVO {
  10 +
  11 + @Schema(description = "主键ID", example = "1")
  12 + private Long id;
  13 +
  14 + @Schema(description = "问题类型编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "PT001")
  15 + @NotEmpty(message = "问题类型编码不能为空")
  16 + private String typeCode;
  17 +
  18 + @Schema(description = "问题类型名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "树木倒伏")
  19 + @NotEmpty(message = "问题类型名称不能为空")
  20 + private String typeName;
  21 +
  22 + @Schema(description = "层级:1一级 2二级 3三级", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  23 + @NotNull(message = "层级不能为空")
  24 + private Integer level;
  25 +
  26 + @Schema(description = "父级类型编码", example = "BIZ_GARDEN")
  27 + private String parentCode;
  28 +
  29 + @Schema(description = "排序序号", example = "1")
  30 + private Integer sort;
  31 +
  32 + @Schema(description = "状态 1启用 0禁用", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  33 + @NotNull(message = "状态不能为空")
  34 + private Integer status;
  35 +
  36 +}
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/convert/AppGardenWorkOrderConvert.java
@@ -24,7 +24,7 @@ public interface AppGardenWorkOrderConvert { @@ -24,7 +24,7 @@ public interface AppGardenWorkOrderConvert {
24 orderReqVO.setPressingType(2);//紧急 24 orderReqVO.setPressingType(2);//紧急
25 orderReqVO.setOrderName(inspectionPlanDO.getPlanName()); 25 orderReqVO.setOrderName(inspectionPlanDO.getPlanName());
26 orderReqVO.setSourceId(1);//来源ID 工单来源 1、巡查 26 orderReqVO.setSourceId(1);//来源ID 工单来源 1、巡查
27 - orderReqVO.setSourceName("园林巡查上报"); 27 + orderReqVO.setSourceName("巡查上报");
28 orderReqVO.setThirdWorkNo(planNo); 28 orderReqVO.setThirdWorkNo(planNo);
29 orderReqVO.setOrderType("C"); 29 orderReqVO.setOrderType("C");
30 orderReqVO.setPressingType(createReqVO.getPressingType()); 30 orderReqVO.setPressingType(createReqVO.getPressingType());
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/dal/dataobject/problemtype/GardenProblemTypeDO.java 0 → 100644
  1 +package com.zteits.urbanops.module.garden.dal.dataobject.problemtype;
  2 +
  3 +import lombok.*;
  4 +import com.baomidou.mybatisplus.annotation.*;
  5 +import com.zteits.urbanops.framework.mybatis.core.dataobject.BaseDO;
  6 +
  7 +/**
  8 + * 问题类型三级分类 DO
  9 + *
  10 + * @author 超级管理员
  11 + */
  12 +@TableName("garden_problem_type")
  13 +@KeySequence("garden_problem_type_seq")
  14 +@Data
  15 +@EqualsAndHashCode(callSuper = true)
  16 +@ToString(callSuper = true)
  17 +@Builder
  18 +@NoArgsConstructor
  19 +@AllArgsConstructor
  20 +public class GardenProblemTypeDO extends BaseDO {
  21 +
  22 + /**
  23 + * 主键ID
  24 + */
  25 + @TableId
  26 + private Long id;
  27 + /**
  28 + * 问题类型编码
  29 + */
  30 + private String typeCode;
  31 + /**
  32 + * 问题类型名称
  33 + */
  34 + private String typeName;
  35 + /**
  36 + * 层级:1一级 2二级 3三级
  37 + */
  38 + private Integer level;
  39 + /**
  40 + * 父级类型编码
  41 + */
  42 + private String parentCode;
  43 + /**
  44 + * 排序序号
  45 + */
  46 + private Integer sort;
  47 + /**
  48 + * 状态 1启用 0禁用
  49 + */
  50 + private Integer status;
  51 +
  52 +}
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/dal/mysql/problemtype/GardenProblemTypeMapper.java 0 → 100644
  1 +package com.zteits.urbanops.module.garden.dal.mysql.problemtype;
  2 +
  3 +import com.zteits.urbanops.framework.common.pojo.PageResult;
  4 +import com.zteits.urbanops.framework.mybatis.core.query.LambdaQueryWrapperX;
  5 +import com.zteits.urbanops.framework.mybatis.core.mapper.BaseMapperX;
  6 +import com.zteits.urbanops.module.garden.controller.admin.problemtype.vo.ProblemTypePageReqVO;
  7 +import com.zteits.urbanops.module.garden.dal.dataobject.problemtype.GardenProblemTypeDO;
  8 +import org.apache.ibatis.annotations.Mapper;
  9 +
  10 +import java.util.ArrayList;
  11 +import java.util.List;
  12 +import java.util.stream.Collectors;
  13 +
  14 +/**
  15 + * 问题类型 Mapper
  16 + *
  17 + * @author 超级管理员
  18 + */
  19 +@Mapper
  20 +public interface GardenProblemTypeMapper extends BaseMapperX<GardenProblemTypeDO> {
  21 +
  22 + default PageResult<GardenProblemTypeDO> selectPage(ProblemTypePageReqVO reqVO) {
  23 + LambdaQueryWrapperX<GardenProblemTypeDO> wrapper = new LambdaQueryWrapperX<GardenProblemTypeDO>()
  24 + .eqIfPresent(GardenProblemTypeDO::getLevel, reqVO.getLevel())
  25 + .eqIfPresent(GardenProblemTypeDO::getStatus, reqVO.getStatus())
  26 + .likeIfPresent(GardenProblemTypeDO::getTypeName, reqVO.getTypeName())
  27 + .likeIfPresent(GardenProblemTypeDO::getTypeCode, reqVO.getTypeCode());
  28 + wrapper.orderByAsc(GardenProblemTypeDO::getSort);
  29 + wrapper.orderByAsc(GardenProblemTypeDO::getId);
  30 +
  31 + // 级联筛选:如果传了 levelOneCode,查出所有二级编码做 IN 查询
  32 + if (reqVO.getLevelOneCode() != null && !reqVO.getLevelOneCode().isEmpty()) {
  33 + List<GardenProblemTypeDO> levelTwoList = selectByParentCodeAndLevel(reqVO.getLevelOneCode(), 2);
  34 + List<String> parentCodes = new ArrayList<>();
  35 + parentCodes.add(reqVO.getLevelOneCode()); // 包含一级自身
  36 + parentCodes.addAll(levelTwoList.stream().map(GardenProblemTypeDO::getTypeCode).collect(Collectors.toList()));
  37 + wrapper.in(GardenProblemTypeDO::getParentCode, parentCodes);
  38 + } else {
  39 + wrapper.eqIfPresent(GardenProblemTypeDO::getParentCode, reqVO.getParentCode());
  40 + }
  41 +
  42 + return selectPage(reqVO, wrapper);
  43 + }
  44 +
  45 + /**
  46 + * 根据 parentCode 和 level 查询子类型列表
  47 + */
  48 + default List<GardenProblemTypeDO> selectByParentCodeAndLevel(String parentCode, Integer level) {
  49 + return selectList(new LambdaQueryWrapperX<GardenProblemTypeDO>()
  50 + .eqIfPresent(GardenProblemTypeDO::getParentCode, parentCode)
  51 + .eqIfPresent(GardenProblemTypeDO::getLevel, level)
  52 + .eq(GardenProblemTypeDO::getStatus, 1)
  53 + .orderByAsc(GardenProblemTypeDO::getSort)
  54 + .orderByAsc(GardenProblemTypeDO::getId));
  55 + }
  56 +
  57 + /**
  58 + * 根据 typeCode 查询唯一记录
  59 + */
  60 + default GardenProblemTypeDO selectByTypeCode(String typeCode) {
  61 + return selectOne(new LambdaQueryWrapperX<GardenProblemTypeDO>()
  62 + .eq(GardenProblemTypeDO::getTypeCode, typeCode));
  63 + }
  64 +
  65 + /**
  66 + * 生成下一个编码:父级编码 + 5位递增序号
  67 + * 如 parentCode=BIZ_GARDEN → BIZ_GARDEN00001, BIZ_GARDEN00002
  68 + */
  69 + default String generateNextCode(String parentCode) {
  70 + List<GardenProblemTypeDO> list = selectList(new LambdaQueryWrapperX<GardenProblemTypeDO>()
  71 + .likeRight(GardenProblemTypeDO::getTypeCode, parentCode)
  72 + .orderByDesc(GardenProblemTypeDO::getTypeCode)
  73 + .last("LIMIT 1"));
  74 + if (list == null || list.isEmpty()) {
  75 + return parentCode + "00001";
  76 + }
  77 + String maxCode = list.get(0).getTypeCode();
  78 + String seqStr = maxCode.substring(parentCode.length());
  79 + try {
  80 + int seq = Integer.parseInt(seqStr) + 1;
  81 + return parentCode + String.format("%05d", seq);
  82 + } catch (NumberFormatException e) {
  83 + return parentCode + "00001";
  84 + }
  85 + }
  86 +
  87 +}
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/enums/ErrorCodeConstants.java
@@ -87,9 +87,11 @@ public interface ErrorCodeConstants { @@ -87,9 +87,11 @@ public interface ErrorCodeConstants {
87 ErrorCode INSPECTION_CYCLE_ERROR = new ErrorCode(1-200-100-003, "获取两个时间之间间隔天数错误"); 87 ErrorCode INSPECTION_CYCLE_ERROR = new ErrorCode(1-200-100-003, "获取两个时间之间间隔天数错误");
88 ErrorCode INSPECTION_PLAN_EXISTS = new ErrorCode(1-200-100-007, "道路对应类型已存在记录"); 88 ErrorCode INSPECTION_PLAN_EXISTS = new ErrorCode(1-200-100-007, "道路对应类型已存在记录");
89 ErrorCode INSPECTION_PLAN_NOT_ALLOW_DELETE = new ErrorCode(1-100-007-005, "计划已开始执行不能删除"); 89 ErrorCode INSPECTION_PLAN_NOT_ALLOW_DELETE = new ErrorCode(1-100-007-005, "计划已开始执行不能删除");
  90 + ErrorCode INSPECTION_COMMIT_PLAN__EXISTS = new ErrorCode(1-100-007-005, "巡检计划明细已提交");
90 91
91 // ========== 养护计划汇总 TODO 补充编号 ========== 92 // ========== 养护计划汇总 TODO 补充编号 ==========
92 ErrorCode MAINTAIN_PLAN_NOT_EXISTS = new ErrorCode(1-100-007-001, "养护计划汇总不存在"); 93 ErrorCode MAINTAIN_PLAN_NOT_EXISTS = new ErrorCode(1-100-007-001, "养护计划汇总不存在");
  94 + ErrorCode MAINTAIN_COMMIT_PLAN__EXISTS = new ErrorCode(1-100-007-007, "养护计划明细已提交");
93 95
94 //========== 频次 TODO 补充编号 ========== 96 //========== 频次 TODO 补充编号 ==========
95 ErrorCode PLAN_RATE_EXISTS = new ErrorCode(1-100-007-001, "养护频次已存在"); 97 ErrorCode PLAN_RATE_EXISTS = new ErrorCode(1-100-007-001, "养护频次已存在");
@@ -145,4 +147,8 @@ public interface ErrorCodeConstants { @@ -145,4 +147,8 @@ public interface ErrorCodeConstants {
145 147
146 ErrorCode EMERGENCY_TASK_NOT_EXISTS = new ErrorCode(1-100-006-002, "抢险任务主不存在"); 148 ErrorCode EMERGENCY_TASK_NOT_EXISTS = new ErrorCode(1-100-006-002, "抢险任务主不存在");
147 149
  150 + // ========== 问题类型配置 1-100-009-000 ==========
  151 + ErrorCode PROBLEM_TYPE_NOT_EXISTS = new ErrorCode(1100009000, "问题类型不存在");
  152 + ErrorCode PROBLEM_TYPE_CODE_EXISTS = new ErrorCode(1100009001, "问题类型编码已存在");
  153 +
148 } 154 }
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/inspectionplan/InspectionPlanCommitServiceImpl.java
@@ -18,6 +18,7 @@ import com.zteits.urbanops.module.garden.convert.AppGardenWorkOrderConvert; @@ -18,6 +18,7 @@ import com.zteits.urbanops.module.garden.convert.AppGardenWorkOrderConvert;
18 import com.zteits.urbanops.module.garden.dal.dataobject.inspectionplan.InspectionPlanCommitDO; 18 import com.zteits.urbanops.module.garden.dal.dataobject.inspectionplan.InspectionPlanCommitDO;
19 import com.zteits.urbanops.module.garden.dal.dataobject.inspectionplan.InspectionPlanDO; 19 import com.zteits.urbanops.module.garden.dal.dataobject.inspectionplan.InspectionPlanDO;
20 import com.zteits.urbanops.module.garden.dal.dataobject.inspectionplan.InspectionPlanDetailDO; 20 import com.zteits.urbanops.module.garden.dal.dataobject.inspectionplan.InspectionPlanDetailDO;
  21 +import com.zteits.urbanops.module.garden.dal.dataobject.maintainplan.MaintainPlanCommitDO;
21 import com.zteits.urbanops.module.garden.dal.dataobject.road.RoadDO; 22 import com.zteits.urbanops.module.garden.dal.dataobject.road.RoadDO;
22 import com.zteits.urbanops.module.garden.dal.mysql.inspectionplan.InspectionPlanCommitMapper; 23 import com.zteits.urbanops.module.garden.dal.mysql.inspectionplan.InspectionPlanCommitMapper;
23 import com.zteits.urbanops.module.garden.dal.mysql.inspectionplan.InspectionPlanDetailMapper; 24 import com.zteits.urbanops.module.garden.dal.mysql.inspectionplan.InspectionPlanDetailMapper;
@@ -43,7 +44,7 @@ import java.util.*; @@ -43,7 +44,7 @@ import java.util.*;
43 import java.util.stream.Collectors; 44 import java.util.stream.Collectors;
44 45
45 import static com.zteits.urbanops.framework.common.exception.util.ServiceExceptionUtil.exception; 46 import static com.zteits.urbanops.framework.common.exception.util.ServiceExceptionUtil.exception;
46 -import static com.zteits.urbanops.module.garden.enums.ErrorCodeConstants.INSPECTION_PLAN_NOT_EXISTS; 47 +import static com.zteits.urbanops.module.garden.enums.ErrorCodeConstants.*;
47 48
48 49
49 /** 50 /**
@@ -76,6 +77,10 @@ public class InspectionPlanCommitServiceImpl implements InspectionPlanCommitServ @@ -76,6 +77,10 @@ public class InspectionPlanCommitServiceImpl implements InspectionPlanCommitServ
76 77
77 @Override 78 @Override
78 public Long createInspectionPlanCommit(InspectionPlanCommitSaveReqVO createReqVO) { 79 public Long createInspectionPlanCommit(InspectionPlanCommitSaveReqVO createReqVO) {
  80 + List<InspectionPlanCommitDO> list = inspectionPlanCommitMapper.selectList(InspectionPlanCommitDO::getPlanNo, createReqVO.getPlanNo());
  81 + if(!CollectionUtils.isEmpty(list)){
  82 + throw exception(INSPECTION_COMMIT_PLAN__EXISTS);
  83 + }
79 // 插入 84 // 插入
80 InspectionPlanCommitDO inspectionPlanCommit = BeanUtils.toBean(createReqVO, InspectionPlanCommitDO.class); 85 InspectionPlanCommitDO inspectionPlanCommit = BeanUtils.toBean(createReqVO, InspectionPlanCommitDO.class);
81 inspectionPlanCommitMapper.insert(inspectionPlanCommit); 86 inspectionPlanCommitMapper.insert(inspectionPlanCommit);
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/maintainplan/MaintainPlanCommitServiceImpl.java
@@ -63,6 +63,10 @@ public class MaintainPlanCommitServiceImpl implements MaintainPlanCommitService @@ -63,6 +63,10 @@ public class MaintainPlanCommitServiceImpl implements MaintainPlanCommitService
63 63
64 @Override 64 @Override
65 public Long createMaintainPlanCommit(MaintainPlanCommitSaveReqVO createReqVO) { 65 public Long createMaintainPlanCommit(MaintainPlanCommitSaveReqVO createReqVO) {
  66 + List<MaintainPlanCommitDO> list = maintainPlanCommitMapper.selectList(MaintainPlanCommitDO::getPlanNo, createReqVO.getPlanNo());
  67 + if(!CollectionUtils.isEmpty(list)){
  68 + throw exception(MAINTAIN_PLAN_NOT_EXISTS);
  69 + }
66 // 插入 70 // 插入
67 MaintainPlanCommitDO maintainPlanCommit = BeanUtils.toBean(createReqVO, MaintainPlanCommitDO.class); 71 MaintainPlanCommitDO maintainPlanCommit = BeanUtils.toBean(createReqVO, MaintainPlanCommitDO.class);
68 maintainPlanCommitMapper.insert(maintainPlanCommit); 72 maintainPlanCommitMapper.insert(maintainPlanCommit);
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/problemtype/GardenProblemTypeService.java 0 → 100644
  1 +package com.zteits.urbanops.module.garden.service.problemtype;
  2 +
  3 +import com.zteits.urbanops.module.garden.controller.admin.problemtype.vo.ProblemTypePageReqVO;
  4 +import com.zteits.urbanops.module.garden.controller.admin.problemtype.vo.ProblemTypeSaveReqVO;
  5 +import com.zteits.urbanops.module.garden.dal.dataobject.problemtype.GardenProblemTypeDO;
  6 +import com.zteits.urbanops.framework.common.pojo.PageResult;
  7 +import jakarta.validation.Valid;
  8 +
  9 +import java.util.List;
  10 +
  11 +/**
  12 + * 问题类型配置 Service 接口
  13 + *
  14 + * @author 超级管理员
  15 + */
  16 +public interface GardenProblemTypeService {
  17 +
  18 + /**
  19 + * 创建问题类型
  20 + *
  21 + * @param createReqVO 创建信息
  22 + * @return 编号
  23 + */
  24 + Long createProblemType(@Valid ProblemTypeSaveReqVO createReqVO);
  25 +
  26 + /**
  27 + * 更新问题类型
  28 + *
  29 + * @param updateReqVO 更新信息
  30 + */
  31 + void updateProblemType(@Valid ProblemTypeSaveReqVO updateReqVO);
  32 +
  33 + /**
  34 + * 删除问题类型
  35 + *
  36 + * @param id 编号
  37 + */
  38 + void deleteProblemType(Long id);
  39 +
  40 + /**
  41 + * 获得问题类型
  42 + *
  43 + * @param id 编号
  44 + * @return 问题类型
  45 + */
  46 + GardenProblemTypeDO getProblemType(Long id);
  47 +
  48 + /**
  49 + * 获得问题类型分页
  50 + *
  51 + * @param pageReqVO 分页查询
  52 + * @return 问题类型分页
  53 + */
  54 + PageResult<GardenProblemTypeDO> getProblemTypePage(ProblemTypePageReqVO pageReqVO);
  55 +
  56 + /**
  57 + * 根据父级编码和层级查询子类型列表
  58 + *
  59 + * @param parentCode 父级编码
  60 + * @param level 层级
  61 + * @return 子类型列表
  62 + */
  63 + List<GardenProblemTypeDO> getProblemTypeByParentCode(String parentCode, Integer level);
  64 +
  65 + /**
  66 + * 根据父级编码生成下一个类型编码
  67 + *
  68 + * @param parentCode 父级编码
  69 + * @return 新编码
  70 + */
  71 + String generateNextCode(String parentCode);
  72 +
  73 + /**
  74 + * 从字典表同步一级类型到 garden_problem_type
  75 + *
  76 + * @return 同步数量
  77 + */
  78 + int syncLevelOneFromDict();
  79 +
  80 +}
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/problemtype/GardenProblemTypeServiceImpl.java 0 → 100644
  1 +package com.zteits.urbanops.module.garden.service.problemtype;
  2 +
  3 +import com.zteits.urbanops.framework.common.enums.CommonStatusEnum;
  4 +import com.zteits.urbanops.module.garden.controller.admin.problemtype.vo.ProblemTypePageReqVO;
  5 +import com.zteits.urbanops.module.garden.controller.admin.problemtype.vo.ProblemTypeSaveReqVO;
  6 +import com.zteits.urbanops.module.system.dal.dataobject.dict.DictDataDO;
  7 +import com.zteits.urbanops.module.system.service.dict.DictDataService;
  8 +import org.springframework.stereotype.Service;
  9 +import org.springframework.validation.annotation.Validated;
  10 +import jakarta.annotation.Resource;
  11 +
  12 +import java.util.List;
  13 +
  14 +import com.zteits.urbanops.module.garden.dal.dataobject.problemtype.GardenProblemTypeDO;
  15 +import com.zteits.urbanops.framework.common.pojo.PageResult;
  16 +import com.zteits.urbanops.framework.common.util.object.BeanUtils;
  17 +
  18 +import com.zteits.urbanops.module.garden.dal.mysql.problemtype.GardenProblemTypeMapper;
  19 +
  20 +import static com.zteits.urbanops.framework.common.exception.util.ServiceExceptionUtil.exception;
  21 +import static com.zteits.urbanops.module.garden.enums.ErrorCodeConstants.*;
  22 +
  23 +/**
  24 + * 问题类型配置 Service 实现类
  25 + *
  26 + * @author 超级管理员
  27 + */
  28 +@Service
  29 +@Validated
  30 +public class GardenProblemTypeServiceImpl implements GardenProblemTypeService {
  31 +
  32 + @Resource
  33 + private GardenProblemTypeMapper gardenProblemTypeMapper;
  34 +
  35 + @Resource
  36 + private DictDataService dictDataService;
  37 +
  38 + @Override
  39 + public Long createProblemType(ProblemTypeSaveReqVO createReqVO) {
  40 + // 校验编码唯一性
  41 + validateTypeCodeUnique(createReqVO.getTypeCode(), null);
  42 + // 插入
  43 + GardenProblemTypeDO problemType = BeanUtils.toBean(createReqVO, GardenProblemTypeDO.class);
  44 + gardenProblemTypeMapper.insert(problemType);
  45 + return problemType.getId();
  46 + }
  47 +
  48 + @Override
  49 + public void updateProblemType(ProblemTypeSaveReqVO updateReqVO) {
  50 + // 校验存在
  51 + validateProblemTypeExists(updateReqVO.getId());
  52 + // 校验编码唯一性(排除自身)
  53 + validateTypeCodeUnique(updateReqVO.getTypeCode(), updateReqVO.getId());
  54 + // 更新
  55 + GardenProblemTypeDO updateObj = BeanUtils.toBean(updateReqVO, GardenProblemTypeDO.class);
  56 + gardenProblemTypeMapper.updateById(updateObj);
  57 + }
  58 +
  59 + @Override
  60 + public void deleteProblemType(Long id) {
  61 + // 校验存在
  62 + validateProblemTypeExists(id);
  63 + // 删除
  64 + gardenProblemTypeMapper.deleteById(id);
  65 + }
  66 +
  67 + private void validateProblemTypeExists(Long id) {
  68 + if (gardenProblemTypeMapper.selectById(id) == null) {
  69 + throw exception(PROBLEM_TYPE_NOT_EXISTS);
  70 + }
  71 + }
  72 +
  73 + private void validateTypeCodeUnique(String typeCode, Long excludeId) {
  74 + GardenProblemTypeDO exist = gardenProblemTypeMapper.selectByTypeCode(typeCode);
  75 + if (exist != null && (excludeId == null || !exist.getId().equals(excludeId))) {
  76 + throw exception(PROBLEM_TYPE_CODE_EXISTS);
  77 + }
  78 + }
  79 +
  80 + @Override
  81 + public GardenProblemTypeDO getProblemType(Long id) {
  82 + return gardenProblemTypeMapper.selectById(id);
  83 + }
  84 +
  85 + @Override
  86 + public PageResult<GardenProblemTypeDO> getProblemTypePage(ProblemTypePageReqVO pageReqVO) {
  87 + return gardenProblemTypeMapper.selectPage(pageReqVO);
  88 + }
  89 +
  90 + @Override
  91 + public List<GardenProblemTypeDO> getProblemTypeByParentCode(String parentCode, Integer level) {
  92 + return gardenProblemTypeMapper.selectByParentCodeAndLevel(parentCode, level);
  93 + }
  94 +
  95 + @Override
  96 + public String generateNextCode(String parentCode) {
  97 + return gardenProblemTypeMapper.generateNextCode(parentCode);
  98 + }
  99 +
  100 + @Override
  101 + public int syncLevelOneFromDict() {
  102 + List<DictDataDO> dictList = dictDataService.getDictDataList(
  103 + CommonStatusEnum.ENABLE.getStatus(), "business_line");
  104 + int count = 0;
  105 + for (DictDataDO dict : dictList) {
  106 + GardenProblemTypeDO exist = gardenProblemTypeMapper.selectByTypeCode(dict.getValue());
  107 + if (exist == null) {
  108 + GardenProblemTypeDO entity = new GardenProblemTypeDO();
  109 + entity.setTypeCode(dict.getValue());
  110 + entity.setTypeName(dict.getLabel());
  111 + entity.setLevel(1);
  112 + entity.setParentCode(null);
  113 + entity.setSort(dict.getSort());
  114 + entity.setStatus(CommonStatusEnum.ENABLE.getStatus());
  115 + gardenProblemTypeMapper.insert(entity);
  116 + count++;
  117 + }
  118 + }
  119 + return count;
  120 + }
  121 +
  122 +}
urbanops-module-garden/src/main/resources/mapper/inspectionplan/InspectionPlanCommitMapper.xml
@@ -102,7 +102,7 @@ @@ -102,7 +102,7 @@
102 </foreach> 102 </foreach>
103 </if> 103 </if>
104 104
105 - order by a.id desc 105 + order by a.create_time desc
106 </select> 106 </select>
107 107
108 <select id="appInspectionPlanCommitListByPlanNo" resultType="com.zteits.urbanops.module.garden.controller.app.inspectionplan.vo.AppInspectionPlanCommitRespVO"> 108 <select id="appInspectionPlanCommitListByPlanNo" resultType="com.zteits.urbanops.module.garden.controller.app.inspectionplan.vo.AppInspectionPlanCommitRespVO">
urbanops-module-garden/src/main/resources/mapper/maintainplan/MaintainPlanCommitMapper.xml
@@ -94,7 +94,7 @@ @@ -94,7 +94,7 @@
94 #{deptId} 94 #{deptId}
95 </foreach> 95 </foreach>
96 </if> 96 </if>
97 - order by c.id desc 97 + order by c.create_time desc
98 </select> 98 </select>
99 99
100 <select id="appMaintainPlanCommitDetailPage" resultMap="BaseResultMap"> 100 <select id="appMaintainPlanCommitDetailPage" resultMap="BaseResultMap">
urbanops-module-system/src/main/java/com/zteits/urbanops/module/system/controller/admin/dept/DeptController.java
@@ -19,12 +19,11 @@ import org.springframework.web.bind.annotation.*; @@ -19,12 +19,11 @@ import org.springframework.web.bind.annotation.*;
19 import jakarta.annotation.Resource; 19 import jakarta.annotation.Resource;
20 import jakarta.validation.Valid; 20 import jakarta.validation.Valid;
21 21
22 -import java.util.HashMap;  
23 -import java.util.Map;  
24 -import java.util.List; 22 +import java.util.*;
25 import java.util.stream.Collectors; 23 import java.util.stream.Collectors;
26 24
27 import static com.zteits.urbanops.framework.common.pojo.CommonResult.success; 25 import static com.zteits.urbanops.framework.common.pojo.CommonResult.success;
  26 +import static com.zteits.urbanops.framework.common.util.collection.CollectionUtils.convertSet;
28 27
29 @Tag(name = "管理后台 - 部门") 28 @Tag(name = "管理后台 - 部门")
30 @RestController 29 @RestController
@@ -129,8 +128,13 @@ public class DeptController { @@ -129,8 +128,13 @@ public class DeptController {
129 @Operation(summary = "查询所有组织") 128 @Operation(summary = "查询所有组织")
130 @GetMapping("/queryAllDeptList") 129 @GetMapping("/queryAllDeptList")
131 @PermitAll 130 @PermitAll
132 - public Map<String, Object> queryAllDeptList() {  
133 - List<DeptDO> sysDepts = deptService.getSubDeptAllList(); 131 + public Map<String, Object> queryAllDeptList( @RequestParam(required = false) Long deptId) {
  132 + List<DeptDO> sysDepts = new ArrayList<>();
  133 + if(deptId != null){
  134 + sysDepts = deptService.getChildDeptList(deptId);
  135 + }else {
  136 + sysDepts = deptService.getDeptAllList();
  137 + }
134 List<Map<String, Object>> deptResps = sysDepts.stream().map(sysDept -> { 138 List<Map<String, Object>> deptResps = sysDepts.stream().map(sysDept -> {
135 Map<String, Object> deptMap = new HashMap<>(); 139 Map<String, Object> deptMap = new HashMap<>();
136 deptMap.put("deptCode", sysDept.getId() + ""); 140 deptMap.put("deptCode", sysDept.getId() + "");
@@ -140,7 +144,7 @@ public class DeptController { @@ -140,7 +144,7 @@ public class DeptController {
140 deptMap.put("orderNum", sysDept.getSort()); 144 deptMap.put("orderNum", sysDept.getSort());
141 return deptMap; 145 return deptMap;
142 }).collect(Collectors.toList()); 146 }).collect(Collectors.toList());
143 - 147 +
144 // 构建返回格式 148 // 构建返回格式
145 Map<String, Object> result = new HashMap<>(); 149 Map<String, Object> result = new HashMap<>();
146 result.put("msg", "操作成功"); 150 result.put("msg", "操作成功");
urbanops-module-system/src/main/java/com/zteits/urbanops/module/system/controller/app/appmodule/AppAppModuleController.java
@@ -7,9 +7,11 @@ import com.zteits.urbanops.module.system.controller.app.appmodule.vo.AppModuleVO @@ -7,9 +7,11 @@ import com.zteits.urbanops.module.system.controller.app.appmodule.vo.AppModuleVO
7 import com.zteits.urbanops.module.system.convert.appmodule.AppModuleConvert; 7 import com.zteits.urbanops.module.system.convert.appmodule.AppModuleConvert;
8 import com.zteits.urbanops.module.system.dal.dataobject.appmodule.AppModuleDO; 8 import com.zteits.urbanops.module.system.dal.dataobject.appmodule.AppModuleDO;
9 import com.zteits.urbanops.module.system.service.appmodule.AppModuleService; 9 import com.zteits.urbanops.module.system.service.appmodule.AppModuleService;
  10 +import com.zteits.urbanops.module.system.service.permission.PermissionService;
10 import io.swagger.v3.oas.annotations.Operation; 11 import io.swagger.v3.oas.annotations.Operation;
11 import io.swagger.v3.oas.annotations.tags.Tag; 12 import io.swagger.v3.oas.annotations.tags.Tag;
12 import jakarta.annotation.Resource; 13 import jakarta.annotation.Resource;
  14 +import lombok.extern.slf4j.Slf4j;
13 import org.springframework.validation.annotation.Validated; 15 import org.springframework.validation.annotation.Validated;
14 import org.springframework.web.bind.annotation.GetMapping; 16 import org.springframework.web.bind.annotation.GetMapping;
15 import org.springframework.web.bind.annotation.RequestMapping; 17 import org.springframework.web.bind.annotation.RequestMapping;
@@ -21,6 +23,7 @@ import java.util.Comparator; @@ -21,6 +23,7 @@ import java.util.Comparator;
21 import java.util.LinkedHashMap; 23 import java.util.LinkedHashMap;
22 import java.util.List; 24 import java.util.List;
23 import java.util.Map; 25 import java.util.Map;
  26 +import java.util.Set;
24 27
25 import static com.zteits.urbanops.framework.common.pojo.CommonResult.success; 28 import static com.zteits.urbanops.framework.common.pojo.CommonResult.success;
26 29
@@ -34,29 +37,60 @@ import static com.zteits.urbanops.framework.common.pojo.CommonResult.success; @@ -34,29 +37,60 @@ import static com.zteits.urbanops.framework.common.pojo.CommonResult.success;
34 @RestController 37 @RestController
35 @RequestMapping("/member/app-module") 38 @RequestMapping("/member/app-module")
36 @Validated 39 @Validated
  40 +@Slf4j
37 public class AppAppModuleController { 41 public class AppAppModuleController {
38 42
  43 + /**
  44 + * 园林巡查员角色ID
  45 + */
  46 + private static final Long ROLE_ID_PATROL = 178L;
  47 +
  48 + /**
  49 + * 园林巡查员角色ID
  50 + */
  51 + private static final Long ROLE_ID_PATROL_ZX = 202L;
  52 + /**
  53 + * 全域督察员角色ID
  54 + */
  55 + private static final Long ROLE_ID_INSPECTOR = 183L;
  56 + /**
  57 + * 巡查工单模块ID
  58 + */
  59 + private static final Long MODULE_ID_PATROL_WORKORDER = 7L;
  60 +
39 @Resource 61 @Resource
40 private AppModuleService appModuleService; 62 private AppModuleService appModuleService;
41 63
  64 + @Resource
  65 + private PermissionService permissionService;
  66 +
42 @GetMapping("/list") 67 @GetMapping("/list")
43 @Operation(summary = "获取 App 功能模块列表", description = "获取用户可见的功能模块列表") 68 @Operation(summary = "获取 App 功能模块列表", description = "获取用户可见的功能模块列表")
44 public CommonResult<List<AppModuleVO>> getAppModuleList(AppModuleListReqVO reqVO) { 69 public CommonResult<List<AppModuleVO>> getAppModuleList(AppModuleListReqVO reqVO) {
45 // 获取当前登录用户ID 70 // 获取当前登录用户ID
46 Long userId = SecurityFrameworkUtils.getLoginUserId(); 71 Long userId = SecurityFrameworkUtils.getLoginUserId();
47 - 72 +
48 // 查询用户可见的模块列表 73 // 查询用户可见的模块列表
49 List<AppModuleDO> list = appModuleService.getVisibleAppModuleList(userId, reqVO); 74 List<AppModuleDO> list = appModuleService.getVisibleAppModuleList(userId, reqVO);
50 - 75 +
  76 + // 如果用户同时拥有园林巡查员(178)和全域督察员(183)角色,则隐藏巡查工单菜单,只显示督查工单菜单
  77 + if (userId != null) {
  78 + Set<Long> roleIds = permissionService.getUserRoleIdListByUserId(userId);
  79 + if (roleIds.contains(ROLE_ID_PATROL_ZX) && roleIds.contains(ROLE_ID_INSPECTOR)) {
  80 + log.info("[getAppModuleList] 用户({})同时拥有巡查员和督察员角色,隐藏巡查工单菜单", userId);
  81 + list.removeIf(module -> MODULE_ID_PATROL_WORKORDER.equals(module.getId()));
  82 + }
  83 + }
  84 +
51 // 填充统计数据(根据extra中的statisticKey配置) 85 // 填充统计数据(根据extra中的statisticKey配置)
52 // appModuleService.fillModuleStatistics(list, userId); 86 // appModuleService.fillModuleStatistics(list, userId);
53 - 87 +
54 // 转换为 VO 列表并构建树 88 // 转换为 VO 列表并构建树
55 List<AppModuleVO> modules = AppModuleConvert.INSTANCE.convertAppList(list); 89 List<AppModuleVO> modules = AppModuleConvert.INSTANCE.convertAppList(list);
56 List<AppModuleVO> moduleTree = buildModuleTree(modules); 90 List<AppModuleVO> moduleTree = buildModuleTree(modules);
57 - 91 +
58 // MapStruct 转换已通过 @AfterMapping 自动填充 statisticCount 92 // MapStruct 转换已通过 @AfterMapping 自动填充 statisticCount
59 - 93 +
60 return success(moduleTree); 94 return success(moduleTree);
61 } 95 }
62 96
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/controller/admin/maininfo/MainInfoController.java
@@ -197,8 +197,21 @@ public class MainInfoController { @@ -197,8 +197,21 @@ public class MainInfoController {
197 197
198 Map<String, BpmUserSimpleReqDTO> bpmTaskRespVOS = bpmTaskApi.getLastTaskMapByProcessInstanceId(processInstanceIdList); 198 Map<String, BpmUserSimpleReqDTO> bpmTaskRespVOS = bpmTaskApi.getLastTaskMapByProcessInstanceId(processInstanceIdList);
199 199
200 - // 5. 转换并返回结果  
201 - return success(MainInfoConvert.INSTANCE.buildMainInfoPage(pageResult, attachmentMap, bpmTaskRespVOS)); 200 + // 5. 查询单位名称
  201 + Map<Long, String> companyNameMap = pageResult.getList().stream()
  202 + .map(MainInfoDO::getCompanyId)
  203 + .filter(Objects::nonNull)
  204 + .distinct()
  205 + .collect(Collectors.toMap(
  206 + companyId -> companyId,
  207 + companyId -> {
  208 + DeptDO dept = deptService.getDept(companyId);
  209 + return dept != null ? dept.getName() : "";
  210 + }
  211 + ));
  212 +
  213 + // 6. 转换并返回结果
  214 + return success(MainInfoConvert.INSTANCE.buildMainInfoPage(pageResult, attachmentMap, bpmTaskRespVOS, companyNameMap));
202 } 215 }
203 216
204 @GetMapping("/export-excel") 217 @GetMapping("/export-excel")
urbanops-module-workorder/src/main/java/com/zteits/urbanops/module/workorder/convert/maininfo/MainInfoConvert.java
@@ -25,7 +25,7 @@ public interface MainInfoConvert { @@ -25,7 +25,7 @@ public interface MainInfoConvert {
25 25
26 MainInfoConvert INSTANCE = Mappers.getMapper(MainInfoConvert.class); 26 MainInfoConvert INSTANCE = Mappers.getMapper(MainInfoConvert.class);
27 27
28 - default PageResult<AdminMainInfoRespVO> buildMainInfoPage(PageResult<MainInfoDO> pageResult, Map<String, AttachmentDO> attachmentMap, Map<String, BpmUserSimpleReqDTO> bpmTaskRespVOS ) { 28 + default PageResult<AdminMainInfoRespVO> buildMainInfoPage(PageResult<MainInfoDO> pageResult, Map<String, AttachmentDO> attachmentMap, Map<String, BpmUserSimpleReqDTO> bpmTaskRespVOS, Map<Long, String> companyNameMap) {
29 List<AdminMainInfoRespVO> mainInfoVOList = CollectionUtils.convertList(pageResult.getList(), mainInfoDO -> { 29 List<AdminMainInfoRespVO> mainInfoVOList = CollectionUtils.convertList(pageResult.getList(), mainInfoDO -> {
30 AdminMainInfoRespVO mainInfoVo = BeanUtils.toBean(mainInfoDO, AdminMainInfoRespVO.class); 30 AdminMainInfoRespVO mainInfoVo = BeanUtils.toBean(mainInfoDO, AdminMainInfoRespVO.class);
31 if (attachmentMap != null && !attachmentMap.isEmpty()) { 31 if (attachmentMap != null && !attachmentMap.isEmpty()) {
@@ -48,6 +48,9 @@ public interface MainInfoConvert { @@ -48,6 +48,9 @@ public interface MainInfoConvert {
48 } 48 }
49 } 49 }
50 } 50 }
  51 + if (companyNameMap != null && mainInfoDO.getCompanyId() != null) {
  52 + mainInfoVo.setCompanyName(companyNameMap.getOrDefault(mainInfoDO.getCompanyId(), ""));
  53 + }
51 return mainInfoVo; 54 return mainInfoVo;
52 }); 55 });
53 return new PageResult<>(mainInfoVOList, pageResult.getTotal()); 56 return new PageResult<>(mainInfoVOList, pageResult.getTotal());
urbanops-server/src/main/resources/application-dev.yaml
@@ -251,7 +251,7 @@ wechat: @@ -251,7 +251,7 @@ wechat:
251 tokenUrl: https://api.weixin.qq.com/cgi-bin/stable_token 251 tokenUrl: https://api.weixin.qq.com/cgi-bin/stable_token
252 sendUrl: https://api.weixin.qq.com/cgi-bin/message/template/send 252 sendUrl: https://api.weixin.qq.com/cgi-bin/message/template/send
253 siot: 253 siot:
254 - roadUrl: https://iot.jichengshanshui.com.cn:28202/prod-api/fence/fenceInfo/getFenceRoadListByLocation 254 + roadUrl: https://test.jichengshanshui.com.cn:28202/prod-api/fence/fenceInfo/getFenceRoadListByLocation
255 255
256 # 高德地图配置 256 # 高德地图配置
257 amap: 257 amap:
urbanops-server/src/main/resources/application.yaml
@@ -3,7 +3,7 @@ spring: @@ -3,7 +3,7 @@ spring:
3 name: urbanops-server 3 name: urbanops-server
4 4
5 profiles: 5 profiles:
6 - active: prod 6 + active: dev
7 7
8 8
9 main: 9 main: