[tag] 初步实现了设施管理功能
This commit is contained in:
parent
2cc4760175
commit
db6e3f77a1
15
pom.xml
15
pom.xml
|
|
@ -59,6 +59,21 @@
|
|||
<artifactId>validation-api</artifactId>
|
||||
<version>2.0.1.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-spatial</artifactId>
|
||||
<version>5.4.32.Final</version> <!-- 或其他合适的版本 -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate.validator</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>6.2.0.Final</version> <!-- 请检查最新版本 -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.locationtech.jts</groupId>
|
||||
<artifactId>jts-core</artifactId>
|
||||
<version>1.18.0</version> <!-- 请使用最新版本 -->
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
package com.waterquality.projectmanagement.controller;
|
||||
|
||||
import com.waterquality.projectmanagement.Response;
|
||||
import com.waterquality.projectmanagement.dto.facility.FacilityCreateDTO;
|
||||
import com.waterquality.projectmanagement.dto.facility.FacilityVO;
|
||||
import com.waterquality.projectmanagement.entity.facility.FacilityStatus;
|
||||
import com.waterquality.projectmanagement.entity.facility.FacilityType;
|
||||
import com.waterquality.projectmanagement.service.FacilityService;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.*;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.web.PageableDefault;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
// FacilityController.java
|
||||
@RestController
|
||||
@RequestMapping("/api/facilities")
|
||||
@RequiredArgsConstructor
|
||||
public class FacilityController {
|
||||
|
||||
private final FacilityService facilityService;
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<Response<FacilityVO>> create(
|
||||
@Valid @RequestBody FacilityCreateDTO dto) {
|
||||
return ResponseEntity.ok(Response.newSuccess(facilityService.createFacility(dto)));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public ResponseEntity<Response<FacilityVO>> getById(@PathVariable Integer id) {
|
||||
return ResponseEntity.ok(Response.newSuccess(
|
||||
facilityService.convertToVO(facilityService.getFacilityById(id))));
|
||||
}
|
||||
|
||||
@GetMapping("/search")
|
||||
public ResponseEntity<Response<Page<FacilityVO>>> search(
|
||||
@RequestParam(required = false) FacilityType type,
|
||||
@RequestParam(required = false) FacilityStatus status,
|
||||
@RequestParam(required = false) String area,
|
||||
@PageableDefault Pageable pageable) {
|
||||
return ResponseEntity.ok(Response.newSuccess(
|
||||
facilityService.searchFacilities(type, status, area, pageable)));
|
||||
}
|
||||
|
||||
|
||||
@PatchMapping("/{id}/status")
|
||||
public ResponseEntity<Response<Void>> updateStatus(
|
||||
@PathVariable Integer id,
|
||||
@RequestParam @NotNull FacilityStatus status) {
|
||||
facilityService.updateStatus(id, status);
|
||||
return ResponseEntity.ok(Response.newSuccess(null));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package com.waterquality.projectmanagement.dto.facility;
|
||||
|
||||
import com.waterquality.projectmanagement.entity.facility.FacilityType;
|
||||
import lombok.*;
|
||||
import org.hibernate.validator.constraints.Range;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.*;
|
||||
import java.time.LocalDate;
|
||||
|
||||
@Data
|
||||
public class FacilityCreateDTO {
|
||||
@NotBlank(message = "设施编码不能为空")
|
||||
@Size(max = 30, message = "编码长度不能超过30字符")
|
||||
private String code;
|
||||
|
||||
@NotNull(message = "设施类型不能为空")
|
||||
private FacilityType type;
|
||||
|
||||
@NotNull(message = "经度不能为空")
|
||||
@Range(min = -180, max = 180, message = "经度范围错误")
|
||||
private Double longitude;
|
||||
|
||||
@NotNull(message = "纬度不能为空")
|
||||
@Range(min = -90, max = 90, message = "纬度范围错误")
|
||||
private Double latitude;
|
||||
|
||||
@NotBlank(message = "所属区域不能为空")
|
||||
private String area;
|
||||
|
||||
@NotNull(message = "管理部门不能为空")
|
||||
private Integer deptId;
|
||||
|
||||
@FutureOrPresent(message = "安装日期不能早于当前日期")
|
||||
private LocalDate installDate;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.waterquality.projectmanagement.dto.facility;
|
||||
|
||||
import com.waterquality.projectmanagement.entity.facility.FacilityStatus;
|
||||
import com.waterquality.projectmanagement.entity.facility.FacilityType;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
// FacilityVO.java
|
||||
@Data
|
||||
public class FacilityVO {
|
||||
private Integer id;
|
||||
private String code;
|
||||
private FacilityType type;
|
||||
private String location;
|
||||
private String area;
|
||||
private FacilityStatus status;
|
||||
private String deptName;
|
||||
private LocalDate installDate;
|
||||
private LocalDate lastMaintainDate;
|
||||
|
||||
}
|
||||
|
|
@ -1,7 +1,11 @@
|
|||
package com.waterquality.projectmanagement.entity.facility;
|
||||
|
||||
import com.waterquality.projectmanagement.entity.department.Department;
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
import org.locationtech.jts.geom.Coordinate;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
@Entity
|
||||
@Table(name = "facilities")
|
||||
|
|
@ -22,8 +26,7 @@ public class Facility {
|
|||
@Column(name = "facility_type", nullable = false)
|
||||
private FacilityType type;
|
||||
|
||||
@Column(columnDefinition = "POINT SRID 4326 NOT NULL")
|
||||
private Point location;
|
||||
private String location;
|
||||
|
||||
@Column(nullable = false, length = 100)
|
||||
private String area;
|
||||
|
|
@ -33,7 +36,7 @@ public class Facility {
|
|||
private FacilityStatus status = FacilityStatus.NORMAL;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "responsible_dept", nullable = false)
|
||||
@JoinColumn(name = "responsible_dept", nullable = true)
|
||||
private Department responsibleDept;
|
||||
|
||||
@Column(name = "install_date")
|
||||
|
|
@ -43,20 +46,6 @@ public class Facility {
|
|||
private LocalDate lastMaintainDate;
|
||||
|
||||
// 空间坐标转换方法
|
||||
public void setCoordinates(Double lng, Double lat) {
|
||||
this.location = GeometryUtils.createPoint(lng, lat);
|
||||
|
||||
}
|
||||
|
||||
public Coordinate getCoordinate() {
|
||||
return this.location.getCoordinate();
|
||||
}
|
||||
}
|
||||
|
||||
// 空间工具类
|
||||
public class GeometryUtils {
|
||||
private static final GeometryFactory GEOMETRY_FACTORY = new GeometryFactory();
|
||||
|
||||
public static Point createPoint(Double lng, Double lat) {
|
||||
return GEOMETRY_FACTORY.createPoint(new Coordinate(lng, lat));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package com.waterquality.projectmanagement.repository;
|
||||
|
||||
import com.waterquality.projectmanagement.entity.department.Department;
|
||||
import com.waterquality.projectmanagement.entity.facility.Facility;
|
||||
import com.waterquality.projectmanagement.entity.facility.FacilityStatus;
|
||||
import com.waterquality.projectmanagement.entity.facility.FacilityType;
|
||||
import org.locationtech.jts.geom.Polygon;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
// FacilityRepository.java
|
||||
public interface FacilityRepository extends JpaRepository<Facility, Integer> {
|
||||
|
||||
// 根据编码查询
|
||||
Optional<Facility> findByCode(String code);
|
||||
|
||||
// 空间范围查询(使用HQL)
|
||||
// @Query("SELECT f FROM Facility f WHERE within(f.location, :polygon) = true")
|
||||
// List<Facility> findWithinArea(@Param("polygon") Polygon polygon);
|
||||
|
||||
// 状态统计(使用原生SQL)
|
||||
@Query(value = "SELECT status, COUNT(*) as count FROM facilities GROUP BY status",
|
||||
nativeQuery = true)
|
||||
List<Map<String, Object>> countByStatus();
|
||||
|
||||
// 分页查询
|
||||
Page<Facility> findByResponsibleDept(Department dept, Pageable pageable);
|
||||
|
||||
// 复杂条件查询
|
||||
@Query("SELECT f FROM Facility f WHERE " +
|
||||
"(:type IS NULL OR f.type = :type) AND " +
|
||||
"(:status IS NULL OR f.status = :status) AND " +
|
||||
"(:area IS NULL OR f.area LIKE %:area%)")
|
||||
Page<Facility> search(
|
||||
@Param("type") FacilityType type,
|
||||
@Param("status") FacilityStatus status,
|
||||
@Param("area") String area,
|
||||
Pageable pageable
|
||||
);
|
||||
|
||||
boolean existsByCode(String code);
|
||||
}
|
||||
|
|
@ -53,4 +53,8 @@ public class DepartmentService {
|
|||
return departmentRepository.findById(id)
|
||||
.orElseThrow(() -> new ResourceNotFoundException("部门不存在"));
|
||||
}
|
||||
|
||||
public Optional<Department> getDepartmentById(Integer deptId) {
|
||||
return departmentRepository.findById(deptId);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
package com.waterquality.projectmanagement.service;
|
||||
|
||||
import com.waterquality.projectmanagement.dto.facility.FacilityCreateDTO;
|
||||
import com.waterquality.projectmanagement.dto.facility.FacilityVO;
|
||||
import com.waterquality.projectmanagement.entity.facility.Facility;
|
||||
import com.waterquality.projectmanagement.entity.facility.FacilityStatus;
|
||||
import com.waterquality.projectmanagement.entity.facility.FacilityType;
|
||||
import com.waterquality.projectmanagement.exception.ResourceNotFoundException;
|
||||
import com.waterquality.projectmanagement.repository.FacilityRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
// FacilityService.java
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class FacilityService {
|
||||
|
||||
private final FacilityRepository facilityRepository;
|
||||
|
||||
@Transactional
|
||||
public FacilityVO createFacility(FacilityCreateDTO dto) {
|
||||
// 校验编码唯一性
|
||||
if (facilityRepository.existsByCode(dto.getCode())) {
|
||||
throw new ResourceNotFoundException("设施编码已存在");
|
||||
}
|
||||
|
||||
// 构建实体
|
||||
Facility facility = new Facility();
|
||||
facility.setCode(dto.getCode());
|
||||
facility.setType(dto.getType());
|
||||
facility.setArea(dto.getArea());
|
||||
facility.setInstallDate(dto.getInstallDate());
|
||||
|
||||
|
||||
// 保存设施
|
||||
Facility saved = facilityRepository.save(facility);
|
||||
return convertToVO(saved);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public Page<FacilityVO> searchFacilities(FacilityType type,
|
||||
FacilityStatus status,
|
||||
String area,
|
||||
Pageable pageable) {
|
||||
return facilityRepository.search(type, status, area, pageable)
|
||||
.map(this::convertToVO);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void updateStatus(Integer facilityId, FacilityStatus status) {
|
||||
Facility facility = getFacilityById(facilityId);
|
||||
if (facility.getStatus() != status) {
|
||||
facility.setStatus(status);
|
||||
facilityRepository.save(facility);
|
||||
log.info("设施状态更新:{} -> {}", facility.getCode(), status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Facility getFacilityById(Integer id) {
|
||||
return facilityRepository.findById(id)
|
||||
.orElseThrow(() -> new ResourceNotFoundException("设施不存在"));
|
||||
}
|
||||
|
||||
public FacilityVO convertToVO(Facility facility) {
|
||||
FacilityVO facilityVO = new FacilityVO();
|
||||
facilityVO.setId(facility.getId());
|
||||
facilityVO.setCode(facility.getCode());
|
||||
facilityVO.setType(facility.getType());
|
||||
|
||||
// 设置地理位置
|
||||
|
||||
facilityVO.setArea(facility.getArea());
|
||||
facilityVO.setStatus(facility.getStatus());
|
||||
facilityVO.setInstallDate(facility.getInstallDate());
|
||||
facilityVO.setLastMaintainDate(facility.getLastMaintainDate());
|
||||
|
||||
return facilityVO;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue