Răsfoiți Sursa

初始化提交

xucaiqin 5 luni în urmă
comite
0d2ba3737f
40 a modificat fișierele cu 2019 adăugiri și 0 ștergeri
  1. 37 0
      .gitignore
  2. 1 0
      README.md
  3. 262 0
      pom.xml
  4. 13 0
      src/main/java/com/sckw/access/AccessApplication.java
  5. 12 0
      src/main/java/com/sckw/access/config/MybatisPlusConfig.java
  6. 51 0
      src/main/java/com/sckw/access/config/RedisConfig.java
  7. 25 0
      src/main/java/com/sckw/access/controller/TApprovalController.java
  8. 47 0
      src/main/java/com/sckw/access/controller/TBarrierGateController.java
  9. 36 0
      src/main/java/com/sckw/access/controller/TVisitorController.java
  10. 36 0
      src/main/java/com/sckw/access/controller/TWhitelistController.java
  11. 52 0
      src/main/java/com/sckw/access/domain/Base.java
  12. 57 0
      src/main/java/com/sckw/access/domain/para/BarrierGateSave.java
  13. 15 0
      src/main/java/com/sckw/access/domain/para/BasePage.java
  14. 46 0
      src/main/java/com/sckw/access/entity/TApproval.java
  15. 67 0
      src/main/java/com/sckw/access/entity/TBarrierGate.java
  16. 109 0
      src/main/java/com/sckw/access/entity/TVisitor.java
  17. 94 0
      src/main/java/com/sckw/access/entity/TWhitelist.java
  18. 39 0
      src/main/java/com/sckw/access/exception/BusinessException.java
  19. 71 0
      src/main/java/com/sckw/access/handler/GlobalExceptionHandler.java
  20. 13 0
      src/main/java/com/sckw/access/mapper/TApprovalMapper.java
  21. 13 0
      src/main/java/com/sckw/access/mapper/TBarrierGateMapper.java
  22. 13 0
      src/main/java/com/sckw/access/mapper/TVisitorMapper.java
  23. 13 0
      src/main/java/com/sckw/access/mapper/TWhitelistMapper.java
  24. 19 0
      src/main/java/com/sckw/access/service/TApprovalService.java
  25. 16 0
      src/main/java/com/sckw/access/service/TBarrierGateService.java
  26. 16 0
      src/main/java/com/sckw/access/service/TVisitorService.java
  27. 16 0
      src/main/java/com/sckw/access/service/TWhitelistService.java
  28. 69 0
      src/main/java/com/sckw/access/util/DateTimeUtil.java
  29. 18 0
      src/main/java/com/sckw/access/util/IdUtil.java
  30. 159 0
      src/main/java/com/sckw/access/util/MD5Util.java
  31. 212 0
      src/main/java/com/sckw/access/util/OkHttpUtils.java
  32. 74 0
      src/main/java/com/sckw/access/util/R.java
  33. 57 0
      src/main/resources/application-dev.yml
  34. 40 0
      src/main/resources/application-pro.yml
  35. 19 0
      src/main/resources/application.yml
  36. 79 0
      src/main/resources/logback.xml
  37. 20 0
      src/main/resources/mapper/TApprovalMapper.xml
  38. 24 0
      src/main/resources/mapper/TBarrierGateMapper.xml
  39. 31 0
      src/main/resources/mapper/TVisitorMapper.xml
  40. 28 0
      src/main/resources/mapper/TWhitelistMapper.xml

+ 37 - 0
.gitignore

@@ -0,0 +1,37 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
+
+logs

+ 1 - 0
README.md

@@ -0,0 +1 @@
+# 门禁系统

+ 262 - 0
pom.xml

@@ -0,0 +1,262 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.sckw.access</groupId>
+    <artifactId>access-control</artifactId>
+    <version>1.0.0</version>
+
+    <properties>
+        <java.version>17</java.version>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <spring-boot.version>3.4.7</spring-boot.version>
+        <maven-clean-plugin.version>3.2.0</maven-clean-plugin.version>
+        <start-class>com.sckw.robot.RobotApplication</start-class>
+        <maven-compiler-plugin.version>3.10.1</maven-compiler-plugin.version>
+        <maven-jar-plugin.version>3.3.0</maven-jar-plugin.version>
+        <maven-resources-plugin.version>3.3.0</maven-resources-plugin.version>
+        <maven-install-plugin.version>3.0.1</maven-install-plugin.version>
+        <maven-deploy-plugin.version>3.0.0</maven-deploy-plugin.version>
+    </properties>
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>${spring-boot.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <!--排除tomcat-->
+            <exclusions>
+                <exclusion>
+                    <artifactId>spring-boot-starter-tomcat</artifactId>
+                    <groupId>org.springframework.boot</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <!--undertow-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-undertow</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-jdbc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.github.xiaoymin</groupId>
+            <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
+            <version>4.4.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <!--commons-lang3-->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+        <!--redis-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-pool2</artifactId>
+        </dependency>
+        <!--security-->
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-crypto</artifactId>
+        </dependency>
+        <!--fastjson-->
+        <dependency>
+            <groupId>com.alibaba.fastjson2</groupId>
+            <artifactId>fastjson2</artifactId>
+            <version>2.0.57</version>
+        </dependency>
+        <!--druid-->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-3-starter</artifactId>
+            <version>1.2.23</version>
+        </dependency>
+        <!--需要指定mysql连接器版本,内置版本过高(9.x.x),否则项目启动时,数据库连接池链接很久-->
+        <dependency>
+            <groupId>com.mysql</groupId>
+            <artifactId>mysql-connector-j</artifactId>
+            <version>8.2.0</version>
+        </dependency>
+        <!--mybatis-plus-->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
+            <version>3.5.12</version>
+        </dependency>
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+            <version>4.9.3</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.8.28</version> <!-- 可根据需要替换为最新版本 -->
+        </dependency>
+
+
+    </dependencies>
+
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-clean-plugin</artifactId>
+                    <version>${maven-clean-plugin.version}</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-compiler-plugin</artifactId>
+                    <version>${maven-compiler-plugin.version}</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-deploy-plugin</artifactId>
+                    <version>${maven-deploy-plugin.version}</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-install-plugin</artifactId>
+                    <version>${maven-install-plugin.version}</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-jar-plugin</artifactId>
+                    <version>${maven-jar-plugin.version}</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-resources-plugin</artifactId>
+                    <version>${maven-resources-plugin.version}</version>
+                    <configuration>
+                        <propertiesEncoding>${project.build.sourceEncoding}</propertiesEncoding>
+                        <delimiters>
+                            <delimiter>@</delimiter>
+                        </delimiters>
+                        <useDefaultDelimiters>false</useDefaultDelimiters>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-maven-plugin</artifactId>
+                    <version>${spring-boot.version}</version>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>repackage</id>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <excludes>
+                        <exclude>
+                            <groupId>org.projectlombok</groupId>
+                            <artifactId>lombok</artifactId>
+                        </exclude>
+                    </excludes>
+                    <mainClass>${start-class}</mainClass>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>17</source>
+                    <target>17</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifest>
+                            <mainClass>${start-class}</mainClass>
+                            <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+                        </manifest>
+                    </archive>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-resources-plugin</artifactId>
+                <configuration>
+                    <propertiesEncoding>${project.build.sourceEncoding}</propertiesEncoding>
+                    <delimiters>
+                        <delimiter>@</delimiter>
+                    </delimiters>
+                    <useDefaultDelimiters>false</useDefaultDelimiters>
+                </configuration>
+            </plugin>
+        </plugins>
+
+        <resources>
+            <resource>
+                <!-- xml放在java目录下-->
+                <directory>src/main/java</directory>
+                <includes>
+                    <include>**/*.xml</include>
+                </includes>
+            </resource>
+            <resource>
+                <directory>src/main/resources</directory>
+                <includes>
+                    <include>**/*.properties</include>
+                    <!-- 配置一下yml文件 -->
+                    <include>**/*.yml</include>
+                    <include>**/*.xml</include>
+                </includes>
+                <filtering>false</filtering>
+            </resource>
+        </resources>
+    </build>
+</project>

+ 13 - 0
src/main/java/com/sckw/access/AccessApplication.java

@@ -0,0 +1,13 @@
+package com.sckw.access;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class AccessApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(AccessApplication.class, args);
+    }
+
+}

+ 12 - 0
src/main/java/com/sckw/access/config/MybatisPlusConfig.java

@@ -0,0 +1,12 @@
+package com.sckw.access.config;
+
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 分页配置
+ */
+@Configuration
+public class MybatisPlusConfig {
+
+
+}

+ 51 - 0
src/main/java/com/sckw/access/config/RedisConfig.java

@@ -0,0 +1,51 @@
+package com.sckw.access.config;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+/**
+ * @author xcq
+ * @date 2023-02-18 19:12:57
+ * @description
+ */
+@Configuration
+public class RedisConfig {
+
+    @Bean
+    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
+        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
+        redisTemplate.setConnectionFactory(redisConnectionFactory);
+        redisTemplate.setKeySerializer(new StringRedisSerializer());
+        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
+
+        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer());
+        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer());
+        redisTemplate.afterPropertiesSet();
+        return redisTemplate;
+    }
+
+    private Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer() {
+        // 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
+        ObjectMapper objectMapper = new ObjectMapper();
+        // 解决jackson2无法序列化LocalDateTime问题
+        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+        objectMapper.registerModule(new JavaTimeModule());
+        // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
+        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
+
+        // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
+        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
+
+        return new Jackson2JsonRedisSerializer<>(objectMapper, Object.class);
+    }
+}

+ 25 - 0
src/main/java/com/sckw/access/controller/TApprovalController.java

@@ -0,0 +1,25 @@
+package com.sckw.access.controller;
+
+import com.sckw.access.service.TApprovalService;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import org.springframework.web.bind.annotation.*;
+
+
+/**
+ * 审批人员管理表
+ *
+ * @author xxxxx
+ */
+@RestController
+@RequestMapping("/approval")
+@Tag(name = "审批人员管理")
+public class TApprovalController {
+    /**
+     * 服务对象
+     */
+    @Resource
+    private TApprovalService tApprovalService;
+
+
+}

+ 47 - 0
src/main/java/com/sckw/access/controller/TBarrierGateController.java

@@ -0,0 +1,47 @@
+package com.sckw.access.controller;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.sckw.access.domain.para.BarrierGateSave;
+import com.sckw.access.entity.TBarrierGate;
+import com.sckw.access.service.TBarrierGateService;
+import com.sckw.access.util.R;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+
+/**
+ * 道闸管理表
+ *
+ * @author xxxxx
+ */
+@RestController
+@RequestMapping("/barrierGate")
+@Tag(name = "道闸管理")
+public class TBarrierGateController {
+    /**
+     * 服务对象
+     */
+    @Resource
+    private TBarrierGateService tBarrierGateService;
+
+    /**
+     * 通过主键查询单条数据
+     *
+     * @param id 主键
+     * @return 单条数据
+     */
+    @GetMapping("page")
+    public R<Object> page(Integer id) {
+        return R.ok(tBarrierGateService.getById(id));
+    }
+
+    @PostMapping("save")
+    public R<Boolean> save(@RequestBody @Validated BarrierGateSave barrierGateSave) {
+        TBarrierGate save = BeanUtil.toBean(barrierGateSave, TBarrierGate.class);
+        return R.ok(tBarrierGateService.save(save));
+    }
+
+
+}

+ 36 - 0
src/main/java/com/sckw/access/controller/TVisitorController.java

@@ -0,0 +1,36 @@
+package com.sckw.access.controller;
+
+import com.sckw.access.entity.TVisitor;
+import com.sckw.access.service.TVisitorService;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import org.springframework.web.bind.annotation.*;
+
+
+/**
+ * 访客管理表
+ *
+ * @author xxxxx
+ */
+@RestController
+@RequestMapping("/visitor")
+@Tag(name = "访客管理")
+public class TVisitorController {
+    /**
+     * 服务对象
+     */
+    @Resource
+    private TVisitorService tVisitorService;
+
+    /**
+     * 通过主键查询单条数据
+     *
+     * @param id 主键
+     * @return 单条数据
+     */
+    @GetMapping("selectOne")
+    public TVisitor selectOne(Integer id) {
+        return tVisitorService.getById(id);
+    }
+
+}

+ 36 - 0
src/main/java/com/sckw/access/controller/TWhitelistController.java

@@ -0,0 +1,36 @@
+package com.sckw.access.controller;
+
+import com.sckw.access.entity.TWhitelist;
+import com.sckw.access.service.TWhitelistService;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import org.springframework.web.bind.annotation.*;
+
+
+/**
+ * 道闸白名单表
+ *
+ * @author xxxxx
+ */
+@RestController
+@RequestMapping("/whitelist")
+@Tag(name = "道闸白名单")
+public class TWhitelistController {
+    /**
+     * 服务对象
+     */
+    @Resource
+    private TWhitelistService tWhitelistService;
+
+    /**
+     * 通过主键查询单条数据
+     *
+     * @param id 主键
+     * @return 单条数据
+     */
+    @GetMapping("selectOne")
+    public TWhitelist selectOne(Integer id) {
+        return tWhitelistService.getById(id);
+    }
+
+}

+ 52 - 0
src/main/java/com/sckw/access/domain/Base.java

@@ -0,0 +1,52 @@
+package com.sckw.access.domain;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author xucaiqin
+ * @date 2025-07-24 13:15:51
+ */
+@Getter
+@Setter
+public class Base {
+
+    /**
+     * 创建人
+     */
+    @TableField(value = "create_by")
+    @Schema(description="创建人")
+    private Long createBy;
+
+    /**
+     * 创建时间
+     */
+    @TableField(value = "create_time")
+    @Schema(description="创建时间")
+    private LocalDateTime createTime;
+
+    /**
+     * 修改人
+     */
+    @TableField(value = "update_by")
+    @Schema(description="修改人")
+    private Long updateBy;
+
+    /**
+     * 更新时间
+     */
+    @TableField(value = "update_time")
+    @Schema(description="更新时间")
+    private LocalDateTime updateTime;
+
+    /**
+     * 删除标识 0-正常 1-删除
+     */
+    @TableField(value = "del_flag")
+    @Schema(description="删除标识 0-正常 1-删除")
+    private Boolean delFlag;
+}

+ 57 - 0
src/main/java/com/sckw/access/domain/para/BarrierGateSave.java

@@ -0,0 +1,57 @@
+package com.sckw.access.domain.para;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.time.LocalDateTime;
+
+/**
+* @date 2025-07-24 11:45:20
+* @author xucaiqin
+*/
+@Schema(description="道闸管理")
+@Getter
+@Setter
+public class BarrierGateSave {
+    /**
+     * id
+     */
+    @Schema(description="id")
+    private Long id;
+
+    /**
+     * 编号
+     */
+    @Schema(description="编号")
+    private String code;
+
+    /**
+     * 道闸名称
+     */
+    @Schema(description="道闸名称")
+    private String name;
+
+    /**
+     * 道闸位置
+     */
+    @Schema(description="道闸位置")
+    private String location;
+
+    /**
+     * 道闸性质 1-进 2-出
+     */
+    @Schema(description="道闸性质 1-进 2-出")
+    private Integer type;
+
+    /**
+     * 启用标识 1-启用 2-禁用
+     */
+    @Schema(description="启用标识 1-启用 2-禁用")
+    private Integer status;
+
+}

+ 15 - 0
src/main/java/com/sckw/access/domain/para/BasePage.java

@@ -0,0 +1,15 @@
+package com.sckw.access.domain.para;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author xucaiqin
+ * @date 2025-07-24 13:13:16
+ */
+@Getter
+@Setter
+public class BasePage {
+    private Integer pageNo;
+    private Integer pageSize;
+}

+ 46 - 0
src/main/java/com/sckw/access/entity/TApproval.java

@@ -0,0 +1,46 @@
+package com.sckw.access.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.sckw.access.domain.Base;
+import io.swagger.v3.oas.annotations.media.Schema;
+import java.time.LocalDateTime;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+* @date 2025-07-24 11:44:43
+* @author xucaiqin
+*/
+
+/**
+ * 审批人员管理表
+ */
+@Schema(description = "审批人员管理表")
+@Getter
+@Setter
+@TableName(value = "t_approval")
+public class TApproval extends Base {
+    /**
+     * id
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    @Schema(description = "id")
+    private Long id;
+
+    /**
+     * 审批人姓名
+     */
+    @TableField(value = "`name`")
+    @Schema(description = "审批人姓名")
+    private String name;
+
+    /**
+     * 手机号
+     */
+    @TableField(value = "mobile")
+    @Schema(description = "手机号")
+    private String mobile;
+}

+ 67 - 0
src/main/java/com/sckw/access/entity/TBarrierGate.java

@@ -0,0 +1,67 @@
+package com.sckw.access.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.sckw.access.domain.Base;
+import io.swagger.v3.oas.annotations.media.Schema;
+import java.time.LocalDateTime;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+* @date 2025-07-24 11:45:20
+* @author xucaiqin
+*/
+/**
+    * 道闸管理表
+    */
+@Schema(description="道闸管理表")
+@Getter
+@Setter
+@TableName(value = "t_barrier_gate")
+public class TBarrierGate extends Base {
+    /**
+     * id
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    @Schema(description="id")
+    private Long id;
+
+    /**
+     * 编号
+     */
+    @TableField(value = "code")
+    @Schema(description="编号")
+    private String code;
+
+    /**
+     * 道闸名称
+     */
+    @TableField(value = "`name`")
+    @Schema(description="道闸名称")
+    private String name;
+
+    /**
+     * 道闸位置
+     */
+    @TableField(value = "`location`")
+    @Schema(description="道闸位置")
+    private String location;
+
+    /**
+     * 道闸性质 1-进 2-出
+     */
+    @TableField(value = "`type`")
+    @Schema(description="道闸性质 1-进 2-出")
+    private Integer type;
+
+    /**
+     * 启用标识 1-启用 2-禁用
+     */
+    @TableField(value = "`status`")
+    @Schema(description="启用标识 1-启用 2-禁用")
+    private Integer status;
+
+}

+ 109 - 0
src/main/java/com/sckw/access/entity/TVisitor.java

@@ -0,0 +1,109 @@
+package com.sckw.access.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.sckw.access.domain.Base;
+import io.swagger.v3.oas.annotations.media.Schema;
+import java.time.LocalDateTime;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+* @date 2025-07-24 11:45:20
+* @author xucaiqin
+*/
+/**
+    * 访客管理表
+    */
+@Schema(description="访客管理表")
+@Getter
+@Setter
+@TableName(value = "t_visitor")
+public class TVisitor extends Base {
+    /**
+     * 编号
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    @Schema(description="编号")
+    private Long id;
+
+    /**
+     * 访客姓名
+     */
+    @TableField(value = "`name`")
+    @Schema(description="访客姓名")
+    private String name;
+
+    /**
+     * 车牌号
+     */
+    @TableField(value = "license_plate")
+    @Schema(description="车牌号")
+    private String licensePlate;
+
+    /**
+     * 人员相片URL
+     */
+    @TableField(value = "photo_url")
+    @Schema(description="人员相片URL")
+    private String photoUrl;
+
+    /**
+     * 车辆类型
+     */
+    @TableField(value = "vehicle_type")
+    @Schema(description="车辆类型")
+    private Object vehicleType;
+
+    /**
+     * 申请进入时间
+     */
+    @TableField(value = "apply_entry_time")
+    @Schema(description="申请进入时间")
+    private LocalDateTime applyEntryTime;
+
+    /**
+     * 申请出门时间
+     */
+    @TableField(value = "apply_exit_time")
+    @Schema(description="申请出门时间")
+    private LocalDateTime applyExitTime;
+
+    /**
+     * 通过道闸
+     */
+    @TableField(value = "barrier_ids")
+    @Schema(description="通过道闸")
+    private String barrierIds;
+
+    /**
+     * 审批人
+     */
+    @TableField(value = "approver_id")
+    @Schema(description="审批人")
+    private Long approverId;
+
+    /**
+     * 审批状态
+     */
+    @TableField(value = "approval_status")
+    @Schema(description="审批状态")
+    private Integer approvalStatus;
+
+    /**
+     * 审批原因
+     */
+    @TableField(value = "approval_reason")
+    @Schema(description="审批原因")
+    private String approvalReason;
+
+    /**
+     * 申请时间
+     */
+    @TableField(value = "apply_time")
+    @Schema(description="申请时间")
+    private LocalDateTime applyTime;
+
+}

+ 94 - 0
src/main/java/com/sckw/access/entity/TWhitelist.java

@@ -0,0 +1,94 @@
+package com.sckw.access.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.sckw.access.domain.Base;
+import io.swagger.v3.oas.annotations.media.Schema;
+import java.time.LocalDateTime;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+* @date 2025-07-24 11:45:20
+* @author xucaiqin
+*/
+/**
+    * 道闸白名单表
+    */
+@Schema(description="道闸白名单表")
+@Getter
+@Setter
+@TableName(value = "t_whitelist")
+public class TWhitelist extends Base {
+    /**
+     * id
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    @Schema(description="id")
+    private Long id;
+
+    /**
+     * 编号
+     */
+    @TableField(value = "code")
+    @Schema(description="编号")
+    private String code;
+
+    /**
+     * 姓名
+     */
+    @TableField(value = "`name`")
+    @Schema(description="姓名")
+    private String name;
+
+    /**
+     * 车牌号
+     */
+    @TableField(value = "license_plate")
+    @Schema(description="车牌号")
+    private String licensePlate;
+
+    /**
+     * 车辆类型
+     */
+    @TableField(value = "vehicle_type")
+    @Schema(description="车辆类型")
+    private Integer vehicleType;
+
+    /**
+     * 联系电话
+     */
+    @TableField(value = "phone")
+    @Schema(description="联系电话")
+    private String phone;
+
+    /**
+     * 适用道闸
+     */
+    @TableField(value = "barrier_ids")
+    @Schema(description="适用道闸")
+    private String barrierIds;
+
+    /**
+     * 有效期开始
+     */
+    @TableField(value = "valid_from")
+    @Schema(description="有效期开始")
+    private LocalDateTime validFrom;
+
+    /**
+     * 有效期结束
+     */
+    @TableField(value = "valid_to")
+    @Schema(description="有效期结束")
+    private LocalDateTime validTo;
+
+    /**
+     * 状态
+     */
+    @TableField(value = "`status`")
+    @Schema(description="状态")
+    private Integer status;
+}

+ 39 - 0
src/main/java/com/sckw/access/exception/BusinessException.java

@@ -0,0 +1,39 @@
+package com.sckw.access.exception;
+
+/**
+ * 业务异常
+ *
+ * @author xcq
+ * @date 2023-02-22 13:54:05
+ **/
+public class BusinessException extends RuntimeException {
+    private int code;
+    private String message;
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    @Override
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public BusinessException() {
+        this.code = 500;
+    }
+
+    public BusinessException(String message) {
+        super(message);
+        this.message = message;
+        this.code = 500;
+    }
+}

+ 71 - 0
src/main/java/com/sckw/access/handler/GlobalExceptionHandler.java

@@ -0,0 +1,71 @@
+package com.sckw.access.handler;
+
+
+import com.sckw.access.exception.BusinessException;
+import com.sckw.access.util.R;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpStatus;
+import org.springframework.validation.BindException;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.FieldError;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+/**
+ * API网关层,统一异常处理
+ *
+ * @author xcq
+ * @date 2023-02-17 16:07:15
+ * @description
+ **/
+@Slf4j
+@RestControllerAdvice
+public class GlobalExceptionHandler {
+    /**
+     * 全局异常处理 500
+     *
+     * @param ex
+     * @return
+     */
+    @ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
+    @ExceptionHandler(value = Exception.class)
+    public R<String> exceptionHandler(Exception ex) {
+        ex.printStackTrace();
+        log.error("全局异常处理:{}", ex.getMessage());
+        return R.failed("系统异常,请稍后重试!", ex.getMessage());
+    }
+
+    /**
+     * 业务异常处理 200
+     *
+     * @param ex
+     * @return
+     */
+    @ResponseStatus(code = HttpStatus.OK)
+    @ExceptionHandler(value = BusinessException.class)
+    public R<String> businessHandler(Exception ex) {
+        log.error("业务异常处理:{}", ex.getMessage());
+        return R.failed(ex.getMessage());
+    }
+
+    /**
+     * 参数异常 400
+     *
+     * @param ex
+     * @return
+     */
+    @ResponseStatus(code = HttpStatus.BAD_REQUEST)
+    @ExceptionHandler(value = BindException.class)
+    public R<Object> bindHandler(BindException ex) {
+        log.error("BindException :{}", ex.getMessage());
+        BindingResult bindingResult = ex.getBindingResult();
+        StringBuilder msg = new StringBuilder();
+        for (FieldError fieldError : bindingResult.getFieldErrors()) {
+            msg.append(fieldError.getDefaultMessage());
+        }
+        return R.failed(msg.toString());
+    }
+
+
+}

+ 13 - 0
src/main/java/com/sckw/access/mapper/TApprovalMapper.java

@@ -0,0 +1,13 @@
+package com.sckw.access.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.sckw.access.entity.TApproval;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @author xucaiqin
+ * @date 2025-07-24 11:44:43
+ */
+@Mapper
+public interface TApprovalMapper extends BaseMapper<TApproval> {
+}

+ 13 - 0
src/main/java/com/sckw/access/mapper/TBarrierGateMapper.java

@@ -0,0 +1,13 @@
+package com.sckw.access.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.sckw.access.entity.TBarrierGate;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @date 2025-07-24 11:45:20
+* @author xucaiqin
+*/
+@Mapper
+public interface TBarrierGateMapper extends BaseMapper<TBarrierGate> {
+}

+ 13 - 0
src/main/java/com/sckw/access/mapper/TVisitorMapper.java

@@ -0,0 +1,13 @@
+package com.sckw.access.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.sckw.access.entity.TVisitor;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @date 2025-07-24 11:45:20
+* @author xucaiqin
+*/
+@Mapper
+public interface TVisitorMapper extends BaseMapper<TVisitor> {
+}

+ 13 - 0
src/main/java/com/sckw/access/mapper/TWhitelistMapper.java

@@ -0,0 +1,13 @@
+package com.sckw.access.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.sckw.access.entity.TWhitelist;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @date 2025-07-24 11:45:20
+* @author xucaiqin
+*/
+@Mapper
+public interface TWhitelistMapper extends BaseMapper<TWhitelist> {
+}

+ 19 - 0
src/main/java/com/sckw/access/service/TApprovalService.java

@@ -0,0 +1,19 @@
+package com.sckw.access.service;
+
+import org.springframework.stereotype.Service;
+import jakarta.annotation.Resource;
+
+import java.util.List;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.sckw.access.entity.TApproval;
+import com.sckw.access.mapper.TApprovalMapper;
+
+/**
+ * @author xucaiqin
+ * @date 2025-07-24 11:44:14
+ */
+@Service
+public class TApprovalService extends ServiceImpl<TApprovalMapper, TApproval> {
+
+}

+ 16 - 0
src/main/java/com/sckw/access/service/TBarrierGateService.java

@@ -0,0 +1,16 @@
+package com.sckw.access.service;
+
+import org.springframework.stereotype.Service;
+import jakarta.annotation.Resource;
+import java.util.List;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.sckw.access.mapper.TBarrierGateMapper;
+import com.sckw.access.entity.TBarrierGate;
+/**
+* @date 2025-07-24 11:45:20
+* @author xucaiqin
+*/
+@Service
+public class TBarrierGateService extends ServiceImpl<TBarrierGateMapper, TBarrierGate> {
+
+}

+ 16 - 0
src/main/java/com/sckw/access/service/TVisitorService.java

@@ -0,0 +1,16 @@
+package com.sckw.access.service;
+
+import org.springframework.stereotype.Service;
+import jakarta.annotation.Resource;
+import java.util.List;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.sckw.access.entity.TVisitor;
+import com.sckw.access.mapper.TVisitorMapper;
+/**
+* @date 2025-07-24 11:45:20
+* @author xucaiqin
+*/
+@Service
+public class TVisitorService extends ServiceImpl<TVisitorMapper, TVisitor> {
+
+}

+ 16 - 0
src/main/java/com/sckw/access/service/TWhitelistService.java

@@ -0,0 +1,16 @@
+package com.sckw.access.service;
+
+import org.springframework.stereotype.Service;
+import jakarta.annotation.Resource;
+import java.util.List;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.sckw.access.mapper.TWhitelistMapper;
+import com.sckw.access.entity.TWhitelist;
+/**
+* @date 2025-07-24 11:45:20
+* @author xucaiqin
+*/
+@Service
+public class TWhitelistService extends ServiceImpl<TWhitelistMapper, TWhitelist> {
+
+}

+ 69 - 0
src/main/java/com/sckw/access/util/DateTimeUtil.java

@@ -0,0 +1,69 @@
+package com.sckw.access.util;
+
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * @author xcq
+ * @date 2022年07月29日 18:06
+ */
+public class DateTimeUtil {
+    /**
+     * 格林威治时间
+     *
+     * @return
+     */
+    public static LocalDateTime getGMT() {
+        return LocalDateTime.of(1970, 1, 1, 0, 0, 0);
+    }
+
+    public static long getSecond() {
+        return LocalDateTime.now().toEpochSecond(ZoneOffset.UTC);
+    }
+
+    public static String formatDateTime(LocalDateTime localDateTime) {
+        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        return localDateTime.format(dateTimeFormatter);
+    }
+
+    /**
+     * 获取日
+     *
+     * @return
+     */
+    public static int getDayOfMonth(LocalDateTime now) {
+        return now.getDayOfMonth();
+    }
+
+    /**
+     * 获取今天在这个月所在的日
+     *
+     * @return 1-31
+     */
+    public static int getDayOfMonth() {
+        return getDayOfMonth(LocalDateTime.now());
+    }
+
+    /**
+     * 格式化当前日期
+     *
+     * @return yyyy-MM
+     */
+    public static String formatCurrentDate(String pattern) {
+        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
+        return dateTimeFormatter.format(LocalDateTime.now());
+    }
+
+    public static LocalDateTime getYYYYMM(String yyyyMM) {
+        String[] split = yyyyMM.split("-");
+        return LocalDateTime.of(Integer.parseInt(split[0]), Integer.parseInt(split[1]), 1, 0, 0);
+    }
+
+    public static String formatYYYYMM() {
+        return formatCurrentDate("yyyy-MM");
+    }
+
+
+
+}

+ 18 - 0
src/main/java/com/sckw/access/util/IdUtil.java

@@ -0,0 +1,18 @@
+package com.sckw.access.util;
+
+import java.util.UUID;
+
+public class IdUtil {
+    public static String UUID() {
+        return UUID.randomUUID().toString().replaceAll("-", "");
+    }
+
+    public static String UUID(int len) {
+        String uuid = UUID();
+        return uuid.substring(0, Math.min(len, 32));
+    }
+
+    public static String UUID(String prefix) {
+        return prefix + "-" + UUID(6) + "-" + System.currentTimeMillis();
+    }
+}

+ 159 - 0
src/main/java/com/sckw/access/util/MD5Util.java

@@ -0,0 +1,159 @@
+package com.sckw.access.util;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * MD5 消息摘要算法(利用哈希算法来加密的)
+ *
+ * @author xcq
+ * @date 2022年07月27日 20:04
+ */
+@Slf4j
+public class MD5Util {
+    //十六进制下数字到字符的映射数组
+    private final static String[] HEX_DIGITS = {"0", "1", "2", "3", "4",
+            "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
+
+    /**
+     * md5加密算法 返回String
+     *
+     * @param originString
+     * @return
+     */
+    public static String encodeByMD5(String originString) {
+        if (originString != null) {
+            try {
+                //创建具有指定算法名称的信息摘要
+                MessageDigest md = MessageDigest.getInstance("MD5");
+                //使用指定的字节数组对摘要进行最后更新,然后完成摘要计算
+                byte[] results = md.digest(originString.getBytes());
+                //将得到的字节数组变成字符串返回
+                StringBuilder sb = new StringBuilder();
+                for (int j : results) {
+                    int n = j;
+                    if (n < 0) {
+                        n = 256 + n;
+                    }
+                    int d1 = n / 16;
+                    int d2 = n % 16;
+                    sb.append(HEX_DIGITS[d1]).append(HEX_DIGITS[d2]);
+                }
+                return sb.toString();
+            } catch (Exception ex) {
+                ex.printStackTrace();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 计算字符串的MD5值
+     *
+     * @param string 明文
+     * @return 字符串的MD5值
+     */
+    public static String md5(String string) {
+        if (string.isEmpty()) {
+            return "";
+        }
+        MessageDigest md5;
+        try {
+            md5 = MessageDigest.getInstance("MD5");
+            byte[] bytes = md5.digest(string.getBytes(StandardCharsets.UTF_8));
+            StringBuilder result = new StringBuilder();
+            for (byte b : bytes) {
+                /* & 0xff 可以将负数转为正数*/
+                String temp = Integer.toHexString(b & 0xff);
+                // 16进制数 temp小于16
+                if (temp.length() == 1) {
+                    temp = "0" + temp;
+                }
+                result.append(temp);
+            }
+            return result.toString();
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /*其它方法*/
+
+    /**
+     * md5摘要
+     *
+     * @param s 需要转换的字符串
+     * @return 返回字节形式的md5摘要数据
+     */
+    public static byte[] byteMD5(String s) {
+        MessageDigest md;
+        try {
+            md = MessageDigest.getInstance("MD5");
+            md.reset();
+            md.update(s.getBytes(StandardCharsets.UTF_8));
+            return md.digest();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 将字节数据转换为16进制的字符串数据
+     *
+     * @param hash 转换后的字节数组
+     * @return 返回16进制的字符串
+     */
+    public static String byteToHex(byte[] hash) {
+        if (hash == null) {
+            return null;
+        }
+        StringBuffer buf = new StringBuffer(hash.length * 2);
+        int i;
+
+        for (i = 0; i < hash.length; i++) {
+            /* & 0xff 可以将负数转为正数*/
+            /* <0x10 表示小于16,需要进行补零*/
+            if ((hash[i] & 0xff) < 0x10) {
+                buf.append("0");
+            }
+            buf.append(Long.toString(hash[i] & 0xff, 16));
+        }
+        return buf.toString();
+    }
+
+    /**
+     * 将字节数组转换为十六进制字符串
+     *
+     * @param data 待转换的字节数组
+     * @return 转换后的十六进制字符串
+     */
+    private static String toHexString(byte[] data) {
+        StringBuilder sb = new StringBuilder();
+        for (byte b : data) {
+            sb.append(String.format("%02X", b));
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 验证MD5校验值是否正确
+     *
+     * @param data       待验证的数据
+     * @param md5ToCheck 待验证的MD5校验值
+     * @return true表示校验通过,false表示校验失败
+     */
+    public static boolean verifyMD5(String data, String md5ToCheck) {
+        String check = md5(data);
+        log.info("我方签名:{}", check);
+        log.info("来访者签名:{}", md5ToCheck);
+        return StringUtils.equals(check, md5ToCheck);
+    }
+
+
+}

+ 212 - 0
src/main/java/com/sckw/access/util/OkHttpUtils.java

@@ -0,0 +1,212 @@
+package com.sckw.access.util;
+
+import com.alibaba.fastjson2.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.*;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+public class OkHttpUtils {
+
+    private static volatile OkHttpClient okHttpClient;
+    private static final Semaphore semaphore = new Semaphore(0);
+
+    private final Map<String, String> headerMap = new LinkedHashMap<>();
+    private final Map<String, String> paraMap = new LinkedHashMap<>();
+    private final Map<String, String> bodyParaMap = new LinkedHashMap<>();
+    private String bodyParaString;
+    private String url;
+    private Request.Builder request;
+
+    static {
+        try {
+            TrustManager[] trustManagers = buildTrustManagers();
+            okHttpClient = new OkHttpClient.Builder()
+                    .connectTimeout(15, TimeUnit.SECONDS)
+                    .writeTimeout(20, TimeUnit.SECONDS)
+                    .readTimeout(20, TimeUnit.SECONDS)
+                    .sslSocketFactory(createSSLSocketFactory(trustManagers), (X509TrustManager) trustManagers[0])
+                    .hostnameVerifier((hostName, session) -> true)
+                    .retryOnConnectionFailure(true)
+                    .build();
+        } catch (Exception e) {
+            log.error("Failed to initialize OkHttpClient", e);
+        }
+    }
+
+    public static OkHttpUtils builder() {
+        return new OkHttpUtils();
+    }
+
+    public OkHttpUtils url(String url) {
+        this.url = url;
+        return this;
+    }
+
+    public OkHttpUtils addPara(String key, String value) {
+        this.paraMap.put(key, value);
+        return this;
+    }
+
+    public OkHttpUtils addBodyPara(String key, String value) {
+        this.bodyParaMap.put(key, value);
+        return this;
+    }
+
+    public OkHttpUtils addBodyJsonStr(String string) {
+        this.bodyParaString = string;
+        return this;
+    }
+
+    public OkHttpUtils addHeader(String key, String value) {
+        this.headerMap.put(key, value);
+        return this;
+    }
+
+    public OkHttpUtils addHeaderMap(Map<String, String> map) {
+        this.headerMap.putAll(map);
+        return this;
+    }
+
+    public OkHttpUtils get() {
+        this.request = new Request.Builder().get().url(buildUrl());
+        return this;
+    }
+
+    public OkHttpUtils post(boolean isJsonPost) {
+        RequestBody requestBody;
+        if (isJsonPost) {
+            String json = StringUtils.isNotBlank(bodyParaString) ? bodyParaString : JSONObject.toJSONString(bodyParaMap);
+            requestBody = RequestBody.create(json, MediaType.parse("application/json; charset=utf-8"));
+        } else {
+            FormBody.Builder formBody = new FormBody.Builder();
+            bodyParaMap.forEach(formBody::add);
+            requestBody = formBody.build();
+        }
+        this.request = new Request.Builder().post(requestBody).url(buildUrl());
+        return this;
+    }
+
+    private String buildUrl() {
+        if (paraMap.isEmpty()) return this.url;
+
+        StringBuilder urlBuilder = new StringBuilder(this.url).append("?");
+        paraMap.forEach((key, value) -> {
+            try {
+                urlBuilder.append(URLEncoder.encode(key, StandardCharsets.UTF_8))
+                        .append("=")
+                        .append(URLEncoder.encode(value, StandardCharsets.UTF_8))
+                        .append("&");
+            } catch (Exception e) {
+                log.warn("Parameter encoding failed: {}={}", key, value, e);
+            }
+        });
+        urlBuilder.deleteCharAt(urlBuilder.length() - 1);
+        return urlBuilder.toString();
+    }
+
+    public String sync() {
+        setHeaders();
+        try (Response response = okHttpClient.newCall(request.build()).execute()) {
+            if (response.body() != null) {
+                return response.body().string();
+            }
+        } catch (IOException e) {
+            log.error("Sync request failed", e);
+        }
+        return null;
+    }
+
+    public String async() {
+        final StringBuilder buffer = new StringBuilder();
+        setHeaders();
+        okHttpClient.newCall(request.build()).enqueue(new Callback() {
+            @Override
+            public void onFailure(Call call, IOException e) {
+                log.error("Async request failed", e);
+                buffer.append("请求失败:").append(e.getMessage());
+                semaphore.release();
+            }
+
+            @Override
+            public void onResponse(Call call, Response response) throws IOException {
+                if (response.body() != null) {
+                    buffer.append(response.body().string());
+                }
+                semaphore.release();
+            }
+        });
+
+        try {
+            semaphore.acquire();
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            log.error("Semaphore interrupted", e);
+        }
+        return buffer.toString();
+    }
+
+    public void async(ICallBack callBack) {
+        setHeaders();
+        okHttpClient.newCall(request.build()).enqueue(new Callback() {
+            @Override
+            public void onFailure(Call call, IOException e) {
+                callBack.onFailure(call, e.getMessage());
+            }
+
+            @Override
+            public void onResponse(Call call, Response response) throws IOException {
+                if (response.body() != null) {
+                    callBack.onSuccessful(call, response.body().string());
+                }
+            }
+        });
+    }
+
+    private void setHeaders() {
+        headerMap.forEach((k, v) -> request.addHeader(k, v));
+    }
+
+    private static SSLSocketFactory createSSLSocketFactory(TrustManager[] trustAllCerts) throws Exception {
+        SSLContext sc = SSLContext.getInstance("SSL");
+        sc.init(null, trustAllCerts, new SecureRandom());
+        return sc.getSocketFactory();
+    }
+
+    private static TrustManager[] buildTrustManagers() {
+        return new TrustManager[]{
+                new X509TrustManager() {
+                    @Override
+                    public void checkClientTrusted(X509Certificate[] chain, String authType) {}
+
+                    @Override
+                    public void checkServerTrusted(X509Certificate[] chain, String authType) {}
+
+                    @Override
+                    public X509Certificate[] getAcceptedIssuers() {
+                        return new X509Certificate[0];
+                    }
+                }
+        };
+    }
+
+    public interface ICallBack {
+        void onSuccessful(Call call, String data);
+
+        void onFailure(Call call, String errorMsg);
+    }
+}

+ 74 - 0
src/main/java/com/sckw/access/util/R.java

@@ -0,0 +1,74 @@
+package com.sckw.access.util;
+
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * @author xcq
+ * @date 2022年06月14日 13:41
+ */
+@ToString
+@NoArgsConstructor
+@AllArgsConstructor
+@Accessors(chain = true)
+public class R<T> implements Serializable {
+    @Serial
+    private static final long serialVersionUID = 1L;
+    /**
+     * 200-成功 500-失败
+     */
+    @Getter
+    @Setter
+    private int code;
+
+    @Getter
+    @Setter
+    private String msg;
+
+    @Getter
+    @Setter
+    private T data;
+
+    public static <T> R<T> ok() {
+        return restResult(null, 200, null);
+    }
+
+    public static <T> R<T> ok(T data) {
+        return restResult(data, 200, null);
+    }
+
+    public static <T> R<T> ok(T data, String msg) {
+        return restResult(data, 200, msg);
+    }
+
+    public static <T> R<T> failed() {
+        return restResult(null, 500, null);
+    }
+
+    public static <T> R<T> failed(String msg) {
+        return restResult(null, 500, msg);
+    }
+
+    public static <T> R<T> failed(T data) {
+        return restResult(data, 500, null);
+    }
+
+    public static <T> R<T> failed(T data, String msg) {
+        return restResult(data, 500, msg);
+    }
+
+    public static <T> R<T> failed(T data, String msg, int code) {
+        return restResult(data, code, msg);
+    }
+
+    private static <T> R<T> restResult(T data, int code, String msg) {
+        R<T> apiResult = new R<>();
+        apiResult.setCode(code);
+        apiResult.setData(data);
+        apiResult.setMsg(msg);
+        return apiResult;
+    }
+}

+ 57 - 0
src/main/resources/application-dev.yml

@@ -0,0 +1,57 @@
+spring:
+  datasource:
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    type: com.alibaba.druid.pool.DruidDataSource
+    username: access_control
+    password: access_control
+    url: jdbc:mysql://10.10.10.230:3306/access_control
+    druid:
+      # 初始连接数
+      initialSize: 5
+      # 最小连接池数量
+      minIdle: 10
+      # 最大连接池数量
+      maxActive: 20
+      # 配置获取连接等待超时的时间
+      maxWait: 60000
+  data:
+    redis:
+      host: 10.10.10.230
+      password: test
+      port: 6379
+      database: 12
+      lettuce:
+        pool:
+          enabled: true
+          max-active: 8
+          max-idle: 16
+          min-idle: 1
+# springdoc-openapi项目配置
+springdoc:
+  swagger-ui:
+    path: /swagger-ui.html
+    tags-sorter: alpha
+    operations-sorter: alpha
+  api-docs:
+    path: /v3/api-docs
+  group-configs:
+    - group: 'default'
+      paths-to-match: '/**'
+      packages-to-scan: com.sckw.access
+# knife4j的增强配置,不需要增强可以不配
+knife4j:
+  enable: true
+  setting:
+    language: zh_cn
+# 日志级别
+logging:
+  level:
+    root: debug
+    com.sckw.access: debug
+
+
+# mybatis-plus 打印sql
+mybatis-plus:
+  configuration:
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+

+ 40 - 0
src/main/resources/application-pro.yml

@@ -0,0 +1,40 @@
+spring:
+  datasource:
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    type: com.alibaba.druid.pool.DruidDataSource
+    username: push
+    password: nzwA3HQLX5yNJh53
+    url: jdbc:mysql://rm-2vcw922e20158115l.mysql.cn-chengdu.rds.aliyuncs.com:3306/access_control?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull
+    druid:
+      # 初始连接数
+      initialSize: 5
+      # 最小连接池数量
+      minIdle: 10
+      # 最大连接池数量
+      maxActive: 20
+      # 配置获取连接等待超时的时间
+      maxWait: 60000
+  data:
+    redis:
+      host: r-2vcqhixqvh8gwzj3by.redis.cn-chengdu.rds.aliyuncs.com
+      password: mCFEETDwBhgB29y2
+      port: 6379
+      database: 13
+      lettuce:
+        pool:
+          enabled: true
+          max-active: 8
+          max-idle: 16
+          min-idle: 1
+
+
+# 日志级别
+logging:
+  level:
+    root: info
+
+
+# mybatis-plus 打印sql
+mybatis-plus:
+  configuration:
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

+ 19 - 0
src/main/resources/application.yml

@@ -0,0 +1,19 @@
+server:
+  port: 8850
+
+spring:
+  application:
+    name: AccessControl
+  profiles:
+    active: dev
+  jackson:
+    date-format: yyyy-MM-dd HH:mm:ss
+    locale: zh
+    time-zone: GMT+8
+    serialization:
+      write-dates-as-timestamps: true
+    default-leniency: true
+  servlet:
+    multipart:
+      max-file-size: 20MB
+      max-request-size: 100MB

+ 79 - 0
src/main/resources/logback.xml

@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <!-- 日志存放路径 -->
+    <property name="log.path" value="/home/ruoyi/logs"/>
+    <!-- 日志输出格式 -->
+    <property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n"/>
+    <!--    logback 1.5.11 打印彩色日志至console的最新方法-->
+    <property name="log.console"
+              value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{36}) - %msg%n"/>
+
+    <!-- 控制台输出 -->
+    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>${log.console}</pattern>
+        </encoder>
+    </appender>
+
+    <!-- 系统日志输出 -->
+    <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${log.path}/sys-info.log</file>
+        <!-- 循环政策:基于时间创建日志文件 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+            <fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
+            <!-- 日志最大的历史 60天 -->
+            <maxHistory>60</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${log.pattern}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 过滤的级别 -->
+            <level>INFO</level>
+            <!-- 匹配时的操作:接收(记录) -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 不匹配时的操作:拒绝(不记录) -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${log.path}/sys-error.log</file>
+        <!-- 循环政策:基于时间创建日志文件 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+            <fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
+            <!-- 日志最大的历史 60天 -->
+            <maxHistory>60</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${log.pattern}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 过滤的级别 -->
+            <level>ERROR</level>
+            <!-- 匹配时的操作:接收(记录) -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 不匹配时的操作:拒绝(不记录) -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+
+
+    <!-- Spring日志级别控制  -->
+    <logger name="org.springframework" level="warn"/>
+
+    <root level="info">
+        <appender-ref ref="console"/>
+    </root>
+
+    <!--系统操作日志-->
+    <root level="info">
+        <appender-ref ref="file_info"/>
+        <appender-ref ref="file_error"/>
+    </root>
+
+
+</configuration>

+ 20 - 0
src/main/resources/mapper/TApprovalMapper.xml

@@ -0,0 +1,20 @@
+<?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.sckw.access.mapper.TApprovalMapper">
+  <resultMap id="BaseResultMap" type="com.sckw.access.entity.TApproval">
+    <!--@mbg.generated-->
+    <!--@Table t_approval-->
+    <id column="id" jdbcType="BIGINT" property="id" />
+    <result column="name" jdbcType="VARCHAR" property="name" />
+    <result column="mobile" jdbcType="VARCHAR" property="mobile" />
+    <result column="create_by" jdbcType="BIGINT" property="createBy" />
+    <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
+    <result column="update_by" jdbcType="BIGINT" property="updateBy" />
+    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
+    <result column="del_flag" jdbcType="BOOLEAN" property="delFlag" />
+  </resultMap>
+  <sql id="Base_Column_List">
+    <!--@mbg.generated-->
+    id, `name`, mobile, create_by, create_time, update_by, update_time, del_flag
+  </sql>
+</mapper>

+ 24 - 0
src/main/resources/mapper/TBarrierGateMapper.xml

@@ -0,0 +1,24 @@
+<?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.sckw.access.mapper.TBarrierGateMapper">
+  <resultMap id="BaseResultMap" type="com.sckw.access.entity.TBarrierGate">
+    <!--@mbg.generated-->
+    <!--@Table t_barrier_gate-->
+    <id column="id" jdbcType="BIGINT" property="id" />
+    <result column="code" jdbcType="VARCHAR" property="code" />
+    <result column="name" jdbcType="VARCHAR" property="name" />
+    <result column="location" jdbcType="VARCHAR" property="location" />
+    <result column="type" jdbcType="TINYINT" property="type" />
+    <result column="status" jdbcType="TINYINT" property="status" />
+    <result column="create_by" jdbcType="BIGINT" property="createBy" />
+    <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
+    <result column="update_by" jdbcType="BIGINT" property="updateBy" />
+    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
+    <result column="del_flag" jdbcType="BOOLEAN" property="delFlag" />
+  </resultMap>
+  <sql id="Base_Column_List">
+    <!--@mbg.generated-->
+    id, code, `name`, `location`, `type`, `status`, create_by, create_time, update_by, 
+    update_time, del_flag
+  </sql>
+</mapper>

+ 31 - 0
src/main/resources/mapper/TVisitorMapper.xml

@@ -0,0 +1,31 @@
+<?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.sckw.access.mapper.TVisitorMapper">
+  <resultMap id="BaseResultMap" type="com.sckw.access.entity.TVisitor">
+    <!--@mbg.generated-->
+    <!--@Table t_visitor-->
+    <id column="id" jdbcType="BIGINT" property="id" />
+    <result column="name" jdbcType="VARCHAR" property="name" />
+    <result column="license_plate" jdbcType="VARCHAR" property="licensePlate" />
+    <result column="photo_url" jdbcType="VARCHAR" property="photoUrl" />
+    <result column="vehicle_type" jdbcType="OTHER" property="vehicleType" />
+    <result column="apply_entry_time" jdbcType="TIMESTAMP" property="applyEntryTime" />
+    <result column="apply_exit_time" jdbcType="TIMESTAMP" property="applyExitTime" />
+    <result column="barrier_ids" jdbcType="VARCHAR" property="barrierIds" />
+    <result column="approver_id" jdbcType="BIGINT" property="approverId" />
+    <result column="approval_status" jdbcType="TINYINT" property="approvalStatus" />
+    <result column="approval_reason" jdbcType="VARCHAR" property="approvalReason" />
+    <result column="apply_time" jdbcType="TIMESTAMP" property="applyTime" />
+    <result column="create_by" jdbcType="BIGINT" property="createBy" />
+    <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
+    <result column="update_by" jdbcType="BIGINT" property="updateBy" />
+    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
+    <result column="del_flag" jdbcType="BOOLEAN" property="delFlag" />
+  </resultMap>
+  <sql id="Base_Column_List">
+    <!--@mbg.generated-->
+    id, `name`, license_plate, photo_url, vehicle_type, apply_entry_time, apply_exit_time, 
+    barrier_ids, approver_id, approval_status, approval_reason, apply_time, create_by, 
+    create_time, update_by, update_time, del_flag
+  </sql>
+</mapper>

+ 28 - 0
src/main/resources/mapper/TWhitelistMapper.xml

@@ -0,0 +1,28 @@
+<?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.sckw.access.mapper.TWhitelistMapper">
+  <resultMap id="BaseResultMap" type="com.sckw.access.entity.TWhitelist">
+    <!--@mbg.generated-->
+    <!--@Table t_whitelist-->
+    <id column="id" jdbcType="BIGINT" property="id" />
+    <result column="code" jdbcType="VARCHAR" property="code" />
+    <result column="name" jdbcType="VARCHAR" property="name" />
+    <result column="license_plate" jdbcType="VARCHAR" property="licensePlate" />
+    <result column="vehicle_type" jdbcType="TINYINT" property="vehicleType" />
+    <result column="phone" jdbcType="VARCHAR" property="phone" />
+    <result column="barrier_ids" jdbcType="VARCHAR" property="barrierIds" />
+    <result column="valid_from" jdbcType="TIMESTAMP" property="validFrom" />
+    <result column="valid_to" jdbcType="TIMESTAMP" property="validTo" />
+    <result column="status" jdbcType="TINYINT" property="status" />
+    <result column="create_by" jdbcType="BIGINT" property="createBy" />
+    <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
+    <result column="update_by" jdbcType="BIGINT" property="updateBy" />
+    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
+    <result column="del_flag" jdbcType="BOOLEAN" property="delFlag" />
+  </resultMap>
+  <sql id="Base_Column_List">
+    <!--@mbg.generated-->
+    id, code, `name`, license_plate, vehicle_type, phone, barrier_ids, valid_from, valid_to, 
+    `status`, create_by, create_time, update_by, update_time, del_flag
+  </sql>
+</mapper>