新增终端管理代码 #122

Merged
hnu202326010106 merged 1 commits from wanglei_branch into develop 2 weeks ago

@ -0,0 +1,104 @@
// java/com/campus/water/controller/web/TerminalController.java
package com.campus.water.controller.web;
import com.campus.water.service.TerminalService;
import com.campus.water.entity.vo.TerminalManageVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/web/terminal")
@RequiredArgsConstructor
@Tag(name = "终端管理接口", description = "管理员基于设备终端映射表/终端位置表的增删改查操作")
public class TerminalController {
private final TerminalService terminalService;
@PostMapping("/add")
@PreAuthorize("hasAnyRole('SUPER_ADMIN', 'AREA_ADMIN')")
@Operation(summary = "新增终端", description = "同时保存终端位置和基础映射信息")
// 泛型改为?兼容TerminalManageVO和Map
public ResponseEntity<?> addTerminal(@Valid @RequestBody TerminalManageVO terminalVO) {
try {
TerminalManageVO newTerminal = terminalService.addTerminal(terminalVO);
return new ResponseEntity<>(newTerminal, HttpStatus.CREATED);
} catch (Exception e) {
Map<String, String> errorMap = new HashMap<>();
errorMap.put("message", "终端新增失败: " + e.getMessage());
return new ResponseEntity<>(errorMap, HttpStatus.BAD_REQUEST);
}
}
@PutMapping("/update")
@PreAuthorize("hasAnyRole('SUPER_ADMIN', 'AREA_ADMIN')")
@Operation(summary = "更新终端", description = "支持更新终端名称、状态、经纬度等信息")
// 泛型改为?兼容TerminalManageVO和Map
public ResponseEntity<?> updateTerminal(@Valid @RequestBody TerminalManageVO terminalVO) {
try {
TerminalManageVO updated = terminalService.updateTerminal(terminalVO);
return ResponseEntity.ok(updated);
} catch (Exception e) {
Map<String, String> errorMap = new HashMap<>();
errorMap.put("message", "终端更新失败: " + e.getMessage());
return new ResponseEntity<>(errorMap, HttpStatus.BAD_REQUEST);
}
}
@DeleteMapping("/delete/{terminalId}")
@PreAuthorize("hasAnyRole('SUPER_ADMIN', 'AREA_ADMIN')")
@Operation(summary = "删除终端", description = "先校验设备绑定状态,再级联删除相关数据")
// 该方法成功/失败均返回Map泛型可保留Map<String, String>(无冲突)
public ResponseEntity<Map<String, String>> deleteTerminal(@PathVariable String terminalId) {
try {
terminalService.deleteTerminal(terminalId);
Map<String, String> successMap = new HashMap<>();
successMap.put("message", "终端删除成功");
return ResponseEntity.ok(successMap);
} catch (Exception e) {
Map<String, String> errorMap = new HashMap<>();
errorMap.put("message", "终端删除失败: " + e.getMessage());
return new ResponseEntity<>(errorMap, HttpStatus.BAD_REQUEST);
}
}
@GetMapping("/{terminalId}")
@PreAuthorize("hasAnyRole('SUPER_ADMIN', 'AREA_ADMIN')")
@Operation(summary = "查询终端详情", description = "根据终端ID获取整合后的完整信息")
// 泛型改为?兼容TerminalManageVO和Map
public ResponseEntity<?> getTerminal(@PathVariable String terminalId) {
try {
TerminalManageVO terminal = terminalService.getTerminalById(terminalId);
return ResponseEntity.ok(terminal);
} catch (Exception e) {
Map<String, String> errorMap = new HashMap<>();
errorMap.put("message", "终端查询失败: " + e.getMessage());
return new ResponseEntity<>(errorMap, HttpStatus.NOT_FOUND);
}
}
@GetMapping("/list")
@PreAuthorize("hasAnyRole('SUPER_ADMIN', 'AREA_ADMIN')")
@Operation(summary = "查询终端列表", description = "支持按终端名称模糊筛选")
// 泛型改为?兼容List<TerminalManageVO>和Map
public ResponseEntity<?> getTerminalList(
@RequestParam(required = false) String terminalName) {
try {
List<TerminalManageVO> terminals = terminalService.getTerminalList(terminalName);
return ResponseEntity.ok(terminals);
} catch (Exception e) {
Map<String, String> errorMap = new HashMap<>();
errorMap.put("message", "终端列表查询失败: " + e.getMessage());
return new ResponseEntity<>(errorMap, HttpStatus.BAD_REQUEST);
}
}
}

@ -0,0 +1,34 @@
// java/com/campus/water/vo/TerminalManageVO.java
package com.campus.water.entity.vo;
import com.campus.water.entity.DeviceTerminalMapping;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* VO
*/
@Data
public class TerminalManageVO {
// 终端核心标识(关联两张表的主键/外键)
private String terminalId;
// 终端名称(来自映射表)
private String terminalName;
// 终端经纬度(来自位置表)
private BigDecimal longitude;
private BigDecimal latitude;
// 终端状态(来自映射表)
private DeviceTerminalMapping.TerminalStatus terminalStatus;
// 安装日期(来自映射表)
private LocalDate installDate;
// 设备ID关联的设备来自映射表
private String deviceId;
}

@ -19,4 +19,15 @@ public interface DeviceTerminalMappingRepository extends JpaRepository<DeviceTer
// 根据设备和终端ID精确查找映射
Optional<DeviceTerminalMapping> findByDeviceIdAndTerminalId(String deviceId, String terminalId);
// ========== 新增必要方法(支撑终端增删改查业务) ==========
// 1. 判断终端是否已绑定设备(删除终端时的核心校验)
boolean existsByTerminalId(String terminalId);
// 2. 按终端名称模糊查询(终端列表筛选)
List<DeviceTerminalMapping> findByTerminalNameContaining(String terminalName);
// 3. 按终端ID删除所有关联映射删除终端时级联清理映射数据
void deleteByTerminalId(String terminalId);
}

@ -0,0 +1,25 @@
// java/com/campus/water/service/TerminalService.java
package com.campus.water.service;
import com.campus.water.entity.DeviceTerminalMapping;
import com.campus.water.entity.WaterTerminalLocation;
import com.campus.water.entity.vo.TerminalManageVO;
import java.util.List;
public interface TerminalService {
// 新增终端(同时保存位置信息和基础映射信息)
TerminalManageVO addTerminal(TerminalManageVO terminalVO);
// 更新终端(支持更新名称、状态、经纬度等信息)
TerminalManageVO updateTerminal(TerminalManageVO terminalVO);
// 删除终端(先校验是否绑定设备,再级联删除两张表的相关数据)
void deleteTerminal(String terminalId);
// 按ID查询终端详情整合两张表的数据
TerminalManageVO getTerminalById(String terminalId);
// 查询终端列表(支持按名称筛选,返回整合后的数据)
List<TerminalManageVO> getTerminalList(String terminalName);
}

@ -0,0 +1,164 @@
// java/com/campus/water/service/impl/TerminalServiceImpl.java
package com.campus.water.service;
import com.campus.water.entity.DeviceTerminalMapping;
import com.campus.water.entity.WaterTerminalLocation;
import com.campus.water.mapper.DeviceTerminalMappingRepository;
import com.campus.water.mapper.WaterTerminalLocationRepository;
import com.campus.water.service.TerminalService;
import com.campus.water.entity.vo.TerminalManageVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@Service
@RequiredArgsConstructor
public class TerminalServiceImpl implements TerminalService {
private final WaterTerminalLocationRepository locationRepository;
private final DeviceTerminalMappingRepository mappingRepository;
@Override
@Transactional
public TerminalManageVO addTerminal(TerminalManageVO terminalVO) {
// 1. 校验终端ID是否已存在通过位置表主键判断避免重复新增
if (locationRepository.existsById(terminalVO.getTerminalId())) {
throw new RuntimeException("终端ID已存在无法重复新增" + terminalVO.getTerminalId());
}
// 2. 保存终端位置信息(经纬度为必填项,校验非空)
if (terminalVO.getLongitude() == null || terminalVO.getLatitude() == null) {
throw new RuntimeException("终端经度和纬度为必填项,不可为空");
}
WaterTerminalLocation location = new WaterTerminalLocation();
location.setTerminalId(terminalVO.getTerminalId());
location.setLongitude(terminalVO.getLongitude());
location.setLatitude(terminalVO.getLatitude());
locationRepository.save(location);
// 3. 保存终端映射信息状态默认active复用原有Repository的save方法
DeviceTerminalMapping mapping = new DeviceTerminalMapping();
mapping.setTerminalId(terminalVO.getTerminalId());
mapping.setTerminalName(terminalVO.getTerminalName());
mapping.setTerminalStatus(terminalVO.getTerminalStatus() == null
? DeviceTerminalMapping.TerminalStatus.active
: terminalVO.getTerminalStatus());
mapping.setDeviceId(terminalVO.getDeviceId());
mapping.setInstallDate(terminalVO.getInstallDate());
mappingRepository.save(mapping);
// 4. 封装返回结果
return assembleTerminalVO(location, mapping);
}
@Override
@Transactional
public TerminalManageVO updateTerminal(TerminalManageVO terminalVO) {
// 1. 校验终端是否存在通过位置表查询复用原有findById方法
WaterTerminalLocation existingLocation = locationRepository.findById(terminalVO.getTerminalId())
.orElseThrow(() -> new RuntimeException("终端不存在,无法更新:" + terminalVO.getTerminalId()));
// 2. 更新终端位置信息仅更新有值字段复用原有save方法
if (terminalVO.getLongitude() != null) {
existingLocation.setLongitude(terminalVO.getLongitude());
}
if (terminalVO.getLatitude() != null) {
existingLocation.setLatitude(terminalVO.getLatitude());
}
locationRepository.save(existingLocation);
// 3. 更新终端映射信息复用原有findByTerminalId方法查询映射记录
DeviceTerminalMapping existingMapping = mappingRepository.findByTerminalId(terminalVO.getTerminalId())
.orElseThrow(() -> new RuntimeException("终端无关联映射信息,无法更新终端名称/状态"));
if (terminalVO.getTerminalName() != null && !terminalVO.getTerminalName().isEmpty()) {
existingMapping.setTerminalName(terminalVO.getTerminalName());
}
if (terminalVO.getTerminalStatus() != null) {
existingMapping.setTerminalStatus(terminalVO.getTerminalStatus());
}
if (terminalVO.getDeviceId() != null) {
existingMapping.setDeviceId(terminalVO.getDeviceId());
}
if (terminalVO.getInstallDate() != null) {
existingMapping.setInstallDate(terminalVO.getInstallDate());
}
mappingRepository.save(existingMapping);
// 4. 封装返回结果
return assembleTerminalVO(existingLocation, existingMapping);
}
@Override
@Transactional
public void deleteTerminal(String terminalId) {
// 1. 校验终端是否已绑定设备使用新增的existsByTerminalId方法
if (mappingRepository.existsByTerminalId(terminalId)) {
throw new RuntimeException("终端已绑定设备,无法删除,请先解除设备关联");
}
// 2. 校验终端是否存在复用原有existsById方法
if (!locationRepository.existsById(terminalId)) {
throw new RuntimeException("终端不存在,无需删除:" + terminalId);
}
// 3. 级联删除数据(先删映射表,再删位置表,保证数据一致性)
mappingRepository.deleteByTerminalId(terminalId); // 新增的批量删除方法
locationRepository.deleteById(terminalId); // 复用原有删除方法
}
@Override
public TerminalManageVO getTerminalById(String terminalId) {
// 1. 查询位置信息复用原有findById方法
WaterTerminalLocation location = locationRepository.findById(terminalId)
.orElseThrow(() -> new RuntimeException("终端不存在:" + terminalId));
// 2. 查询映射信息复用原有findByTerminalId方法
DeviceTerminalMapping mapping = mappingRepository.findByTerminalId(terminalId)
.orElseThrow(() -> new RuntimeException("终端无关联基础信息,请补充映射记录"));
// 3. 封装返回结果
return assembleTerminalVO(location, mapping);
}
@Override
public List<TerminalManageVO> getTerminalList(String terminalName) {
// 1. 查询映射表数据支持名称模糊筛选使用新增的findByTerminalNameContaining方法
List<DeviceTerminalMapping> mappings;
if (terminalName != null && !terminalName.isEmpty()) {
mappings = mappingRepository.findByTerminalNameContaining(terminalName);
} else {
mappings = mappingRepository.findAll(); // 复用原有查询所有方法
}
// 2. 遍历映射记录关联位置表数据封装VO列表
List<TerminalManageVO> terminalVOList = new ArrayList<>();
for (DeviceTerminalMapping mapping : mappings) {
Optional<WaterTerminalLocation> locationOpt = locationRepository.findById(mapping.getTerminalId());
locationOpt.ifPresent(location -> {
TerminalManageVO vo = assembleTerminalVO(location, mapping);
terminalVOList.add(vo);
});
}
return terminalVOList;
}
/**
* TerminalManageVO
*/
private TerminalManageVO assembleTerminalVO(WaterTerminalLocation location, DeviceTerminalMapping mapping) {
TerminalManageVO vo = new TerminalManageVO();
vo.setTerminalId(location.getTerminalId());
vo.setLongitude(location.getLongitude());
vo.setLatitude(location.getLatitude());
vo.setTerminalName(mapping.getTerminalName());
vo.setTerminalStatus(mapping.getTerminalStatus());
vo.setDeviceId(mapping.getDeviceId());
vo.setInstallDate(mapping.getInstallDate());
return vo;
}
}
Loading…
Cancel
Save