提交 76a93dbb 作者: 谭志磊

feat : 新增监控点位管理功能, 参数校验注解无效

上级 306331f2
......@@ -9,6 +9,8 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-amqp'
implementation 'org.springframework.boot:spring-boot-starter-validation'
// 💬 Mock/Test Env
runtimeOnly 'com.h2database:h2'
// 💬 Prod/Dev Env
......@@ -24,7 +26,7 @@ dependencies {
// Optional: Doc
implementation project(":basic-common:doc")
implementation "io.swagger:swagger-annotations:${swaggerAnnotationsVersion}"
implementation "org.hibernate.validator:hibernate-validator:${hibernateValidatorVersion}"
// implementation "org.hibernate.validator:hibernate-validator:${hibernateValidatorVersion}"
// Optional: Auth
implementation project(":basic-auth")
......
......@@ -44,24 +44,33 @@ public class Video implements Serializable {
@Comment("坐标点信息")
Point point;
@Comment("分类")
String type;
@Comment("标识")
String uuid;
@Comment("rtsp 媒体地址")
String rtsp;
@Comment("m3u8 地址")
String m3u8;
@Comment("备注")
String remark;
@Comment("创建时间")
LocalDateTime createTime;
@Comment("状态")
String status;
@Comment("摄像头名称")
String videoName;
@Comment("分类")
String type;
@Comment("rtsp 媒体地址")
String rtsp;
@Comment("是否在线")
Boolean online;
@Comment("是否启用")
Boolean enable;
@Comment("创建时间")
LocalDateTime createTime;
}
......@@ -3,6 +3,7 @@ package com.yiring.app.domain.video;
import java.io.Serializable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
/**
......@@ -12,4 +13,4 @@ import org.springframework.stereotype.Repository;
*/
@Repository
public interface VideoRepository extends JpaRepository<Video, Serializable> {}
public interface VideoRepository extends JpaRepository<Video, Serializable>, JpaSpecificationExecutor<Video> {}
......@@ -55,7 +55,7 @@ public class CarParam {
@ApiModelProperty(value = "来访原因", example = "视察", required = true)
@NotEmpty(message = "来访原因不能为空")
@Size(min = 2, max = 20, message = "来访原因超出范围")
@Size(min = 1, max = 20, message = "来访原因超出范围")
String reason;
// @ApiModelProperty(value = "收卡时间", example = "2022-04-11 17:25:33")
// LocalDateTime cardRecTime;
......
......@@ -38,6 +38,6 @@ public class DictParam {
@NotEmpty(message = "是否启用必填")
String status;
@ApiModelProperty(value = "备注", example = "性别", required = true)
@ApiModelProperty(value = "备注", example = "性别")
String remark;
}
......@@ -5,9 +5,9 @@ import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import lombok.*;
import lombok.experimental.FieldDefaults;
import org.locationtech.jts.geom.Point;
/**
* 监控视频入参类
......@@ -23,27 +23,41 @@ import org.locationtech.jts.geom.Point;
@FieldDefaults(level = AccessLevel.PRIVATE)
public class VideoParam implements Serializable {
@ApiModelProperty(value = "标识", example = "", required = true)
@ApiModelProperty(value = "编号", example = "88888888", required = true)
@NotEmpty(message = "标识不能为空")
String uuid;
@ApiModelProperty(value = "rtsp 媒体地址", example = "", required = true)
@NotEmpty(message = "rtsp 媒体地址不能为空")
String rtsp;
@ApiModelProperty(value = "m3u8 地址", example = "")
@NotEmpty(message = "m3u8 地址不能为空")
@ApiModelProperty(value = "m3u8 媒体地址", example = "", required = true)
@NotEmpty(message = "m3u8 媒体地址不能为空")
String m3u8;
@ApiModelProperty(value = "坐标点信息", example = "")
Point point;
@ApiModelProperty(value = "摄像头名称", example = "摄像头1", required = true)
@NotEmpty(message = "摄像头名称不能为空")
String videoName;
@ApiModelProperty(value = "经度", example = "1", required = true)
@NotEmpty(message = "经度")
double lon;
@ApiModelProperty(value = "纬度", example = "1", required = true)
@NotEmpty(message = "纬度")
double lat;
@ApiModelProperty(value = "备注", example = "厂区摄像头")
@Size(max = 100, message = "备注不能超过100字")
String remark;
// @ApiModelProperty(value = "m3u8 地址", example = "")
// @NotEmpty(message = "m3u8 地址不能为空")
// String m3u8;
// Point point;
@ApiModelProperty(value = "分类", example = "")
String type;
// @ApiModelProperty(value = "分类", example = "")
// String type;
@ApiModelProperty(value = "是否在线", example = "")
Boolean online;
// @ApiModelProperty(value = "是否在线", example = "")
// Boolean online;
@ApiModelProperty(value = "是否启用", example = "")
Boolean enable;
// @ApiModelProperty(value = "是否启用", example = "")
// Boolean enable;
}
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.param.video;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import lombok.*;
import lombok.experimental.FieldDefaults;
/**
* 监控视频入参类
*
* @author tzl
* 2022/4/8 16:07
*/
@ApiModel("VideoQueryParam")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class VideoQueryParam implements Serializable {
@ApiModelProperty(value = "编号", example = "88888888")
String uuid;
@ApiModelProperty(value = "摄像头名称", example = "摄像头1")
String videoName;
@ApiModelProperty(value = "状态", example = "1")
String status;
// @ApiModelProperty(value = "m3u8 地址", example = "")
// @NotEmpty(message = "m3u8 地址不能为空")
// String m3u8;
// Point point;
// @ApiModelProperty(value = "分类", example = "")
// String type;
// @ApiModelProperty(value = "是否在线", example = "")
// Boolean online;
// @ApiModelProperty(value = "是否启用", example = "")
// Boolean enable;
}
......@@ -74,7 +74,7 @@ public class CarServiceImpl implements CarService {
}
Car car = optional.get();
//如果标签卡在使用中无法修改
if (StringUtils.isNotBlank(car.getLabelCardStatus()) && "使用中".equals(car.getLabelCardStatus())) {
if (StringUtils.isNotBlank(car.getLabelCardStatus()) && "2".equals(car.getLabelCardStatus())) {
return Result.no(Status.BAD_REQUEST, "标签卡使用中,信息无法修改");
}
if (!car.getCarNum().equals(carParam.getCarNum())) {
......@@ -130,7 +130,7 @@ public class CarServiceImpl implements CarService {
//正在使用中的信息无法删除
Car entity = optional.get();
if ("使用中".equals(entity.getLabelCardStatus())) {
if ("2".equals(entity.getLabelCardStatus())) {
return Result.no(Status.BAD_REQUEST, "标签卡使用中,信息无法删除");
}
carRepository.delete(entity);
......@@ -172,18 +172,18 @@ public class CarServiceImpl implements CarService {
@Override
public boolean hasCarInfoByCarNum(String param) {
Car entity = Car.builder().carNum(param).labelCardStatus("未发卡").build();
Car entity = Car.builder().carNum(param).labelCardStatus("1").build();
long count = carRepository.count(Example.of(entity));
entity = Car.builder().carNum(param).labelCardStatus("使用中").build();
entity = Car.builder().carNum(param).labelCardStatus("2").build();
long count1 = carRepository.count(Example.of(entity));
return count + count1 > 0;
}
@Override
public boolean hasCarInfoByMobile(String param) {
Car entity = Car.builder().driverMobile(param).labelCardStatus("未发卡").build();
Car entity = Car.builder().driverMobile(param).labelCardStatus("1").build();
long count = carRepository.count(Example.of(entity));
entity = Car.builder().driverMobile(param).labelCardStatus("使用中").build();
entity = Car.builder().driverMobile(param).labelCardStatus("2").build();
long count1 = carRepository.count(Example.of(entity));
return count + count1 > 0;
}
......
......@@ -120,7 +120,6 @@ public class DictServiceImpl implements DictService {
if (hasValue(dictParam.getDictType(), dictParam.getDictValue())) {
return Result.no(Status.BAD_REQUEST, "该类型,字典值已存在");
}
Dict dict = new Dict();
dict.setCreateTime(LocalDateTime.now());
BeanUtils.copyProperties(dictParam, dict);
......
......@@ -2,7 +2,14 @@
package com.yiring.app.service.video;
import com.yiring.app.param.video.VideoParam;
import com.yiring.app.param.video.VideoQueryParam;
import com.yiring.app.vo.video.VideoVo;
import com.yiring.common.core.Result;
import com.yiring.common.param.IdParam;
import com.yiring.common.param.PageParam;
import com.yiring.common.vo.PageVo;
import java.awt.*;
import org.locationtech.jts.geom.Point;
/**
* @author tzl
......@@ -11,10 +18,49 @@ import com.yiring.common.core.Result;
public interface VideoService {
/**
* 监控视频点位添加
*
* @param videoParam VideoParam
* @return Result<String>
* @author tzl
* @date 2022/4/8 16:23
*/
Result<String> saveVideo(VideoParam videoParam);
/**
* 删除监控点位信息
* @param idParam 主键id
* @return Result<String>
* @author tzl
* @date 2022/4/15 10:16
*/
Result<String> deleteVideo(IdParam idParam);
/**
* 修改监控点位信息
* @param videoParam 修改的参数
* @param idParam 主键id
* @return Result<String>
* @author tzl
* @date 2022/4/15 10:19
*/
Result<String> updateVideo(VideoParam videoParam, IdParam idParam);
/**
* 查询监控点坐标
* @param idParam 主键id
* @return Result<Point> 坐标信息
* @author tzl
* @date 2022/4/15 14:15
*/
Result<Point> selectPoint(IdParam idParam);
/**
* 分页查询
* @param videoQueryParam 筛选条件
* @param param 分页参数
* @return Result<PageVo<VideoVo>> 分页结果集
* @author tzl
* @date 2022/4/15 14:35
*/
Result<PageVo<VideoVo>> pageVideo(VideoQueryParam videoQueryParam, PageParam param);
}
......@@ -4,10 +4,28 @@ package com.yiring.app.service.video.impl;
import com.yiring.app.domain.video.Video;
import com.yiring.app.domain.video.VideoRepository;
import com.yiring.app.param.video.VideoParam;
import com.yiring.app.param.video.VideoQueryParam;
import com.yiring.app.service.video.VideoService;
import com.yiring.app.util.GeoUtils;
import com.yiring.app.vo.video.VideoVo;
import com.yiring.common.core.Result;
import com.yiring.common.core.Status;
import com.yiring.common.param.IdParam;
import com.yiring.common.param.PageParam;
import com.yiring.common.util.StrUtils;
import com.yiring.common.vo.PageVo;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import org.locationtech.jts.geom.Point;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
/**
......@@ -22,18 +40,125 @@ public class VideoServiceImpl implements VideoService {
@Override
public Result<String> saveVideo(VideoParam videoParam) {
if (has(videoParam.getUuid())) {
return Result.no(Status.BAD_REQUEST, "您输入的编号已存在");
}
Video video = Video
.builder()
.createTime(LocalDateTime.now())
.enable(videoParam.getEnable())
// .enable(videoParam.getEnable())
// .m3u8(videoParam.getM3u8())
// .point(videoParam.getPoint())
.m3u8(videoParam.getM3u8())
.point(videoParam.getPoint())
.rtsp(videoParam.getRtsp())
.online(videoParam.getOnline())
.type(videoParam.getType())
.point(GeoUtils.createPoint(videoParam.getLon(), videoParam.getLat()))
// .online(videoParam.getOnline())
// .type(videoParam.getType())
//默认正常
.videoName(videoParam.getVideoName())
.status("1")
.remark(videoParam.getRemark())
.uuid(videoParam.getUuid())
.build();
videoRepository.saveAndFlush(video);
//还需要同步添加国标28181中对应的摄像头信息
//标识uuid对应流id,m3u8对应拉流地址,如m3u8中有标注 则将类型切换为FFmpeg,摄像头名称videoName对应名称,流名称默认"stream",超时时间默认60
return Result.ok();
}
@Override
public Result<String> deleteVideo(IdParam idParam) {
Optional<Video> optional = videoRepository.findById(idParam.getId());
if (optional.isEmpty()) {
return Result.no(Status.NOT_FOUND);
}
Video video = optional.get();
videoRepository.delete(video);
//还需要同步删除国标28181中对应的摄像头信息
return Result.ok();
}
@Override
public Result<String> updateVideo(VideoParam videoParam, IdParam idParam) {
Optional<Video> optional = videoRepository.findById(idParam.getId());
if (optional.isEmpty()) {
return Result.no(Status.NOT_FOUND);
}
Video video = optional.get();
if (!video.getUuid().equals(videoParam.getUuid())) {
//当修改编号时
if (has(videoParam.getUuid())) {
return Result.no(Status.BAD_REQUEST, "您输入的编号已存在");
}
}
BeanUtils.copyProperties(videoParam, video);
videoRepository.saveAndFlush(video);
//还需要同步修改国标28181中对应的摄像头信息
return Result.ok();
}
@Override
public Result<Point> selectPoint(IdParam idParam) {
Optional<Video> optional = videoRepository.findById(idParam.getId());
if (optional.isEmpty()) {
return Result.no(Status.NOT_FOUND);
}
Video video = optional.get();
return Result.ok(video.getPoint());
}
@Override
public Result<PageVo<VideoVo>> pageVideo(VideoQueryParam videoQueryParam, PageParam param) {
Page<Video> all = videoRepository.findAll(condition(videoQueryParam), PageParam.toPageable(param));
List<VideoVo> data = all
.get()
.map(video -> {
VideoVo vo = new VideoVo();
BeanUtils.copyProperties(video, vo);
return vo;
})
.collect(Collectors.toList());
PageVo<VideoVo> vo = PageVo.build(data, all.getTotalElements());
return Result.ok(vo);
}
/**
* 条件查询
* @param videoQueryParam 筛选条件
* @return Specification
*/
public Specification<Video> condition(VideoQueryParam videoQueryParam) {
return (root, query, criteriaBuilder) -> {
List<Predicate> list = new ArrayList<>();
if (StrUtils.isNotBlank(videoQueryParam.getVideoName())) {
list.add(
criteriaBuilder.like(
root.get("videoName").as(String.class),
"%" + videoQueryParam.getVideoName() + "%"
)
);
}
if (StrUtils.isNotBlank(videoQueryParam.getUuid())) {
list.add(
criteriaBuilder.like(root.get("uuid").as(String.class), "%" + videoQueryParam.getUuid() + "%")
);
}
if (StrUtils.isNotBlank(videoQueryParam.getStatus())) {
list.add(criteriaBuilder.equal(root.get("uuid").as(String.class), videoQueryParam.getStatus()));
}
Predicate[] predicates = new Predicate[list.size()];
query.where(list.toArray(predicates));
return criteriaBuilder.and(list.toArray(predicates));
};
}
boolean has(String uuid) {
Video video = Video.builder().uuid(uuid).build();
return videoRepository.count(Example.of(video)) > 0;
}
}
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.util;
import lombok.experimental.UtilityClass;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
/**
* 空间函数工具类
*
* @author Jim
* @version 0.1
* 2022/4/15 9:52
*/
@SuppressWarnings({ "unused" })
@UtilityClass
public class GeoUtils {
private final GeometryFactory factory = new GeometryFactory();
/**
* 创建点
*
* @param lon 经度
* @param lat 纬度
* @return 点
*/
public Point createPoint(double lon, double lat) {
return factory.createPoint(new Coordinate(lon, lat));
}
}
/* (C) 2022 YiRing, Inc. */
package com.yiring.app.vo.video;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import lombok.*;
import lombok.experimental.FieldDefaults;
import org.locationtech.jts.geom.Point;
/**
* @author tzl
* 2022/4/15 10:48
*/
@ApiModel("VideoVo")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class VideoVo implements Serializable {
@ApiModelProperty(value = "坐标点信息", example = "")
Point point;
@ApiModelProperty(value = "编号", example = "88888888")
String uuid;
@ApiModelProperty(value = "m3u8地址", example = "")
String m3u8;
@ApiModelProperty(value = "备注", example = "摄像头")
String remark;
@ApiModelProperty(value = "摄像头名称", example = "摄像头1")
String videoName;
@ApiModelProperty(value = "状态", example = "正常")
String status;
}
......@@ -32,8 +32,8 @@ import org.springframework.web.bind.annotation.RestController;
* 2022/4/11 17:02
*/
@Slf4j
@Validated
@Api(tags = "Car")
@Validated
@RestController
@RequestMapping("/Car/")
public class CarController {
......
......@@ -2,13 +2,19 @@
package com.yiring.app.web.video;
import com.yiring.app.param.video.VideoParam;
import com.yiring.app.param.video.VideoQueryParam;
import com.yiring.app.service.video.VideoService;
import com.yiring.app.vo.video.VideoVo;
import com.yiring.common.core.Result;
import com.yiring.common.param.IdParam;
import com.yiring.common.param.PageParam;
import com.yiring.common.vo.PageVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import javax.annotation.Resource;
import javax.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.locationtech.jts.geom.Point;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
......@@ -29,9 +35,33 @@ public class VideoController {
@Resource
VideoService videoService;
@ApiOperation(value = "新增监控点位")
@ApiOperation(value = "新增监控点位信息")
@PostMapping("saveVideo")
public Result<String> findLatest(@Valid VideoParam videoParam) {
return videoService.saveVideo(videoParam);
}
@ApiOperation(value = "删除监控点位信息")
@PostMapping("deleteVideo")
public Result<String> deleteVideo(@Valid IdParam idParam) {
return videoService.deleteVideo(idParam);
}
@ApiOperation(value = "修改监控点位信息")
@PostMapping("updateVideo")
public Result<String> updateVideo(@Valid VideoParam videoParam, @Valid IdParam idParam) {
return videoService.updateVideo(videoParam, idParam);
}
@ApiOperation(value = "查看监控点位位置")
@PostMapping("selectPoint")
public Result<Point> selectPoint(@Valid IdParam idParam) {
return videoService.selectPoint(idParam);
}
@ApiOperation(value = "分页查询监控点位信息")
@PostMapping("pageVideo")
public Result<PageVo<VideoVo>> pageVideo(@Valid VideoQueryParam videoQueryParam, @Valid PageParam param) {
return videoService.pageVideo(videoQueryParam, param);
}
}
......@@ -54,6 +54,9 @@ public class Dict implements Serializable {
@Comment("状态(0正常 1停用)")
String status;
@Comment("备注")
String remark;
@Comment("创建时间")
LocalDateTime createTime;
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论