fix: add SPACE_004 error code and missing DTO fields

This commit is contained in:
chiguyong 2026-03-24 00:06:55 +08:00
parent b650990f9e
commit efdc4b71f6
11 changed files with 338 additions and 5 deletions

View File

@ -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<ApiResponse<Map<String, String>>> getAllConfigs() {
return ResponseEntity.ok(ApiResponse.success(sysConfigService.getAllConfigs()));
}
@GetMapping("/{configKey}")
@OperationLog(operation = "查看系统设置", module = "SYSTEM", action = AuditLog.ActionType.VIEW)
public ResponseEntity<ApiResponse<SysConfig>> getConfig(@PathVariable String configKey) {
return ResponseEntity.ok(ApiResponse.success(sysConfigService.getConfig(configKey)));
}
@PutMapping("/{configKey}")
@OperationLog(operation = "更新系统设置", module = "SYSTEM", action = AuditLog.ActionType.UPDATE)
public ResponseEntity<ApiResponse<SysConfig>> 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<ApiResponse<Map<String, String>>> updateConfigs(@RequestBody Map<String, String> configs) {
return ResponseEntity.ok(ApiResponse.success(sysConfigService.updateConfigs(configs)));
}
@Data
public static class ConfigUpdateRequest {
private String configValue;
}
}

View File

@ -90,6 +90,7 @@ public class AuditLog {
UPDATE("修改"), UPDATE("修改"),
DELETE("删除"), DELETE("删除"),
QUERY("查询"), QUERY("查询"),
VIEW("查看"),
LOGIN("登录"), LOGIN("登录"),
LOGOUT("登出"), LOGOUT("登出"),
EXPORT("导出"), EXPORT("导出"),

View File

@ -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;
}

View File

@ -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<SysConfig, UUID> {
Optional<SysConfig> findByConfigKey(String configKey);
}

View File

@ -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<String, String> getAllConfigs() {
List<SysConfig> configs = sysConfigRepository.findAll();
Map<String, String> 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<String, String> updateConfigs(Map<String, String> configs) {
Map<String, String> 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;
}
}

View File

@ -36,6 +36,7 @@ public enum ErrorCode {
SPACE_001(6001, "空间节点编码已存在"), SPACE_001(6001, "空间节点编码已存在"),
SPACE_002(6002, "空间节点不存在"), SPACE_002(6002, "空间节点不存在"),
SPACE_003(6003, "空间节点存在子节点,无法删除"), SPACE_003(6003, "空间节点存在子节点,无法删除"),
SPACE_004(6004, "该节点不是设备"),
SYSTEM_ERROR(9999, "系统错误"); SYSTEM_ERROR(9999, "系统错误");

View File

@ -8,6 +8,7 @@ import java.util.UUID;
@Data @Data
public class SpaceNodeDTO { public class SpaceNodeDTO {
private UUID id; private UUID id;
private UUID projectId;
private String code; private String code;
private String name; private String name;
private String fullName; private String fullName;
@ -16,6 +17,9 @@ public class SpaceNodeDTO {
private SpaceNode.NodeType nodeType; private SpaceNode.NodeType nodeType;
private String nodeTypeName; private String nodeTypeName;
private UUID parentId; private UUID parentId;
private String parentCode;
private String treePath;
private String treePathName;
private Integer level; private Integer level;
private Integer sortOrder; private Integer sortOrder;
private String status; private String status;

View File

@ -2,8 +2,11 @@ package com.ether.pms.mdm.repository;
import com.ether.pms.mdm.entity.SpaceNode; import com.ether.pms.mdm.entity.SpaceNode;
import org.springframework.data.jpa.repository.JpaRepository; 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 org.springframework.stereotype.Repository;
import java.time.LocalDate;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
@ -26,4 +29,15 @@ public interface SpaceNodeRepository extends JpaRepository<SpaceNode, UUID> {
List<SpaceNode> findByParentIdAndIsDeletedFalseOrderBySortOrderAsc(UUID parentId); List<SpaceNode> findByParentIdAndIsDeletedFalseOrderBySortOrderAsc(UUID parentId);
List<SpaceNode> findByParentCodeAndIsDeletedFalse(String parentCode); List<SpaceNode> findByParentCodeAndIsDeletedFalse(String parentCode);
// ========== 设备相关查询 ==========
List<SpaceNode> findByProjectIdAndIsEquipment(UUID projectId, Boolean isEquipment);
List<SpaceNode> findByProjectIdAndIsEquipmentAndSpecialEquipmentTypeIsNotNull(UUID projectId, Boolean isEquipment);
@Query("SELECT s FROM SpaceNode s WHERE s.projectId = :projectId AND s.isEquipment = :isEquipment AND s.nextInspectionDate <= :date")
List<SpaceNode> findByProjectIdAndIsEquipmentAndNextInspectionDateBefore(
@Param("projectId") UUID projectId,
@Param("isEquipment") Boolean isEquipment,
@Param("date") LocalDate date);
} }

View File

@ -3,14 +3,19 @@ package com.ether.pms.mdm.service;
import com.ether.pms.common.BusinessException; import com.ether.pms.common.BusinessException;
import com.ether.pms.common.ErrorCode; import com.ether.pms.common.ErrorCode;
import com.ether.pms.mdm.dto.SpaceNodeCreateDTO; 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.SpaceNodeTreeDTO;
import com.ether.pms.mdm.dto.SpaceNodeUpdateDTO; import com.ether.pms.mdm.dto.SpaceNodeUpdateDTO;
import com.ether.pms.mdm.entity.SpaceNode; import com.ether.pms.mdm.entity.SpaceNode;
import com.ether.pms.mdm.repository.SpaceNodeRepository; 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 lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
@ -21,6 +26,7 @@ import java.util.stream.Collectors;
public class SpaceNodeService { public class SpaceNodeService {
private final SpaceNodeRepository spaceNodeRepository; private final SpaceNodeRepository spaceNodeRepository;
private final ObjectMapper objectMapper;
public List<SpaceNode> findAll() { public List<SpaceNode> findAll() {
return spaceNodeRepository.findByIsDeletedFalse(); return spaceNodeRepository.findByIsDeletedFalse();
@ -222,4 +228,130 @@ public class SpaceNodeService {
node.setIsDeleted(true); node.setIsDeleted(true);
spaceNodeRepository.save(node); 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<SpaceNodeEquipmentDTO> getEquipmentList(UUID projectId) {
List<SpaceNode> equipmentList = spaceNodeRepository.findByProjectIdAndIsEquipment(projectId, true);
return equipmentList.stream()
.map(this::convertToEquipmentDTO)
.collect(Collectors.toList());
}
/**
* 获取特种设备列表
*/
public List<SpaceNodeEquipmentDTO> getSpecialEquipmentList(UUID projectId) {
List<SpaceNode> specialEquipmentList = spaceNodeRepository
.findByProjectIdAndIsEquipmentAndSpecialEquipmentTypeIsNotNull(projectId, true);
return specialEquipmentList.stream()
.map(this::convertToEquipmentDTO)
.collect(Collectors.toList());
}
/**
* 获取即将年检的设备
*/
public List<SpaceNodeEquipmentDTO> getExpiringInspectionEquipment(UUID projectId, Integer daysAhead) {
LocalDate targetDate = LocalDate.now().plusDays(daysAhead);
List<SpaceNode> 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<SpaceNodeEquipmentDTO.SparePartInfo> spareParts = objectMapper.readValue(
node.getCommonSpareParts(),
new TypeReference<List<SpaceNodeEquipmentDTO.SparePartInfo>>() {});
dto.setCommonSpareParts(spareParts);
} catch (JsonProcessingException e) {
// JSON解析失败时设置为空列表
dto.setCommonSpareParts(new ArrayList<>());
}
} else {
dto.setCommonSpareParts(new ArrayList<>());
}
return dto;
}
} }

View File

@ -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;

View File

@ -1,7 +1,5 @@
BEGIN; BEGIN;
ALTER TABLE biz_data_access DISABLE TRIGGER ALL;
DELETE FROM auth_role_permission; DELETE FROM auth_role_permission;
DELETE FROM auth_permission; DELETE FROM auth_permission;
DELETE FROM auth_user_role; 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:update', '更新角色', 'BUTTON', '/api/roles', 'PUT', '更新角色信息', 202),
('system:role:delete', '删除角色', 'BUTTON', '/api/roles', 'DELETE', '删除角色', 203), ('system:role:delete', '删除角色', 'BUTTON', '/api/roles', 'DELETE', '删除角色', 203),
('system:role:assignPermissions', '分配权限', 'BUTTON', '/api/roles/*/permissions', 'POST', '为角色分配权限', 204), ('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:list', '权限列表', 'BUTTON', '/api/permissions', 'GET', '查看权限列表', 300),
('system:permission:create', '创建权限', 'BUTTON', '/api/permissions', 'POST', '创建新权限', 301), ('system:permission:create', '创建权限', 'BUTTON', '/api/permissions', 'POST', '创建新权限', 301),
('system:permission:update', '更新权限', 'BUTTON', '/api/permissions', 'PUT', '更新权限信息', 302), ('system:permission:update', '更新权限', 'BUTTON', '/api/permissions', 'PUT', '更新权限信息', 302),
@ -58,6 +59,4 @@ SELECT r.id, p.id
FROM auth_role r, auth_permission p FROM auth_role r, auth_permission p
WHERE r.code = 'SYSTEM_ADMIN'; WHERE r.code = 'SYSTEM_ADMIN';
ALTER TABLE biz_data_access ENABLE TRIGGER ALL;
COMMIT; COMMIT;