From 8af05699ca2a18db08dd8869bb2fd0ddf02da84c Mon Sep 17 00:00:00 2001 From: wu Date: Mon, 23 Dec 2024 09:26:41 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AC=AC=E4=B8=80=E6=AC=A1=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 33 + pom.xml | 100 ++ .../com/parkingLot/ParkingLotApplication.java | 13 + .../parkingLot/base/constant/HttpStatus.java | 93 ++ .../base/controller/BaseController.java | 78 ++ .../parkingLot/base/domain/AjaxResult.java | 202 ++++ .../parkingLot/config/GlobalCorsConfig.java | 39 + .../exception/GlobalExceptionHandler.java | 87 ++ .../controller/RemoteCallController.java | 45 + .../java/com/parkingLot/dto/AreaInfoDTO.java | 31 + .../java/com/parkingLot/dto/CarInfoDTO.java | 65 ++ src/main/java/com/parkingLot/dto/DataDTO.java | 31 + .../dto/Response/CommonResponse.java | 28 + .../java/com/parkingLot/quartz/QuartzImg.java | 943 ++++++++++++++++++ .../parkingLot/service/RemoteCallService.java | 27 + .../service/impl/RemoteCallServiceImpl.java | 113 +++ .../com/parkingLot/utils/SignatureUtil.java | 85 ++ src/main/resources/application-dev.yml | 18 + src/main/resources/application.yml | 13 + src/main/resources/logback.xml | 93 ++ .../static/templates/192.168.1.101_正面.bmp | Bin 0 -> 15924 bytes .../static/templates/192.168.1.102_正面.bmp | Bin 0 -> 17286 bytes .../static/templates/192.168.1.103_正面.bmp | Bin 0 -> 16745 bytes .../static/templates/192.168.1.104_正面.bmp | Bin 0 -> 16642 bytes .../static/templates/192.168.1.91_反面.bmp | Bin 0 -> 3444 bytes .../static/templates/192.168.1.91_正面.bmp | Bin 0 -> 2573 bytes .../static/templates/192.168.1.92_正面.bmp | Bin 0 -> 2294 bytes .../static/templates/192.168.1.93_反面.bmp | Bin 0 -> 1052 bytes .../static/templates/192.168.1.93_正面.bmp | Bin 0 -> 2996 bytes .../static/templates/192.168.1.94_正面.bmp | Bin 0 -> 3390 bytes .../static/templates/192.168.1.95_反面.bmp | Bin 0 -> 1081 bytes .../static/templates/192.168.1.95_正面.bmp | Bin 0 -> 2927 bytes .../static/templates/192.168.1.96_反面.bmp | Bin 0 -> 3466 bytes .../static/templates/192.168.1.96_正面.bmp | Bin 0 -> 2741 bytes .../ParkingLotApplicationTests.java | 13 + 35 files changed, 2150 insertions(+) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/java/com/parkingLot/ParkingLotApplication.java create mode 100644 src/main/java/com/parkingLot/base/constant/HttpStatus.java create mode 100644 src/main/java/com/parkingLot/base/controller/BaseController.java create mode 100644 src/main/java/com/parkingLot/base/domain/AjaxResult.java create mode 100644 src/main/java/com/parkingLot/config/GlobalCorsConfig.java create mode 100644 src/main/java/com/parkingLot/config/exception/GlobalExceptionHandler.java create mode 100644 src/main/java/com/parkingLot/controller/RemoteCallController.java create mode 100644 src/main/java/com/parkingLot/dto/AreaInfoDTO.java create mode 100644 src/main/java/com/parkingLot/dto/CarInfoDTO.java create mode 100644 src/main/java/com/parkingLot/dto/DataDTO.java create mode 100644 src/main/java/com/parkingLot/dto/Response/CommonResponse.java create mode 100644 src/main/java/com/parkingLot/quartz/QuartzImg.java create mode 100644 src/main/java/com/parkingLot/service/RemoteCallService.java create mode 100644 src/main/java/com/parkingLot/service/impl/RemoteCallServiceImpl.java create mode 100644 src/main/java/com/parkingLot/utils/SignatureUtil.java create mode 100644 src/main/resources/application-dev.yml create mode 100644 src/main/resources/application.yml create mode 100644 src/main/resources/logback.xml create mode 100644 src/main/resources/static/templates/192.168.1.101_正面.bmp create mode 100644 src/main/resources/static/templates/192.168.1.102_正面.bmp create mode 100644 src/main/resources/static/templates/192.168.1.103_正面.bmp create mode 100644 src/main/resources/static/templates/192.168.1.104_正面.bmp create mode 100644 src/main/resources/static/templates/192.168.1.91_反面.bmp create mode 100644 src/main/resources/static/templates/192.168.1.91_正面.bmp create mode 100644 src/main/resources/static/templates/192.168.1.92_正面.bmp create mode 100644 src/main/resources/static/templates/192.168.1.93_反面.bmp create mode 100644 src/main/resources/static/templates/192.168.1.93_正面.bmp create mode 100644 src/main/resources/static/templates/192.168.1.94_正面.bmp create mode 100644 src/main/resources/static/templates/192.168.1.95_反面.bmp create mode 100644 src/main/resources/static/templates/192.168.1.95_正面.bmp create mode 100644 src/main/resources/static/templates/192.168.1.96_反面.bmp create mode 100644 src/main/resources/static/templates/192.168.1.96_正面.bmp create mode 100644 src/test/java/com/parkingLot/ParkingLotApplicationTests.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..953cff7 --- /dev/null +++ b/pom.xml @@ -0,0 +1,100 @@ + + + 4.0.0 + com.parkingLot + parkingLot + 0.0.1-SNAPSHOT + ParkingLot + Demo project for Spring Boot + + 1.8 + UTF-8 + UTF-8 + 2.6.13 + + + + + cn.hutool + hutool-all + 5.8.25 + + + com.alibaba.fastjson2 + fastjson2 + 2.0.41 + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-web + + + + + com.google.guava + guava + 28.1-jre + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + + + + parkingLot + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + UTF-8 + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + com.parkingLot.ParkingLotApplication + + + + repackage + + repackage + + + + + + + + diff --git a/src/main/java/com/parkingLot/ParkingLotApplication.java b/src/main/java/com/parkingLot/ParkingLotApplication.java new file mode 100644 index 0000000..bec8d01 --- /dev/null +++ b/src/main/java/com/parkingLot/ParkingLotApplication.java @@ -0,0 +1,13 @@ +package com.parkingLot; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ParkingLotApplication { + + public static void main(String[] args) { + SpringApplication.run(ParkingLotApplication.class, args); + } + +} diff --git a/src/main/java/com/parkingLot/base/constant/HttpStatus.java b/src/main/java/com/parkingLot/base/constant/HttpStatus.java new file mode 100644 index 0000000..81c9f7d --- /dev/null +++ b/src/main/java/com/parkingLot/base/constant/HttpStatus.java @@ -0,0 +1,93 @@ +package com.parkingLot.base.constant; + +/** + * 返回状态码 + * + * @author ruoyi + */ +public class HttpStatus { + /** + * 操作成功 + */ + public static final int SUCCESS = 200; + + /** + * 对象创建成功 + */ + public static final int CREATED = 201; + + /** + * 请求已经被接受 + */ + public static final int ACCEPTED = 202; + + /** + * 操作已经执行成功,但是没有返回数据 + */ + public static final int NO_CONTENT = 204; + + /** + * 资源已被移除 + */ + public static final int MOVED_PERM = 301; + + /** + * 重定向 + */ + public static final int SEE_OTHER = 303; + + /** + * 资源没有被修改 + */ + public static final int NOT_MODIFIED = 304; + + /** + * 参数列表错误(缺少,格式不匹配) + */ + public static final int BAD_REQUEST = 400; + + /** + * 未授权 + */ + public static final int UNAUTHORIZED = 401; + + /** + * 访问受限,授权过期 + */ + public static final int FORBIDDEN = 403; + + /** + * 资源,服务未找到 + */ + public static final int NOT_FOUND = 404; + + /** + * 不允许的http方法 + */ + public static final int BAD_METHOD = 405; + + /** + * 资源冲突,或者资源被锁 + */ + public static final int CONFLICT = 409; + + /** + * 不支持的数据,媒体类型 + */ + public static final int UNSUPPORTED_TYPE = 415; + + /** + * 系统内部错误 + */ + public static final int ERROR = 500; + + /** + * 接口未实现 + */ + public static final int NOT_IMPLEMENTED = 501; + + /** + * 系统警告消息 + */ + public static final int WARN = 601; +} diff --git a/src/main/java/com/parkingLot/base/controller/BaseController.java b/src/main/java/com/parkingLot/base/controller/BaseController.java new file mode 100644 index 0000000..2e00531 --- /dev/null +++ b/src/main/java/com/parkingLot/base/controller/BaseController.java @@ -0,0 +1,78 @@ +package com.parkingLot.base.controller; + +import com.parkingLot.base.domain.AjaxResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * web层通用数据处理 + * + * @author ruoyi + */ +public class BaseController { + protected final Logger logger = LoggerFactory.getLogger(this.getClass()); + + + /** + * 返回成功 + */ + public AjaxResult success() { + return AjaxResult.success(); + } + + /** + * 返回失败消息 + */ + public AjaxResult error() { + return AjaxResult.error(); + } + + /** + * 返回成功消息 + */ + public AjaxResult success(String message) { + return AjaxResult.success(message); + } + + /** + * 返回成功消息 + */ + public AjaxResult success(Object data) { + return AjaxResult.success(data); + } + + /** + * 返回失败消息 + */ + public AjaxResult error(String message) { + return AjaxResult.error(message); + } + + /** + * 返回警告消息 + */ + public AjaxResult warn(String message) { + return AjaxResult.warn(message); + } + + /** + * 响应返回结果 + * + * @param rows 影响行数 + * @return 操作结果 + */ + protected AjaxResult toAjax(int rows) { + return rows > 0 ? AjaxResult.success() : AjaxResult.error(); + } + + /** + * 响应返回结果 + * + * @param result 结果 + * @return 操作结果 + */ + protected AjaxResult toAjax(boolean result) { + return result ? success() : error(); + } + +} diff --git a/src/main/java/com/parkingLot/base/domain/AjaxResult.java b/src/main/java/com/parkingLot/base/domain/AjaxResult.java new file mode 100644 index 0000000..109781a --- /dev/null +++ b/src/main/java/com/parkingLot/base/domain/AjaxResult.java @@ -0,0 +1,202 @@ +package com.parkingLot.base.domain; + + +import cn.hutool.core.bean.BeanUtil; +import com.parkingLot.base.constant.HttpStatus; + +import java.util.HashMap; +import java.util.Objects; + +/** + * 操作消息提醒 + * + * @author ruoyi + */ +public class AjaxResult extends HashMap { + /** + * 状态码 + */ + public static final String CODE_TAG = "code"; + /** + * 返回内容 + */ + public static final String MSG_TAG = "msg"; + /** + * 数据对象 + */ + public static final String DATA_TAG = "data"; + private static final long serialVersionUID = 1L; + + /** + * 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。 + */ + public AjaxResult() { + } + + /** + * 初始化一个新创建的 AjaxResult 对象 + * + * @param code 状态码 + * @param msg 返回内容 + */ + public AjaxResult(int code, String msg) { + super.put(CODE_TAG, code); + super.put(MSG_TAG, msg); + } + + /** + * 初始化一个新创建的 AjaxResult 对象 + * + * @param code 状态码 + * @param msg 返回内容 + * @param data 数据对象 + */ + public AjaxResult(int code, String msg, Object data) { + super.put(CODE_TAG, code); + super.put(MSG_TAG, msg); + if (BeanUtil.isNotEmpty(data)) { + super.put(DATA_TAG, data); + } + } + + /** + * 返回成功消息 + * + * @return 成功消息 + */ + public static AjaxResult success() { + return AjaxResult.success("操作成功"); + } + + /** + * 返回成功数据 + * + * @return 成功消息 + */ + public static AjaxResult success(Object data) { + return AjaxResult.success("操作成功", data); + } + + /** + * 返回成功消息 + * + * @param msg 返回内容 + * @return 成功消息 + */ + public static AjaxResult success(String msg) { + return AjaxResult.success(msg, null); + } + + /** + * 返回成功消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 成功消息 + */ + public static AjaxResult success(String msg, Object data) { + return new AjaxResult(HttpStatus.SUCCESS, msg, data); + } + + /** + * 返回警告消息 + * + * @param msg 返回内容 + * @return 警告消息 + */ + public static AjaxResult warn(String msg) { + return AjaxResult.warn(msg, null); + } + + /** + * 返回警告消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 警告消息 + */ + public static AjaxResult warn(String msg, Object data) { + return new AjaxResult(HttpStatus.WARN, msg, data); + } + + /** + * 返回错误消息 + * + * @return 错误消息 + */ + public static AjaxResult error() { + return AjaxResult.error("操作失败"); + } + + /** + * 返回错误消息 + * + * @param msg 返回内容 + * @return 错误消息 + */ + public static AjaxResult error(String msg) { + return AjaxResult.error(msg, null); + } + + /** + * 返回错误消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 错误消息 + */ + public static AjaxResult error(String msg, Object data) { + return new AjaxResult(HttpStatus.ERROR, msg, data); + } + + /** + * 返回错误消息 + * + * @param code 状态码 + * @param msg 返回内容 + * @return 错误消息 + */ + public static AjaxResult error(int code, String msg) { + return new AjaxResult(code, msg, null); + } + + /** + * 是否为成功消息 + * + * @return 结果 + */ + public boolean isSuccess() { + return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG)); + } + + /** + * 是否为警告消息 + * + * @return 结果 + */ + public boolean isWarn() { + return Objects.equals(HttpStatus.WARN, this.get(CODE_TAG)); + } + + /** + * 是否为错误消息 + * + * @return 结果 + */ + public boolean isError() { + return Objects.equals(HttpStatus.ERROR, this.get(CODE_TAG)); + } + + /** + * 方便链式调用 + * + * @param key 键 + * @param value 值 + * @return 数据对象 + */ + @Override + public AjaxResult put(String key, Object value) { + super.put(key, value); + return this; + } +} diff --git a/src/main/java/com/parkingLot/config/GlobalCorsConfig.java b/src/main/java/com/parkingLot/config/GlobalCorsConfig.java new file mode 100644 index 0000000..3d9935b --- /dev/null +++ b/src/main/java/com/parkingLot/config/GlobalCorsConfig.java @@ -0,0 +1,39 @@ +package com.parkingLot.config; + + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; + + +/** + * 跨域配置 + * + * @author wu + * @since 2024/12/16 15:47 + */ +@Configuration +public class GlobalCorsConfig { + @Bean + public CorsFilter corsFilter() { + //1. 添加 CORS配置信息 + CorsConfiguration config = new CorsConfiguration(); + // 放行哪些原始域 + config.addAllowedOriginPattern("*"); + // 是否发送 Cookie + config.setAllowCredentials(true); + // 放行哪些请求方式 + config.addAllowedMethod("*"); + // 放行哪些原始请求头部信息 + config.addAllowedHeader("*"); + // 暴露哪些头部信息 + config.addExposedHeader("*"); + //2. 添加映射路径 + UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource(); + corsConfigurationSource.registerCorsConfiguration("/**", config); + //3. 返回新的CorsFilter + return new CorsFilter(corsConfigurationSource); + } +} diff --git a/src/main/java/com/parkingLot/config/exception/GlobalExceptionHandler.java b/src/main/java/com/parkingLot/config/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..d86880f --- /dev/null +++ b/src/main/java/com/parkingLot/config/exception/GlobalExceptionHandler.java @@ -0,0 +1,87 @@ +package com.parkingLot.config.exception; + +import com.parkingLot.base.domain.AjaxResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.validation.BindException; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; + +import javax.servlet.http.HttpServletRequest; + +/** + * 全局异常处理器 + * + * @author ruoyi + */ +@RestControllerAdvice +public class GlobalExceptionHandler { + private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class); + + + /** + * 请求方式不支持 + */ + @ExceptionHandler(HttpRequestMethodNotSupportedException.class) + public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, + HttpServletRequest request) { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod()); + return AjaxResult.error(e.getMessage()); + } + + + /** + * 请求参数类型不匹配 + */ + @ExceptionHandler(MethodArgumentTypeMismatchException.class) + public AjaxResult handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request) { + String requestURI = request.getRequestURI(); + log.error("请求参数类型不匹配'{}',发生系统异常.", requestURI, e); + return AjaxResult.error(String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), e.getValue())); + } + + /** + * 拦截未知的运行时异常 + */ + @ExceptionHandler(RuntimeException.class) + public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',发生未知异常.", requestURI, e); + return AjaxResult.error(e.getMessage()); + } + + /** + * 系统异常 + */ + @ExceptionHandler(Exception.class) + public AjaxResult handleException(Exception e, HttpServletRequest request) { + String requestURI = request.getRequestURI(); + log.error("请求地址'{}',发生系统异常.", requestURI, e); + return AjaxResult.error(e.getMessage()); + } + + /** + * 自定义验证异常 + */ + @ExceptionHandler(BindException.class) + public AjaxResult handleBindException(BindException e) { + log.error(e.getMessage(), e); + String message = e.getAllErrors().get(0).getDefaultMessage(); + return AjaxResult.error(message); + } + + /** + * 自定义验证异常 + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { + log.error(e.getMessage(), e); + String message = e.getBindingResult().getFieldError().getDefaultMessage(); + return AjaxResult.error(message); + } + +} diff --git a/src/main/java/com/parkingLot/controller/RemoteCallController.java b/src/main/java/com/parkingLot/controller/RemoteCallController.java new file mode 100644 index 0000000..711dd5a --- /dev/null +++ b/src/main/java/com/parkingLot/controller/RemoteCallController.java @@ -0,0 +1,45 @@ +package com.parkingLot.controller; + +import com.parkingLot.base.controller.BaseController; +import com.parkingLot.dto.Response.CommonResponse; +import com.parkingLot.service.RemoteCallService; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * @author wu + * @since 2024/12/12 16:39 + */ +@RestController +@RequestMapping("/remoteCall") +public class RemoteCallController extends BaseController { + + @Resource + private RemoteCallService remoteCallService; + + + /** + * 区域剩余车位查询 + * + * @return 响应类 + */ + @GetMapping("/GetAreaFreeSpaceNum") + public CommonResponse GetAreaFreeSpaceNum() { + return remoteCallService.GetAreaFreeSpaceNum(); + } + + /** + * 根据车牌查询在场数据 + * + * @param plateNo 车牌号 + * @return 响应类 + */ + @GetMapping("/GetCarInfoByPlateNo") + public CommonResponse GetCarInfoByPlateNo(@RequestParam("plateNo") String plateNo) { + return remoteCallService.GetCarInfoByPlateNo(plateNo); + } +} \ No newline at end of file diff --git a/src/main/java/com/parkingLot/dto/AreaInfoDTO.java b/src/main/java/com/parkingLot/dto/AreaInfoDTO.java new file mode 100644 index 0000000..0fa12cc --- /dev/null +++ b/src/main/java/com/parkingLot/dto/AreaInfoDTO.java @@ -0,0 +1,31 @@ +package com.parkingLot.dto; + +import lombok.Data; + +/** + * @author wu + * @since 2024/12/17 13:59 + */ +@Data +public class AreaInfoDTO { + + /** + * 区域编号 + */ + private Integer areaCode; + + /** + * 区域名称 + */ + private String areaName; + + /** + * 区域剩余停车位数 + */ + private Integer freeSpaceNum; + + /** + * 区域停车位数 + */ + private Integer placeCount; +} diff --git a/src/main/java/com/parkingLot/dto/CarInfoDTO.java b/src/main/java/com/parkingLot/dto/CarInfoDTO.java new file mode 100644 index 0000000..60e85d7 --- /dev/null +++ b/src/main/java/com/parkingLot/dto/CarInfoDTO.java @@ -0,0 +1,65 @@ +package com.parkingLot.dto; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author wu + * @since 2024/12/17 14:29 + */ +@Data +public class CarInfoDTO implements Serializable { + + private static final long serialVersionUID = 5405232225738524744L; + + /** + * 车颜色 + */ + private String carColor; + + /** + * 车辆类型 + */ + private String carStyle; + + /** + * 固定车类型 + */ + private Integer carType; + + /** + * 车辆进出场地点 + */ + private String entryPlace; + + /** + * 入场时间 (yyyy-MM-dd HH:mm:ss) + */ + private String entryTime; + + /** + * 车辆进出场图片名称 + */ + private String imgName; + + /** + * 图片信息类型:1:base64位图片信息;2=图片URL(可公网访问地址)0:没有图片信息 + */ + private Integer imgType; + + /** + * 总停车时间(分钟) + */ + private Integer parkingTime; + + /** + * 车牌号,全车牌 + */ + private String plateNo; + + /** + * 出入场唯一记录ID + */ + private String trafficId; +} diff --git a/src/main/java/com/parkingLot/dto/DataDTO.java b/src/main/java/com/parkingLot/dto/DataDTO.java new file mode 100644 index 0000000..6107da2 --- /dev/null +++ b/src/main/java/com/parkingLot/dto/DataDTO.java @@ -0,0 +1,31 @@ +package com.parkingLot.dto; + +import lombok.Data; + +import java.util.List; + +/** + * @author wu + * @since 2024/12/17 13:58 + */ +@Data +public class DataDTO { + + private List areaInfo; + + + /** + * 空闲车位数 + */ + private Integer freeSpaceNum; + + /** + * 停车场名称 + */ + private String parkName; + + /** + * 总车位数 + */ + private Integer totalNum; +} diff --git a/src/main/java/com/parkingLot/dto/Response/CommonResponse.java b/src/main/java/com/parkingLot/dto/Response/CommonResponse.java new file mode 100644 index 0000000..25a6dcb --- /dev/null +++ b/src/main/java/com/parkingLot/dto/Response/CommonResponse.java @@ -0,0 +1,28 @@ +package com.parkingLot.dto.Response; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * 科拓通用响应 + * + * @author wu + * @since 2024/12/17 13:57 + */ +@Data +public class CommonResponse implements Serializable { + private static final long serialVersionUID = -4789816950186563398L; + + + @JsonProperty("data") + private Object data; + + @JsonProperty("resCode") + private String resCode; + + @JsonProperty("resMsg") + private String resMsg; + +} diff --git a/src/main/java/com/parkingLot/quartz/QuartzImg.java b/src/main/java/com/parkingLot/quartz/QuartzImg.java new file mode 100644 index 0000000..a1ad610 --- /dev/null +++ b/src/main/java/com/parkingLot/quartz/QuartzImg.java @@ -0,0 +1,943 @@ +package com.parkingLot.quartz; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; +import com.parkingLot.dto.AreaInfoDTO; +import com.parkingLot.dto.DataDTO; +import com.parkingLot.dto.Response.CommonResponse; +import com.parkingLot.service.RemoteCallService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +/** + * 定时任务更新图片 + * + * @author wu + * @since 2024/12/17 09:15 + */ +@Slf4j +@Configuration +@EnableScheduling +public class QuartzImg { + + @javax.annotation.Resource + private RemoteCallService remoteCallService; + + private DataDTO dataDTO; + + /** + * 获取停车场实时数据 + */ + private void getAreaFreeSpaceNum() { + CommonResponse commonResponse = remoteCallService.GetAreaFreeSpaceNum(); + Object data = commonResponse.getData(); + if (data == null) { + return; + } + dataDTO = BeanUtil.copyProperties(data, DataDTO.class); + } + + /** + * 镇南镇北输出反面91更新图片 + */ + @Scheduled(cron = "0 */1 * * * *") + public void updateImgOne() { + getAreaFreeSpaceNum(); + try { + // 加载图片资源 + Resource resource = new ClassPathResource("static/templates/192.168.1.91_反面.bmp"); + InputStream inputStream = resource.getInputStream(); + Image src = ImageIO.read(inputStream); + + int width = src.getWidth(null); + int height = src.getHeight(null); + + // 创建一个新的BufferedImage对象用于绘制 + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics g = image.createGraphics(); + // 绘制原始图片 + g.drawImage(src, 0, 0, width, height, null); + // 设置字体颜色 + g.setColor(new Color(152, 251, 152)); // 设置字体颜色为淡绿色 + // 设置加粗字体,大小为18 + Font font = new Font("黑体", Font.BOLD, 18); + g.setFont(font); + // 要绘制的字符串 + String[] text = new String[2]; + // 创建FontMetrics对象用于获取字符串的宽度 + FontMetrics fm = g.getFontMetrics(font); + if (CollectionUtil.isEmpty(dataDTO.getAreaInfo())) { + return; + } + for (AreaInfoDTO dto : dataDTO.getAreaInfo()) { + if ("镇南停车场".equals(dto.getAreaName())) { + text[0] = String.valueOf(dto.getFreeSpaceNum()); + } + if ("镇北停车场".equals(dto.getAreaName())) { + text[1] = String.valueOf(dto.getFreeSpaceNum()); + } + } + // 设置初始y坐标 + int yPosition = height - 133; // 初始y位置 + // 循环绘制每个字符串,计算它们的宽度并进行右对齐 + for (String str : text) { + int stringWidth = fm.stringWidth(str); // 计算字符串的宽度 + // 计算绘制文本的x坐标,使文本右对齐 + int xPosition = width - 2 - stringWidth; + g.drawString(str, xPosition, yPosition); // 绘制字符串 + // 调整y坐标,确保文本不重叠 + yPosition = height - 68; + } + // 释放图形上下文 + g.dispose(); + // 输出文件路径 + File out = new File("D:\\fujica\\PushScreenInfo\\192.168.1.91输出反面.bmp"); + // 检查目标文件所在的目录是否存在 + File parentDir = out.getParentFile(); + if (!parentDir.exists()) { + // 如果目录不存在,创建该目录 + parentDir.mkdirs(); + } + // 保存修改后的图片 + ImageIO.write(image, "bmp", out); + log.info("图片保存成功!"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * 镇东镇北输出正面91更新图片 + */ + @Scheduled(cron = "2 */1 * * * *") + public void updateImgTow() { + try { + // 加载图片资源 + Resource resource = new ClassPathResource("static/templates/192.168.1.91_正面.bmp"); + InputStream inputStream = resource.getInputStream(); + Image src = ImageIO.read(inputStream); + int width = src.getWidth(null); + int height = src.getHeight(null); + + // 创建一个新的BufferedImage对象用于绘制 + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics g = image.createGraphics(); + // 绘制原始图片 + g.drawImage(src, 0, 0, width, height, null); + // 设置字体颜色 + g.setColor(new Color(152, 251, 152)); // 设置字体颜色为淡绿色 + // 设置加粗字体,大小为18 + Font font = new Font("黑体", Font.BOLD, 18); + g.setFont(font); + // 要绘制的字符串 + String[] text = new String[2]; + ; + // 创建FontMetrics对象用于获取字符串的宽度 + FontMetrics fm = g.getFontMetrics(font); + if (CollectionUtil.isEmpty(dataDTO.getAreaInfo())) { + return; + } + for (AreaInfoDTO dto : dataDTO.getAreaInfo()) { + if ("镇东停车场".equals(dto.getAreaName())) { + text[0] = String.valueOf(dto.getFreeSpaceNum()); + } + if ("镇北停车场".equals(dto.getAreaName())) { + text[1] = String.valueOf(dto.getFreeSpaceNum()); + } + } + // 设置初始y坐标 + int yPosition = height - 133; // 初始y位置 + // 循环绘制每个字符串,计算它们的宽度并进行右对齐 + for (String str : text) { + int stringWidth = fm.stringWidth(str); // 计算字符串的宽度 + // 计算绘制文本的x坐标,使文本右对齐 + int xPosition = width - 2 - stringWidth; + g.drawString(str, xPosition, yPosition); // 绘制字符串 + // 调整y坐标,确保文本不重叠 + yPosition = height - 68; + } + // 释放图形上下文 + g.dispose(); + // 输出文件路径 + File out = new File("D:\\fujica\\PushScreenInfo\\192.168.1.91输出正面.bmp"); + // 检查目标文件所在的目录是否存在 + File parentDir = out.getParentFile(); + if (!parentDir.exists()) { + // 如果目录不存在,创建该目录 + parentDir.mkdirs(); + } + // 保存修改后的图片 + ImageIO.write(image, "bmp", out); + log.info("图片保存成功!"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * 镇东镇北输出正面92更新图片 + */ + @Scheduled(cron = "2 */1 * * * *") + public void updateImgThree() { + try { + // 加载图片资源 + Resource resource = new ClassPathResource("static/templates/192.168.1.92_正面.bmp"); + InputStream inputStream = resource.getInputStream(); + Image src = ImageIO.read(inputStream); + int width = src.getWidth(null); + int height = src.getHeight(null); + + // 创建一个新的BufferedImage对象用于绘制 + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics g = image.createGraphics(); + // 绘制原始图片 + g.drawImage(src, 0, 0, width, height, null); + // 设置字体颜色 + g.setColor(new Color(152, 251, 152)); // 设置字体颜色为淡绿色 + // 设置加粗字体,大小为18 + Font font = new Font("黑体", Font.BOLD, 18); + g.setFont(font); + // 要绘制的字符串 + String[] text = new String[2]; + ; + // 创建FontMetrics对象用于获取字符串的宽度 + FontMetrics fm = g.getFontMetrics(font); + if (CollectionUtil.isEmpty(dataDTO.getAreaInfo())) { + return; + } + for (AreaInfoDTO dto : dataDTO.getAreaInfo()) { + if ("镇东停车场".equals(dto.getAreaName())) { + text[0] = String.valueOf(dto.getFreeSpaceNum()); + } + if ("镇北停车场".equals(dto.getAreaName())) { + text[1] = String.valueOf(dto.getFreeSpaceNum()); + } + } + // 设置初始y坐标 + int yPosition = height - 133; // 初始y位置 + // 循环绘制每个字符串,计算它们的宽度并进行右对齐 + for (String str : text) { + int stringWidth = fm.stringWidth(str); // 计算字符串的宽度 + // 计算绘制文本的x坐标,使文本右对齐 + int xPosition = width - 2 - stringWidth; + g.drawString(str, xPosition, yPosition); // 绘制字符串 + // 调整y坐标,确保文本不重叠 + yPosition = height - 68; + } + // 释放图形上下文 + g.dispose(); + // 输出文件路径 + File out = new File("D:\\fujica\\PushScreenInfo\\192.168.1.92输出正面.bmp"); + // 检查目标文件所在的目录是否存在 + File parentDir = out.getParentFile(); + if (!parentDir.exists()) { + // 如果目录不存在,创建该目录 + parentDir.mkdirs(); + } + // 保存修改后的图片 + ImageIO.write(image, "bmp", out); + log.info("图片保存成功!"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * 镇东镇北输出正面93更新图片 + */ + @Scheduled(cron = "2 */1 * * * *") + public void updateImgFour() { + try { + // 加载图片资源 + Resource resource = new ClassPathResource("static/templates/192.168.1.93_正面.bmp"); + InputStream inputStream = resource.getInputStream(); + Image src = ImageIO.read(inputStream); + int width = src.getWidth(null); + int height = src.getHeight(null); + + // 创建一个新的BufferedImage对象用于绘制 + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics g = image.createGraphics(); + // 绘制原始图片 + g.drawImage(src, 0, 0, width, height, null); + // 设置字体颜色 + g.setColor(new Color(152, 251, 152)); // 设置字体颜色为淡绿色 + // 设置加粗字体,大小为18 + Font font = new Font("黑体", Font.BOLD, 18); + g.setFont(font); + // 要绘制的字符串 + String[] text = new String[2]; + ; + // 创建FontMetrics对象用于获取字符串的宽度 + FontMetrics fm = g.getFontMetrics(font); + if (CollectionUtil.isEmpty(dataDTO.getAreaInfo())) { + return; + } + for (AreaInfoDTO dto : dataDTO.getAreaInfo()) { + if ("镇东停车场".equals(dto.getAreaName())) { + text[0] = String.valueOf(dto.getFreeSpaceNum()); + } + if ("镇北停车场".equals(dto.getAreaName())) { + text[1] = String.valueOf(dto.getFreeSpaceNum()); + } + } + // 设置初始y坐标 + int yPosition = height - 133; // 初始y位置 + // 循环绘制每个字符串,计算它们的宽度并进行右对齐 + for (String str : text) { + int stringWidth = fm.stringWidth(str); // 计算字符串的宽度 + // 计算绘制文本的x坐标,使文本右对齐 + int xPosition = width - 2 - stringWidth; + g.drawString(str, xPosition, yPosition); // 绘制字符串 + // 调整y坐标,确保文本不重叠 + yPosition = height - 68; + } + // 释放图形上下文 + g.dispose(); + // 输出文件路径 + File out = new File("D:\\fujica\\PushScreenInfo\\192.168.1.93输出正面.bmp"); + // 检查目标文件所在的目录是否存在 + File parentDir = out.getParentFile(); + if (!parentDir.exists()) { + // 如果目录不存在,创建该目录 + parentDir.mkdirs(); + } + // 保存修改后的图片 + ImageIO.write(image, "bmp", out); + log.info("图片保存成功!"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * 镇南镇北输出正面94更新图片 + */ + @Scheduled(cron = "2 */1 * * * *") + public void updateImgFive() { + try { + // 加载图片资源 + Resource resource = new ClassPathResource("static/templates/192.168.1.94_正面.bmp"); + InputStream inputStream = resource.getInputStream(); + Image src = ImageIO.read(inputStream); + int width = src.getWidth(null); + int height = src.getHeight(null); + + // 创建一个新的BufferedImage对象用于绘制 + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics g = image.createGraphics(); + // 绘制原始图片 + g.drawImage(src, 0, 0, width, height, null); + // 设置字体颜色 + g.setColor(new Color(152, 251, 152)); // 设置字体颜色为淡绿色 + // 设置加粗字体,大小为18 + Font font = new Font("黑体", Font.BOLD, 18); + g.setFont(font); + // 要绘制的字符串 + String[] text = new String[2]; + ; + // 创建FontMetrics对象用于获取字符串的宽度 + FontMetrics fm = g.getFontMetrics(font); + if (CollectionUtil.isEmpty(dataDTO.getAreaInfo())) { + return; + } + for (AreaInfoDTO dto : dataDTO.getAreaInfo()) { + if ("镇南停车场".equals(dto.getAreaName())) { + text[0] = String.valueOf(dto.getFreeSpaceNum()); + } + if ("镇北停车场".equals(dto.getAreaName())) { + text[1] = String.valueOf(dto.getFreeSpaceNum()); + } + } + // 设置初始y坐标 + int yPosition = height - 133; // 初始y位置 + // 循环绘制每个字符串,计算它们的宽度并进行右对齐 + for (String str : text) { + int stringWidth = fm.stringWidth(str); // 计算字符串的宽度 + // 计算绘制文本的x坐标,使文本右对齐 + int xPosition = width - 2 - stringWidth; + g.drawString(str, xPosition, yPosition); // 绘制字符串 + // 调整y坐标,确保文本不重叠 + yPosition = height - 68; + } + // 释放图形上下文 + g.dispose(); + // 输出文件路径 + File out = new File("D:\\fujica\\PushScreenInfo\\192.168.1.94输出正面.bmp"); + // 检查目标文件所在的目录是否存在 + File parentDir = out.getParentFile(); + if (!parentDir.exists()) { + // 如果目录不存在,创建该目录 + parentDir.mkdirs(); + } + // 保存修改后的图片 + ImageIO.write(image, "bmp", out); + log.info("图片保存成功!"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * 镇东镇北输出正面95更新图片 + */ + @Scheduled(cron = "2 */1 * * * *") + public void updateImgSix() { + try { + // 加载图片资源 + Resource resource = new ClassPathResource("static/templates/192.168.1.95_正面.bmp"); + InputStream inputStream = resource.getInputStream(); + Image src = ImageIO.read(inputStream); + int width = src.getWidth(null); + int height = src.getHeight(null); + + // 创建一个新的BufferedImage对象用于绘制 + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics g = image.createGraphics(); + // 绘制原始图片 + g.drawImage(src, 0, 0, width, height, null); + // 设置字体颜色 + g.setColor(new Color(152, 251, 152)); // 设置字体颜色为淡绿色 + // 设置加粗字体,大小为18 + Font font = new Font("黑体", Font.BOLD, 18); + g.setFont(font); + // 要绘制的字符串 + String[] text = new String[2]; + ; + // 创建FontMetrics对象用于获取字符串的宽度 + FontMetrics fm = g.getFontMetrics(font); + if (CollectionUtil.isEmpty(dataDTO.getAreaInfo())) { + return; + } + for (AreaInfoDTO dto : dataDTO.getAreaInfo()) { + if ("镇东停车场".equals(dto.getAreaName())) { + text[0] = String.valueOf(dto.getFreeSpaceNum()); + } + if ("镇北停车场".equals(dto.getAreaName())) { + text[1] = String.valueOf(dto.getFreeSpaceNum()); + } + } + // 设置初始y坐标 + int yPosition = height - 133; // 初始y位置 + // 循环绘制每个字符串,计算它们的宽度并进行右对齐 + for (String str : text) { + int stringWidth = fm.stringWidth(str); // 计算字符串的宽度 + // 计算绘制文本的x坐标,使文本右对齐 + int xPosition = width - 2 - stringWidth; + g.drawString(str, xPosition, yPosition); // 绘制字符串 + // 调整y坐标,确保文本不重叠 + yPosition = height - 68; + } + // 释放图形上下文 + g.dispose(); + // 输出文件路径 + File out = new File("D:\\fujica\\PushScreenInfo\\192.168.1.95输出正面.bmp"); + // 检查目标文件所在的目录是否存在 + File parentDir = out.getParentFile(); + if (!parentDir.exists()) { + // 如果目录不存在,创建该目录 + parentDir.mkdirs(); + } + // 保存修改后的图片 + ImageIO.write(image, "bmp", out); + log.info("图片保存成功!"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * 镇东镇南输出反面96更新图片 + */ + @Scheduled(cron = "2 */1 * * * *") + public void updateImgSeven() { + try { + // 加载图片资源 + Resource resource = new ClassPathResource("static/templates/192.168.1.96_反面.bmp"); + InputStream inputStream = resource.getInputStream(); + Image src = ImageIO.read(inputStream); + int width = src.getWidth(null); + int height = src.getHeight(null); + + // 创建一个新的BufferedImage对象用于绘制 + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics g = image.createGraphics(); + // 绘制原始图片 + g.drawImage(src, 0, 0, width, height, null); + // 设置字体颜色 + g.setColor(new Color(152, 251, 152)); // 设置字体颜色为淡绿色 + // 设置加粗字体,大小为18 + Font font = new Font("黑体", Font.BOLD, 18); + g.setFont(font); + // 要绘制的字符串 + String[] text = new String[2]; + ; + // 创建FontMetrics对象用于获取字符串的宽度 + FontMetrics fm = g.getFontMetrics(font); + if (CollectionUtil.isEmpty(dataDTO.getAreaInfo())) { + return; + } + for (AreaInfoDTO dto : dataDTO.getAreaInfo()) { + if ("镇东停车场".equals(dto.getAreaName())) { + text[0] = String.valueOf(dto.getFreeSpaceNum()); + } + if ("镇南停车场".equals(dto.getAreaName())) { + text[1] = String.valueOf(dto.getFreeSpaceNum()); + } + } + // 设置初始y坐标 + int yPosition = height - 133; // 初始y位置 + // 循环绘制每个字符串,计算它们的宽度并进行右对齐 + for (String str : text) { + int stringWidth = fm.stringWidth(str); // 计算字符串的宽度 + // 计算绘制文本的x坐标,使文本右对齐 + int xPosition = width - 2 - stringWidth; + g.drawString(str, xPosition, yPosition); // 绘制字符串 + // 调整y坐标,确保文本不重叠 + yPosition = height - 68; + } + // 释放图形上下文 + g.dispose(); + // 输出文件路径 + File out = new File("D:\\fujica\\PushScreenInfo\\192.168.1.96输出反面.bmp"); + // 检查目标文件所在的目录是否存在 + File parentDir = out.getParentFile(); + if (!parentDir.exists()) { + // 如果目录不存在,创建该目录 + parentDir.mkdirs(); + } + // 保存修改后的图片 + ImageIO.write(image, "bmp", out); + log.info("图片保存成功!"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + + /** + * 镇东镇北输出正面96更新图片 + */ + @Scheduled(cron = "2 */1 * * * *") + public void updateImgEight() { + try { + // 加载图片资源 + Resource resource = new ClassPathResource("static/templates/192.168.1.96_正面.bmp"); + InputStream inputStream = resource.getInputStream(); + Image src = ImageIO.read(inputStream); + int width = src.getWidth(null); + int height = src.getHeight(null); + + // 创建一个新的BufferedImage对象用于绘制 + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics g = image.createGraphics(); + // 绘制原始图片 + g.drawImage(src, 0, 0, width, height, null); + // 设置字体颜色 + g.setColor(new Color(152, 251, 152)); // 设置字体颜色为淡绿色 + // 设置加粗字体,大小为18 + Font font = new Font("黑体", Font.BOLD, 18); + g.setFont(font); + // 要绘制的字符串 + String[] text = new String[2]; + ; + // 创建FontMetrics对象用于获取字符串的宽度 + FontMetrics fm = g.getFontMetrics(font); + if (CollectionUtil.isEmpty(dataDTO.getAreaInfo())) { + return; + } + for (AreaInfoDTO dto : dataDTO.getAreaInfo()) { + if ("镇东停车场".equals(dto.getAreaName())) { + text[0] = String.valueOf(dto.getFreeSpaceNum()); + } + if ("镇北停车场".equals(dto.getAreaName())) { + text[1] = String.valueOf(dto.getFreeSpaceNum()); + } + } + // 设置初始y坐标 + int yPosition = height - 133; // 初始y位置 + // 循环绘制每个字符串,计算它们的宽度并进行右对齐 + for (String str : text) { + int stringWidth = fm.stringWidth(str); // 计算字符串的宽度 + // 计算绘制文本的x坐标,使文本右对齐 + int xPosition = width - 2 - stringWidth; + g.drawString(str, xPosition, yPosition); // 绘制字符串 + // 调整y坐标,确保文本不重叠 + yPosition = height - 68; + } + // 释放图形上下文 + g.dispose(); + // 输出文件路径 + File out = new File("D:\\fujica\\PushScreenInfo\\192.168.1.96输出正面.bmp"); + // 检查目标文件所在的目录是否存在 + File parentDir = out.getParentFile(); + if (!parentDir.exists()) { + // 如果目录不存在,创建该目录 + parentDir.mkdirs(); + } + // 保存修改后的图片 + ImageIO.write(image, "bmp", out); + log.info("图片保存成功!"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * 镇东镇南镇北输出正面101更新图片 + */ + @Scheduled(cron = "2 */1 * * * *") + public void updateImgNine() { + try { + // 加载图片资源 + Resource resource = new ClassPathResource("static/templates/192.168.1.101_正面.bmp"); + InputStream inputStream = resource.getInputStream(); + Image src = ImageIO.read(inputStream); + int width = src.getWidth(null); + int height = src.getHeight(null); + + // 创建一个新的BufferedImage对象用于绘制 + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics g = image.createGraphics(); + // 绘制原始图片 + g.drawImage(src, 0, 0, width, height, null); + // 设置字体颜色 + g.setColor(new Color(152, 251, 152)); // 设置字体颜色为淡绿色 + // 设置加粗字体,大小为18 + Font font = new Font("黑体", Font.BOLD, 50); + g.setFont(font); + // 要绘制的字符串 + String[] text = new String[3]; + // 创建FontMetrics对象用于获取字符串的宽度 + FontMetrics fm = g.getFontMetrics(font); + if (CollectionUtil.isEmpty(dataDTO.getAreaInfo())) { + return; + } + for (AreaInfoDTO dto : dataDTO.getAreaInfo()) { + if ("镇东停车场".equals(dto.getAreaName())) { + text[2] = String.valueOf(dto.getFreeSpaceNum()); + } + if ("镇南停车场".equals(dto.getAreaName())) { + text[1] = String.valueOf(dto.getFreeSpaceNum()); + } + if ("镇北停车场".equals(dto.getAreaName())) { + text[0] = String.valueOf(dto.getFreeSpaceNum()); + } + } + // 设置初始y坐标 + int yPosition = height - 20; // 初始y位置 + // 循环绘制每个字符串,计算它们的宽度并进行右对齐 + for (String str : text) { + int stringWidth = fm.stringWidth(str); // 计算字符串的宽度 + // 计算绘制文本的x坐标,使文本右对齐 + int xPosition = width - 5 - stringWidth; + g.drawString(str, xPosition, yPosition); // 绘制字符串 + // 调整y坐标,确保文本不重叠 + yPosition = yPosition - 70; + } + // 释放图形上下文 + g.dispose(); + // 输出文件路径 + File out = new File("D:\\fujica\\PushScreenInfo\\192.168.1.101输出正面.bmp"); + // 检查目标文件所在的目录是否存在 + File parentDir = out.getParentFile(); + if (!parentDir.exists()) { + // 如果目录不存在,创建该目录 + parentDir.mkdirs(); + } + // 保存修改后的图片 + ImageIO.write(image, "bmp", out); + log.info("图片保存成功!"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * 镇东镇南镇北输出正面102更新图片 + */ + @Scheduled(cron = "2 */1 * * * *") + public void updateImgTen() { + try { + // 加载图片资源 + Resource resource = new ClassPathResource("static/templates/192.168.1.102_正面.bmp"); + InputStream inputStream = resource.getInputStream(); + Image src = ImageIO.read(inputStream); + int width = src.getWidth(null); + int height = src.getHeight(null); + + // 创建一个新的BufferedImage对象用于绘制 + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics g = image.createGraphics(); + // 绘制原始图片 + g.drawImage(src, 0, 0, width, height, null); + // 设置字体颜色 + g.setColor(new Color(152, 251, 152)); // 设置字体颜色为淡绿色 + // 设置加粗字体,大小为18 + Font font = new Font("黑体", Font.BOLD, 50); + g.setFont(font); + // 要绘制的字符串 + String[] text = new String[3]; + // 创建FontMetrics对象用于获取字符串的宽度 + FontMetrics fm = g.getFontMetrics(font); + if (CollectionUtil.isEmpty(dataDTO.getAreaInfo())) { + return; + } + for (AreaInfoDTO dto : dataDTO.getAreaInfo()) { + if ("镇东停车场".equals(dto.getAreaName())) { + text[2] = String.valueOf(dto.getFreeSpaceNum()); + } + if ("镇南停车场".equals(dto.getAreaName())) { + text[1] = String.valueOf(dto.getFreeSpaceNum()); + } + if ("镇北停车场".equals(dto.getAreaName())) { + text[0] = String.valueOf(dto.getFreeSpaceNum()); + } + } + // 设置初始y坐标 + int yPosition = height - 20; // 初始y位置 + // 循环绘制每个字符串,计算它们的宽度并进行右对齐 + for (String str : text) { + int stringWidth = fm.stringWidth(str); // 计算字符串的宽度 + // 计算绘制文本的x坐标,使文本右对齐 + int xPosition = width - 5 - stringWidth; + g.drawString(str, xPosition, yPosition); // 绘制字符串 + // 调整y坐标,确保文本不重叠 + yPosition = yPosition - 70; + } + // 释放图形上下文 + g.dispose(); + // 输出文件路径 + File out = new File("D:\\fujica\\PushScreenInfo\\192.168.1.102输出正面.bmp"); + // 检查目标文件所在的目录是否存在 + File parentDir = out.getParentFile(); + if (!parentDir.exists()) { + // 如果目录不存在,创建该目录 + parentDir.mkdirs(); + } + // 保存修改后的图片 + ImageIO.write(image, "bmp", out); + log.info("图片保存成功!"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * 镇东镇南镇北输出正面103更新图片 + */ + @Scheduled(cron = "2 */1 * * * *") + public void updateImgEleven() { + try { + // 加载图片资源 + Resource resource = new ClassPathResource("static/templates/192.168.1.103_正面.bmp"); + InputStream inputStream = resource.getInputStream(); + Image src = ImageIO.read(inputStream); + int width = src.getWidth(null); + int height = src.getHeight(null); + + // 创建一个新的BufferedImage对象用于绘制 + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics g = image.createGraphics(); + // 绘制原始图片 + g.drawImage(src, 0, 0, width, height, null); + // 设置字体颜色 + g.setColor(new Color(152, 251, 152)); // 设置字体颜色为淡绿色 + // 设置加粗字体,大小为18 + Font font = new Font("黑体", Font.BOLD, 50); + g.setFont(font); + // 要绘制的字符串 + String[] text = new String[3]; + // 创建FontMetrics对象用于获取字符串的宽度 + FontMetrics fm = g.getFontMetrics(font); + if (CollectionUtil.isEmpty(dataDTO.getAreaInfo())) { + return; + } + for (AreaInfoDTO dto : dataDTO.getAreaInfo()) { + if ("镇东停车场".equals(dto.getAreaName())) { + text[2] = String.valueOf(dto.getFreeSpaceNum()); + } + if ("镇南停车场".equals(dto.getAreaName())) { + text[1] = String.valueOf(dto.getFreeSpaceNum()); + } + if ("镇北停车场".equals(dto.getAreaName())) { + text[0] = String.valueOf(dto.getFreeSpaceNum()); + } + } + // 设置初始y坐标 + int yPosition = height - 20; // 初始y位置 + // 循环绘制每个字符串,计算它们的宽度并进行右对齐 + for (String str : text) { + int stringWidth = fm.stringWidth(str); // 计算字符串的宽度 + // 计算绘制文本的x坐标,使文本右对齐 + int xPosition = width - 5 - stringWidth; + g.drawString(str, xPosition, yPosition); // 绘制字符串 + // 调整y坐标,确保文本不重叠 + yPosition = yPosition - 70; + } + // 释放图形上下文 + g.dispose(); + // 输出文件路径 + File out = new File("D:\\fujica\\PushScreenInfo\\192.168.1.103输出正面.bmp"); + // 检查目标文件所在的目录是否存在 + File parentDir = out.getParentFile(); + if (!parentDir.exists()) { + // 如果目录不存在,创建该目录 + parentDir.mkdirs(); + } + // 保存修改后的图片 + ImageIO.write(image, "bmp", out); + log.info("图片保存成功!"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * 镇东镇南镇北输出正面104更新图片 + */ + @Scheduled(cron = "2 */1 * * * *") + public void updateImgTwelve() { + try { + // 加载图片资源 + Resource resource = new ClassPathResource("static/templates/192.168.1.104_正面.bmp"); + InputStream inputStream = resource.getInputStream(); + Image src = ImageIO.read(inputStream); + int width = src.getWidth(null); + int height = src.getHeight(null); + + // 创建一个新的BufferedImage对象用于绘制 + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics g = image.createGraphics(); + // 绘制原始图片 + g.drawImage(src, 0, 0, width, height, null); + // 设置字体颜色 + g.setColor(new Color(152, 251, 152)); // 设置字体颜色为淡绿色 + // 设置加粗字体,大小为18 + Font font = new Font("黑体", Font.BOLD, 50); + g.setFont(font); + // 要绘制的字符串 + String[] text = new String[3]; + // 创建FontMetrics对象用于获取字符串的宽度 + FontMetrics fm = g.getFontMetrics(font); + if (CollectionUtil.isEmpty(dataDTO.getAreaInfo())) { + return; + } + for (AreaInfoDTO dto : dataDTO.getAreaInfo()) { + if ("镇东停车场".equals(dto.getAreaName())) { + text[2] = String.valueOf(dto.getFreeSpaceNum()); + } + if ("镇南停车场".equals(dto.getAreaName())) { + text[1] = String.valueOf(dto.getFreeSpaceNum()); + } + if ("镇北停车场".equals(dto.getAreaName())) { + text[0] = String.valueOf(dto.getFreeSpaceNum()); + } + } + // 设置初始y坐标 + int yPosition = height - 20; // 初始y位置 + // 循环绘制每个字符串,计算它们的宽度并进行右对齐 + for (String str : text) { + int stringWidth = fm.stringWidth(str); // 计算字符串的宽度 + // 计算绘制文本的x坐标,使文本右对齐 + int xPosition = width - 5 - stringWidth; + g.drawString(str, xPosition, yPosition); // 绘制字符串 + // 调整y坐标,确保文本不重叠 + yPosition = yPosition - 70; + } + // 释放图形上下文 + g.dispose(); + // 输出文件路径 + File out = new File("D:\\fujica\\PushScreenInfo\\192.168.1.104输出正面.bmp"); + // 检查目标文件所在的目录是否存在 + File parentDir = out.getParentFile(); + if (!parentDir.exists()) { + // 如果目录不存在,创建该目录 + parentDir.mkdirs(); + } + // 保存修改后的图片 + ImageIO.write(image, "bmp", out); + log.info("图片保存成功!"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * 镇东镇南镇北镇北输出正反91更新图片 + */ + @Scheduled(cron = "5 */1 * * * *") + public void updateImgThirteen() { + try { + // 加载第一个图像 + File file1 = new File("D:\\fujica\\PushScreenInfo\\192.168.1.91输出正面.bmp"); + BufferedImage image1 = ImageIO.read(file1); + // 加载第二个图像 + File file2 = new File("D:\\fujica\\PushScreenInfo\\192.168.1.91输出反面.bmp"); + BufferedImage image2 = ImageIO.read(file2); + // 计算合并后图像的宽度和高度 + int totalWidth = image1.getWidth() + image2.getWidth(); // 宽度是两个图像宽度之和 + int maxHeight = Math.max(image1.getHeight(), image2.getHeight()); // 高度是两个图像中较大的高度 + // 创建一个新的BufferedImage对象,用于保存合并后的图像 + BufferedImage mergedImage = new BufferedImage(totalWidth, maxHeight, BufferedImage.TYPE_INT_RGB); + Graphics g = mergedImage.createGraphics(); + // 绘制第一个图像到合并图像的左侧 + g.drawImage(image1, 0, 0, null); + // 绘制第二个图像到合并图像的右侧 + g.drawImage(image2, image1.getWidth(), 0, null); + // 释放图形上下文 + g.dispose(); + // 保存合并后的图像 + File outFile = new File("D:\\fujica\\PushScreenInfo\\192.168.1.91输出正反.bmp"); + ImageIO.write(mergedImage, "bmp", outFile); + log.info("图像合并并保存成功!"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * 镇东镇东镇北镇南输出正反96更新图片 + */ + @Scheduled(cron = "5 */1 * * * *") + public void updateImgFourteen() { + try { + // 加载第一个图像 + File file1 = new File("D:\\fujica\\PushScreenInfo\\192.168.1.96输出正面.bmp"); + BufferedImage image1 = ImageIO.read(file1); + // 加载第二个图像 + File file2 = new File("D:\\fujica\\PushScreenInfo\\192.168.1.96输出反面.bmp"); + BufferedImage image2 = ImageIO.read(file2); + // 计算合并后图像的宽度和高度 + int totalWidth = image1.getWidth() + image2.getWidth(); // 宽度是两个图像宽度之和 + int maxHeight = Math.max(image1.getHeight(), image2.getHeight()); // 高度是两个图像中较大的高度 + // 创建一个新的BufferedImage对象,用于保存合并后的图像 + BufferedImage mergedImage = new BufferedImage(totalWidth, maxHeight, BufferedImage.TYPE_INT_RGB); + Graphics g = mergedImage.createGraphics(); + // 绘制第一个图像到合并图像的左侧 + g.drawImage(image1, 0, 0, null); + // 绘制第二个图像到合并图像的右侧 + g.drawImage(image2, image1.getWidth(), 0, null); + // 释放图形上下文 + g.dispose(); + // 保存合并后的图像 + File outFile = new File("D:\\fujica\\PushScreenInfo\\192.168.1.96输出正反.bmp"); + ImageIO.write(mergedImage, "bmp", outFile); + log.info("图像合并并保存成功!"); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/com/parkingLot/service/RemoteCallService.java b/src/main/java/com/parkingLot/service/RemoteCallService.java new file mode 100644 index 0000000..794dd85 --- /dev/null +++ b/src/main/java/com/parkingLot/service/RemoteCallService.java @@ -0,0 +1,27 @@ +package com.parkingLot.service; + +import com.parkingLot.dto.Response.CommonResponse; + +/** + * @author wu + * @since 2024/12/13 09:11 + */ +public interface RemoteCallService { + + + /** + * 区域剩余车位查询 + * + * @return 响应类 + */ + CommonResponse GetAreaFreeSpaceNum(); + + /** + * 根据车牌查询在场数据 + * + * @param plateNo 车牌号 + * @return 响应类 + */ + CommonResponse GetCarInfoByPlateNo(String plateNo); + +} diff --git a/src/main/java/com/parkingLot/service/impl/RemoteCallServiceImpl.java b/src/main/java/com/parkingLot/service/impl/RemoteCallServiceImpl.java new file mode 100644 index 0000000..021799c --- /dev/null +++ b/src/main/java/com/parkingLot/service/impl/RemoteCallServiceImpl.java @@ -0,0 +1,113 @@ +package com.parkingLot.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpRequest; +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson2.JSONObject; +import com.parkingLot.dto.CarInfoDTO; +import com.parkingLot.dto.DataDTO; +import com.parkingLot.dto.Response.CommonResponse; +import com.parkingLot.service.RemoteCallService; +import com.parkingLot.utils.SignatureUtil; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.util.Map; + +/** + * @author wu + * @since 2024/12/13 09:11 + */ +@Service +public class RemoteCallServiceImpl implements RemoteCallService { + + @Value("${url}") + private String url; + + @Value("${appId}") + private String appId; + + @Value("${appSecret}") + private String appSecret; + + @Value("${parkId}") + private String parkId; + + /** + * 通用请求 + * + * @param serviceCode 方法名 + * @return 通用请求 + */ + private JSONObject getMap(String serviceCode) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("appId", appId); + jsonObject.put("parkId", parkId); + jsonObject.put("ts", System.currentTimeMillis()); + jsonObject.put("reqId", IdUtil.fastSimpleUUID()); + jsonObject.put("serviceCode", serviceCode); + return jsonObject; + } + + /** + * 区域剩余车位查询 + * + * @return 响应类 + */ + @Override + public CommonResponse GetAreaFreeSpaceNum() { + CommonResponse response = new CommonResponse(); + JSONObject jsonObject = getMap("getAreaFreeSpaceNum"); + String key = SignatureUtil.paramsSign(jsonObject, appSecret); + jsonObject.put("key", key); + String body = jsonObject.toJSONString(); + String result = HttpRequest.post(url + "api/wec/GetAreaFreeSpaceNum") + .header("version", "1.0.0") + .header("accept-language", "zh-CN") + .body(body).execute().body(); + Map map = JSONUtil.parseObj(result); + Object dataObj = map.get("data"); + response.setResMsg((String) map.get("resMsg")); + response.setResCode((String) map.get("resCode")); + if (dataObj == null || dataObj == "" || StrUtil.isEmpty(String.valueOf(dataObj))) { + return response; + } + Map data = JSONUtil.parseObj(dataObj); + DataDTO dataDTO = BeanUtil.toBeanIgnoreCase(data, DataDTO.class, false); + response.setData(dataDTO); + return response; + } + + /** + * 根据车牌查询在场数据 + * + * @param plateNo 车牌号 + * @return 响应类 + */ + @Override + public CommonResponse GetCarInfoByPlateNo(String plateNo) { + CommonResponse response = new CommonResponse(); + JSONObject jsonObject = getMap("getCarInfoByPlateNo"); + jsonObject.put("plateNo", plateNo); + String key = SignatureUtil.paramsSign(jsonObject, appSecret); + jsonObject.put("key", key); + String body = jsonObject.toJSONString(); + String result = HttpRequest.post(url + "api/wec/GetCarInfoByPlateNo") + .header("version", "1.0.0") + .header("accept-language", "zh-CN") + .body(body).execute().body(); + Map map = JSONUtil.parseObj(result); + Object dataObj = map.get("data"); + response.setResMsg((String) map.get("resMsg")); + response.setResCode((String) map.get("resCode")); + if (dataObj == null || dataObj == "" || StrUtil.isEmpty(String.valueOf(dataObj))) { + return response; + } + Map data = JSONUtil.parseObj(dataObj); + CarInfoDTO dataDTO = BeanUtil.toBeanIgnoreCase(data, CarInfoDTO.class, false); + response.setData(dataDTO); + return response; + } +} diff --git a/src/main/java/com/parkingLot/utils/SignatureUtil.java b/src/main/java/com/parkingLot/utils/SignatureUtil.java new file mode 100644 index 0000000..66b6726 --- /dev/null +++ b/src/main/java/com/parkingLot/utils/SignatureUtil.java @@ -0,0 +1,85 @@ +package com.parkingLot.utils; + +import com.alibaba.fastjson2.JSONObject; +import com.google.common.base.Joiner; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Map; +import java.util.TreeMap; + +/** + * 科拓签名工具 + * + * @author wu + * @since 2024/12/13 09:21 + */ +public class SignatureUtil { + + /** + * 参数签名 + * 示例: + * 参数对象:{"amount":100,"orderNo":"闽C12345","payTime":"2020-03-06 10:57:22","freeDetail":"[{\"code\":\"\",\"money\":100,\"time\":0,\"type\":0}]","paySource":"85d15350778b11e9bbaa506b4b2f6421","outOrderNo":"T20200306124536001","parkId":"1000001","payableAmount":200,"reqId":"5be4e3e6d5704a7d91ccbd9731d970f5","payType":1006,"payMethod":6,"appId":"85d15350778b11e9bbaa506b4b2f6421","freeTime":0,"paymentExt":"{\"deviceNo\":\"123456\"}","freeMoney":100,"ts":1583744086841} + * url拼接:amount=100&freeDetail=[{"code":"","money":100,"time":0,"type":0}]&freeMoney=100&freeTime=0&orderNo=闽C12345&outOrderNo=T20200306124536001&parkId=1000001&payMethod=6&paySource=85d15350778b11e9bbaa506b4b2f6421&payTime=2020-03-06 10:57:22&payType=1006&payableAmount=200&paymentExt={"deviceNo":"123456"}&reqId=5be4e3e6d5704a7d91ccbd9731d970f5&ts=1583744086841&EED96C219E83450A + * 签名结果:B19F7863ADCC8B5442A757AC7B90F6AC + * + * @param requestBody 参数对象 + * @param appSecret 秘钥 + * @return 签名 + */ + public static String paramsSign(JSONObject requestBody, String appSecret) { + TreeMap params = new TreeMap<>(); + //过滤掉key,appId字段,空属性及Map或List等复杂对象 + requestBody.entrySet().stream().filter( + p -> !"key".equals(p.getKey()) + && !"appId".equals(p.getKey()) + && p.getValue() != null + && !(p.getValue() instanceof Map) + && !(p.getValue() instanceof Iterable)) + .forEach(p -> { + if (!p.getValue().equals("")) { + params.put(p.getKey(), p.getValue().toString()); + } + }); + //拼接appSecret + String temp = Joiner.on("&").withKeyValueSeparator("=").join(params).concat("&").concat(appSecret); + return md5(temp).toUpperCase(); + } + + /** + * 对文本执行 md5 摘要加密, 此算法与 mysql,JavaScript生成的md5摘要进行过一致性对比. + * + * @param plainText 需要摘要的文本 + * @return 返回值中的字母为小写 + */ + private static String md5(String plainText) { + if (null == plainText) { + plainText = ""; + } + String mD5Str = null; + try { + // JDK 支持以下6种消息摘要算法,不区分大小写 + // md5,sha(sha-1),md2,sha-256,sha-384,sha-512 + MessageDigest md = MessageDigest.getInstance("MD5"); + md.update(plainText.getBytes(StandardCharsets.UTF_8)); + byte[] b = md.digest(); + int i; + StringBuilder builder = new StringBuilder(32); + for (byte value : b) { + i = value; + if (i < 0) { + i += 256; + } + if (i < 16) { + builder.append("0"); + } + builder.append(Integer.toHexString(i)); + } + mD5Str = builder.toString(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return mD5Str; + } +} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml new file mode 100644 index 0000000..efeb8f6 --- /dev/null +++ b/src/main/resources/application-dev.yml @@ -0,0 +1,18 @@ +# 日志配置 +logging: + level: + com.parkingLot: error + org.springframework: error + +# 科拓请求地址 +url: https://kp-open.keytop.cn/unite-api/ + +# 科拓appId +appId: 13798 + +# 科拓appSecret +appSecret: f387dfe312244e46913b2123c70f934e + +# 车场id +parkId: 512025407 + diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..30a08e1 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,13 @@ +server: + port: 9004 + servlet: + # 应用的访问路径 + context-path: /api +spring: + profiles: + active: dev +# 日志配置 +logging: + level: + com.parkingLot: info + org.springframework: info diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 0000000..bae3bd0 --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/sys-info.log + + + + ${log.path}/sys-info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/sys-error.log + + + + ${log.path}/sys-error.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + ${log.path}/sys-user.log + + + ${log.path}/sys-user.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/static/templates/192.168.1.101_正面.bmp b/src/main/resources/static/templates/192.168.1.101_正面.bmp new file mode 100644 index 0000000000000000000000000000000000000000..13348106cf40726d56f4f60d2336676f5d71f7c5 GIT binary patch literal 15924 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
    D!%dI%AJO#YOQ}OTq@S5W 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/static/templates/192.168.1.102_正面.bmp b/src/main/resources/static/templates/192.168.1.102_正面.bmp new file mode 100644 index 0000000000000000000000000000000000000000..22eebfcf976094bd38eb9dc9e377eaf77e04ec35 GIT binary patch literal 17286 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

    +Py<&TmjA11jkang-ljqZOs+{lVdtzU? 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 XEDW5XCM|RVFn=lv8uDebW^euvWWy`s literal 0 HcmV?d00001 diff --git a/src/main/resources/static/templates/192.168.1.91_反面.bmp b/src/main/resources/static/templates/192.168.1.91_反面.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2fc81b0094c43409d5315d0855d9c015be164c99 GIT binary patch literal 3444 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/static/templates/192.168.1.91_正面.bmp b/src/main/resources/static/templates/192.168.1.91_正面.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c1ea71ddf51e452abcc5aa65619140b5fe1bf2e0 GIT binary patch literal 2573 zcmcguYdF&l8~;x;W6Zf^DJA6)(ZL*sP0Ar@p`3^1JcosH9NQ4p-qN9hxg-qUBCOjuiyRcKK-uy7S_^4L`YT$000p)Q)8>0=(=Mp zC}hX4$9aC(37}vr6C#RYpb-AF{BmeR^=vCiG*--#T868?c_myn%s%&CScsr%&n^U$o>UfKAE& z6RxV@3Vj`&QIp|rp4O*i63c{6Kft@9DBm+_STG+dvvvKDG|NWRl?6=#9XV|m>rUT*>e|KYv4PF z)MN^snp~SDCU7qn(ICH+1ykaae|m$&h%eq)=;>hCf=m2hrR#VpH0&Y&8&Lmsw%HTw z)Lhxvyu<*HB!K~1fJx-D{mD?WjpXoMc;ltxXbZIKhv9zOUfrn+7?~D0bHeN--&;P< zJHQoV27v;+t1ptLRU45_tXD%Ys1=!mb}w>nJ01N(yCH??iC5dNA>MQ6U@FJ7J=wwW zNY~dQrmq$l)Vdf~xxUpa?|TpE7k&?&Hy8 zrlJ!5S@0&owlst33Ku`b?86IfNJX@|ep%KxFw?Gy3m{aDzP>mH%W--ua<%$bp{H`= zisbjt?ETExcR+vy)c@HxcRBSax`8>`U%bFgD5$=N5t*hbcNRdOomoNa_l@MfvTjlJ z)f*pD7U=AflKxJW24@|XYajBw1zk&*1orkGh^Ll_V6;P{+!=arOq9XhxmXG#dgVda zEy4iZQc`aO#?=>C{%~qB0XDt0BDW~Vh4yJa{Tb{HcU_v9N$ATnc?ZkcU*$y^LJ6h- zzhU1U^fe!oBI^lronNcLKG+GhMVpwO$cvqLS;N3L<7OmU#8)xr2pL@6dmc)`fOqDj z6Nj?Sd+XXLje?&U>72=EF0X(FF~(F3PvxJiuP1(M%{QNTP~Vu zdu@GQvbIqFHA+LaSTh_Pj(hH=g%xMky=!xL5smY^s|vZXq)aEV@9L&1rk{`hWJD6R zJRF;?7F?HN95;*qoF=vm$XP!H0x}GY%l~$mBI0d4|!E5SyP*64(VIt;iBKM;?aIzZdv5 zcwR4w@Zsi!wiWVKj^0pb(%BA-myC?iQN^+T+5l0&Pq}_joG;8e)#1=^P~@YlyiUV9 zGa%dd(44_@ZgE5swnS}aXiCztNgy>`4-vQLACDl!%i0L2u7%6JXN83Hc+!v)*Ua3G zGcHl>XWc9;_#vRO5wr)dZ97?TnMhaYhNu2Mls{(l-*i3$h*8B?hRr3JfWs8kz^qE8 zbKlH!*Rt)enlK^KFQ_~>6B&#p zf;R{-AZe;Pkkta%8um5bE(8bDV{5w${hx9g9#;3A2Ln-dkr#mSuF(+)yi8Cm%BOwc z)TGX^$Ub13VuR~SKmK0oFu{onf&U;hjnKy|Bg&ExTEr~-PnXBf_Hs)Jghv~DEW>*3<@Ls*a<0Zz#x>eL5!reF$s zhMU|ys_TiuIB-|f3!h`h(3q8KGZB}fc78rny&aX>bUXvp#U2PJDM@cgG^?`u2I{ql zeL3#M%#kJSx|U0#SM9}il?ILnnvnd`;Hnwq1cN7yQSZ?@Nuz|jE4Sh{k z?CxRK=V`Dg{RGoBRM>edhX{5c2PWtou(n(rDh0^5dpQ(cPOg{p1o@~T2EaVI|Jo+g?4Xx_g*^Hf1b&4a zGtihaXQ(OTUk2QJ3qoTd7m1%CNTMBsBL$y*uBK_(klK2`+%69ml`gZHC8QP7m~uO6 zViH84>hAH+knav1^7_%#oh~Wza)xgtCpHn literal 0 HcmV?d00001 diff --git a/src/main/resources/static/templates/192.168.1.92_正面.bmp b/src/main/resources/static/templates/192.168.1.92_正面.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0a0da05f59a7f07d62ad029af3966a0110822b5e GIT binary patch literal 2294 zcmcguX*kpi7yr-rPbNJvO*eIGEJI@#rA&wh!z7h0Sw=&$MMVfj8I$acB3qWRM;W3F z*(PJFZj3F=ScYOOSqlld`gWiDzVFxf!#Tg-dCqe_opXNYM4Db8>=rsG1OUKpqceE( zZFJZ+CVa=XUk`Qpv<(m+bAlc~Z%0jS2cWC&d0hZ_N!_(^1-2dU^g3hX0|3IT-v(** zeC7lI@Mt5v?!^GoY=(B+I3Cd&P7Ngkw?tOpXW(e$F@zNE4Cn;`2|OhJxwZfjfg|Jf zLh(5D(MA|T>cE>F$(D4h&8bXmCbr>;ZOx2pa!v3Sy|{A7&;IhFAQV9cKuG`s#{vII zLvj%TYtz$)@1u+IG#?t=@7^R?uk>#5f9afE7q%CH6r0+g-CAiD*wUQ+X7d0Z?)k$^ zL9UJ%MP9A5sU(Jc*%~QavQWs%TXOe`;hg+kLzN4CwjUlOkyLNY?P_^?+Wd~6xM>QbzZrl7_6BfR zKp*aLaCG1k1-D?u+wzKoj*MzSj@YU%u*{@*c@SrHq?p{Iph4^VyHXA0UWjh^w6!6%Zz`06YQyhp-r$w&e0q(kX z#6h;6|8UjMxZ#GEYCIhbq-eSVLwH|6kzNpjf)*R;5alUt&CsSJgvp$2rh z$t`8S?A)7gYvY-C!Fkr&#D6wbiX63SX-HNqI`;=9Z}EY6nRwyR+ju}FhdG77*$87s zG3n>`@Uof~lP~JnA#c&U=~5}yC&wU%I&)B6$T+2qORF7+2khX*abZo-E}=C3yY>WU z2WjFGqFZ4ST zP!1*>4)<>BvNT$5TD}5Y(7Vf7YE0a?SCoLR;v{dVN|8gwrq-aR{bf(gK-A@xdFqjD5vvDg1o()E#EI;<2sRpL z*8NvCR=R)$skd{i#{+@$g&N>aQ+aa@E*t*pw(D}@WE3a-kc9V_1G~+XNvgW!j|)E6 zxbNaGPWLF1Wj@Qz5%<_~?kI--@ib^CgrRpLX39#%UE`K>RviP=6J#;u13hIt8Mzf4=+ME6S_tp}@CxGY(p0?{5^+^_ou(>@3Py@geZ(B>ks)C5Dd z@kV|}{#gQ}YCJ4ukR_C4XTs}PLXHe+7X6X;EoL2NtGS*hI5(pv zFjce?nBUuqA<+leC8HTqmkJ*z*5-_UT4QxKc35{;5pS)3-CHr7 zE581#WcHXJ;>AU0!m1dWvHb>Sh<0+DG__y_{k@lP%M`9wUB%= z<&mfeTOsS~40(TH0(Z^OtZ`Z2Zh$`)mK*Y;21KZsra;Tk*`=hxQV;L3+fVn1D2ww_!rh=- z&^766$GBsz4bsb)!-Tdkkbeuu)=U8g1&CU)+c3=crsYWj zXTvMVEZ(!+cLIhDTvaqU^hxDzh9xJ^XxGVCF%-?x<}~}UVP8s@5IXq{nUw|z(gm!U zy80%{W`;XWLe>{7s}RJi_dalA#L$zS$~?rqsFsHMyGzIHM_H&V0n-TDf#DZpb;nZO|H`{yX5%2q3z(w^FiX2sWJcWOFzboq&TrO11A&6Ev(hZG#G{wMEB1s!2$dN0(TLRH&(Js6~YE|Ewq*jLmqI zD)ckGwk&{G(OYylKN8H{3z1n&^9X~XCYHXwZh;EdHOb6%K!x{S@q1b> zostwuoR}F`;<3-yY?8C7{xgj9A=4xnic?)0IER$9xdI8_F}a-vrt19$W+6(vGLtuG z2>twI5yn^4OKw+Bg$#~r-DzXPMAI6f!s}9Sg8qNG&i@#?{}1KGfWHJ3@?A1_D9_7o P|0;ly!38{B&w=tcSl<1^ literal 0 HcmV?d00001 diff --git a/src/main/resources/static/templates/192.168.1.93_反面.bmp b/src/main/resources/static/templates/192.168.1.93_反面.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2d640ad821ea81fd170ec15ed7737ce89a517c78 GIT binary patch literal 1052 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 GvHt}7UQh-A literal 0 HcmV?d00001 diff --git a/src/main/resources/static/templates/192.168.1.94_正面.bmp b/src/main/resources/static/templates/192.168.1.94_正面.bmp new file mode 100644 index 0000000000000000000000000000000000000000..347ff5b281949a61ff46b8f30baf1427a2ec256c GIT binary patch literal 3390 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 be^}2|FKap5eboq<-5ESx{an^LB{Ts5N~EO5 literal 0 HcmV?d00001 diff --git a/src/main/resources/static/templates/192.168.1.95_正面.bmp b/src/main/resources/static/templates/192.168.1.95_正面.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f9fef3f75307b2d9236ea0d42572df9d33619846 GIT binary patch literal 2927 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 BBpd($ literal 0 HcmV?d00001 diff --git a/src/main/resources/static/templates/192.168.1.96_反面.bmp b/src/main/resources/static/templates/192.168.1.96_反面.bmp new file mode 100644 index 0000000000000000000000000000000000000000..7e371f538549552b58fa37104192397646900846 GIT binary patch literal 3466 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 Nkx!c%mKiux{{@Cq9+?0D literal 0 HcmV?d00001 diff --git a/src/main/resources/static/templates/192.168.1.96_正面.bmp b/src/main/resources/static/templates/192.168.1.96_正面.bmp new file mode 100644 index 0000000000000000000000000000000000000000..48d4af3cd21e01213908ca7060900b5f9bc390b7 GIT binary patch literal 2741 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 VPxgt1zuv2wfVruaNsX}^