feat(device): refactor device management API and implement CRUD operations

- Rename CreateDriveRequest to CreateDeviceRequest
- Add DeviceQueryRequest for pagination and filtering
- Add UpdateDeviceRequest for device updates
- Refactor DeviceController with RESTful endpoints
- Implement getAllDevices with pagination and search
- Implement createDevice endpoint
- Implement updateDevice endpoint
- Implement deleteDevice endpoint
- Remove real delete endpoint
- Add DeviceResponse and OptionResponse DTOs
- Update DeviceService interface and implementation
- Add device type options endpoint
- Update device type controller mappings
This commit is contained in:
Chaos
2025-11-27 17:11:57 +08:00
parent 79ef40bd34
commit af8959220a
11 changed files with 231 additions and 33 deletions

View File

@@ -7,7 +7,7 @@ import lombok.Data;
import java.time.LocalDate; import java.time.LocalDate;
@Data @Data
public class CreateDriveRequest { public class CreateDeviceRequest {
//限制必填 不限制特殊字符 //限制必填 不限制特殊字符
@NotBlank(message = "设备名称不能为空") @NotBlank(message = "设备名称不能为空")
private String name; private String name;

View File

@@ -0,0 +1,12 @@
package cn.nopj.chaos_api.dto.request;
import lombok.Data;
@Data
public class DeviceQueryRequest {
private Integer pageNum = 1;
private Integer pageSize = 10;
private Integer type;
private String keyword;
private String status;
}

View File

@@ -0,0 +1,22 @@
package cn.nopj.chaos_api.dto.request;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import lombok.Data;
import java.time.LocalDate;
@Data
public class UpdateDeviceRequest {
@NotBlank(message = "设备id不能为空")
private Long id;
private String name;
private String model;
private Long typeId;
private Long locationId;
private String snmpCommunity;
private String manufacturer;
private LocalDate purchaseDate;
private int status;
private String remark;
}

View File

@@ -0,0 +1,20 @@
package cn.nopj.chaos_api.dto.response;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OptionResponse {
/**
* 选项标签
*/
private String label;
/**
* 值
*/
private String value;
}

View File

@@ -1,15 +1,18 @@
package cn.nopj.chaos_api.service; package cn.nopj.chaos_api.service;
import cn.nopj.chaos_api.dto.request.CreateDriveRequest; import cn.nopj.chaos_api.dto.request.CreateDeviceRequest;
import cn.nopj.chaos_api.dto.request.DeviceQueryRequest;
import cn.nopj.chaos_api.dto.request.UpdateDeviceRequest;
import cn.nopj.chaos_api.dto.response.DeviceResponse; import cn.nopj.chaos_api.dto.response.DeviceResponse;
import com.baomidou.mybatisplus.core.metadata.IPage;
public interface DeviceService { public interface DeviceService {
/** /**
* 新建设备信息 * 新建设备信息
* @param createDriveRequest 设备信息 * @param createDeviceRequest 设备信息
* @return 新建设备信息结果 * @return 新建设备信息结果
*/ */
DeviceResponse createDevice(CreateDriveRequest createDriveRequest); DeviceResponse createDevice(CreateDeviceRequest createDeviceRequest);
/** /**
* 根据id查询设备信息 * 根据id查询设备信息
@@ -29,4 +32,17 @@ public interface DeviceService {
* @param id 设备id * @param id 设备id
*/ */
void deleteDeviceReal(Long id); void deleteDeviceReal(Long id);
/**
* 查询所有设备信息
* @return 所有设备信息
*/
IPage<DeviceResponse> getAllDevices(DeviceQueryRequest request);
/**
* 更新设备信息
* @param updateDeviceRequest 设备信息
* @return 更新设备信息结果
*/
DeviceResponse updateDevice(UpdateDeviceRequest updateDeviceRequest);
} }

View File

@@ -1,6 +1,7 @@
package cn.nopj.chaos_api.service; package cn.nopj.chaos_api.service;
import cn.nopj.chaos_api.dto.response.DeviceTypeResponse; import cn.nopj.chaos_api.dto.response.DeviceTypeResponse;
import cn.nopj.chaos_api.dto.response.OptionResponse;
import java.util.List; import java.util.List;
@@ -10,4 +11,10 @@ public interface DeviceTypeService {
* @return 所有设备类型 * @return 所有设备类型
*/ */
List<DeviceTypeResponse> getAllDeviceTypes(); List<DeviceTypeResponse> getAllDeviceTypes();
/**
* 获取设备类型选项
* @return 设备类型选项
*/
List<OptionResponse> getDeviceTypeOptions();
} }

View File

@@ -3,31 +3,39 @@ package cn.nopj.chaos_api.service.impl;
import cn.nopj.chaos_api.common.constants.ErrorCode; import cn.nopj.chaos_api.common.constants.ErrorCode;
import cn.nopj.chaos_api.common.exceotion.BizException; import cn.nopj.chaos_api.common.exceotion.BizException;
import cn.nopj.chaos_api.domain.entity.Device; import cn.nopj.chaos_api.domain.entity.Device;
import cn.nopj.chaos_api.dto.request.CreateDriveRequest; import cn.nopj.chaos_api.dto.request.CreateDeviceRequest;
import cn.nopj.chaos_api.dto.request.DeviceQueryRequest;
import cn.nopj.chaos_api.dto.request.UpdateDeviceRequest;
import cn.nopj.chaos_api.dto.response.DeviceResponse; import cn.nopj.chaos_api.dto.response.DeviceResponse;
import cn.nopj.chaos_api.mapper.DeviceMapper; import cn.nopj.chaos_api.mapper.DeviceMapper;
import cn.nopj.chaos_api.service.DeviceService; import cn.nopj.chaos_api.service.DeviceService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.util.Objects;
@Service @Service
@Slf4j @Slf4j
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements DeviceService { public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements DeviceService {
@Override @Override
@Transactional @Transactional
public DeviceResponse createDevice(CreateDriveRequest createDriveRequest) { public DeviceResponse createDevice(CreateDeviceRequest createDeviceRequest) {
Device device = new Device(); Device device = new Device();
device.setName(createDriveRequest.getName()); device.setName(createDeviceRequest.getName());
device.setModel(createDriveRequest.getModel()); device.setModel(createDeviceRequest.getModel());
device.setTypeId(createDriveRequest.getTypeId()); device.setTypeId(createDeviceRequest.getTypeId());
device.setLocationId(createDriveRequest.getLocationId()); device.setLocationId(createDeviceRequest.getLocationId());
device.setSnmpCommunity(createDriveRequest.getSnmpCommunity()); device.setSnmpCommunity(createDeviceRequest.getSnmpCommunity());
device.setManufacturer(createDriveRequest.getManufacturer()); device.setManufacturer(createDeviceRequest.getManufacturer());
device.setPurchaseDate(createDriveRequest.getPurchaseDate()); device.setPurchaseDate(createDeviceRequest.getPurchaseDate());
device.setStatus(createDriveRequest.getStatus()); device.setStatus(createDeviceRequest.getStatus());
device.setRemark(createDriveRequest.getRemark()); device.setRemark(createDeviceRequest.getRemark());
int rows = this.baseMapper.insert(device); int rows = this.baseMapper.insert(device);
if (rows > 0){ if (rows > 0){
@@ -70,4 +78,86 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
} }
log.info("删除设备成功"); log.info("删除设备成功");
} }
public IPage<DeviceResponse> getAllDevices(DeviceQueryRequest request) {
if (request == null) {
request = new DeviceQueryRequest();
}
long current = Objects.requireNonNullElse(request.getPageNum(), 1);
long size = Objects.requireNonNullElse(request.getPageSize(), 10);
Page<Device> page = new Page<>(current, size);
LambdaQueryWrapper<Device> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(request.getType() != null && request.getType() > 0, Device::getTypeId, request.getType());
if (StringUtils.hasText(request.getKeyword())) {
String keyword = request.getKeyword();
wrapper.and(w -> w
.like(Device::getName, keyword)
.or()
.like(Device::getModel, keyword)
.or()
.like(Device::getManufacturer, keyword)
.or()
.like(Device::getRemark, keyword)
.or()
.like(Device::getSnmpCommunity, keyword)
);
}
IPage<Device> deviceIPage = this.baseMapper.selectPage(page, wrapper);
return deviceIPage.convert(DeviceResponse::new);
}
@Override
public DeviceResponse updateDevice(UpdateDeviceRequest updateDeviceRequest) {
Device device = new Device();
//判断各字段是否为空 不为空再更新
if (updateDeviceRequest.getId() != null){
device.setId(updateDeviceRequest.getId());
}
if (updateDeviceRequest.getName() != null){
device.setName(updateDeviceRequest.getName());
}
if (updateDeviceRequest.getModel() != null){
device.setModel(updateDeviceRequest.getModel());
}
if (updateDeviceRequest.getTypeId() != null){
device.setTypeId(updateDeviceRequest.getTypeId());
}
if (updateDeviceRequest.getLocationId() != null){
device.setLocationId(updateDeviceRequest.getLocationId());
}
if (updateDeviceRequest.getSnmpCommunity() != null){
device.setSnmpCommunity(updateDeviceRequest.getSnmpCommunity());
}
if (updateDeviceRequest.getManufacturer() != null){
device.setManufacturer(updateDeviceRequest.getManufacturer());
}
if (updateDeviceRequest.getPurchaseDate() != null){
device.setPurchaseDate(updateDeviceRequest.getPurchaseDate());
}
if (updateDeviceRequest.getStatus() >= 0 && updateDeviceRequest.getStatus() <= 2){
device.setStatus(updateDeviceRequest.getStatus());
}
if (updateDeviceRequest.getRemark() != null){
device.setRemark(updateDeviceRequest.getRemark());
}
int rows = this.baseMapper.updateById(device);
if (rows > 0){
return new DeviceResponse(device);
}else {
throw new BizException("更新设备失败");
}
}
} }

View File

@@ -4,8 +4,10 @@ import cn.nopj.chaos_api.common.constants.ErrorCode;
import cn.nopj.chaos_api.common.exceotion.BizException; import cn.nopj.chaos_api.common.exceotion.BizException;
import cn.nopj.chaos_api.domain.entity.DeviceType; import cn.nopj.chaos_api.domain.entity.DeviceType;
import cn.nopj.chaos_api.dto.response.DeviceTypeResponse; import cn.nopj.chaos_api.dto.response.DeviceTypeResponse;
import cn.nopj.chaos_api.dto.response.OptionResponse;
import cn.nopj.chaos_api.mapper.DriveTypeMapper; import cn.nopj.chaos_api.mapper.DriveTypeMapper;
import cn.nopj.chaos_api.service.DeviceTypeService; import cn.nopj.chaos_api.service.DeviceTypeService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -22,4 +24,16 @@ public class DeviceTypeServiceImpl extends ServiceImpl<DriveTypeMapper, DeviceTy
} }
return deviceTypes.stream().map(DeviceTypeResponse::new).toList(); return deviceTypes.stream().map(DeviceTypeResponse::new).toList();
} }
@Override
public List<OptionResponse> getDeviceTypeOptions() {
LambdaQueryWrapper<DeviceType> wrapper = new LambdaQueryWrapper<>();
return this.lambdaQuery()
.select(DeviceType::getId, DeviceType::getName)
//todo
;
}
} }

View File

@@ -1,10 +1,13 @@
package cn.nopj.chaos_api.controller; package cn.nopj.chaos_api.controller;
import cn.nopj.chaos_api.dto.request.CreateDriveRequest; import cn.nopj.chaos_api.dto.request.CreateDeviceRequest;
import cn.nopj.chaos_api.dto.request.DeviceQueryRequest;
import cn.nopj.chaos_api.dto.request.UpdateDeviceRequest;
import cn.nopj.chaos_api.dto.response.DeviceResponse; import cn.nopj.chaos_api.dto.response.DeviceResponse;
import cn.nopj.chaos_api.model.ApiResult; import cn.nopj.chaos_api.model.ApiResult;
import cn.nopj.chaos_api.service.DeviceService; import cn.nopj.chaos_api.service.DeviceService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@@ -14,7 +17,7 @@ import org.springframework.web.bind.annotation.*;
* 设备管理 * 设备管理
*/ */
@RestController @RestController
@RequestMapping("/api/device") @RequestMapping("/api/devices")
public class DeviceController { public class DeviceController {
private final DeviceService deviceService; private final DeviceService deviceService;
@@ -23,14 +26,24 @@ public class DeviceController {
this.deviceService = deviceService; this.deviceService = deviceService;
} }
/**
* 查询所有设备信息
* @return 所有设备信息
*/
@GetMapping
public ApiResult<IPage<DeviceResponse>> getAllDevices(DeviceQueryRequest request){
return ApiResult.success(deviceService.getAllDevices(request));
}
/** /**
* 新建设备信息 * 新建设备信息
* @param createDriveRequest 设备信息 * @param createDeviceRequest 设备信息
* @return 新建设备信息结果 * @return 新建设备信息结果
*/ */
@PostMapping("/create") @PostMapping
public ApiResult<DeviceResponse> createDevice(@RequestBody @Validated CreateDriveRequest createDriveRequest){ public ApiResult<DeviceResponse> createDevice(@RequestBody @Validated CreateDeviceRequest createDeviceRequest){
return ApiResult.success(deviceService.createDevice(createDriveRequest)); return ApiResult.success(deviceService.createDevice(createDeviceRequest));
} }
/** /**
@@ -43,7 +56,7 @@ public class DeviceController {
} }
/** /**
* 逻辑删除指定设备信息 * 删除指定设备信息
* @return 逻辑删除指定设备信息结果 * @return 逻辑删除指定设备信息结果
*/ */
@DeleteMapping("/{id}") @DeleteMapping("/{id}")
@@ -51,16 +64,13 @@ public class DeviceController {
deviceService.deleteDevice(id); deviceService.deleteDevice(id);
return ApiResult.success("删除成功"); return ApiResult.success("删除成功");
} }
/** /**
* 真实删除指定设备信息 * 修改指定设备信息
* @return 真实删除指定设备信息结果 * @return 修改指定设备信息结果
*/ */
@PreAuthorize("hasAuthority('admin')") @PutMapping({"/{id}"})
@DeleteMapping("/deleteReal") public ApiResult<DeviceResponse> updateDevice(@RequestBody @Validated UpdateDeviceRequest updateDeviceRequest){
public ApiResult<String> deleteDeviceReal(@RequestParam(value = "id") Long id){ return ApiResult.success(deviceService.updateDevice(updateDeviceRequest));
deviceService.deleteDeviceReal(id);
return ApiResult.success("删除成功");
} }
} }

View File

@@ -1,8 +1,10 @@
package cn.nopj.chaos_api.controller; package cn.nopj.chaos_api.controller;
import cn.nopj.chaos_api.dto.response.DeviceTypeResponse; import cn.nopj.chaos_api.dto.response.DeviceTypeResponse;
import cn.nopj.chaos_api.dto.response.OptionResponse;
import cn.nopj.chaos_api.model.ApiResult; import cn.nopj.chaos_api.model.ApiResult;
import cn.nopj.chaos_api.service.DeviceTypeService; import cn.nopj.chaos_api.service.DeviceTypeService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@@ -14,7 +16,7 @@ import java.util.List;
* @author nopj * @author nopj
*/ */
@RestController @RestController
@RequestMapping("/api/deviceType") @RequestMapping("/api/device-types")
public class DeviceTypeController { public class DeviceTypeController {
private final DeviceTypeService deviceTypeService; private final DeviceTypeService deviceTypeService;
@@ -22,14 +24,18 @@ public class DeviceTypeController {
this.deviceTypeService = deviceTypeService; this.deviceTypeService = deviceTypeService;
} }
/** /**
* 获取所有设备类型 * 获取所有设备类型
* *
* @return 所有设备类型 * @return 所有设备类型
*/ */
@RequestMapping("/all") @GetMapping
public ApiResult<List<DeviceTypeResponse>> getAllDeviceTypes() { public ApiResult<List<DeviceTypeResponse>> getAllDeviceTypes() {
return ApiResult.success(deviceTypeService.getAllDeviceTypes()); return ApiResult.success(deviceTypeService.getAllDeviceTypes());
} }
@GetMapping("/options")
public ApiResult<List<OptionResponse>> getDeviceTypeOptions() {
return ApiResult.success(deviceTypeService.getDeviceTypeOptions());
}
} }

View File

@@ -92,4 +92,5 @@ public class UserController {
ApiResult<UserProfileResponse> setNickname(@PathVariable Long userId, @RequestBody @Validated SetUserNicknameRequest request){ ApiResult<UserProfileResponse> setNickname(@PathVariable Long userId, @RequestBody @Validated SetUserNicknameRequest request){
return ApiResult.success(userProfileService.setUserNickname(userId,request.getNickname())); return ApiResult.success(userProfileService.setUserNickname(userId,request.getNickname()));
} }
} }