@FeignClient(name = "${self.job-center.apiclient.name}",
path = "${self.job-center.apiclient.path}",configuration = FeignInterceptor.class)
@RequestMapping(method = RequestMethod.POST)
public interface JobCenterApiClient {
@RequestMapping(value = "${self.job-center.apiclient.notifyJobResultUri}")
ApiResp<Void> notifyJobResult(JobResult result);
}
@Configuration
@EnableAsync
public class ThreadPoolConfig {
/**
* 获取当前机器的核数, 不一定准确 请根据实际场景 CPU密集 || IO 密集
*/
public static final int cpuNum = Runtime.getRuntime().availableProcessors();
// 核心线程池大小
@Value("${self.pool.corePoolSize}")
private Optional<Integer> corePoolSize;
// 最大可创建的线程数
@Value("${self.pool.maxPoolSize}")
private Optional<Integer> maxPoolSize;
// 队列最大长度
@Value("${self.pool.queueCapacity}")
private Optional<Integer> queueCapacity;
// 线程池维护线程所允许的空闲时间
@Value("${self.pool.keepAliveSeconds}")
private Optional<Integer> keepAliveSeconds;
@Bean(name = "selfThreadPoolTaskExecutor")
public ThreadPoolTaskExecutor threadPoolTaskExecutor()
{
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setMaxPoolSize(maxPoolSize.orElse(cpuNum * 2));
executor.setCorePoolSize(corePoolSize.orElse(cpuNum));
executor.setQueueCapacity(queueCapacity.orElse(500));
executor.setKeepAliveSeconds(keepAliveSeconds.orElse(300));
// 线程池对拒绝任务(无线程可用)的处理策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
@Bean(name = "constThreadPoolTaskExecutor")
public TaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 设置核心线程数
executor.setCorePoolSize(ThreadPoolConsts.Number.TWENTY);
// 设置最大线程数
executor.setMaxPoolSize(ThreadPoolConsts.Number.FIFTY);
// 设置队列容量
executor.setQueueCapacity(ThreadPoolConsts.Number.THREE_THOUSAND);
// 设置线程活跃时间(秒)
executor.setKeepAliveSeconds(ThreadPoolConsts.Number.SIX_HUNDRED);
// 设置默认线程名称
executor.setThreadNamePrefix(ThreadPoolConsts.Namefix.Thread_Name_Prefix);
// 设置拒绝策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 等待所有任务结束后再关闭线程池
executor.setWaitForTasksToCompleteOnShutdown(true);
return executor;
}
}
public interface ThreadPoolConsts {
interface Number {
// 代表无,不存在等
int MINUS_ONE = -1;
int MINUS_TWO = -2;
int ZERO = 0;
int ONE = 1;
int TWO = 2;
int THREE = 3;
int FOUR = 4;
int FIVE = 5;
int SIX = 6;
int SEVEN = 7;
int EIGHT = 8;
int NINE = 9;
int TEN = 10;
int TWENTY = 20;
int FIFTY = 50;
int ONE_HUNDRED = 100;
int TWO_HUNDRED = 200;
int SIX_HUNDRED = 600;
int THREE_THOUSAND = 3000;
}
interface Namefix {
String Thread_Name_Prefix = "async-task-";
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BaseResult {
@ApiModelProperty(value = "提示信息")
private String msg;
@ApiModelProperty(value = "错误码(200为成功)",example ="200")
private int code;
@ApiModelProperty(value = "是否成功")
public boolean isSuccess() {
return code == ResponseCode.SUCCESS.getCode();
}
}
@Data
@ApiModel(value="统一结果对象", description="")
public class Result<T> extends BaseResult{
private final static Result<?> EMPTY = new Result<>();
@ApiModelProperty(value = "响应数据对象")
private T data;
private Result() {
this.data = null;
}
private Result(T data, int code) {
super(null,code);
this.data = data;
}
private Result(String msg, int code) {
super(msg,code);
}
/**
*
* 功能描述: 创建一个空Result类
*/
public static <T> Result<T> empty() {
@SuppressWarnings("unchecked")
Result<T> t = (Result<T>) EMPTY;
return t;
}
/**
*
* 功能描述: 生成一个成功状态Result类
* @param: data
* @return: Result<T>
*/
public static <T> Result<T> success(T data) {
Result<T> result = new Result<>(data, ResponseCode.SUCCESS.getCode());
result.setMsg(ResponseCode.SUCCESS.getMsg());
return result;
}
public static <T> Result<T> success() {
return new Result<>(null, ResponseCode.SUCCESS.getCode());
}
public static <T> Result<T> fail(String message) {
return (Result<T>)new Result<>(message, ResponseCode.FAIL.getCode());
}
public static <T> Result<T> fail(ResultCode resultCode) {
return (Result<T>)new Result<>(resultCode.getMsg(), resultCode.getCode());
}
public static <T> Result<T> fail(int code,String message) {
return (Result<T>)new Result<>(message, code);
}
/**
*
* 功能描述: 判断是否传入值是否为空,非空则返回值,为空则返回失败信息
* @param: message 返回的错误信息
* @return: Result<T>
*/
public <T> Result<T> orFail(String message) {
if (null != data) {
return (Result<T>) this;
} else {
super.setMsg(getMsg());
super.setCode(ResponseCode.FAIL.getCode());
}
return (Result<T>) this;
}
}
@Getter
@AllArgsConstructor
public enum ResponseCode implements ResultCode{
FAIL(0,"失败!"),
SUCCESS(200,"成功"),
;
private final int code;
private final String msg;
}
public interface ResultCode extends Serializable {
/**
* 获取消息
*/
String getMsg();
/**
* 获取状态码
*/
int getCode();
}
/**
* 通用分页表单
*/
@Data
@ApiModel(value = "通用分页表单",description = "通用分页表单")
public class PageRequest {
@ApiModelProperty(value = "页码",required = true,example = "1")
private Integer pageNo = 1;
@ApiModelProperty(value = "页容量",required = true,example = "20")
private Integer pageSize = 20;
@ApiModelProperty(value = "起始记录的下标",hidden = true)
private Integer startIndex;
@ApiModelProperty(hidden = true,value = "最大页容量")
private Integer maxSize;
public Page convertPage(){
return new Page<>(getPageNo(), getPageSize());
}
public Integer getPageSize(){
if (maxSize != null && pageSize > maxSize){
pageSize = maxSize;
}
return pageSize;
}
public int getStartIndex(){
startIndex = (getPageNo() - 1) * getPageSize();
return startIndex;
}
}
@Data
public class PageResult<T> extends BaseResult{
private final static PageResult<?> EMPTY = new PageResult<>();
@ApiModelProperty(value = "分页对象")
private PageData<T> data;
private PageResult() {
this.data = null;
}
private PageResult(String message, int code) {
super(message,code);
}
private PageResult(ResultCode resultCode) {
super(resultCode.getMsg(),resultCode.getCode());
}
private PageResult(List<T> list, int code) {
super(null,code);
PageData<T> data = new PageData<>(list);
this.data = data;
}
private PageResult(IPage<T> page, int code) {
super(null,code);
PageData<T> data = new PageData<>(page);
this.data = data;
}
/**
* 功能描述: 创建一个空PageResult类
*/
public static <T> PageResult<T> empty() {
@SuppressWarnings("unchecked")
PageResult<T> t = (PageResult<T>) EMPTY;
return t;
}
/**
* 功能描述: 生成一个成功状态PageResult类
*/
public static <T> PageResult<T> success(List<T> data) {
return new PageResult<>(data, ResponseCode.SUCCESS.getCode());
}
public static <T> PageResult<T> success(IPage<T> page) {
return new PageResult<>(page, ResponseCode.SUCCESS.getCode());
}
/**
* 功能描述: 生成一个失败状态PageResult类
*/
public static <T> PageResult<T> fail(String message) {
return new PageResult<>(message, ResponseCode.FAIL.getCode());
}
/**
* 功能描述: 设置页码信息
*/
public <T> PageResult<T> page(int pageNo, int pageSize) {
if (ResponseCode.SUCCESS.getCode() == super.getCode()) {
data.setPageNo(pageNo);
data.setPageSize(pageSize);
}
return (PageResult<T>) this;
}
public <T> PageResult<T> page(PageRequest pageRequest){
return page(pageRequest.getPageNo(),pageRequest.getPageSize());
}
/**
* 功能描述: 设置总数
*/
public <T> PageResult<T> total(int total) {
if (data != null) {
data.setTotal(total);
}
return (PageResult<T>) this;
}
/**
* 功能描述: 判断是否传入值是否为空,非空则返回值,为空则返回失败信息
*/
public <T> PageResult<T> orFail(String message) {
if (null != data.records) {
return (PageResult<T>) this;
} else {
super.setCode(ResponseCode.FAIL.getCode());
super.setMsg(message);
// this.msg = message;
// this.code = "0";
}
return (PageResult<T>) this;
}
@Override
public int hashCode() {
return Objects.hashCode(data);
}
@Override
public String toString() {
return data != null
? String.format("result[%s]", data)
: "result.empty";
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class PageData<T> {
/**
* 接口数据
*/
@ApiModelProperty(value = "结果集")
private List<T> records;
@ApiModelProperty(value = "当前页码",example = "1")
private long pageNo;
@ApiModelProperty(value = "总记录数",example = "100")
private long total;
@ApiModelProperty(value = "页容量",example = "20")
private long pageSize;
public PageData(List<T> records){
this.records = records;
}
public PageData(IPage<T> page) {
this.total = page.getTotal();
this.records = page.getRecords();
this.pageNo = page.getCurrent();
this.pageSize = page.getSize();
}
}
}
//PageResponse使用方式
@GetMapping("/select")
@ApiOperation("查询模版下拉选项")
public ResponseEntity<PageResponse<ResultTemplateSelectVO>> getTemplateListByConfig(TemplateQueryDTO templateQueryDTO) {
templateQueryDTO.setUserId(getUserId());
Page<ResultTemplate> page = resultTemplateService.listTemplateByServiceType(templateQueryDTO);
List<ResultTemplateSelectVO> result = resultTemplateConvert.resultTemplateList2ResultTemplateSelectVOList(page.getRecords());
if (page.getCurrent() == 1) {
result.add(0, new ResultTemplateSelectVO(-1L, "千寻默认csv"));
}
PageResponse<ResultTemplateSelectVO> response = new PageResponse<>();
response.setList(result);
response.setTotal(page.getTotal());
response.setPage(page.getCurrent());
response.setLimit(page.getSize());
return ResponseEntity.ok(response);
}
//config包下新增
/**
* 全局异常处理,处理可预见的异常,Order 排序优先级高
*/
@Slf4j
@Order(Ordered.HIGHEST_PRECEDENCE)
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class })
@RestControllerAdvice
public class CustomRestControllerAdvice {
@ExceptionHandler(MissingServletRequestParameterException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Result<String> handleError(MissingServletRequestParameterException e) {
log.warn("缺少请求参数:{}", e.getMessage());
String message = String.format("缺少必要的请求参数: %s", e.getParameterName());
return Result.fail(message);
}
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Result<String> handleError(MethodArgumentTypeMismatchException e) {
log.warn("请求参数格式错误:{}", e.getMessage());
String message = String.format("请求参数格式错误: %s", e.getName());
return Result.fail(message);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Result<String> handleError(MethodArgumentNotValidException e) {
log.warn("参数验证失败:{}", e.getMessage());
return handleError(e.getBindingResult());
}
@ExceptionHandler(BindException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Result<String> handleError(BindException e) {
log.warn("参数绑定失败:{}", e.getMessage());
return handleError(e.getBindingResult());
}
private Result<String> handleError(BindingResult result) {
FieldError error = result.getFieldError();
String message = String.format("%s:%s", error.getField(), error.getDefaultMessage());
return Result.fail(message);
}
@ExceptionHandler(ConstraintViolationException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Result<String> handleError(ConstraintViolationException e) {
log.warn("参数验证失败:{}", e.getMessage());
Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
ConstraintViolation<?> violation = violations.iterator().next();
String path = ((PathImpl) violation.getPropertyPath()).getLeafNode().getName();
String message = String.format("%s:%s", path, violation.getMessage());
return Result.fail(message);
}
@ExceptionHandler(NoHandlerFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public Result<String> handleError(NoHandlerFoundException e) {
log.error("404没找到请求:{}", e.getMessage());
return Result.fail(e.getMessage());
}
@ExceptionHandler(HttpMessageNotReadableException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Result<String> handleError(HttpMessageNotReadableException e) {
log.error("消息不能读取:{}", e.getMessage());
return Result.fail(e.getMessage());
}
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
public Result<String> handleError(HttpRequestMethodNotSupportedException e) {
log.error("不支持当前请求方法:{}", e.getMessage());
return Result.fail(e.getMessage());
}
@ExceptionHandler(HttpMediaTypeNotSupportedException.class)
@ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
public Result<String> handleError(HttpMediaTypeNotSupportedException e) {
log.error("不支持当前媒体类型:{}", e.getMessage());
return Result.fail(e.getMessage());
}
@ExceptionHandler(HttpMediaTypeNotAcceptableException.class)
@ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
public Result<String> handleError(HttpMediaTypeNotAcceptableException e) {
String message = e.getMessage() + " " + StringUtils.join(e.getSupportedMediaTypes());
log.error("不接受的媒体类型:{}", message);
return Result.fail(message);
}
@ExceptionHandler(Throwable.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public Result<String> handleError(Throwable e) {
log.error("服务器异常:{}", e);
return Result.fail(e.getMessage());
}
@ExceptionHandler(value = AuthException.class)
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public Result<String> handleAuthException(AuthException ex) {
String temp = ex.getAuthExceptionEnum().getMessage();
return Result.fail(temp);
}
}
//exception包下新增
public class AuthException extends RuntimeException {
private final AuthExceptionEnum authExceptionEnum;
public AuthException(AuthExceptionEnum authExceptionEnum) {
super(authExceptionEnum.getMessage());
this.authExceptionEnum = authExceptionEnum;
}
public AuthExceptionEnum getAuthExceptionEnum() {
return this.authExceptionEnum;
}
}
public enum AuthExceptionEnum {
/**
* 401登陆失败,500内部错误
*/
INVALID_REQUEST(401, "没有鉴权信息"),
INVALID_TOKEN(401, "token失效"),
RESET_PASSWORD(401, "首次登陆请修改密码"),
UNAUTHORIZED(401, "无权限"),
INVALID_AK(401, "appKey错误"),
INVALID_SIGN(401, "请求的接口加签错误"),
INVALID_API(401, "请求的接口不在开放API范围"),
FAILED(401, "鉴权失败"),
UNKNOWN(500, "未知错误");
private final int code;
private final String message;
AuthExceptionEnum(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
}
/**
* 全局统一异常处理
*/
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(value = Exception.class)
@ResponseBody
public ApiResponse handlerException(Exception e) {
if (e instanceof NoHandlerFoundException) {
log.error("【全局异常拦截】NoHandlerFoundException: 请求方法 {}, 请求路径 {}", ((NoHandlerFoundException) e).getRequestURL(), ((NoHandlerFoundException) e).getHttpMethod());
return ApiResponse.ofStatus(Status.REQUEST_NOT_FOUND);
} else if (e instanceof HttpRequestMethodNotSupportedException) {
log.error("【全局异常拦截】HttpRequestMethodNotSupportedException: 当前请求方式 {}, 支持请求方式 {}", ((HttpRequestMethodNotSupportedException) e).getMethod(), JSONUtil.toJsonStr(((HttpRequestMethodNotSupportedException) e).getSupportedHttpMethods()));
return ApiResponse.ofStatus(Status.HTTP_BAD_METHOD);
} else if (e instanceof MethodArgumentNotValidException) {
log.error("【全局异常拦截】MethodArgumentNotValidException", e);
return ApiResponse.of(Status.BAD_REQUEST.getCode(), ((MethodArgumentNotValidException) e).getBindingResult().getAllErrors().get(0).getDefaultMessage(), null);
} else if (e instanceof ConstraintViolationException) {
log.error("【全局异常拦截】ConstraintViolationException", e);
return ApiResponse.of(Status.BAD_REQUEST.getCode(), CollUtil.getFirst(((ConstraintViolationException) e).getConstraintViolations()).getMessage(), null);
} else if (e instanceof MethodArgumentTypeMismatchException) {
log.error("【全局异常拦截】MethodArgumentTypeMismatchException: 参数名 {}, 异常信息 {}", ((MethodArgumentTypeMismatchException) e).getName(), ((MethodArgumentTypeMismatchException) e).getMessage());
return ApiResponse.ofStatus(Status.PARAM_NOT_MATCH);
} else if (e instanceof HttpMessageNotReadableException) {
log.error("【全局异常拦截】HttpMessageNotReadableException: 错误信息 {}", ((HttpMessageNotReadableException) e).getMessage());
return ApiResponse.ofStatus(Status.PARAM_NOT_NULL);
} else if (e instanceof BadCredentialsException) {
log.error("【全局异常拦截】BadCredentialsException: 错误信息 {}", e.getMessage());
return ApiResponse.ofStatus(Status.USERNAME_PASSWORD_ERROR);
} else if (e instanceof DisabledException) {
log.error("【全局异常拦截】BadCredentialsException: 错误信息 {}", e.getMessage());
return ApiResponse.ofStatus(Status.USER_DISABLED);
} else if (e instanceof BaseException) {
log.error("【全局异常拦截】DataManagerException: 状态码 {}, 异常信息 {}", ((BaseException) e).getCode(), e.getMessage());
return ApiResponse.ofException((BaseException) e);
}
log.error("【全局异常拦截】: 异常信息 {} ", e.getMessage());
return ApiResponse.ofStatus(Status.ERROR);
}
}
@Data
public class ApiResponse implements Serializable {
private static final long serialVersionUID = 8993485788201922830L;
private Integer code;
private String message;
private Object data;
private ApiResponse() {
}
private ApiResponse(Integer code, String message, Object data) {
this.code = code;
this.message = message;
this.data = data;
}
public static ApiResponse of(Integer code, String message, Object data) {
return new ApiResponse(code, message, data);
}
public static ApiResponse ofSuccess() {
return ofSuccess(null);
}
public static ApiResponse ofSuccess(Object data) {
return ofStatus(Status.SUCCESS, data);
}
public static ApiResponse ofMessage(String message) {
return of(Status.SUCCESS.getCode(), message, null);
}
public static ApiResponse ofStatus(Status status) {
return ofStatus(status, null);
}
public static ApiResponse ofStatus(IStatus status, Object data) {
return of(status.getCode(), status.getMessage(), data);
}
public static <T extends BaseException> ApiResponse ofException(T t) {
return of(t.getCode(), t.getMessage(), t.getData());
}
}
public interface IStatus {
Integer getCode();
String getMessage();
}
@Getter
public enum Status implements IStatus {
/**
* 操作成功!
*/
SUCCESS(200, "操作成功!"),
/**
* 操作异常!
*/
ERROR(500, "操作异常!"),
/**
* 退出成功!
*/
LOGOUT(200, "退出成功!"),
/**
* 请先登录!
*/
UNAUTHORIZED(401, "请先登录!"),
/**
* 暂无权限访问!
*/
ACCESS_DENIED(403, "权限不足!"),
/**
* 请求不存在!
*/
REQUEST_NOT_FOUND(404, "请求不存在!"),
/**
* 请求方式不支持!
*/
HTTP_BAD_METHOD(405, "请求方式不支持!"),
/**
* 请求异常!
*/
BAD_REQUEST(400, "请求异常!"),
/**
* 参数不匹配!
*/
PARAM_NOT_MATCH(400, "参数不匹配!"),
/**
* 参数不能为空!
*/
PARAM_NOT_NULL(400, "参数不能为空!"),
/**
* 当前用户已被锁定,请联系管理员解锁!
*/
USER_DISABLED(403, "当前用户已被锁定,请联系管理员解锁!"),
/**
* 用户名或密码错误!
*/
USERNAME_PASSWORD_ERROR(5001, "用户名或密码错误!"),
/**
* token 已过期,请重新登录!
*/
TOKEN_EXPIRED(5002, "token 已过期,请重新登录!"),
/**
* token 解析失败,请尝试重新登录!
*/
TOKEN_PARSE_ERROR(5002, "token 解析失败,请尝试重新登录!"),
/**
* 当前用户已在别处登录,请尝试更改密码或重新登录!
*/
TOKEN_OUT_OF_CTRL(5003, "当前用户已在别处登录,请尝试更改密码或重新登录!"),
/**
* 无法手动踢出自己,请尝试退出登录操作!
*/
KICKOUT_SELF(5004, "无法手动踢出自己,请尝试退出登录操作!");
/**
* 状态码
*/
private Integer code;
/**
* 返回信息
*/
private String message;
Status(Integer code, String message) {
this.code = code;
this.message = message;
}
public static Status fromCode(Integer code) {
Status[] statuses = Status.values();
for (Status status : statuses) {
if (status.getCode().equals(code)) {
return status;
}
}
return SUCCESS;
}
@Override
public String toString() {
return String.format(" Status:{code=%s, message=%s} ", getCode(), getMessage());
}
}
//DateUtil用法
String date = DateUtil.formatDate(localDate);
String[] dateTime = DateUtil.getDateTime(localDate,0);
String startTime = dateTime[0];
String endTime = dateTime[1];
public class DateUtil {
public static final String PATTERN_DATETIME = "yyyy-MM-dd HH:mm:ss";
public static final String PATTERN_DATETIME_MINI = "yyyyMMddHHmmss";
public static final String PATTERN_DATE = "yyyy-MM-dd";
public static final String PATTERN_TIME = "HH:mm:ss";
public static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATETIME);
public static final DateTimeFormatter DATETIME_MINI_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATETIME_MINI);
public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATE);
public static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_TIME);
/**
* 获取当前日期
*/
public static Date now() {
return new Date();
}
/**
* 添加年
*/
public static Date plusYears(Date date, int yearsToAdd) {
return DateUtil.set(date, Calendar.YEAR, yearsToAdd);
}
/**
* 添加月
*/
public static Date plusMonths(Date date, int monthsToAdd) {
return DateUtil.set(date, Calendar.MONTH, monthsToAdd);
}
/**
* 添加周
*/
public static Date plusWeeks(Date date, int weeksToAdd) {
return DateUtil.plus(date, Period.ofWeeks(weeksToAdd));
}
/**
* 添加天
*/
public static Date plusDays(Date date, long daysToAdd) {
return DateUtil.plus(date, Duration.ofDays(daysToAdd));
}
/**
* 添加小时
*/
public static Date plusHours(Date date, long hoursToAdd) {
return DateUtil.plus(date, Duration.ofHours(hoursToAdd));
}
/**
* 添加分钟
*/
public static Date plusMinutes(Date date, long minutesToAdd) {
return DateUtil.plus(date, Duration.ofMinutes(minutesToAdd));
}
/**
* 添加秒
*/
public static Date plusSeconds(Date date, long secondsToAdd) {
return DateUtil.plus(date, Duration.ofSeconds(secondsToAdd));
}
/**
* 添加毫秒
*/
public static Date plusMillis(Date date, long millisToAdd) {
return DateUtil.plus(date, Duration.ofMillis(millisToAdd));
}
/**
* 添加纳秒
*/
public static Date plusNanos(Date date, long nanosToAdd) {
return DateUtil.plus(date, Duration.ofNanos(nanosToAdd));
}
/**
* 日期添加时间量
*/
public static Date plus(Date date, TemporalAmount amount) {
Instant instant = date.toInstant();
return Date.from(instant.plus(amount));
}
/**
* 减少年
*/
public static Date minusYears(Date date, int years) {
return DateUtil.set(date, Calendar.YEAR, -years);
}
/**
* 减少月
*/
public static Date minusMonths(Date date, int months) {
return DateUtil.set(date, Calendar.MONTH, -months);
}
/**
* 减少周
*/
public static Date minusWeeks(Date date, int weeks) {
return DateUtil.minus(date, Period.ofWeeks(weeks));
}
/**
* 减少天
*/
public static Date minusDays(Date date, long days) {
return DateUtil.minus(date, Duration.ofDays(days));
}
/**
* 减少小时
*/
public static Date minusHours(Date date, long hours) {
return DateUtil.minus(date, Duration.ofHours(hours));
}
/**
* 减少分钟
*/
public static Date minusMinutes(Date date, long minutes) {
return DateUtil.minus(date, Duration.ofMinutes(minutes));
}
/**
* 减少秒
*/
public static Date minusSeconds(Date date, long seconds) {
return DateUtil.minus(date, Duration.ofSeconds(seconds));
}
/**
* 减少毫秒
*/
public static Date minusMillis(Date date, long millis) {
return DateUtil.minus(date, Duration.ofMillis(millis));
}
/**
* 减少纳秒
*/
public static Date minusNanos(Date date, long nanos) {
return DateUtil.minus(date, Duration.ofNanos(nanos));
}
/**
* 日期减少时间量
*/
public static Date minus(Date date, TemporalAmount amount) {
Instant instant = date.toInstant();
return Date.from(instant.minus(amount));
}
/**
* 设置日期属性
*/
private static Date set(Date date, int calendarField, int amount) {
Assert.notNull(date, "The date must not be null");
Calendar c = Calendar.getInstance();
c.setLenient(false);
c.setTime(date);
c.add(calendarField, amount);
return c.getTime();
}
/**
* java8 日期时间格式化
*/
public static String formatDateTime(TemporalAccessor temporal) {
return DATETIME_FORMATTER.format(temporal);
}
/**
* java8 日期时间格式化
*/
public static String formatDateTimeMini(TemporalAccessor temporal) {
return DATETIME_MINI_FORMATTER.format(temporal);
}
/**
* java8 日期时间格式化
*/
public static String formatDate(TemporalAccessor temporal) {
return DATE_FORMATTER.format(temporal);
}
/**
* java8 时间格式化
*/
public static String formatTime(TemporalAccessor temporal) {
return TIME_FORMATTER.format(temporal);
}
/**
* java8 日期格式化
*/
public static String format(TemporalAccessor temporal, String pattern) {
return DateTimeFormatter.ofPattern(pattern).format(temporal);
}
/**
* 将字符串转换为时间
*/
public static <T> T parse(String dateStr, String pattern, TemporalQuery<T> query) {
return DateTimeFormatter.ofPattern(pattern).parse(dateStr, query);
}
/**
* 时间转 Instant
*/
public static Instant toInstant(LocalDateTime dateTime) {
return dateTime.atZone(ZoneId.systemDefault()).toInstant();
}
/**
* Instant 转 时间
*/
public static LocalDateTime toDateTime(Instant instant) {
return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
}
/**
* 转换成 date
*/
public static Date toDate(LocalDateTime dateTime) {
return Date.from(DateUtil.toInstant(dateTime));
}
/**
* 转换成 date
*/
public static Date toDate(final LocalDate localDate) {
return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
}
/**
* Converts local date time to Calendar.
*/
public static Calendar toCalendar(final LocalDateTime localDateTime) {
return GregorianCalendar.from(ZonedDateTime.of(localDateTime, ZoneId.systemDefault()));
}
/**
* localDateTime 转换成毫秒数
*/
public static long toMilliseconds(final LocalDateTime localDateTime) {
return localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
}
/**
* localDate 转换成毫秒数
*/
public static long toMilliseconds(LocalDate localDate) {
return toMilliseconds(localDate.atStartOfDay());
}
/**
* 转换成java8 时间
*/
public static LocalDateTime fromCalendar(final Calendar calendar) {
TimeZone tz = calendar.getTimeZone();
ZoneId zid = tz == null ? ZoneId.systemDefault() : tz.toZoneId();
return LocalDateTime.ofInstant(calendar.toInstant(), zid);
}
/**
* 转换成java8 时间
*/
public static LocalDateTime fromInstant(final Instant instant) {
return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
}
/**
* 转换成java8 时间
*/
public static LocalDateTime fromDate(final Date date) {
return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
}
/**
* 转换成java8 时间
*/
public static LocalDateTime fromMilliseconds(final long milliseconds) {
return LocalDateTime.ofInstant(Instant.ofEpochMilli(milliseconds), ZoneId.systemDefault());
}
/**
* 比较2个时间差,跨度比较小
*/
public static Duration between(Temporal startInclusive, Temporal endExclusive) {
return Duration.between(startInclusive, endExclusive);
}
/**
* 比较2个时间差,跨度比较大,年月日为单位
*/
public static Period between(LocalDate startDate, LocalDate endDate) {
return Period.between(startDate, endDate);
}
/**
* 比较2个 时间差
*/
public static Duration between(Date startDate, Date endDate) {
return Duration.between(startDate.toInstant(), endDate.toInstant());
}
public static String getDate(LocalDateTime dateTime ,String format){
if(dateTime == null){
dateTime = LocalDateTime.now();
}
return dateTime.format(DateTimeFormatter.ofPattern(format));
}
public static String[] getDateTime(LocalDate dateTime,int addDay){
LocalDate plusDate = dateTime.plusDays(addDay);
String[] dates = new String[2];
if(addDay>=0){
dates[0] = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd 00:00:00"));
dates[1] = plusDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd 23:59:59"));
}else{
dates[0] = plusDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd 00:00:00"));
dates[1] = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd 23:59:59"));
}
return dates;
}
public static void main(String[] args) {
System.out.println(getDateTime(LocalDate.now(), -6)[0]);
System.out.println(getDateTime(LocalDate.now(), -6)[1]);
}
}
//DateTimeUtil用法
LocalDate localDate = StringUtils.isBlank(monitorItemRequest.getDate())?LocalDate.now(): DateTimeUtil.parseDate(monitorItemRequest.getDate());
/**
* DateTime 工具类
**/
public class DateTimeUtil {
public static final DateTimeFormatter DATETIME_FORMAT = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATETIME);
public static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATE);
public static final DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ofPattern(DateUtil.PATTERN_TIME);
/**
* 日期时间格式化
*/
public static String formatDateTime(TemporalAccessor temporal) {
return DATETIME_FORMAT.format(temporal);
}
/**
* 日期时间格式化
*/
public static String formatDate(TemporalAccessor temporal) {
return DATE_FORMAT.format(temporal);
}
/**
* 时间格式化
*/
public static String formatTime(TemporalAccessor temporal) {
return TIME_FORMAT.format(temporal);
}
/**
* 日期格式化
*/
public static String format(TemporalAccessor temporal, String pattern) {
return DateTimeFormatter.ofPattern(pattern).format(temporal);
}
/**
* 将字符串转换为时间
*/
public static LocalDateTime parseDateTime(String dateStr, String pattern) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
return DateTimeUtil.parseDateTime(dateStr, formatter);
}
/**
* 将字符串转换为时间
*/
public static LocalDateTime parseDateTime(String dateStr, DateTimeFormatter formatter) {
return LocalDateTime.parse(dateStr, formatter);
}
/**
* 将字符串转换为时间
*/
public static LocalDateTime parseDateTime(String dateStr) {
return DateTimeUtil.parseDateTime(dateStr, DateTimeUtil.DATETIME_FORMAT);
}
/**
* 将字符串转换为时间
*/
public static LocalDate parseDate(String dateStr, String pattern) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
return DateTimeUtil.parseDate(dateStr, formatter);
}
/**
* 将字符串转换为时间
*/
public static LocalDate parseDate(String dateStr, DateTimeFormatter formatter) {
return LocalDate.parse(dateStr, formatter);
}
/**
* 将字符串转换为日期
*/
public static LocalDate parseDate(String dateStr) {
return DateTimeUtil.parseDate(dateStr, DateTimeUtil.DATE_FORMAT);
}
/**
* 将字符串转换为时间
*/
public static LocalTime parseTime(String dateStr, String pattern) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
return DateTimeUtil.parseTime(dateStr, formatter);
}
/**
* 将字符串转换为时间
*/
public static LocalTime parseTime(String dateStr, DateTimeFormatter formatter) {
return LocalTime.parse(dateStr, formatter);
}
/**
* 将字符串转换为时间
*/
public static LocalTime parseTime(String dateStr) {
return DateTimeUtil.parseTime(dateStr, DateTimeUtil.TIME_FORMAT);
}
/**
* 时间转 Instant
*/
public static Instant toInstant(LocalDateTime dateTime) {
return dateTime.atZone(ZoneId.systemDefault()).toInstant();
}
/**
* Instant 转 时间
*/
public static LocalDateTime toDateTime(Instant instant) {
return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
}
/**
* 转换成 date
*/
public static Date toDate(LocalDateTime dateTime) {
return Date.from(DateTimeUtil.toInstant(dateTime));
}
/**
* 比较2个时间差,跨度比较小
*/
public static Duration between(Temporal startInclusive, Temporal endExclusive) {
return Duration.between(startInclusive, endExclusive);
}
/**
* 比较2个时间差,跨度比较大,年月日为单位
*/
public static Period between(LocalDate startDate, LocalDate endDate) {
return Period.between(startDate, endDate);
}
}
//DateConverterUtil用法
Date todayStart = DateConverterUtil.getTodayStart();
Date todayEnd = DateConverterUtil.getTodayEnd();
Date weekStart = DateConverterUtil.getWeekStart();
Date weekEnd = DateConverterUtil.getWeekEnd();
Date monthStart = DateConverterUtil.getMonthStart();
Date monthEnd = DateConverterUtil.getMonthEnd();
@Component
@Slf4j
public class DateConverterUtil {
private final static String startStr = " 00:00:00";
private final static String endStr = " 23:59:59";
private final static String yyyyMMdd = "yyyy-MM-dd";
private final static String yyyyMMddHHmmss = "yyyy-MM-dd HH:mm:ss";
private static final List<String> formarts = new ArrayList<>(4);
static {
formarts.add("yyyy-MM");
formarts.add("yyyy-MM-dd");
formarts.add("yyyy-MM-dd HH:mm");
formarts.add("yyyy-MM-dd HH:mm:ss");
}
public Date convert(String source) {
try {
if (StringUtils.isBlank(source)) {
return null;
}
if (source.matches("^\\d{4}-\\d{1,2}$")) {
return parseDate(source, formarts.get(0));
} else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")) {
return parseDate(source, formarts.get(1));
} else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}$")) {
return parseDate(source, formarts.get(2));
} else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")) {
return parseDate(source, formarts.get(3));
} else {
return null;
}
} catch (Exception e) {
log.error("convert error",e);
return null;
}
}
/**
* 格式化日期
*/
private Date parseDate(String dateStr, String format) {
Date date = null;
try {
DateFormat dateFormat = new SimpleDateFormat(format);
date = dateFormat.parse(dateStr);
} catch (Exception e) {
}
return date;
}
public static Date long2Date(Long time) {
try {
if (time == null) {
return null;
}
return new Date(time);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 获取本月开始日期
**/
public static Date getMonthStart() throws ParseException {
Calendar cal=Calendar.getInstance();
cal.add(Calendar.MONTH, 0);
cal.set(Calendar.DAY_OF_MONTH, 1);
Date time=cal.getTime();
SimpleDateFormat yyyyMMddHHmmssFormat = new SimpleDateFormat(yyyyMMddHHmmss);
return yyyyMMddHHmmssFormat.parse(new SimpleDateFormat(yyyyMMdd).format(time)+startStr);
}
/**
* 获取本月最后一天
**/
public static Date getMonthEnd() throws ParseException {
Calendar cal=Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
Date time=cal.getTime();
SimpleDateFormat yyyyMMddHHmmssFormat = new SimpleDateFormat(yyyyMMddHHmmss);
return yyyyMMddHHmmssFormat.parse(new SimpleDateFormat(yyyyMMdd).format(time)+endStr);
}
/**
* 获取本周的第一天
**/
public static Date getWeekStart() throws ParseException {
Calendar cal=Calendar.getInstance();
cal.add(Calendar.WEEK_OF_MONTH, 0);
cal.set(Calendar.DAY_OF_WEEK, 2);
Date time=cal.getTime();
SimpleDateFormat yyyyMMddHHmmssFormat = new SimpleDateFormat(yyyyMMddHHmmss);
return yyyyMMddHHmmssFormat.parse(new SimpleDateFormat(yyyyMMdd).format(time)+startStr);
}
/**
* 获取本周的最后一天
**/
public static Date getWeekEnd() throws ParseException {
Calendar cal=Calendar.getInstance();
cal.set(Calendar.DAY_OF_WEEK, cal.getActualMaximum(Calendar.DAY_OF_WEEK));
cal.add(Calendar.DAY_OF_WEEK, 1);
Date time=cal.getTime();
SimpleDateFormat yyyyMMddHHmmssFormat = new SimpleDateFormat(yyyyMMddHHmmss);
return yyyyMMddHHmmssFormat.parse(new SimpleDateFormat(yyyyMMdd).format(time)+endStr);
}
/**
* 获取今天开始时间
**/
public static Date getTodayStart() throws ParseException {
SimpleDateFormat yyyyMMddFormat = new SimpleDateFormat(yyyyMMdd);
SimpleDateFormat yyyyMMddHHmmssFormat = new SimpleDateFormat(yyyyMMddHHmmss);
Date currentDate = new Date();
return yyyyMMddHHmmssFormat.parse(yyyyMMddFormat.format(currentDate)+startStr);
}
/**
* 获取今天结束时间
**/
public static Date getTodayEnd() throws ParseException {
SimpleDateFormat yyyyMMddFormat = new SimpleDateFormat(yyyyMMdd);
SimpleDateFormat yyyyMMddHHmmssFormat = new SimpleDateFormat(yyyyMMddHHmmss);
Date currentDate = new Date();
return yyyyMMddHHmmssFormat.parse(yyyyMMddFormat.format(currentDate)+endStr);
}
/**
* 获取年月日
**/
public static String getFormatDate(Date date) {
String strDateFormat = "YYYY年MM月dd日";
SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat);
return sdf.format(date);
}
/**
* 获取年月
**/
public static String getFormatDateMonth(Date date) {
String strDateFormat = "yyyy-MM";
SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat);
return sdf.format(date);
}
/**
* 获取年月
**/
public static String getFormatDateWeek(Date date) {
String strDateFormat = "MM月dd日";
SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat);
return sdf.format(date);
}
}
@Override
public List<MonitorItemVO> queryDay7AlarmDetail(NoticeAlarmRecordStatusRequest noticeAlarmRecordStatusRequest) {
NoticeMonitorPointQuery query = new NoticeMonitorPointQuery();
query.setTypes(Arrays.asList(WarningTypeEnum.DZZH.getCode(),WarningTypeEnum.STSK.getCode()));
query.setAreaCode(StringUtils.defaultIfBlank(noticeAlarmRecordStatusRequest.getAreaCode(),areaCode));
List<NoticeMonitorObjectDTO> noticeMonitorObjectDTOList = noticeMonitorObjectService.listNoticeMonitorPoint(query);
List<Long> pointIds = noticeMonitorObjectDTOList.stream().flatMap(obj -> obj.getNoticeMonitorPoints().stream().map(mp -> mp.getId())).collect(Collectors.toList());
if(CollectionUtils.isEmpty(pointIds)){
return Collections.emptyList();
}
String startTime = "";
String endTime = "";
LocalDate localDate = StringUtils.isBlank(noticeAlarmRecordStatusRequest.getDate())?LocalDate.now(): DateTimeUtil.parseDate(noticeAlarmRecordStatusRequest.getDate());
String[] dateTime = DateUtil.getDateTime(localDate,-6);
startTime = dateTime[0];
endTime = dateTime[1];
LambdaQueryWrapper<NoticeAlarmRecord> noticeAlarmRecordLambdaQueryWrapper = Wrappers.lambdaQuery(NoticeAlarmRecord.class)
.in(NoticeAlarmRecord::getPointId, pointIds)
.eq(StringUtils.isNotBlank(noticeAlarmRecordStatusRequest.getStatus()),NoticeAlarmRecord::getStatus,noticeAlarmRecordStatusRequest.getStatus())
.between(NoticeAlarmRecord::getTriggerTime, startTime, endTime)
.orderByDesc(NoticeAlarmRecord::getTriggerTime);
List<NoticeAlarmRecord> list = noticeAlarmRecordService.list(noticeAlarmRecordLambdaQueryWrapper);
List<Long> recordPointIds = list.stream().map(rc->rc.getPointId()).collect(Collectors.toList());
List<String> types = list.stream().map(rc -> rc.getItemCode()).collect(Collectors.toList());
List<MonitorItemVO> results = new ArrayList<>();
Map<Long, NoticeMonitorPointDTO> noticeMonitorPointDTOMap = noticeMonitorPointService.mapNoticeMonitorPoint(query);
List<NoticeMonitorItem> noticeMonitorItemList = noticeMonitorItemService.countByPointIdAndType(recordPointIds,types);
Map<String, NoticeMonitorItem> noticeMonitorItemMap = noticeMonitorItemList.stream().collect(Collectors.toMap(NoticeMonitorItem::getType, Function.identity(), (key1, key2) -> key1));
for (NoticeAlarmRecord record : list) {
MonitorItemVO monitorItem = new MonitorItemVO();
monitorItem.setRecordId(record.getId());
monitorItem.setAlarmLevel(record.getAlarmLevel());
monitorItem.setStatus(record.getStatus());
monitorItem.setType(record.getItemCode());
monitorItem.setItemCode(record.getItemCode());
NoticeMonitorItem noticeMonitorItem = noticeMonitorItemMap.get(record.getItemCode());
if(noticeMonitorItem!=null){
monitorItem.setItemCodeName(noticeMonitorItem.getName());
}
monitorItem.setTriggerTime(record.getTriggerTime());
monitorItem.setAlarmDesc(record.getAlarmDesc());
NoticeMonitorPointDTO noticeMonitorPointDTO = noticeMonitorPointDTOMap.get(record.getPointId());
if(noticeMonitorPointDTO != null){
NoticeMonitorObject noticeMonitorObject = noticeMonitorPointDTO.getNoticeMonitorObject();
if(noticeMonitorObject != null){
monitorItem.setAreaDetail(noticeMonitorObject.getAreaDetail());
}
monitorItem.setAltitude(noticeMonitorPointDTO.getAltitude());
monitorItem.setLongitude(noticeMonitorPointDTO.getLongitude());
monitorItem.setLatitude(noticeMonitorPointDTO.getLatitude());
monitorItem.setName(noticeMonitorPointDTO.getName());
}
results.add(monitorItem);
}
return results;
}
}
@Override
public List<MonitorItemVO> queryMonitorItemWarnRecord(MonitorItemRequest monitorItemRequest, PageRequest pageRequest) {
NoticeMonitorPointQuery query = new NoticeMonitorPointQuery();
query.setTypes(Arrays.asList(WarningTypeEnum.DZZH.getCode(),WarningTypeEnum.STSK.getCode()));
query.setAreaCode(StringUtils.defaultIfBlank(monitorItemRequest.getAreaCode(),areaCode));
List<NoticeMonitorObjectDTO> noticeMonitorObjectDTOList = noticeMonitorObjectService.listNoticeMonitorPoint(query);
List<Long> pointIds = noticeMonitorObjectDTOList.stream().flatMap(obj -> obj.getNoticeMonitorPoints().stream().map(mp -> mp.getId())).collect(Collectors.toList());
if(CollectionUtils.isEmpty(pointIds)){
return Collections.emptyList();
}
LocalDate localDate = StringUtils.isBlank(monitorItemRequest.getDate())?LocalDate.now(): DateTimeUtil.parseDate(monitorItemRequest.getDate());
String[] dateTime = DateUtil.getDateTime(localDate,0);
String startTime = dateTime[0];
String endTime = dateTime[1];
LambdaQueryWrapper<NoticeAlarmRecord> noticeAlarmRecordLambdaQueryWrapper = Wrappers.lambdaQuery(NoticeAlarmRecord.class)
.in(NoticeAlarmRecord::getPointId, pointIds)
.eq(NoticeAlarmRecord::getItemCode, monitorItemRequest.getType())
.between(NoticeAlarmRecord::getTriggerTime,startTime,endTime)
.orderByDesc(NoticeAlarmRecord::getTriggerTime);
IPage<NoticeAlarmRecord> page = noticeAlarmRecordService.listByPage(pageRequest.convertPage(), noticeAlarmRecordLambdaQueryWrapper);
List<NoticeAlarmRecord> records = page.getRecords();
List<MonitorItemVO> monitorItemVOS = new ArrayList<>();
if(records == null){
return monitorItemVOS;
}
List<Long> recordPointIds = records.stream().map(rc->rc.getPointId()).collect(Collectors.toList());
List<String> types = records.stream().map(rc -> rc.getItemCode()).collect(Collectors.toList());
Map<Long, NoticeMonitorPointDTO> noticeMonitorPointDTOMap = noticeMonitorPointService.mapNoticeMonitorPoint(query);
List<NoticeMonitorItem> noticeMonitorItemList = noticeMonitorItemService.countByPointIdAndType(recordPointIds,types);
Map<String, NoticeMonitorItem> noticeMonitorItemMap = noticeMonitorItemList.stream().collect(Collectors.toMap(NoticeMonitorItem::getType, Function.identity(), (key1, key2) -> key1));
for (NoticeAlarmRecord record : records) {
MonitorItemVO monitorItem = new MonitorItemVO();
monitorItem.setAlarmLevel(record.getAlarmLevel());
monitorItem.setStatus(record.getStatus());
monitorItem.setItemCode(record.getItemCode());
NoticeMonitorItem noticeMonitorItem = noticeMonitorItemMap.get(record.getItemCode());
if(noticeMonitorItem!=null){
monitorItem.setItemCodeName(noticeMonitorItem.getName());
}
monitorItem.setType(record.getItemCode());
monitorItem.setTriggerTime(record.getTriggerTime());
monitorItem.setAlarmDesc(record.getAlarmDesc());
NoticeMonitorPointDTO noticeMonitorPointDTO = noticeMonitorPointDTOMap.get(record.getPointId());
if(noticeMonitorPointDTO != null){
NoticeMonitorObject noticeMonitorObject = noticeMonitorPointDTO.getNoticeMonitorObject();
if(noticeMonitorObject != null){
monitorItem.setAreaDetail(noticeMonitorObject.getAreaDetail());
}
monitorItem.setAltitude(noticeMonitorPointDTO.getAltitude());
monitorItem.setLongitude(noticeMonitorPointDTO.getLongitude());
monitorItem.setLatitude(noticeMonitorPointDTO.getLatitude());
monitorItem.setName(noticeMonitorPointDTO.getName());
}
monitorItemVOS.add(monitorItem);
}
return monitorItemVOS;
}
/**
* 告警处理详情接口
*/
@Override
public AlarmDetailVO queryAlarmDetail(AlarmDetailRequest alarmDetailRequest) {
NoticeAlarmRecord noticeAlarmRecord = noticeAlarmRecordService.getById(alarmDetailRequest.getRecordId());
AlarmDetailVO alarmDetai = new AlarmDetailVO();
if(noticeAlarmRecord == null){
return alarmDetai;
}
LambdaQueryWrapper<NoticeAlarmProcessRecord> noticeAlarmProcessRecordLambdaQueryWrapper = Wrappers.lambdaQuery(NoticeAlarmProcessRecord.class)
.eq(NoticeAlarmProcessRecord::getRecordId, alarmDetailRequest.getRecordId())
.orderByDesc(NoticeAlarmProcessRecord::getGmtCreate)
.last("limit 1");
NoticeAlarmProcessRecord noticeAlarmProcessRecord = noticeAlarmProcessRecordService.getOne(noticeAlarmProcessRecordLambdaQueryWrapper);
NoticeMonitorPoint noticeMonitorPoint = noticeMonitorPointService.getById(noticeAlarmRecord.getPointId());
alarmDetai.setAlarmDesc(noticeAlarmRecord.getAlarmDesc());
alarmDetai.setAlarmLevel(noticeAlarmRecord.getAlarmLevel());
LambdaQueryWrapper<NoticeMonitorItem> noticeMonitorItemLambdaQueryWrapper = Wrappers.lambdaQuery(NoticeMonitorItem.class)
.eq(NoticeMonitorItem::getType, noticeAlarmRecord.getItemCode())
.last("limit 1");
NoticeMonitorItem noticeMonitorItem = noticeMonitorItemService.getOne(noticeMonitorItemLambdaQueryWrapper);
alarmDetai.setItemCodeName(noticeMonitorItem.getName());
alarmDetai.setItemCode(noticeAlarmRecord.getItemCode());
alarmDetai.setStatus(noticeAlarmRecord.getStatus());
alarmDetai.setTriggerTime(noticeAlarmRecord.getTriggerTime());
alarmDetai.setType(noticeAlarmRecord.getItemCode());
if(noticeAlarmProcessRecord != null){
alarmDetai.setProcessUser(noticeAlarmProcessRecord.getProcessUser());
alarmDetai.setFalsePositive(noticeAlarmProcessRecord.getFalsePositive());
alarmDetai.setOpinions(noticeAlarmProcessRecord.getOpinions());
alarmDetai.setGmtCreate(noticeAlarmProcessRecord.getGmtCreate());
}
if(noticeMonitorPoint != null){
alarmDetai.setName(noticeMonitorPoint.getName());
}
return alarmDetai;
}
@Override
public List<MonitorInspectionStatisticsVO> queryInspectionStatistics(BaseWarningRequest baseWarningRequest) {
baseWarningRequest.setAreaCode(StringUtils.defaultIfBlank(baseWarningRequest.getAreaCode(),areaCode));
List<NoticeInspectionDetailDTO> noticeInspectionDetailDTOList = noticeMonitorObjectService.listNoticeInspectionDetail(baseWarningRequest);
List<Long> objectIdList = noticeInspectionDetailDTOList.stream().flatMap(obj -> obj.getNoticeInspectionDetails().stream().map(mp -> mp.getObjectId())).collect(Collectors.toList());
List<MonitorInspectionStatisticsVO> responseList= new ArrayList<>();
if (CollectionUtils.isEmpty(objectIdList)) {
// 没有数据权限
responseList.add(MonitorInspectionStatisticsVO.builder()
.timeScale("today")
.normalCount(0L)
.inspectionCount(0L)
.normalRate(BigDecimal.ZERO)
.build());
responseList.add(MonitorInspectionStatisticsVO.builder()
.timeScale("week")
.normalCount(0L)
.inspectionCount(0L)
.normalRate(BigDecimal.ZERO)
.build());
responseList.add(MonitorInspectionStatisticsVO.builder()
.timeScale("month")
.normalCount(0L)
.inspectionCount(0L)
.normalRate(BigDecimal.ZERO)
.build());
return responseList;
}
try {
// 今日
Date todayStart = DateConverterUtil.getTodayStart();
Date todayEnd = DateConverterUtil.getTodayEnd();
BigDecimal todayCount = new BigDecimal(Optional.ofNullable(noticeInspectionDetailService.countAll( todayStart,todayEnd, objectIdList)).orElse(0));
BigDecimal todayErrorCount = new BigDecimal(Optional.ofNullable(noticeInspectionDetailService.countError(todayStart,todayEnd,objectIdList)).orElse(0));
BigDecimal todayNormalCount = todayCount.subtract(todayErrorCount);
responseList.add(MonitorInspectionStatisticsVO.builder()
.timeScale("today")
.normalCount(todayNormalCount.longValue())
.inspectionCount(todayCount.longValue())
.normalRate(BigDecimal.ZERO.equals(todayCount) ? BigDecimal.ONE : todayNormalCount.divide(todayCount, 2, RoundingMode.HALF_UP ))
.build());
// 本周
Date weekStart = DateConverterUtil.getWeekStart();
Date weekEnd = DateConverterUtil.getWeekEnd();
BigDecimal weekCount = new BigDecimal(Optional.ofNullable(noticeInspectionDetailService.countAll(weekStart,weekEnd,objectIdList)).orElse(0));
BigDecimal weekErrorCount = new BigDecimal(Optional.ofNullable(noticeInspectionDetailService.countError(weekStart,weekEnd,objectIdList)).orElse(0));
BigDecimal weekNormalCount = weekCount.subtract(weekErrorCount);
responseList.add(MonitorInspectionStatisticsVO.builder()
.timeScale("week")
.normalCount(weekNormalCount.longValue())
.inspectionCount(weekCount.longValue())
.normalRate(BigDecimal.ZERO.equals(weekCount) ? BigDecimal.ONE : weekNormalCount.divide(weekCount, 2, RoundingMode.HALF_UP))
.build());
// 本月
Date monthStart = DateConverterUtil.getMonthStart();
Date monthEnd = DateConverterUtil.getMonthEnd();
BigDecimal monthCount = new BigDecimal(Optional.ofNullable(noticeInspectionDetailService.countAll( monthStart, monthEnd,objectIdList)).orElse(0));
BigDecimal monthErrorCount = new BigDecimal(Optional.ofNullable(noticeInspectionDetailService.countError(monthStart, monthEnd,objectIdList)).orElse(0));
BigDecimal monthNormalCount = monthCount.subtract(monthErrorCount);
responseList.add(MonitorInspectionStatisticsVO.builder()
.timeScale("month")
.normalCount(monthNormalCount.longValue())
.inspectionCount(monthCount.longValue())
.normalRate(BigDecimal.ZERO.equals(monthCount) ? BigDecimal.ONE : monthNormalCount.divide(monthCount, 2, RoundingMode.HALF_UP))
.build());
} catch (ParseException e) {
log.error("日期转换异常", e);
throw new ApiException("日期转换异常", e);
}
return responseList;
}
@Override
public List<AlarmInfoVO> queryAlarmInfo(MonitorItemObjectRequest monitorItemRequest,PageRequest pageRequest){
List<AlarmInfoVO> alarmInfoVOList = new ArrayList<>();
LocalDate localDate = StringUtils.isBlank(monitorItemRequest.getDate())?LocalDate.now(): DateTimeUtil.parseDate(monitorItemRequest.getDate());
String date = DateUtil.formatDate(localDate);
NoticeMonitorPointQuery query = new NoticeMonitorPointQuery();
query.setTypes(Arrays.asList(WarningTypeEnum.DZZH.getCode(),WarningTypeEnum.STSK.getCode()));
query.setAreaCode(StringUtils.defaultIfBlank(monitorItemRequest.getAreaCode(),areaCode));
List<NoticeMonitorObjectDTO> noticeMonitorObjectDTOList = noticeMonitorObjectService.listNoticeMonitorPoint(query);
Map<Long, NoticeMonitorPointDTO> mapNoticeMonitorPoint = noticeMonitorPointService.mapNoticeMonitorPoint(query);
if(CollectionUtils.isEmpty(noticeMonitorObjectDTOList)){
return new ArrayList<>();
}
String[] dateTime = DateUtil.getDateTime(localDate,0);
String startTime = dateTime[0];
String endTime = dateTime[1];
List<Long> pointIds = noticeMonitorObjectDTOList.stream().filter(nmo -> nmo.getId().equals(monitorItemRequest.getObjectId())).flatMap(obj -> obj.getNoticeMonitorPoints().stream().map(mp -> mp.getId())).collect(Collectors.toList());
LambdaQueryWrapper<NoticeAlarmRecord> noticeAlarmRecordLambdaQueryWrapper = Wrappers.lambdaQuery(NoticeAlarmRecord.class)
.in(NoticeAlarmRecord::getPointId, pointIds)
.between(NoticeAlarmRecord::getTriggerTime, startTime, endTime)
.orderByDesc(NoticeAlarmRecord::getTriggerTime);
List<NoticeAlarmRecord> alarmRecordList = new ArrayList<>();
try{
Page page = noticeAlarmRecordService.page(pageRequest.convertPage(), noticeAlarmRecordLambdaQueryWrapper);
// List<NoticeAlarmRecord> alarmRecordList = noticeAlarmRecordService.getAlarmRecord(pointIds, startTime, endTime,monitorItemRequest.getType());
alarmRecordList = page.getRecords();
}catch (Exception e){
System.out.println(e.getMessage());
}
List<Long> recordIdList = alarmRecordList.stream().map(mp -> mp.getId()).collect(Collectors.toList());
List<Long> recordPointIds = alarmRecordList.stream().map(rc->rc.getPointId()).collect(Collectors.toList());
List<String> types = alarmRecordList.stream().map(rc -> rc.getItemCode()).collect(Collectors.toList());
List<NoticeAlarmProcessRecord> processRecordList = noticeAlarmProcessRecordService.getProcessRecord(recordIdList);
Map<Long, NoticeAlarmProcessRecord> noticeAlarmProcessRecordMap = processRecordList.stream().collect(Collectors.toMap(NoticeAlarmProcessRecord::getRecordId, Function.identity(), (key1, key2) -> key1));
List<NoticeMonitorItem> noticeMonitorItemList = noticeMonitorItemService.countByPointIdAndType(recordPointIds,types);
Map<String, NoticeMonitorItem> noticeMonitorItemMap = noticeMonitorItemList.stream().collect(Collectors.toMap(NoticeMonitorItem::getType, Function.identity(), (key1, key2) -> key1));
for (NoticeAlarmRecord noticeAlarmRecord : alarmRecordList) {
AlarmInfoVO alarmInfoVO = new AlarmInfoVO();
alarmInfoVO.setDate(date);
NoticeMonitorPointDTO noticeMonitorPointDTO = getNoticeMonitorObjectDTO(noticeAlarmRecord,mapNoticeMonitorPoint);
NoticeMonitorObject noticeMonitorObject = noticeMonitorPointDTO == null ? new NoticeMonitorObjectDTO() : noticeMonitorPointDTO.getNoticeMonitorObject();
alarmInfoVO.setRecordId(noticeAlarmRecord.getId());
alarmInfoVO.setAreaDetail(noticeMonitorObject.getAreaDetail());
alarmInfoVO.setAltitude(noticeMonitorPointDTO.getAltitude());
alarmInfoVO.setLatitude(noticeMonitorPointDTO.getLatitude());
alarmInfoVO.setLongitude(noticeMonitorPointDTO.getLongitude());
alarmInfoVO.setName(noticeMonitorPointDTO.getName());
NoticeMonitorItem noticeMonitorItem = noticeMonitorItemMap.get(noticeAlarmRecord.getItemCode());
if(noticeMonitorItem!=null){
alarmInfoVO.setItemCodeName(noticeMonitorItem.getName());
}
alarmInfoVO.setItemCode(noticeAlarmRecord.getItemCode());
alarmInfoVO.setAlarmLevel(noticeAlarmRecord.getAlarmLevel());
alarmInfoVO.setAlarmDesc(noticeAlarmRecord.getAlarmDesc());
alarmInfoVO.setStatus(noticeAlarmRecord.getStatus());
alarmInfoVO.setAlarmDate(noticeAlarmRecord.getTriggerTime());
NoticeAlarmProcessRecord noticeAlarmProcessRecord = noticeAlarmProcessRecordMap.get(noticeAlarmRecord.getId());
if(noticeAlarmProcessRecord != null){
alarmInfoVO.setProcessUser(noticeAlarmProcessRecord.getProcessUser());
alarmInfoVO.setProcessDate(noticeAlarmProcessRecord.getGmtCreate());
}
alarmInfoVOList.add(alarmInfoVO);
}
return alarmInfoVOList;
}
/**
* 返回监测点ID
*/
public List<Long> listPointId(List<NoticeMonitorObjectDTO> noticeMonitorObjectDTOList,String type){
Stream<NoticeMonitorObjectDTO> stream = noticeMonitorObjectDTOList.stream();
if(StringUtils.isNotBlank(type)){
stream = stream.filter(obj -> StringUtils.equalsIgnoreCase(obj.getType(), type));
}
return stream.flatMap(obj -> obj.getNoticeMonitorPoints().stream().map(mp -> mp.getId())).collect(Collectors.toList());
}
@Override
public List<WarningVO> queryDay7warning(WarningRequest warningRequest) {
List<WarningVO> list = new ArrayList<>();
LocalDate localDate = StringUtils.isBlank(warningRequest.getDate())?LocalDate.now(): DateTimeUtil.parseDate(warningRequest.getDate());
NoticeMonitorPointQuery query = new NoticeMonitorPointQuery();
query.setTypes(Arrays.asList(WarningTypeEnum.DZZH.getCode(),WarningTypeEnum.STSK.getCode()));
query.setAreaCode(StringUtils.defaultIfBlank(warningRequest.getAreaCode(),areaCode));
List<NoticeMonitorObjectDTO> noticeMonitorObjectDTOList = noticeMonitorObjectService.listNoticeMonitorPoint(query);
List<Long> dzzhPointIds = listPointId(noticeMonitorObjectDTOList, WarningTypeEnum.DZZH.getCode());
List<Long> stskPointIds = listPointId(noticeMonitorObjectDTOList, WarningTypeEnum.STSK.getCode());
List<WarningSumVO> dzzhList = listWarnType(warningRequest,dzzhPointIds);
List<WarningSumVO> stskList = listWarnType(warningRequest,stskPointIds);
int n = 0;
while(n < 7){
String[] dateTime = DateUtil.getDateTime(localDate, -n);
WarningVO warning = new WarningVO();
warning.setDate(dateTime[0].substring(0,dateTime[0].length()-9));
warning.setDzzhSum(0L);
warning.setStskSum(0L);
list.add(warning);
n++;
}
if(dzzhList.isEmpty()&&stskList.isEmpty()){
return list;
}
list.forEach(warningVO -> {
dzzhList.forEach(dzzh->{
if(StringUtils.equals(dzzh.getDate(),warningVO.getDate())){
warningVO.setDzzhSum(dzzh.getWarningSum());
}
});
stskList.forEach(stsk->{
if(StringUtils.equals(stsk.getDate(),warningVO.getDate())){
warningVO.setStskSum(stsk.getWarningSum());
}
});
});
return list;
}
public List<WarningSumVO> listWarnType(WarningRequest warningRequest,List<Long> points){
try {
LocalDate localDate = StringUtils.isBlank(warningRequest.getDate())?LocalDate.now(): DateTimeUtil.parseDate(warningRequest.getDate());
String startTime = "";
String endTime = "";
String[] dateTime = DateUtil.getDateTime(localDate,-6);
startTime = dateTime[0];
endTime = dateTime[1];
NoticeRecordQuery noticeRecordQuery = new NoticeRecordQuery();
noticeRecordQuery.setPointIds(points);
noticeRecordQuery.setStartDate(startTime);
noticeRecordQuery.setEndDate(endTime);
List<WarningSumVO> list = noticeAlarmRecordService.countWarnType(noticeRecordQuery);
return list;
}catch (Exception e){
log.error("areacode异常", e);
return new ArrayList<>();
}
}
IDEA连接数据库,使用MybatisPlus生成所有表的entity,service,mapper和controller,再配置swagger和全局异常处理以及通用返回体,引入依赖如下:
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId>
<version>3.4.2</version>
</dependency>
<!--Mybatis-Plus-Generator-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.1</version>
<exclusions>
<exclusion>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--Velocity-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
swagger:
base-packages: com.example.trmsfile.controller
description: 文件项目接口文档
title: 文件项目接口文档
server:
port: 9090
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://172.16.218.82/trms_data?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
username: root
password: MyPass123@
servlet:
multipart:
enabled: true
max-file-size: -1
max-request-size: -1
#mybatis-plus配置
mybatis-plus:
mapper-locations: classpath*:mapper/*Mapper.xml
#实体扫描,多个package用逗号或者分号分隔
typeAliasesPackage: com.example.**.entity
#typeEnumsPackage: com.qxwz.enums
global-config:
# 关闭MP3.0自带的banner
banner: true
db-config:
#主键类型 0:"数据库ID自增", 1:"不操作", 2:"用户输入ID",3:"数字型snowflake", 4:"全局唯一ID UUID", 5:"字符串型snowflake";
id-type: assign_id
#字段策略
insert-strategy: not_null
update-strategy: not_null
select-strategy: not_empty
#驼峰下划线转换
table-underline: true
# 逻辑删除配置
# 逻辑删除全局值(1表示已删除,这也是Mybatis Plus的默认配置)
logic-delete-value: 1
# 逻辑未删除全局值(0表示未删除,这也是Mybatis Plus的默认配置)
logic-not-delete-value: 0
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
file:
path: "/Users/zuoping.liu/Documents/"
/**
* oss 业务接口
*
*/
public interface OssService {
String uploadFile (MultipartFile file, String fileName);
void preview (Long rid, HttpServletResponse response);
void downloadFile (Long rid, HttpServletResponse response) throws IOException;
void deleteOneFile (String objectName);
void deleteFileList (List<String> keys);
}
@Service
@Slf4j
public class OssServiceImpl implements OssService {
@Autowired
ReportMapper reportMapper;
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
private String baseFolder;
@PostConstruct
public void init () {
this.endpoint = "https://oss-cn-shanghai.aliyuncs.com";
//this.victoriaConfig.configs().getProperty("OSS_ENDPOINT");
this.accessKeyId = "LTAI5t8Ld9BBLiZC4Pw3R11N";
//this.victoriaConfig.configs().getProperty("OSS_KEY_ID");
this.accessKeySecret = "Dc2k4l8Et4Vot0HaR9yzRnqkNZHJPQ";
this.bucketName = "dragon-wu-2";
this.baseFolder = "trms-file";
}
@Override
public String uploadFile (MultipartFile file, String fileName) {
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
InputStream inputStream = null;
String objectName = "";
try {
inputStream = file.getInputStream();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
String date = simpleDateFormat.format(new Date());
objectName = this.baseFolder + "/" + date + "/" + UUIDUtil.getUUID() + "_" + fileName;
ossClient.putObject(bucketName, objectName, inputStream);
} catch (Exception e) {
log.error("上传文件失败", e);
}
ossClient.shutdown();
return objectName;
}
@Override
public void downloadFile (Long rid, HttpServletResponse response) throws IOException {
Report report = this.reportMapper.selectById(rid);
String objectName = report.getPath();
String title = report.getTitle();
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
OSSObject ossObject = ossClient.getObject(bucketName, objectName);
BufferedInputStream bis = new BufferedInputStream(ossObject.getObjectContent());
response.setHeader("Content-Disposition",
"attachment;filename="
+ new String(title.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
response.setHeader("Content-Type",
"application/octet-stream");
BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
this.write(bis, bos);
ossClient.shutdown();
}
@Override
public void preview (Long rid, HttpServletResponse response) {
Report report = this.reportMapper.selectById(rid);
String objectName = report.getPath();
String title = report.getTitle();
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
OSSObject ossObject = ossClient.getObject(bucketName, objectName);
InputStream fileStream = ossObject.getObjectContent();
HttpUtil.addCommonResponseHeader(title, response);
try {
BufferedInputStream bis = new BufferedInputStream(fileStream);
BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
this.write(bis, bos);
} catch (Exception e) {
log.error("预览文件失败", e);
}
ossClient.shutdown();
}
@Override
public void deleteOneFile (String objectName) {
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
ossClient.deleteObject(bucketName, objectName);
ossClient.shutdown();
}
@Override
public void deleteFileList (List<String> keys) {
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
ossClient.deleteObjects(new DeleteObjectsRequest(bucketName).withKeys(keys));
ossClient.shutdown();
}
private void write(BufferedInputStream bis, BufferedOutputStream bos) throws IOException {
int len;
byte[] b = new byte[1024];
while ((len = bis.read(b)) != -1) {
bos.write(b, 0, len);
}
bos.close();
bis.close();
}
}
public interface ReportService extends IService<Report> {
UploadFileResponse uploadFile1(MultipartFile file);
}
@Service
@Slf4j
public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> implements ReportService {
@Autowired
ReportMapper reportMapper;
@Autowired
private OssService ossService;
@Override
public UploadFileResponse uploadFile1(MultipartFile file) {
String fileName = org.springframework.util.StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename()));
if (fileName.contains("..")) {
log.error("File name contains invalid path sequence");
}
String realName = this.ossService.uploadFile(file, fileName);
Report report = new Report();
report.setUid("zuoping.liu");
report.setVersionLock(0);
report.setTitle(fileName);
report.setPath(realName);
report.setSize(FileUtil.getFileSizeDesc(file.getSize()));
LocalDateTime localDateTime = LocalDateTime.now();
report.setCreateTime(localDateTime);
report.setLastUpdateTime(localDateTime);
report.setDelFlag(false);
report.setCid0(191L);
// report表新增
int result = reportMapper.insert(report);
if (result <= 0) {
log.error("新增报告失败, sql返回结果: {}", result);
return null;
}
return new UploadFileResponse(fileName, file.getContentType(), FileUtil.getFileSizeDesc(file.getSize()), realName);
}
}
@RestController
@RequestMapping("api/trms/report")
@Api(tags = "文件项目接口")
@Slf4j
public class ReportController {
@Autowired
ReportService reportService;
@Autowired
private OssService ossService;
@ApiOperation(value = "1、上传文件",
notes = "上传文件")
@ApiOperationSupport(order = 1)
@PostMapping(value = "uploadFile1")
public Result<UploadFileResponse> uploadFile(HttpServletRequest request,
@RequestParam("file1") MultipartFile file) {
UploadFileResponse data = reportService.uploadFile1(file);
return Result.success(data);
}
@ApiOperation(value = "1、下载文件",
notes = "下载文件")
@ApiOperationSupport(order = 1)
@GetMapping("downloadFile/{rid}")
public ResponseEntity<Void> downloadFile(@PathVariable("rid") Long rid,
HttpServletResponse response,
HttpServletRequest request) throws IOException {
this.ossService.downloadFile(rid, response);
return ResponseEntity.ok().build();
}
@ApiOperation(value = "2、预览文件",
notes = "预览文件")
@ApiOperationSupport(order = 2)
@GetMapping("preview/{rid}")
public ResponseEntity<Void> preview(@PathVariable("rid") Long rid,
HttpServletResponse response,
HttpServletRequest request) {
this.ossService.preview(rid, response);
return ResponseEntity.ok().build();
}
//constant包下
public class CommonConstant {
public static final String NULL_STR = "null";
public static final String SLASH_STR = "/";
public static final String UTF_8_STR = "UTF-8";
public static final String COMMON_SEPARATOR = "__,__";
public static final String EMPTY_STR = "";
public static final String POINT_STR = ".";
public static final String HYPHEN_STR = "-";
public static final Long ZERO_LONG = 0L;
public static final Long TWO_LONG = 2L;
public static final String ZERO_STR = "0";
public static final Integer ZERO_INT = 0;
public static final Integer ONE_INT = 1;
public static final Integer TWO_INT = 2;
public static final Integer MINUS_ONE_INT = -1;
public static final String TOP_STR = "TOP";
public static final String TRUE_STR = "true";
public static final Long ONE_DAY_LONG = 24L * 60L * 60L * 1000L;
public static final Long FIVE_MINUTES_LONG = 5L * 60L * 1000L;
public static final Long ONE_HOUR_LONG = 60L * 60L * 1000L;
public static final String CONTENT_TYPE_STR = "content-type";
/**
* 登录用户ID的key
*/
public static final String LOGIN_USER_ID = "LOGIN_USER_ID";
/**
* 分享ID
*/
public static final String SHARE_ID = "SHARE_ID";
/**
* 用户登录后存储redis的key前缀
*/
public static final String USER_LOGIN_PREFIX = "USER_LOGIN_";
/**
* 用户校验分享码通过之后存储redis的key前缀
*/
public static final String SHARE_CODE_PREFIX = "SHARE_CODE_";
/**
* 跨域设置枚举类
*/
public enum CorsConfigEnum {
/**
* 允许所有远程访问
*/
CORS_ORIGIN("Access-Control-Allow-Origin", "*"),
/**
* 允许认证
*/
CORS_CREDENTIALS("Access-Control-Allow-Credentials", "true"),
/**
* 允许远程调用的请求类型
*/
CORS_METHODS("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT"),
/**
* 指定本次预检请求的有效期,单位是秒
*/
CORS_MAX_AGE("Access-Control-Max-Age", "3600"),
/**
* 允许所有请求头
*/
CORS_HEADERS("Access-Control-Allow-Headers", "*");
private String key;
private String value;
CorsConfigEnum(String key, String value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}
//exception包下
public class FileStorageException extends RuntimeException {
public FileStorageException(String message) {
super(message);
}
public FileStorageException(String message, Throwable cause) {
super(message, cause);
}
}
//resp包下
@Data
@AllArgsConstructor
public class UploadFileResponse {
private String fileName;
private String fileType;
private String fileSize;
private String realName;
}
//util包下
public class FileUtil {
private static final String KB_STR = "K";
private static final String MB_STR = "M";
private static final String GB_STR = "G";
private static final Integer UNIT = 1024;
private static final String FILE_SIZE_DESC_FORMAT = "%.2f";
/**
* 获取文件大小字符串
*/
public static String getFileSizeDesc(long size) {
double fileSize = (double) size;
String fileSizeSuffix = KB_STR;
fileSize = fileSize / UNIT;
if (fileSize > UNIT) {
fileSize = fileSize / UNIT;
fileSizeSuffix = MB_STR;
}
if (fileSize > UNIT) {
fileSize = fileSize / UNIT;
fileSizeSuffix = GB_STR;
}
return String.format(FILE_SIZE_DESC_FORMAT, fileSize) + fileSizeSuffix;
}
/**
* 通过文件名获取文件后缀
*/
public static String getFileSuffix(String fileName) {
if (StringUtils.isBlank(fileName) || (fileName.indexOf(CommonConstant.POINT_STR) == CommonConstant.MINUS_ONE_INT)) {
return CommonConstant.EMPTY_STR;
}
return fileName.substring(fileName.lastIndexOf(CommonConstant.POINT_STR)).toLowerCase();
}
}
public class HttpUtil {
/**
* 添加跨域的响应头
*
* @param response
*/
public static void addCorsResponseHeader(HttpServletResponse response) {
response.setHeader(CommonConstant.CorsConfigEnum.CORS_ORIGIN.getKey(), CommonConstant.CorsConfigEnum.CORS_ORIGIN.getValue());
response.setHeader(CommonConstant.CorsConfigEnum.CORS_CREDENTIALS.getKey(), CommonConstant.CorsConfigEnum.CORS_CREDENTIALS.getValue());
response.setHeader(CommonConstant.CorsConfigEnum.CORS_METHODS.getKey(), CommonConstant.CorsConfigEnum.CORS_METHODS.getValue());
response.setHeader(CommonConstant.CorsConfigEnum.CORS_MAX_AGE.getKey(), CommonConstant.CorsConfigEnum.CORS_MAX_AGE.getValue());
response.setHeader(CommonConstant.CorsConfigEnum.CORS_HEADERS.getKey(), CommonConstant.CorsConfigEnum.CORS_HEADERS.getValue());
}
public static void addCommonResponseHeader(String title, HttpServletResponse response) {
response.reset();
HttpUtil.addCorsResponseHeader(response);
if (title.substring(title.length()-4, title.length()).equals(".pdf")) {
response.setHeader(CommonConstant.CONTENT_TYPE_STR, "application/pdf");
response.setContentType("application/pdf");
} else if (title.substring(title.length()-4, title.length()).equals(".doc")) {
response.setHeader(CommonConstant.CONTENT_TYPE_STR, "application/msword");
response.setContentType("application/msword");
} else {
response.setHeader(CommonConstant.CONTENT_TYPE_STR, "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
}
}
}
public class UUIDUtil {
public static String getUUID() {
return UUID.randomUUID().toString().replace("-","").toUpperCase();
}
}
public interface ReportService extends IService<Report> {
void preview(Long id, HttpServletResponse response);
String storeFile(MultipartFile file);
Resource loadFileAsResource(String fileName) throws MalformedURLException;
UploadFileResponse uploadFile2(MultipartFile file);
}
@Service
@Slf4j
public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> implements ReportService {
@Autowired
ReportMapper reportMapper;
@Autowired
private OssService ossService;
@Value("${file.path}")
private String fileStorageLocation;
@Override
public UploadFileResponse uploadFile2(MultipartFile file) {
Report report = new Report();
report.setUid("zuoping.liu");
report.setVersionLock(0);
// 处理展示的重复文件名
List<String> titleList = reportMapper.selectTitleList("zuoping.liu");
String filename = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename()));
String realName = storeFile(file);
String suffix = FileUtil.getFileSuffix(filename);
StringBuilder sb = new StringBuilder();
if (!org.apache.commons.lang3.StringUtils.isBlank(filename) && titleList.contains(filename)){
List<String> filter = titleList.stream().filter(title -> title.contains(filename)
|| title.contains(filename.substring(0, filename.lastIndexOf(".")) + "(")).collect(Collectors.toList());
sb.append(filename, 0, filename.lastIndexOf("."))
.append("(")
.append(filter.size())
.append(")")
.append(FileUtil.getFileSuffix(suffix));
}else {
sb.append(filename);
}
report.setTitle(sb.toString());
report.setPath(realName);
report.setSize(FileUtil.getFileSizeDesc(file.getSize()));
LocalDateTime localDateTime = LocalDateTime.now();
report.setCreateTime(localDateTime);
report.setLastUpdateTime(localDateTime);
report.setDelFlag(false);
report.setCid0(191L);
// report表新增
int result = reportMapper.insert(report);
if (result <= 0) {
log.error("新增报告失败, sql返回结果: {}", result);
return null;
}
return new UploadFileResponse(filename,file.getContentType(),FileUtil.getFileSizeDesc(file.getSize()), realName);
}
@Override
public void preview(Long id, HttpServletResponse response) {
String path = fileStorageLocation+"/"+reportMapper.selectReportPathById(id);
if (Objects.isNull(path)) {
throw new FileStorageException("文件不存在");
}
preview(new File(path),id, response);
}
/**
* 文件预览
*/
private void preview(File file,Long id, HttpServletResponse response) {
addCommonResponseHeader(id,response);
writeFile2Response(file, response);
}
/**
* 添加公用的响应头
*/
private void addCommonResponseHeader(Long id,HttpServletResponse response) {
response.reset();
HttpUtil.addCorsResponseHeader(response);
String title = reportMapper.selectReportTitleById(id);
if(title.substring(title.length()-4,title.length()).equals(".pdf")){
response.setHeader(CommonConstant.CONTENT_TYPE_STR, "application/pdf");
response.setContentType("application/pdf");
}else if(title.substring(title.length()-4,title.length()).equals(".doc")){
response.setHeader(CommonConstant.CONTENT_TYPE_STR, "application/msword");
response.setContentType("application/msword");
}else{
response.setHeader(CommonConstant.CONTENT_TYPE_STR, "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
}
}
/**
* 单位长度
*/
private static final Integer UNIT_INT = 1024;
/**
* 文件写入响应实体
*/
private void writeFile2Response(File file, HttpServletResponse response) {
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {
byte[] buffer = new byte[UNIT_INT];
OutputStream os = response.getOutputStream();
int i = bis.read(buffer);
while (i != CommonConstant.MINUS_ONE_INT) {
os.write(buffer, CommonConstant.ZERO_INT, i);
i = bis.read(buffer);
}
} catch (Exception e) {
//log.error("文件写入响应实体失败", e);
}
}
@Override
public String storeFile(MultipartFile file) {
String filename = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename()));
String suffix = FileUtil.getFileSuffix(filename);
// 处理展示的重复文件名
List<String> titleList = reportMapper.selectTitleList("zuoping.liu");
StringBuilder sb = new StringBuilder();
if (!org.apache.commons.lang3.StringUtils.isBlank(filename) && titleList.contains(filename)){
List<String> filter = titleList.stream().filter(title -> title.contains(filename)
|| title.contains(filename.substring(0, filename.lastIndexOf(".")) + "(")).collect(Collectors.toList());
sb.append(filename, 0, filename.lastIndexOf("."))
.append("(")
.append(filter.size())
.append(")")
.append(FileUtil.getFileSuffix(suffix));
}else {
sb.append(filename);
}
try {
if (filename.contains("..")) {
throw new FileStorageException("File name contains invalid path sequence");
}
String realName = sb.toString();
String targetLocation = this.fileStorageLocation + realName;
File dest = new File(targetLocation);
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
file.transferTo(dest);
return realName;
} catch (IOException ex) {
throw new FileStorageException("Could not store file " + filename + ". Please try again later!", ex);
}
}
@Override
public Resource loadFileAsResource(String fileName) throws MalformedURLException {
Path path = Paths.get(fileStorageLocation);
Path targetPath = path.resolve(fileName).normalize();
Resource resource = new UrlResource(targetPath.toUri());
return resource;
}
}
@RestController
@RequestMapping("api/trms/report")
@Api(tags = "文件项目接口")
@Slf4j
public class ReportController {
@Autowired
ReportService reportService;
@Autowired
private OssService ossService;
@ApiOperation(value = "2、上传文件2",
notes = "上传文件2")
@ApiOperationSupport(order = 2)
@PostMapping(value = "/uploadFile2")
public Result<UploadFileResponse> uploadFile2(HttpServletRequest request,
@RequestParam("file2") MultipartFile file){
UploadFileResponse data = reportService.uploadFile2(file);
return Result.success(data);
}
@ApiOperation(value = "3、下载文件2",
notes = "下载文件")
@ApiOperationSupport(order = 3)
@GetMapping("/downloadFile")
public ResponseEntity<Resource> downloadFile2(@RequestParam("fileName") String fileName, HttpServletRequest request) throws MalformedURLException {
Resource resource = reportService.loadFileAsResource(fileName);
String contentType = null;
try{
contentType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
}catch (IOException ex){
log.info("Could not determine file type");
}
if (contentType == null){
contentType = "application/octet-stream";
}
return ResponseEntity.ok().contentType(MediaType.parseMediaType(contentType))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
.body(resource);
}
@ApiOperation(value = "4、预览文件2",
notes = "预览文件")
@ApiOperationSupport(order = 4)
@GetMapping("preview")
public void preview2(@RequestParam("id") Long id,
HttpServletResponse response){
reportService.preview(id,response);
}
}
// 处理展示的重复文件名
List<String> titleList = reportMapper.selectTitleList("zuoping.liu");
String filename = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename()));
String realName = storeFile(file);
String suffix = FileUtil.getFileSuffix(filename);
StringBuilder sb = new StringBuilder();
if (!org.apache.commons.lang3.StringUtils.isBlank(filename) && titleList.contains(filename)){
List<String> filter = titleList.stream().filter(title -> title.contains(filename)
|| title.contains(filename.substring(0, filename.lastIndexOf(".")) + " (")).collect(Collectors.toList());
sb.append(filename, 0, filename.lastIndexOf("."))
.append("(")
.append(filter.size())
.append(")")
.append(FileUtil.getFileSuffix(suffix));
}else {
sb.append(filename);
}
report.setTitle(sb.toString());
compute() 方法对 hashMap 中指定 key 的值进行重新计算。
@Select("select uid, count(*) from report where YEARWEEK( date_format( create_time,'%Y-%m-%d' ) ) = YEARWEEK( now() ) group by uid order by count(*) desc")
List<Map<Object, Object>> selectWeekDetail();
List<Map<Object, Object>> maps1 = this.reportMapper.selectWeekDetail();
Map<String, Object> weekData = new HashMap<>();
for (Map<Object, Object> map : maps1) {
String uid = (String) map.get("uid");
String fullName = commonServiceImpl.getStaffNameByDomain(uid);
weekData.put(fullName, map.get("count(*)"));
}
weekData.compute(key, (k, v) -> {
if (v == null) {
item.setWeekUpload(0l);
return 0;
} else {
item.setWeekUpload((Long)v);
return v;
}
});
List<ItemAnalysis> itemAnalyses = new ArrayList<>();
itemAnalyses.sort((r1, r2) -> {
Long t1 = r1.getTotalUpload();
Long t2 = r2.getTotalUpload();
return t2.compareTo(t1);//倒序排序;t1.compareTo(t2):正序排序
});
//本周
//detail
List<Map<Object, Object>> maps1 = this.reportMapper.selectWeekDetail();
//报告总数
Long weekUpload = this.reportMapper.selectWeekUpload();
//上周报告总数
Long lastWeekUpload = this.reportMapper.selectLastWeekUpload();
@Select("select count(*) from report where YEARWEEK( date_format( create_time,'%Y-%m-%d' ) ) = YEARWEEK( now() )")
Long selectWeekUpload();
@Select("select count(*) from report where YEARWEEK(date_format(create_time,'%Y-%m-%d')) = YEARWEEK(now())-1")
Long selectLastWeekUpload();
@Table(name = "category")
@Data
public class Category implements Serializable {
@Id
@KeySql(useGeneratedKeys = true)
private Long id;
private Long parentId;
private Integer access;
private Boolean isParent;
private String name;
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
private Date lastUpdateTime;
private transient List<Map<String, Long>> referList;
}
@Data
@Table(name = "sys_group")
public class Group implements Serializable {
@Id
@KeySql(useGeneratedKeys = true)
private Long id;
private String name;
private String description;
private Boolean isExclusive;
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
private Date lastUpdateTime;
private transient List<Map<String, String>> memberList;
private transient List<Map<String, Long>> referList;
}
<resultMap id="categoryMap" type="com.qxwz.qa.trms.pojo.Category">
<result property="id" jdbcType="BIGINT" column="id" javaType="Long"/>
<result property="parentId" jdbcType="BIGINT" column="parent_id" javaType="Long"/>
<result property="name" jdbcType="VARCHAR" column="name"/>
<result property="access" jdbcType="INTEGER" column="access"/>
<result property="lastUpdateTime" jdbcType="TIMESTAMP" column="last_update_time"/>
<collection property="referList" resultMap="referMap"/>
</resultMap>
<resultMap id="referMap" type="Map">
<result property="key" jdbcType="BIGINT" column="rid" javaType="Long"/>
</resultMap>
<select id="selectAllWithRefer" resultMap="categoryMap">
SELECT c.*, r.id rid
FROM category c
left join report r on r.cid = c.id or r.cid0 = c.id
order by c.id
</select>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.qxwz.qa.trms.mapper.GroupMapper">
<resultMap id="groupMap" type="com.qxwz.qa.trms.pojo.Group">
<result property="id" jdbcType="BIGINT" column="id" javaType="Long"/>
<result property="name" jdbcType="VARCHAR" column="name"/>
<result property="description" jdbcType="VARCHAR" column="description"/>
<result property="lastUpdateTime" jdbcType="TIMESTAMP" column="last_update_time"/>
<collection property="memberList" resultMap="memberMap"/>
<collection property="referList" resultMap="referMap"/>
</resultMap>
<resultMap id="memberMap" type="Map">
<result property="key" jdbcType="VARCHAR" column="user_key" javaType="String"/>
</resultMap>
<resultMap id="referMap" type="Map">
<result property="key" jdbcType="BIGINT" column="group_id" javaType="Long"/>
</resultMap>
<select id="selectAllWithMemberAndRefer" resultMap="groupMap">
SELECT sg.*, gu.user_key, rg.group_id
FROM sys_group sg
left join group_user gu on gu.group_id = sg.id
left join report_group_access rg on rg.group_id = sg.id
where sg.is_exclusive = 0
order by sg.id
</select>
</mapper>
@Override
public List<Category> queryCategoryListByIds(List<Long> cids) {
return this.categoryMapper.selectByIds(cids);
}
@Select("<script>" +
"select * from category where id in " +
"<foreach collection='list' open='(' item='id' separator=',' close=')'> #{id}" +
"</foreach>" +
"</script>")
List<Category> selectByIds(List<Long> cids);
/**
* 题目要求: 一分钟内完成此题:只能用一行代码实现!
* 现有5个用户!筛选:
* 1. ID必须是偶数
* 2. 年龄必须大于23岁
* 3. 用户名转为大写字母
* 4. 用户名字母倒着排序
* 5. 只输出一个用户!
*/
public class Test {
public static void main(String[] args) {
User u1 = new User(1, "a", 21);
User u2 = new User(2, "b", 22);
User u3 = new User(3, "c", 23);
User u4 = new User(4, "d", 24);
User u5 = new User(6, "e", 25);
// 集合就是存储
List<User> users = Arrays.asList(u1, u2, u3, u4, u5);
users.stream()
.filter(u -> u.getId() % 2 == 0)
.filter(u -> u.getAge() > 23)
.map(u -> u.getName().toUpperCase())
.sorted(Comparator.reverseOrder())
.limit(1)
.forEach(System.out::println);
}
}
List<String> fullNameList = staffList.stream()
.map(item -> commonService.getStaffNameByDomain(item))
.filter(item -> !item.isEmpty())
.collect(Collectors.toList());
List<Group> groups = this.queryAllWithMemberAndRefer();
List<String> lists = new ArrayList<>();
for (Group group : groups) {
List<String> staffNames = group.getMemberList()
.stream().map(item -> item.get("key"))
.collect(Collectors.toList());
StringBuilder sb = new StringBuilder();
for (String member : staffNames) {
String fullName = commonService.getStaffNameByDomain(member);
if (StringUtils.isNotEmpty(fullName)) {
sb.append(fullName);
if (staffNames.indexOf(member) != staffNames.size()-1) {
sb.append(", ");
}
}
}
lists.add(sb.toString());
}
return lists;
//exception包下新增
public class BusinessException extends RuntimeException{
private int code;
private String msg;
public BusinessException(int code, String msg){
super(msg);
this.code = code;
this.msg = msg;
}
public BusinessException(){}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
public class FileStorageException extends RuntimeException {
public FileStorageException(String message) {
super(message);
}
public FileStorageException(String message, Throwable cause) {
super(message, cause);
}
}
@RestControllerAdvice
public class GlobalExceptionHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(value = BusinessException.class)
public JsonData handleBusinessException(BusinessException e, HttpServletRequest request){
LOGGER.error("url {}, code {}, msg {}", request.getRequestURL(), e.getCode(), e.getMsg());
return new JsonData(e.getCode(), e.getMsg());
}
@ExceptionHandler(value = HttpMessageNotReadableException.class)
public JsonData<Object> handleHttpMessageNotReadableException(HttpMessageNotReadableException e, HttpServletRequest request){
LOGGER.error("url {}, msg {}", request.getRequestURL(), e.getMessage());
return new JsonData<>(StateType.BAD_REQUEST.getCode(), "缺少必需的请求参数");
}
@ExceptionHandler(value = Exception.class)
public JsonData<Object> handleException(Exception e, HttpServletRequest request){
LOGGER.error("url {}, msg {}", request.getRequestURL(), e.getMessage());
return new JsonData<>(StateType.INTERNAL_SERVER_ERROR.getCode(),StateType.INTERNAL_SERVER_ERROR.value());
}
}
@Override
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
public Long create(AlarmConfigCreateRequest request, String createUser) {
request.validate();
Long id = alarmConfigDao.save(alarmConfigConvertor.request2Entity(request, createUser));
saveRule(request.getFieldConfig(), id);
return id;
}
@Slf4j
@Component
public class AlarmConfigConvertor {
public NoticeAlarmConfigEntity request2Entity(AlarmConfigCreateRequest request, String createUser) {
return Optional.ofNullable(request)
.map(s -> new NoticeAlarmConfigEntity()
.setEnv(AppEnv.getDeployEnv())
.setItemType(s.getItemCode())
.setName(s.getName())
.setObjectId(s.getObjectId())
.setSendFrequency(s.getSendFrequency())
.setConfigStatus(AlarmConfigStatusConstant.ENABLE)
.setPoints(JSON.toJSONString(s.getPointIdList()))
.setIsDeleted(false)
.setCreateUser(createUser)
.setModifyUser(createUser))
.orElse(null);
}
public List<FieldSummary> indexConfig2FieldSummaryList(List<NoticeIndexConfigEntity> source) {
return Optional.ofNullable(source).map(entities ->
entities.stream().map(x -> indexConfig2FieldSummary(x)).collect(Collectors.toList())
).orElse(new ArrayList<>());
}
public FieldSummary indexConfig2FieldSummary(NoticeIndexConfigEntity source) {
return Optional.ofNullable(source).map(x -> new FieldSummary()
.setKey(x.getSensorIndex())
.setName(x.getSensorIndexName())
.setUnitCode(x.getUnit())
.setUnitName(x.getUnitName())
.setDesc(x.getRemark())).orElse(null);
}
}
@Component
public class NoticeItemAuth implements BaseAuthData{
@Autowired
private MonitorObjectDao monitorObjectDao;
@Autowired
private MonitorObjectMemberRefDao monitorObjectMemberRefDao;
@Autowired
private MonitorObjectPointRefDao monitorObjectPointRefDao;
@Autowired
private MonitorPointDao monitorPointDao;
@Autowired
private MonitorItemDao monitorItemDao;
@Override
public List<NoticeItemAuthModel> getAuthList(SessionInfoUser user) {
// 获取监测对象信息
List<Long> objectIds = Lists.newArrayList();
if (LoginMemberTypeEnum.SUB_USER.getValue().equals(user.getLoginMemberType())) {
objectIds = monitorObjectMemberRefDao.queryObjectIdListByUserId(user.getSessionInfoSubUser().getSubMemberId());
if (CollectionUtils.isNotEmpty(objectIds)) {
objectIds.addAll(Optional.ofNullable(monitorObjectMemberRefDao.queryObjectIdListByUserId(user.getSessionInfoSubUser().getSubMemberId()))
.orElseGet(ArrayList::new));
}
} else {
objectIds.addAll(Optional.ofNullable(monitorObjectDao.queryList(new NoticeMonitorObjectEntity().setCreateUser(String.valueOf(user.getMemberId())), Lists.newArrayList()))
.orElseGet(ArrayList::new)
.stream()
.map(NoticeMonitorObjectEntity::getId)
.collect(Collectors.toList()));
}
List<Long> pointIds = Lists.newArrayList();
// 获取监测点信息
if (CollectionUtils.isNotEmpty(objectIds)) {
List<String> pointCodeList = monitorObjectPointRefDao.queryByMonitorIds(objectIds);
if (CollectionUtils.isNotEmpty(pointCodeList)) {
pointIds.addAll(Optional.ofNullable(monitorPointDao.queryIdByCode(pointCodeList)).orElseGet(ArrayList::new));
}
}
// 获取检测项信息
if (CollectionUtils.isNotEmpty(pointIds)) {
return Optional.ofNullable(monitorItemDao.queryListByPointIds(pointIds))
.orElseGet(ArrayList::new)
.stream()
.map(item -> {
NoticeItemAuthModel model = new NoticeItemAuthModel();
model.setId(item.getId());
return model;
})
.collect(Collectors.toList());
}
return Lists.newArrayList();
}
}
@Data
@Accessors(chain = true)
public class CommonQueryResult implements Serializable {
private static final long serialVersionUID = -7168106982749055931L;
/**
* 度量
*/
private String metric;
/**
* 标签 map
*/
private Map<String, String> tags;
/**
* 聚合tag列表
*/
private List<String> aggregateTags;
/**
* 值 map
*/
private LinkedHashMap<Long, Object> dps = new LinkedHashMap<>();
}
@Slf4j
@Component
public class AliTsdbConvertor {
@Autowired
private IndexConfigService indexConfigService;
public List<CommonQueryResult> convertResultList(List<QueryResult> source) {
return Optional.ofNullable(source)
.map(result -> result.stream().map(x -> convertResult(x)).collect(Collectors.toList()))
.orElse(null);
}
public CommonQueryResult convertResult( QueryResult source) {
return Optional.ofNullable(source).map(result -> new CommonQueryResult()
.setAggregateTags(result.getAggregateTags())
.setDps(result.getDps())
.setMetric(result.getMetric())
.setTags(result.getTags())
.setAggregateTags(result.getAggregateTags()))
.orElse(null);
}
/**
* 将tsdb度量转成测值key,如 L1_JS-gX 转为 gX
* @param metric 度量
* @return 测值
*/
private NoticeIndexConfigEntity getIndexByMetric(String metric) {
return indexConfigService.queryByMetric(metric);
}
public List<ItemDataResponse> convertResponseList(List<CommonQueryResult> source, DataQuery dataQuery) {
if (CollectionUtils.isEmpty(source)) {
return null;
}
LinkedHashMap<Long, List<ItemIndex>> dataMap = new LinkedHashMap<>(source.size() + 1);
source.stream().forEach(data -> {
NoticeIndexConfigEntity indexConfig = indexConfigService.queryByMetric(data.getMetric());
Optional.ofNullable(data.getDps()).ifPresent(x -> {
x.entrySet().stream().forEachOrdered(entity -> {
List<ItemIndex> indexList = Lists.newArrayList();
Long timeStamp = entity.getKey();
if (dataMap.containsKey(timeStamp)) {
indexList = dataMap.get(timeStamp);
}
DataUnit dataUnit = null ;
String indexKey = null;
Double value = null == entity.getValue()? null : (Double) entity.getValue();
if (Objects.nonNull(dataQuery) && Boolean.TRUE.equals(dataQuery.getRate())) {
if (null != indexConfig) {
indexKey = indexConfig.getSensorIndex();
dataUnit = new DataUnit().setCode(this.unitFormate(indexConfig, dataQuery)).setName(this.unitNameFormate(indexConfig, dataQuery));
}
indexList.add(new ItemIndex().setKey(indexKey)
.setValue(this.rateFormate(value,dataQuery))
.setUnit(dataUnit));
} else {
if (null != indexConfig) {
indexKey = indexConfig.getSensorIndex();
dataUnit = new DataUnit().setCode(indexConfig.getUnit()).setName(indexConfig.getUnitName());
}
indexList.add(new ItemIndex().setKey(indexKey)
.setValue(value)
.setUnit(dataUnit));
}
dataMap.put(entity.getKey(), indexList);
});
});
});
return dataMap.entrySet()
.stream()
.map(entry -> new ItemDataResponse().setTimeStamp(entry.getKey()).setDataList(entry.getValue()))
.collect(Collectors.toList());
}
/**
* 格式化变化率
* @param rate
* @param dataQuery
* @return
*/
private Double rateFormate(Double rate, DataQuery dataQuery) {
if (Objects.isNull(rate)) {
return rate;
}
if (StringUtils.isBlank(dataQuery.getDownsample())) {
return rate;
}
BigDecimal formateRate = new BigDecimal(rate);
switch(dataQuery.getDownsample()) {
case "1h-avg" :
formateRate = formateRate.multiply(new BigDecimal(60 * 60));
break;
case "1dc-avg" :
formateRate = formateRate.multiply(new BigDecimal(60 * 60 * 24));
break;
case "1wc-avg" :
formateRate = formateRate.multiply(new BigDecimal(60 * 60 * 24 * 7));
break;
default:
}
return formateRate.doubleValue();
}
/**
* 变化率英文单位格式化
* @param indexConfig
* @param dataQuery
* @return
*/
private String unitFormate(NoticeIndexConfigEntity indexConfig, DataQuery dataQuery) {
String unitCode = indexConfig.getUnit();
switch(dataQuery.getDownsample()) {
case "1h-avg" :
unitCode = String.format("%s/%s",indexConfig.getUnit(), "hour");
break;
case "1dc-avg" :
unitCode = String.format("%s/%s",indexConfig.getUnit(), "day");
break;
case "1wc-avg" :
unitCode = String.format("%s/%s",indexConfig.getUnit(), "week");
break;
default:
unitCode = String.format("%s/%s",indexConfig.getUnit(), "s");
break;
}
return unitCode;
}
/**
* 变化率中文单位格式化
* @param indexConfig
* @param dataQuery
* @return
*/
private String unitNameFormate(NoticeIndexConfigEntity indexConfig, DataQuery dataQuery) {
String unitName = indexConfig.getUnit();
switch(dataQuery.getDownsample()) {
case "1h-avg" :
unitName = String.format("%s/%s",indexConfig.getUnitName(), "小时");
break;
case "1dc-avg" :
unitName = String.format("%s/%s",indexConfig.getUnitName(), "天");
break;
case "1wc-avg" :
unitName = String.format("%s/%s",indexConfig.getUnitName(), "周");
break;
default:
unitName = String.format("%s/%s",indexConfig.getUnitName(), "秒");
break;
}
return unitName;
}
}
@Override
public List<RainfallCalendarResponse> queryRainfallCalendar(Long pointId, Long startTime, Long endTime) {
Map<ItemEnum, List<String>> rainfallConfigs = Maps.newHashMap();
rainfallConfigs.put(ItemEnum.L3_YL, Arrays.asList(totalValueIndex));
ThemeAnalysisUtilsBo checkRainfall = themeAnalysisUtils.check(pointId, rainfallConfigs);
List<ItemDataResponse> rainfallResp = themeAnalysisUtils.queryTsdb(Lists.newArrayList(checkRainfall), startTime, endTime, TimeScaleEnum.last_day);
return rainfallResp.stream().map(response ->
new RainfallCalendarResponse()
.setTimeStamp(response.getTimeStamp())
.setDailyRainfallAccumulation(new BigDecimal(response.getDataList()
.stream()
.filter(itemIndex -> totalValueIndex.equals(itemIndex.getKey()))
.findFirst()
.orElseGet(() -> new ItemIndex().setValue(0D))
.getValue())
.setScale(2, RoundingMode.HALF_UP)))
.collect(Collectors.toList());
}
Resttemplate
/**
* RestTemplate 远程调用工具类
*
* @author jiang.peng
* @createDate 2021-12-10
*
*/
public class RestTemplateUtils {
private static final RestTemplate restTemplate = new RestTemplate();
// ----------------------------------GET-------------------------------------------------------
/**
* GET请求调用方式
*
* @param url 请求URL
* @param responseType 返回对象类型
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> get(String url, Class<T> responseType) {
return restTemplate.getForEntity(url, responseType);
}
/**
* GET请求调用方式
*
* @param url 请求URL
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> get(String url, Class<T> responseType, Object... uriVariables) {
return restTemplate.getForEntity(url, responseType, uriVariables);
}
/**
* GET请求调用方式
*
* @param url 请求URL
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> get(String url, Class<T> responseType, Map<String, ?> uriVariables) {
return restTemplate.getForEntity(url, responseType, uriVariables);
}
/**
* 带请求头的GET请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> get(String url, Map<String, String> headers, Class<T> responseType, Object... uriVariables) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setAll(headers);
return get(url, httpHeaders, responseType, uriVariables);
}
/**
* 带请求头的GET请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> get(String url, HttpHeaders headers, Class<T> responseType, Object... uriVariables) {
HttpEntity<?> requestEntity = new HttpEntity<>(headers);
return exchange(url, HttpMethod.GET, requestEntity, responseType, uriVariables);
}
/**
* 带请求头的GET请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> get(String url, Map<String, String> headers, Class<T> responseType, Map<String, ?> uriVariables) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setAll(headers);
return get(url, httpHeaders, responseType, uriVariables);
}
/**
* 带请求头的GET请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> get(String url, HttpHeaders headers, Class<T> responseType, Map<String, ?> uriVariables) {
HttpEntity<?> requestEntity = new HttpEntity<>(headers);
return exchange(url, HttpMethod.GET, requestEntity, responseType, uriVariables);
}
// ----------------------------------POST-------------------------------------------------------
/**
* POST请求调用方式
*
* @param url 请求URL
* @param responseType 返回对象类型
* @return
*/
public static <T> ResponseEntity<T> post(String url, Class<T> responseType) {
return restTemplate.postForEntity(url, HttpEntity.EMPTY, responseType);
}
/**
* POST请求调用方式
*
* @param url 请求URL
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> post(String url, Object requestBody, Class<T> responseType) {
return restTemplate.postForEntity(url, requestBody, responseType);
}
/**
* POST请求调用方式
*
* @param url 请求URL
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> post(String url, Object requestBody, Class<T> responseType, Object... uriVariables) {
return restTemplate.postForEntity(url, requestBody, responseType, uriVariables);
}
/**
* POST请求调用方式
*
* @param url 请求URL
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> post(String url, Object requestBody, Class<T> responseType, Map<String, ?> uriVariables) {
return restTemplate.postForEntity(url, requestBody, responseType, uriVariables);
}
/**
* 带请求头的POST请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> post(String url, Map<String, String> headers, Object requestBody, Class<T> responseType, Object... uriVariables) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setAll(headers);
return post(url, httpHeaders, requestBody, responseType, uriVariables);
}
/**
* 带请求头的POST请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> post(String url, HttpHeaders headers, Object requestBody, Class<T> responseType, Object... uriVariables) {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
return post(url, requestEntity, responseType, uriVariables);
}
/**
* 带请求头的POST请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> post(String url, Map<String, String> headers, Object requestBody, Class<T> responseType, Map<String, ?> uriVariables) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setAll(headers);
return post(url, httpHeaders, requestBody, responseType, uriVariables);
}
/**
* 带请求头的POST请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> post(String url, HttpHeaders headers, Object requestBody, Class<T> responseType, Map<String, ?> uriVariables) {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
return post(url, requestEntity, responseType, uriVariables);
}
/**
* 自定义请求头和请求体的POST请求调用方式
*
* @param url 请求URL
* @param requestEntity 请求头和请求体封装对象
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> post(String url, HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) {
return restTemplate.exchange(url, HttpMethod.POST, requestEntity, responseType, uriVariables);
}
/**
* 自定义请求头和请求体的POST请求调用方式
*
* @param url 请求URL
* @param requestEntity 请求头和请求体封装对象
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> post(String url, HttpEntity<?> requestEntity, Class<T> responseType, Map<String, ?> uriVariables) {
return restTemplate.exchange(url, HttpMethod.POST, requestEntity, responseType, uriVariables);
}
// ----------------------------------PUT-------------------------------------------------------
/**
* PUT请求调用方式
*
* @param url 请求URL
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> put(String url, Class<T> responseType, Object... uriVariables) {
return put(url, HttpEntity.EMPTY, responseType, uriVariables);
}
/**
* PUT请求调用方式
*
* @param url 请求URL
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> put(String url, Object requestBody, Class<T> responseType, Object... uriVariables) {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody);
return put(url, requestEntity, responseType, uriVariables);
}
/**
* PUT请求调用方式
*
* @param url 请求URL
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> put(String url, Object requestBody, Class<T> responseType, Map<String, ?> uriVariables) {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody);
return put(url, requestEntity, responseType, uriVariables);
}
/**
* 带请求头的PUT请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> put(String url, Map<String, String> headers, Object requestBody, Class<T> responseType, Object... uriVariables) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setAll(headers);
return put(url, httpHeaders, requestBody, responseType, uriVariables);
}
/**
* 带请求头的PUT请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> put(String url, HttpHeaders headers, Object requestBody, Class<T> responseType, Object... uriVariables) {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
return put(url, requestEntity, responseType, uriVariables);
}
/**
* 带请求头的PUT请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> put(String url, Map<String, String> headers, Object requestBody, Class<T> responseType, Map<String, ?> uriVariables) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setAll(headers);
return put(url, httpHeaders, requestBody, responseType, uriVariables);
}
/**
* 带请求头的PUT请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> put(String url, HttpHeaders headers, Object requestBody, Class<T> responseType, Map<String, ?> uriVariables) {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
return put(url, requestEntity, responseType, uriVariables);
}
/**
* 自定义请求头和请求体的PUT请求调用方式
*
* @param url 请求URL
* @param requestEntity 请求头和请求体封装对象
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> put(String url, HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) {
return restTemplate.exchange(url, HttpMethod.PUT, requestEntity, responseType, uriVariables);
}
/**
* 自定义请求头和请求体的PUT请求调用方式
*
* @param url 请求URL
* @param requestEntity 请求头和请求体封装对象
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> put(String url, HttpEntity<?> requestEntity, Class<T> responseType, Map<String, ?> uriVariables) {
return restTemplate.exchange(url, HttpMethod.PUT, requestEntity, responseType, uriVariables);
}
// ----------------------------------DELETE-------------------------------------------------------
/**
* DELETE请求调用方式
*
* @param url 请求URL
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, Class<T> responseType, Object... uriVariables) {
return delete(url, HttpEntity.EMPTY, responseType, uriVariables);
}
/**
* DELETE请求调用方式
*
* @param url 请求URL
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, Class<T> responseType, Map<String, ?> uriVariables) {
return delete(url, HttpEntity.EMPTY, responseType, uriVariables);
}
/**
* DELETE请求调用方式
*
* @param url 请求URL
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, Object requestBody, Class<T> responseType, Object... uriVariables) {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody);
return delete(url, requestEntity, responseType, uriVariables);
}
/**
* DELETE请求调用方式
*
* @param url 请求URL
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, Object requestBody, Class<T> responseType, Map<String, ?> uriVariables) {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody);
return delete(url, requestEntity, responseType, uriVariables);
}
/**
* 带请求头的DELETE请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, Map<String, String> headers, Class<T> responseType, Object... uriVariables) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setAll(headers);
return delete(url, httpHeaders, responseType, uriVariables);
}
/**
* 带请求头的DELETE请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, HttpHeaders headers, Class<T> responseType, Object... uriVariables) {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(headers);
return delete(url, requestEntity, responseType, uriVariables);
}
/**
* 带请求头的DELETE请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, Map<String, String> headers, Class<T> responseType, Map<String, ?> uriVariables) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setAll(headers);
return delete(url, httpHeaders, responseType, uriVariables);
}
/**
* 带请求头的DELETE请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, HttpHeaders headers, Class<T> responseType, Map<String, ?> uriVariables) {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(headers);
return delete(url, requestEntity, responseType, uriVariables);
}
/**
* 带请求头的DELETE请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, Map<String, String> headers, Object requestBody, Class<T> responseType, Object... uriVariables) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setAll(headers);
return delete(url, httpHeaders, requestBody, responseType, uriVariables);
}
/**
* 带请求头的DELETE请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, HttpHeaders headers, Object requestBody, Class<T> responseType, Object... uriVariables) {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
return delete(url, requestEntity, responseType, uriVariables);
}
/**
* 带请求头的DELETE请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, Map<String, String> headers, Object requestBody, Class<T> responseType, Map<String, ?> uriVariables) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setAll(headers);
return delete(url, httpHeaders, requestBody, responseType, uriVariables);
}
/**
* 带请求头的DELETE请求调用方式
*
* @param url 请求URL
* @param headers 请求头参数
* @param requestBody 请求参数体
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, HttpHeaders headers, Object requestBody, Class<T> responseType, Map<String, ?> uriVariables) {
HttpEntity<Object> requestEntity = new HttpEntity<Object>(requestBody, headers);
return delete(url, requestEntity, responseType, uriVariables);
}
/**
* 自定义请求头和请求体的DELETE请求调用方式
*
* @param url 请求URL
* @param requestEntity 请求头和请求体封装对象
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) {
return restTemplate.exchange(url, HttpMethod.DELETE, requestEntity, responseType, uriVariables);
}
/**
* 自定义请求头和请求体的DELETE请求调用方式
*
* @param url 请求URL
* @param requestEntity 请求头和请求体封装对象
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> delete(String url, HttpEntity<?> requestEntity, Class<T> responseType, Map<String, ?> uriVariables) {
return restTemplate.exchange(url, HttpMethod.DELETE, requestEntity, responseType, uriVariables);
}
// ----------------------------------通用方法-------------------------------------------------------
/**
* 通用调用方式
*
* @param url 请求URL
* @param method 请求方法类型
* @param requestEntity 请求头和请求体封装对象
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,按顺序依次对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) {
return restTemplate.exchange(url, method, requestEntity, responseType, uriVariables);
}
/**
* 通用调用方式
*
* @param url 请求URL
* @param method 请求方法类型
* @param requestEntity 请求头和请求体封装对象
* @param responseType 返回对象类型
* @param uriVariables URL中的变量,与Map中的key对应
* @return ResponseEntity 响应对象封装类
*/
public static <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Map<String, ?> uriVariables) {
return restTemplate.exchange(url, method, requestEntity, responseType, uriVariables);
}
/**
* 获取RestTemplate实例对象,可自由调用其方法
*
* @return RestTemplate实例对象
*/
public static RestTemplate getRestTemplate() {
return restTemplate;
}
}
@Component("ysy")
@Slf4j
@ConditionalOnProperty(name = "video.service.provider", havingValue = "ysy")
public class YsyVideoServiceImpl implements VideoService {
private static final String CODE_SUCCESS = "200";
/**
* 通道号
*/
private static final int VIDEO_CHANNEL_NO = 1;
/**
* 视频播放速度,0-慢,1-适中,2-快,海康设备参数不可为0
*/
private static final int VIDEO_SPEED = 1;
@Autowired
private DeviceServiceSide deviceServiceSide;
@Autowired
private ThreadPoolTaskExecutor executor;
@Value("${ysy.service.host:https://open.ys7.com}")
private String serviceHost;
@Value("${ysy.service.url.live_address:/api/lapp/v2/live/address/get}")
private String liveAddressUrl;
@Value("${ysy.service.url.ptz:/api/lapp/device/ptz/start}")
private String ptzUrl;
@Value("${ysy.service.url.ptz:/api/lapp/device/ptz/stop}")
private String stopPtzUrl;
/**
* 设备操作单次时间
*/
@Value("${ysy.service.ptz.ms:1000}")
private int ptzTime;
/**
* 上一次的视频操作
*/
private ThreadLocal<Integer> currentOperation;
@Override
public DeviceVideoStreamResponse getDeviceStreamUrl(Long deviceId) {
//获取设备信息
YsyDevice ysyDevice = deviceServiceSide.getVideoDeviceDetail(deviceId);
if (null == ysyDevice) {
throw new ApiException(ErrorCode.INTERNAL_ERROR, "获取不到视频设备信息");
}
log.info("getVideoDeviceDetail:{}", ysyDevice.toString());
String accessToken = ysyDevice.getAccessToken();
String requestUrl = serviceHost + liveAddressUrl;
Map<String, Object> params = new HashMap<>();
params.put("accessToken", accessToken);
params.put("deviceSerial", ysyDevice.getDeviceSerial());
ResponseEntity<String> response = RestTemplateUtils.post(buildRealUrl(requestUrl, params), HttpEntity.EMPTY, String.class, params);
String body = response.getBody();
if (StringUtils.isNotBlank(body)) {
JSONObject jb = JSON.parseObject(body);
String code = jb.getString("code");
if (CODE_SUCCESS.equalsIgnoreCase(code)) {
Map dataMap = jb.getObject("data", Map.class);
String videoUrl = (String) dataMap.get("url");
return new DeviceVideoStreamResponse().setUrl(videoUrl).setAccessToken(accessToken);
} else {
log.info("[{}]获取视频流地址失败,错误码:{}", deviceId, code);
throw new ApiException(ErrorCode.INTERNAL_ERROR, "获取视频流地址失败!");
}
} else {
log.info("获取视频流地址失败,body is empty");
throw new ApiException(ErrorCode.INTERNAL_ERROR, "获取视频流地址失败!");
}
}
@Override
public void deviceOperation(Long deviceId, int operation) {
//获取设备信息
YsyDevice ysyDevice = deviceServiceSide.getVideoDeviceDetail(deviceId);
log.info("getVideoDeviceDetail:{}", ysyDevice.toString());
String requestUrl = serviceHost + ptzUrl;
Map<String, Object> params = new HashMap<>();
params.put("accessToken", ysyDevice.getAccessToken());
params.put("deviceSerial", ysyDevice.getDeviceSerial());
params.put("channelNo", VIDEO_CHANNEL_NO);
params.put("direction", operation);
params.put("speed", VIDEO_SPEED);
ResponseEntity<String> response = RestTemplateUtils.post(buildRealUrl(requestUrl, params), HttpEntity.EMPTY, String.class, params);
String body = response.getBody();
if (StringUtils.isNotBlank(body)) {
JSONObject jb = JSON.parseObject(body);
String code = jb.getString("code");
if (!CODE_SUCCESS.equalsIgnoreCase(code)) {
log.info("[{}]视频操作失败,错误码:{}", deviceId, code);
throw new ApiException(ErrorCode.INTERNAL_ERROR, jb.getString("msg"));
} else {
//成功后需要停止,否则会一直转动
executor.execute(() -> {
try {
Thread.sleep(ptzTime);
stopOperation(ysyDevice);
} catch (Exception e) {
log.error("e:{}", e);
}
});
}
} else {
log.info("视频操作失败,body is empty");
throw new ApiException(ErrorCode.INTERNAL_ERROR, "操作失败!");
}
}
/**
* 停止视频操作
* @param device 设备信息
* @return void
*/
private void stopOperation(YsyDevice device) {
String requestUrl = serviceHost + stopPtzUrl;
Map<String, Object> params = new HashMap<>();
params.put("accessToken", device.getAccessToken());
params.put("deviceSerial", device.getDeviceSerial());
params.put("channelNo", VIDEO_CHANNEL_NO);
// Integer operation = currentOperation.get();
// if (null == operation) {
// params.put("direction", operation);
// }
ResponseEntity<String> response = RestTemplateUtils.post(buildRealUrl(requestUrl, params), HttpEntity.EMPTY, String.class, params);
String body = response.getBody();
if (StringUtils.isNotBlank(body)) {
JSONObject jb = JSON.parseObject(body);
String code = jb.getString("code");
if (!CODE_SUCCESS.equalsIgnoreCase(code)) {
log.info("[{}]视频停止操作失败,错误码:{}", device, code);
}
} else {
log.info("获取视频流地址失败,body is empty");
}
}
/**
* 构建实际的请求地址url
* @param url 请求host
* @param params 参数列表
* @return
*/
private String buildRealUrl(String url, Map<String, Object> params) {
if (null == params || params.isEmpty()) {
return url;
}
StringBuilder sb = new StringBuilder().append(url).append("?");
params.keySet().forEach(key -> sb.append(key).append("={").append(key).append("}&"));
//去掉最后一个&
sb.deleteCharAt(sb.length() - 1);
return sb.toString();
}
}
// 查询日累计雨量
List<RainfallCalendarResponse> rainfallCalendarResponseList = this.queryRainfallCalendar(pointId, startTime, endTime);
// 计算总累计雨量
Map<Long, BigDecimal> sumMap = Maps.newHashMap();
List<BigDecimal> values = rainfallCalendarResponseList.stream()
.map(RainfallCalendarResponse::getDailyRainfallAccumulation)
.collect(Collectors.toList());
for (int i=0; i<rainfallCalendarResponseList.size(); i++) {
sumMap.put(rainfallCalendarResponseList.get(i).getTimeStamp(),
values.subList(0, i+1).stream().reduce(BigDecimal.ZERO, BigDecimal::add));
}
return rainfallCalendarResponseList.stream().map(item -> new RainfallAnalysisResponse()
.setTimeStamp(item.getTimeStamp())
.setDailyRainfallAccumulation(item.getDailyRainfallAccumulation())
.setSingleRainfallAccumulation(singleMap.get(item.getTimeStamp()))
.setTotalRainfallAccumulation(sumMap.get(item.getTimeStamp())))
.collect(Collectors.toList());
List<ItemDataResponse> rainfallResp = themeAnalysisUtils.queryTsdb(Lists.newArrayList(checkRainfall), startTime, endTime, TimeScaleEnum.last_day);
return rainfallResp.stream().map(response ->
new RainfallCalendarResponse()
.setTimeStamp(response.getTimeStamp())
.setDailyRainfallAccumulation(new BigDecimal(response.getDataList()
.stream()
.filter(itemIndex -> totalValueIndex.equals(itemIndex.getKey()))
.findFirst()
.orElseGet(() -> new ItemIndex().setValue(0D))
.getValue())
.setScale(2, RoundingMode.HALF_UP)))
.collect(Collectors.toList());
// 数据运算
return resp.stream().map(itemDataResponse -> {
AnalysisReservoirWaterLevelResponse response = new AnalysisReservoirWaterLevelResponse();
BigDecimal relativeWaterLevel = BigDecimal.ZERO;
BigDecimal absolutelyWaterLevel = BigDecimal.ZERO;
BigDecimal value = BigDecimal.ZERO;
/**
* 计算方式
* 相对库水位:压力式水位计:基准水位+(当前测值value-基准测值),雷达(超声波)水位计:基准水位-(当前测值value-基准测值)。
* 绝对库水位:压力式水位计:设备海拔+当前测值value,雷达(超声波)水位计:设备海拔-当前测值value
* 若value≤0,则弹出提示“监测数据异常”,展示页面不显示曲线;。
*/
for (ItemIndex itemIndex : itemDataResponse.getDataList()) {
if (sensorIndex.equals(itemIndex.getKey())) {
Double doubleValue = itemIndex.getValue();
if (doubleValue <= 0D) {
log.error("监测数据异常");
throw new ApiException(ErrorCode.INTERNAL_ERROR, "监测数据异常");
}
value = new BigDecimal(doubleValue);
break;
}
}
BigDecimal temp = value.subtract(referenceValue);
if (observationMethod.equals(ObservationMethodEnum.pressure.getCode())) {
relativeWaterLevel = referenceWaterLevel.add(temp);
absolutelyWaterLevel = deviceAltitude.add(value);
} else if (observationMethod.equals(ObservationMethodEnum.radar.getCode())) {
relativeWaterLevel = referenceWaterLevel.subtract(temp);
absolutelyWaterLevel = deviceAltitude.subtract(value);
}
return response.setTimestamp(itemDataResponse.getTimeStamp())
.setAbsolutelyWaterLevel(absolutelyWaterLevel.setScale(2, RoundingMode.HALF_UP))
.setRelativeWaterLevel(relativeWaterLevel.setScale(2, RoundingMode.HALF_UP));
}).collect(Collectors.toList());
// 4、库水位
List<AnalysisReservoirWaterLevelResponse> reservoirWaterLevelResp = analysisReservoirWaterLevelService.queryReservoirWaterLevel(waterLevelId,dataType,startTime,endTime);
// 5、组装数据
return new AnalysisSeepageFlowResponse().setSeepageFlows(seepageFlowResp
.stream()
.map(item -> {
// 渗流量
BigDecimal value = BigDecimal.ZERO;
for (ItemIndex itemIndex : item.getDataList()) {
if (sensorIndex.equals(itemIndex.getKey())) {
value = new BigDecimal(itemIndex.getValue());
}
}
return new SeepageFlowModel().setTimestamp(item.getTimeStamp())
.setSeepageFlowValue(value.setScale(2, RoundingMode.HALF_UP));
}).collect(Collectors.toList()))
.setRainfallValues(rainfallResp.stream().map(item -> {
// 雨量
BigDecimal value = BigDecimal.ZERO;
for (ItemIndex itemIndex : item.getDataList()) {
if (sensorIndex.equals(itemIndex.getKey())) {
value = new BigDecimal(itemIndex.getValue());
}
}
return new RainfallValuesModel().setTimestamp(item.getTimeStamp())
.setRainfallValue(value.setScale(2, RoundingMode.HALF_UP));
}).collect(Collectors.toList()))
.setReservoirWaterLevels(reservoirWaterLevelResp);
respList.add(MonitorItemChartsResponse.builder()
.itemType(entry.getKey()) .itemTypeName(Optional.ofNullable(ItemEnum.getNameByCode(entry.getKey())).orElse(""))
.count(entry.getValue())
.rate(BigDecimal.ONE.subtract(cumulativeRate))
.build());
return respList.stream() .sorted(Comparator.comparing(MonitorItemChartsResponse::getRate).reversed()).collect(Collectors.toList());
@Getter
public enum ItemEnum {
L1_QJ(ItemTypeConstant.L1_QJ, "倾角"),
L1_LF(ItemTypeConstant.L1_LF, "裂缝"),
L1_GP(ItemTypeConstant.L1_GP, "地表位移"),
L1_SW(ItemTypeConstant.L1_SW, "深部位移"),
L1_JS(ItemTypeConstant.L1_JS, "加速度"),
L1_ZD(ItemTypeConstant.L1_ZD, "振动"),
L1_BT(ItemTypeConstant.L1_BT, "崩塌"),
L1_JZ(ItemTypeConstant.L1_JZ, "地表位移基站"),
private String code;
private String name;
ItemEnum(String code, String name) {
this.code = code;
this.name = name;
}
/**
* 根据code获取枚举
* @param code
* @return
*/
public static ItemEnum getEnumByCode(String code) {
return Arrays.stream(ItemEnum.values())
.filter(ItemEnum -> code.equals(ItemEnum.getCode()))
.findFirst()
.orElse(null);
}
/**
* 根据code获取名称
* @param code
* @return
*/
public static String getNameByCode(String code) {
return Arrays.stream(ItemEnum.values())
.filter(ItemEnum -> code.equals(ItemEnum.getCode()))
.findFirst()
.map(ItemEnum::getName)
.orElse(null);
}
}
/**
* 预警设备
*/
private static final Set<String> ALARM_ITEM_SET = Collections
.unmodifiableSet(new HashSet<>(Arrays.asList("L4_LB","L4_SP")));
List<String> filterList = typeList.stream().filter(type -> ! ALARM_ITEM_SET.contains(type)).collect(Collectors.toList());
Map<String, Long> typeMap = filterList
.stream()
.collect(Collectors.groupingBy(type -> type, Collectors.counting()));