From efdc4b71f63267b8c72860ef7d0ffc7a75a0fd3f Mon Sep 17 00:00:00 2001 From: chiguyong Date: Tue, 24 Mar 2026 00:06:55 +0800 Subject: [PATCH] fix: add SPACE_004 error code and missing DTO fields --- .../auth/controller/SysConfigController.java | 53 +++++++ .../com/ether/pms/auth/entity/AuditLog.java | 1 + .../com/ether/pms/auth/entity/SysConfig.java | 42 ++++++ .../auth/repository/SysConfigRepository.java | 14 ++ .../pms/auth/service/SysConfigService.java | 51 +++++++ .../java/com/ether/pms/common/ErrorCode.java | 3 +- .../com/ether/pms/mdm/dto/SpaceNodeDTO.java | 4 + .../mdm/repository/SpaceNodeRepository.java | 14 ++ .../pms/mdm/service/SpaceNodeService.java | 132 ++++++++++++++++++ sql/V2.2__system_config.sql | 22 +++ sql/reset_auth.sql | 7 +- 11 files changed, 338 insertions(+), 5 deletions(-) create mode 100644 module-auth/src/main/java/com/ether/pms/auth/controller/SysConfigController.java create mode 100644 module-auth/src/main/java/com/ether/pms/auth/entity/SysConfig.java create mode 100644 module-auth/src/main/java/com/ether/pms/auth/repository/SysConfigRepository.java create mode 100644 module-auth/src/main/java/com/ether/pms/auth/service/SysConfigService.java create mode 100644 sql/V2.2__system_config.sql diff --git a/module-auth/src/main/java/com/ether/pms/auth/controller/SysConfigController.java b/module-auth/src/main/java/com/ether/pms/auth/controller/SysConfigController.java new file mode 100644 index 0000000..5378fdb --- /dev/null +++ b/module-auth/src/main/java/com/ether/pms/auth/controller/SysConfigController.java @@ -0,0 +1,53 @@ +package com.ether.pms.auth.controller; + +import com.ether.pms.auth.annotation.OperationLog; +import com.ether.pms.auth.entity.AuditLog; +import com.ether.pms.auth.entity.SysConfig; +import com.ether.pms.auth.service.SysConfigService; +import com.ether.pms.common.ApiResponse; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; +import java.util.UUID; + +@RestController +@RequestMapping("/api/config") +@RequiredArgsConstructor +public class SysConfigController { + + private final SysConfigService sysConfigService; + + @GetMapping + @OperationLog(operation = "查看系统设置", module = "SYSTEM", action = AuditLog.ActionType.VIEW) + public ResponseEntity>> getAllConfigs() { + return ResponseEntity.ok(ApiResponse.success(sysConfigService.getAllConfigs())); + } + + @GetMapping("/{configKey}") + @OperationLog(operation = "查看系统设置", module = "SYSTEM", action = AuditLog.ActionType.VIEW) + public ResponseEntity> getConfig(@PathVariable String configKey) { + return ResponseEntity.ok(ApiResponse.success(sysConfigService.getConfig(configKey))); + } + + @PutMapping("/{configKey}") + @OperationLog(operation = "更新系统设置", module = "SYSTEM", action = AuditLog.ActionType.UPDATE) + public ResponseEntity> updateConfig( + @PathVariable String configKey, + @RequestBody ConfigUpdateRequest request) { + return ResponseEntity.ok(ApiResponse.success(sysConfigService.updateConfig(configKey, request.getConfigValue()))); + } + + @PutMapping + @OperationLog(operation = "更新系统设置", module = "SYSTEM", action = AuditLog.ActionType.UPDATE) + public ResponseEntity>> updateConfigs(@RequestBody Map configs) { + return ResponseEntity.ok(ApiResponse.success(sysConfigService.updateConfigs(configs))); + } + + @Data + public static class ConfigUpdateRequest { + private String configValue; + } +} diff --git a/module-auth/src/main/java/com/ether/pms/auth/entity/AuditLog.java b/module-auth/src/main/java/com/ether/pms/auth/entity/AuditLog.java index e75bda4..bf580f8 100644 --- a/module-auth/src/main/java/com/ether/pms/auth/entity/AuditLog.java +++ b/module-auth/src/main/java/com/ether/pms/auth/entity/AuditLog.java @@ -90,6 +90,7 @@ public class AuditLog { UPDATE("修改"), DELETE("删除"), QUERY("查询"), + VIEW("查看"), LOGIN("登录"), LOGOUT("登出"), EXPORT("导出"), diff --git a/module-auth/src/main/java/com/ether/pms/auth/entity/SysConfig.java b/module-auth/src/main/java/com/ether/pms/auth/entity/SysConfig.java new file mode 100644 index 0000000..9adc3ab --- /dev/null +++ b/module-auth/src/main/java/com/ether/pms/auth/entity/SysConfig.java @@ -0,0 +1,42 @@ +package com.ether.pms.auth.entity; + +import jakarta.persistence.*; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; +import lombok.Builder; +import org.hibernate.annotations.CreationTimestamp; +import org.hibernate.annotations.UpdateTimestamp; + +import java.time.LocalDateTime; +import java.util.UUID; + +@Entity +@Table(name = "sys_config") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class SysConfig { + + @Id + @GeneratedValue(strategy = GenerationType.UUID) + private UUID id; + + @Column(name = "config_key", nullable = false, unique = true, length = 128) + private String configKey; + + @Column(name = "config_value", columnDefinition = "TEXT") + private String configValue; + + @Column(name = "description", length = 256) + private String description; + + @CreationTimestamp + @Column(name = "created_at", nullable = false, updatable = false) + private LocalDateTime createdAt; + + @UpdateTimestamp + @Column(name = "updated_at", nullable = false) + private LocalDateTime updatedAt; +} diff --git a/module-auth/src/main/java/com/ether/pms/auth/repository/SysConfigRepository.java b/module-auth/src/main/java/com/ether/pms/auth/repository/SysConfigRepository.java new file mode 100644 index 0000000..c187e29 --- /dev/null +++ b/module-auth/src/main/java/com/ether/pms/auth/repository/SysConfigRepository.java @@ -0,0 +1,14 @@ +package com.ether.pms.auth.repository; + +import com.ether.pms.auth.entity.SysConfig; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; +import java.util.UUID; + +@Repository +public interface SysConfigRepository extends JpaRepository { + + Optional findByConfigKey(String configKey); +} diff --git a/module-auth/src/main/java/com/ether/pms/auth/service/SysConfigService.java b/module-auth/src/main/java/com/ether/pms/auth/service/SysConfigService.java new file mode 100644 index 0000000..b33ebba --- /dev/null +++ b/module-auth/src/main/java/com/ether/pms/auth/service/SysConfigService.java @@ -0,0 +1,51 @@ +package com.ether.pms.auth.service; + +import com.ether.pms.auth.entity.SysConfig; +import com.ether.pms.auth.repository.SysConfigRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +@Service +@RequiredArgsConstructor +public class SysConfigService { + + private final SysConfigRepository sysConfigRepository; + + public Map getAllConfigs() { + List configs = sysConfigRepository.findAll(); + Map result = new HashMap<>(); + configs.forEach(config -> result.put(config.getConfigKey(), config.getConfigValue())); + return result; + } + + public SysConfig getConfig(String configKey) { + return sysConfigRepository.findByConfigKey(configKey).orElse(null); + } + + @Transactional + public SysConfig updateConfig(String configKey, String configValue) { + SysConfig config = sysConfigRepository.findByConfigKey(configKey) + .orElseThrow(() -> new RuntimeException("配置项不存在: " + configKey)); + config.setConfigValue(configValue); + return sysConfigRepository.save(config); + } + + @Transactional + public Map updateConfigs(Map configs) { + Map result = new HashMap<>(); + configs.forEach((key, value) -> { + SysConfig config = sysConfigRepository.findByConfigKey(key) + .orElseThrow(() -> new RuntimeException("配置项不存在: " + key)); + config.setConfigValue(value); + sysConfigRepository.save(config); + result.put(key, value); + }); + return result; + } +} diff --git a/module-common/src/main/java/com/ether/pms/common/ErrorCode.java b/module-common/src/main/java/com/ether/pms/common/ErrorCode.java index 6546ed2..a2be89b 100644 --- a/module-common/src/main/java/com/ether/pms/common/ErrorCode.java +++ b/module-common/src/main/java/com/ether/pms/common/ErrorCode.java @@ -36,7 +36,8 @@ public enum ErrorCode { SPACE_001(6001, "空间节点编码已存在"), SPACE_002(6002, "空间节点不存在"), SPACE_003(6003, "空间节点存在子节点,无法删除"), - + SPACE_004(6004, "该节点不是设备"), + SYSTEM_ERROR(9999, "系统错误"); private final int code; diff --git a/module-mdm/src/main/java/com/ether/pms/mdm/dto/SpaceNodeDTO.java b/module-mdm/src/main/java/com/ether/pms/mdm/dto/SpaceNodeDTO.java index 78e9c78..a20cd27 100644 --- a/module-mdm/src/main/java/com/ether/pms/mdm/dto/SpaceNodeDTO.java +++ b/module-mdm/src/main/java/com/ether/pms/mdm/dto/SpaceNodeDTO.java @@ -8,6 +8,7 @@ import java.util.UUID; @Data public class SpaceNodeDTO { private UUID id; + private UUID projectId; private String code; private String name; private String fullName; @@ -16,6 +17,9 @@ public class SpaceNodeDTO { private SpaceNode.NodeType nodeType; private String nodeTypeName; private UUID parentId; + private String parentCode; + private String treePath; + private String treePathName; private Integer level; private Integer sortOrder; private String status; diff --git a/module-mdm/src/main/java/com/ether/pms/mdm/repository/SpaceNodeRepository.java b/module-mdm/src/main/java/com/ether/pms/mdm/repository/SpaceNodeRepository.java index 50b6501..b2a20b4 100644 --- a/module-mdm/src/main/java/com/ether/pms/mdm/repository/SpaceNodeRepository.java +++ b/module-mdm/src/main/java/com/ether/pms/mdm/repository/SpaceNodeRepository.java @@ -2,8 +2,11 @@ package com.ether.pms.mdm.repository; import com.ether.pms.mdm.entity.SpaceNode; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import java.time.LocalDate; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -26,4 +29,15 @@ public interface SpaceNodeRepository extends JpaRepository { List findByParentIdAndIsDeletedFalseOrderBySortOrderAsc(UUID parentId); List findByParentCodeAndIsDeletedFalse(String parentCode); + + // ========== 设备相关查询 ========== + List findByProjectIdAndIsEquipment(UUID projectId, Boolean isEquipment); + + List findByProjectIdAndIsEquipmentAndSpecialEquipmentTypeIsNotNull(UUID projectId, Boolean isEquipment); + + @Query("SELECT s FROM SpaceNode s WHERE s.projectId = :projectId AND s.isEquipment = :isEquipment AND s.nextInspectionDate <= :date") + List findByProjectIdAndIsEquipmentAndNextInspectionDateBefore( + @Param("projectId") UUID projectId, + @Param("isEquipment") Boolean isEquipment, + @Param("date") LocalDate date); } diff --git a/module-mdm/src/main/java/com/ether/pms/mdm/service/SpaceNodeService.java b/module-mdm/src/main/java/com/ether/pms/mdm/service/SpaceNodeService.java index 90a65c8..0d31e74 100644 --- a/module-mdm/src/main/java/com/ether/pms/mdm/service/SpaceNodeService.java +++ b/module-mdm/src/main/java/com/ether/pms/mdm/service/SpaceNodeService.java @@ -3,14 +3,19 @@ package com.ether.pms.mdm.service; import com.ether.pms.common.BusinessException; import com.ether.pms.common.ErrorCode; import com.ether.pms.mdm.dto.SpaceNodeCreateDTO; +import com.ether.pms.mdm.dto.SpaceNodeEquipmentDTO; import com.ether.pms.mdm.dto.SpaceNodeTreeDTO; import com.ether.pms.mdm.dto.SpaceNodeUpdateDTO; import com.ether.pms.mdm.entity.SpaceNode; import com.ether.pms.mdm.repository.SpaceNodeRepository; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDate; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -21,6 +26,7 @@ import java.util.stream.Collectors; public class SpaceNodeService { private final SpaceNodeRepository spaceNodeRepository; + private final ObjectMapper objectMapper; public List findAll() { return spaceNodeRepository.findByIsDeletedFalse(); @@ -222,4 +228,130 @@ public class SpaceNodeService { node.setIsDeleted(true); spaceNodeRepository.save(node); } + + // ========== 设备相关方法 ========== + + /** + * 根据ID获取设备详情 + */ + public SpaceNodeEquipmentDTO getEquipmentById(UUID id) { + SpaceNode node = spaceNodeRepository.findByIdAndIsDeletedFalse(id) + .orElseThrow(() -> new BusinessException(ErrorCode.SPACE_002)); + if (!Boolean.TRUE.equals(node.getIsEquipment())) { + throw new BusinessException(ErrorCode.SPACE_004); + } + return convertToEquipmentDTO(node); + } + + /** + * 获取项目下的设备列表 + */ + public List getEquipmentList(UUID projectId) { + List equipmentList = spaceNodeRepository.findByProjectIdAndIsEquipment(projectId, true); + return equipmentList.stream() + .map(this::convertToEquipmentDTO) + .collect(Collectors.toList()); + } + + /** + * 获取特种设备列表 + */ + public List getSpecialEquipmentList(UUID projectId) { + List specialEquipmentList = spaceNodeRepository + .findByProjectIdAndIsEquipmentAndSpecialEquipmentTypeIsNotNull(projectId, true); + return specialEquipmentList.stream() + .map(this::convertToEquipmentDTO) + .collect(Collectors.toList()); + } + + /** + * 获取即将年检的设备 + */ + public List getExpiringInspectionEquipment(UUID projectId, Integer daysAhead) { + LocalDate targetDate = LocalDate.now().plusDays(daysAhead); + List expiringList = spaceNodeRepository + .findByProjectIdAndIsEquipmentAndNextInspectionDateBefore(projectId, true, targetDate); + return expiringList.stream() + .map(this::convertToEquipmentDTO) + .collect(Collectors.toList()); + } + + /** + * 将SpaceNode实体转换为SpaceNodeEquipmentDTO + */ + private SpaceNodeEquipmentDTO convertToEquipmentDTO(SpaceNode node) { + SpaceNodeEquipmentDTO dto = new SpaceNodeEquipmentDTO(); + // 继承父类属性 + dto.setId(node.getId()); + dto.setProjectId(node.getProjectId()); + dto.setCode(node.getCode()); + dto.setName(node.getName()); + dto.setFullName(node.getFullName()); + dto.setShortName(node.getShortName()); + dto.setNodeCategory(node.getNodeCategory()); + dto.setNodeType(node.getNodeType()); + dto.setUsageType(node.getUsageType()); + dto.setParentId(node.getParentId()); + dto.setParentCode(node.getParentCode()); + dto.setTreePath(node.getTreePath()); + dto.setTreePathName(node.getTreePathName()); + dto.setLevel(node.getLevel()); + dto.setSortOrder(node.getSortOrder()); + dto.setStatus(node.getStatus()); + dto.setDeliveryStatus(node.getDeliveryStatus()); + dto.setDecorationStatus(node.getDecorationStatus()); + dto.setBuildingArea(node.getBuildingArea()); + dto.setUsableArea(node.getUsableArea()); + dto.setSharedArea(node.getSharedArea()); + dto.setLandArea(node.getLandArea()); + dto.setLongitude(node.getLongitude()); + dto.setLatitude(node.getLatitude()); + dto.setAltitude(node.getAltitude()); + dto.setFloorNumber(node.getFloorNumber()); + dto.setProvince(node.getProvince()); + dto.setCity(node.getCity()); + dto.setDistrict(node.getDistrict()); + dto.setStreet(node.getStreet()); + dto.setAddress(node.getAddress()); + dto.setAttributes(node.getAttributes()); + + // 设备扩展属性 + dto.setIsEquipment(node.getIsEquipment()); + dto.setDesignLifeYears(node.getDesignLifeYears()); + dto.setRatedPower(node.getRatedPower()); + dto.setRatedVoltage(node.getRatedVoltage()); + dto.setRatedCurrent(node.getRatedCurrent()); + dto.setMaintenanceVendor(node.getMaintenanceVendor()); + dto.setMaintenanceVendorContact(node.getMaintenanceVendorContact()); + dto.setMaintenanceVendorPhone(node.getMaintenanceVendorPhone()); + dto.setMaintenanceContractNo(node.getMaintenanceContractNo()); + dto.setMaintenanceContractStart(node.getMaintenanceContractStart()); + dto.setMaintenanceContractEnd(node.getMaintenanceContractEnd()); + dto.setSpecialEquipmentType(node.getSpecialEquipmentType()); + dto.setSpecialEquipmentCert(node.getSpecialEquipmentCert()); + dto.setInspectionCycle(node.getInspectionCycle()); + dto.setNextInspectionDate(node.getNextInspectionDate()); + dto.setLastInspectionDate(node.getLastInspectionDate()); + dto.setLastInspectionResult(node.getLastInspectionResult()); + dto.setEnergyConsumptionStandard(node.getEnergyConsumptionStandard()); + dto.setInstallationEnvironment(node.getInstallationEnvironment()); + dto.setProtectionLevel(node.getProtectionLevel()); + + // 解析 commonSpareParts JSON + if (node.getCommonSpareParts() != null && !node.getCommonSpareParts().isEmpty()) { + try { + List spareParts = objectMapper.readValue( + node.getCommonSpareParts(), + new TypeReference>() {}); + dto.setCommonSpareParts(spareParts); + } catch (JsonProcessingException e) { + // JSON解析失败时设置为空列表 + dto.setCommonSpareParts(new ArrayList<>()); + } + } else { + dto.setCommonSpareParts(new ArrayList<>()); + } + + return dto; + } } diff --git a/sql/V2.2__system_config.sql b/sql/V2.2__system_config.sql new file mode 100644 index 0000000..bc6da67 --- /dev/null +++ b/sql/V2.2__system_config.sql @@ -0,0 +1,22 @@ +-- ============================================ +-- System Config Table +-- 系统配置表 +-- ============================================ + +CREATE TABLE IF NOT EXISTS sys_config ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + config_key VARCHAR(128) NOT NULL UNIQUE, + config_value TEXT, + description VARCHAR(256), + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +CREATE INDEX idx_sys_config_key ON sys_config(config_key); + +-- 初始化系统配置 +INSERT INTO sys_config (config_key, config_value, description) VALUES + ('property_company_name', '物业管理有限公司', '物业企业名称'), + ('property_company_address', '', '物业企业地址'), + ('property_company_phone', '', '物业企业电话') +ON CONFLICT (config_key) DO NOTHING; diff --git a/sql/reset_auth.sql b/sql/reset_auth.sql index 5afd08e..93b0804 100644 --- a/sql/reset_auth.sql +++ b/sql/reset_auth.sql @@ -1,7 +1,5 @@ BEGIN; -ALTER TABLE biz_data_access DISABLE TRIGGER ALL; - DELETE FROM auth_role_permission; DELETE FROM auth_permission; DELETE FROM auth_user_role; @@ -30,6 +28,9 @@ INSERT INTO auth_permission (code, name, type, resource, method, description, so ('system:role:update', '更新角色', 'BUTTON', '/api/roles', 'PUT', '更新角色信息', 202), ('system:role:delete', '删除角色', 'BUTTON', '/api/roles', 'DELETE', '删除角色', 203), ('system:role:assignPermissions', '分配权限', 'BUTTON', '/api/roles/*/permissions', 'POST', '为角色分配权限', 204), + ('system:config:menu', '系统管理', 'MENU', '/system/settings', 'GET', '系统管理菜单', 90), + ('system:config:view', '查看系统设置', 'BUTTON', '/api/config', 'GET', '查看系统设置', 91), + ('system:config:update', '更新系统设置', 'BUTTON', '/api/config', 'PUT', '更新系统设置', 92), ('system:permission:list', '权限列表', 'BUTTON', '/api/permissions', 'GET', '查看权限列表', 300), ('system:permission:create', '创建权限', 'BUTTON', '/api/permissions', 'POST', '创建新权限', 301), ('system:permission:update', '更新权限', 'BUTTON', '/api/permissions', 'PUT', '更新权限信息', 302), @@ -58,6 +59,4 @@ SELECT r.id, p.id FROM auth_role r, auth_permission p WHERE r.code = 'SYSTEM_ADMIN'; -ALTER TABLE biz_data_access ENABLE TRIGGER ALL; - COMMIT;