skyline vor 2 Jahren
Commit
615ebc7291
100 geänderte Dateien mit 4408 neuen und 0 gelöschten Zeilen
  1. 33 0
      .gitignore
  2. BIN
      .mvn/wrapper/maven-wrapper.jar
  3. 2 0
      .mvn/wrapper/maven-wrapper.properties
  4. 0 0
      README.md
  5. 54 0
      admin/pom.xml
  6. 16 0
      admin/src/main/java/com/kym/admin/AdminApplication.java
  7. 98 0
      admin/src/main/java/com/kym/admin/common/aspect/SysLogAspect.java
  8. 27 0
      admin/src/main/java/com/kym/admin/config/SaTokenConfigure.java
  9. 32 0
      admin/src/main/java/com/kym/admin/controller/AdminUserController.java
  10. 18 0
      admin/src/main/java/com/kym/admin/controller/AdminUserRoleController.java
  11. 18 0
      admin/src/main/java/com/kym/admin/controller/CompanyController.java
  12. 18 0
      admin/src/main/java/com/kym/admin/controller/PermissionController.java
  13. 18 0
      admin/src/main/java/com/kym/admin/controller/RoleController.java
  14. 18 0
      admin/src/main/java/com/kym/admin/controller/RolePermissionController.java
  15. 18 0
      admin/src/main/java/com/kym/admin/controller/StationController.java
  16. 18 0
      admin/src/main/java/com/kym/admin/controller/SystemLogController.java
  17. 31 0
      admin/src/main/java/com/kym/admin/utils/HttpContextUtils.java
  18. 181 0
      admin/src/main/java/com/kym/admin/utils/IDGenerator.java
  19. 56 0
      admin/src/main/java/com/kym/admin/utils/IPUtils.java
  20. 99 0
      admin/src/main/java/com/kym/admin/utils/MybatisPlusGeneratorForAdmin.java
  21. 96 0
      admin/src/main/java/com/kym/admin/utils/MybatisPlusGeneratorForMiniApp.java
  22. 60 0
      admin/src/main/resources/application.yml
  23. 49 0
      admin/src/main/resources/generatorConfig.xml
  24. 201 0
      admin/src/main/resources/logback-spring.xml
  25. 25 0
      admin/src/main/resources/mappers/AdminUserMapper.xml
  26. 20 0
      admin/src/main/resources/mappers/AdminUserRoleMapper.xml
  27. 21 0
      admin/src/main/resources/mappers/CompanyMapper.xml
  28. 21 0
      admin/src/main/resources/mappers/PermissionMapper.xml
  29. 21 0
      admin/src/main/resources/mappers/RoleMapper.xml
  30. 20 0
      admin/src/main/resources/mappers/RolePermissionMapper.xml
  31. 22 0
      admin/src/main/resources/mappers/StationMapper.xml
  32. 25 0
      admin/src/main/resources/mappers/SystemLogMapper.xml
  33. 8 0
      admin/src/main/resources/templates/application.properties
  34. 38 0
      common/.gitignore
  35. 63 0
      common/pom.xml
  36. 51 0
      common/src/main/java/com/kym/common/Assert.java
  37. 51 0
      common/src/main/java/com/kym/common/R.java
  38. 15 0
      common/src/main/java/com/kym/common/annotation/SysLog.java
  39. 29 0
      common/src/main/java/com/kym/common/config/Properties.java
  40. 31 0
      common/src/main/java/com/kym/common/config/WechatPaymentConfig.java
  41. 21 0
      common/src/main/java/com/kym/common/config/WxMiniAppConfig.java
  42. 12 0
      common/src/main/java/com/kym/common/constant/IResponseCode.java
  43. 42 0
      common/src/main/java/com/kym/common/constant/ResponseEnum.java
  44. 13 0
      common/src/main/java/com/kym/common/enums/Api.java
  45. 36 0
      common/src/main/java/com/kym/common/enums/EnPlusApi.java
  46. 24 0
      common/src/main/java/com/kym/common/enums/WxApi.java
  47. 35 0
      common/src/main/java/com/kym/common/exception/BaseException.java
  48. 26 0
      common/src/main/java/com/kym/common/exception/BusinessException.java
  49. 25 0
      common/src/main/java/com/kym/common/exception/BusinessExceptionAssert.java
  50. 83 0
      common/src/main/java/com/kym/common/handler/GlobalExceptionHandler.java
  51. 45 0
      common/src/main/java/com/kym/common/handler/ResponseResultHandler.java
  52. 148 0
      common/src/main/java/com/kym/common/utils/AESUtil.java
  53. 31 0
      common/src/main/java/com/kym/common/utils/HttpContextUtils.java
  54. 168 0
      common/src/main/java/com/kym/common/utils/HttpUtil.java
  55. 181 0
      common/src/main/java/com/kym/common/utils/IDGenerator.java
  56. 56 0
      common/src/main/java/com/kym/common/utils/IPUtils.java
  57. 89 0
      common/src/main/java/com/kym/common/utils/MybatisPlusGenerator.java
  58. 20 0
      entity/pom.xml
  59. 70 0
      entity/src/main/java/com/kym/entity/admin/AdminUser.java
  60. 51 0
      entity/src/main/java/com/kym/entity/admin/AdminUserRole.java
  61. 59 0
      entity/src/main/java/com/kym/entity/admin/ChargeOrder.java
  62. 50 0
      entity/src/main/java/com/kym/entity/admin/Company.java
  63. 56 0
      entity/src/main/java/com/kym/entity/admin/Permission.java
  64. 56 0
      entity/src/main/java/com/kym/entity/admin/Role.java
  65. 51 0
      entity/src/main/java/com/kym/entity/admin/RolePermission.java
  66. 55 0
      entity/src/main/java/com/kym/entity/admin/Station.java
  67. 76 0
      entity/src/main/java/com/kym/entity/admin/SystemLog.java
  68. 10 0
      entity/src/main/java/com/kym/entity/common/RedisKeys.java
  69. 62 0
      entity/src/main/java/com/kym/entity/enplus/ConnectorInfo.java
  70. 23 0
      entity/src/main/java/com/kym/entity/enplus/ConnectorStatsInfo.java
  71. 40 0
      entity/src/main/java/com/kym/entity/enplus/ConnectorStatusInfo.java
  72. 39 0
      entity/src/main/java/com/kym/entity/enplus/EnRespQueryToken.java
  73. 16 0
      entity/src/main/java/com/kym/entity/enplus/EnResponse.java
  74. 55 0
      entity/src/main/java/com/kym/entity/enplus/EquipmentInfo.java
  75. 25 0
      entity/src/main/java/com/kym/entity/enplus/EquipmentStatsInfo.java
  76. 150 0
      entity/src/main/java/com/kym/entity/enplus/StationInfo.java
  77. 36 0
      entity/src/main/java/com/kym/entity/enplus/StationStatsInfo.java
  78. 24 0
      entity/src/main/java/com/kym/entity/enplus/StationStatusInfo.java
  79. 49 0
      entity/src/main/java/com/kym/entity/miniapp/Account.java
  80. 96 0
      entity/src/main/java/com/kym/entity/miniapp/Cars.java
  81. 59 0
      entity/src/main/java/com/kym/entity/miniapp/ChargeOrder.java
  82. 50 0
      entity/src/main/java/com/kym/entity/miniapp/Collect.java
  83. 79 0
      entity/src/main/java/com/kym/entity/miniapp/User.java
  84. 86 0
      entity/src/main/java/com/kym/entity/miniapp/WalletDetail.java
  85. 31 0
      entity/src/main/java/com/kym/entity/miniapp/WxPhoneNum.java
  86. 19 0
      entity/src/main/java/com/kym/entity/miniapp/vo/vo/UserVo.java
  87. 38 0
      mapper/.gitignore
  88. 28 0
      mapper/pom.xml
  89. 16 0
      mapper/src/main/java/com/kym/mapper/admin/AdminUserMapper.java
  90. 16 0
      mapper/src/main/java/com/kym/mapper/admin/AdminUserRoleMapper.java
  91. 16 0
      mapper/src/main/java/com/kym/mapper/admin/CompanyMapper.java
  92. 16 0
      mapper/src/main/java/com/kym/mapper/admin/PermissionMapper.java
  93. 16 0
      mapper/src/main/java/com/kym/mapper/admin/RoleMapper.java
  94. 16 0
      mapper/src/main/java/com/kym/mapper/admin/RolePermissionMapper.java
  95. 16 0
      mapper/src/main/java/com/kym/mapper/admin/StationMapper.java
  96. 16 0
      mapper/src/main/java/com/kym/mapper/admin/SystemLogMapper.java
  97. 16 0
      mapper/src/main/java/com/kym/mapper/miniapp/AccountMapper.java
  98. 16 0
      mapper/src/main/java/com/kym/mapper/miniapp/CarsMapper.java
  99. 16 0
      mapper/src/main/java/com/kym/mapper/miniapp/ChargeOrderMapper.java
  100. 16 0
      mapper/src/main/java/com/kym/mapper/miniapp/CollectMapper.java

+ 33 - 0
.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/

BIN
.mvn/wrapper/maven-wrapper.jar


+ 2 - 0
.mvn/wrapper/maven-wrapper.properties

@@ -0,0 +1,2 @@
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.2/apache-maven-3.9.2-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar

+ 0 - 0
README.md


+ 54 - 0
admin/pom.xml

@@ -0,0 +1,54 @@
+<?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>
+    <parent>
+        <groupId>com.kym</groupId>
+        <artifactId>charge</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+
+    <groupId>org.kym</groupId>
+    <artifactId>admin</artifactId>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>com.kym</groupId>
+            <artifactId>service</artifactId>
+            <version>0.0.1-SNAPSHOT</version>
+        </dependency>
+
+    </dependencies>
+
+    <properties>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <exclude>
+                            <groupId>org.projectlombok</groupId>
+                            <artifactId>lombok</artifactId>
+                        </exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.mybatis.generator</groupId>
+                <artifactId>mybatis-generator-maven-plugin</artifactId>
+                <version>1.4.2</version>
+            </plugin>
+        </plugins>
+
+    </build>
+
+</project>

+ 16 - 0
admin/src/main/java/com/kym/admin/AdminApplication.java

@@ -0,0 +1,16 @@
+package com.kym.admin;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+
+@SpringBootApplication(scanBasePackages = {"com.kym"})
+@MapperScan(basePackages = {"com.kym.mapper"})
+public class AdminApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(AdminApplication.class, args);
+    }
+
+}

+ 98 - 0
admin/src/main/java/com/kym/admin/common/aspect/SysLogAspect.java

@@ -0,0 +1,98 @@
+package com.kym.admin.common.aspect;
+
+import cn.dev33.satoken.stp.StpUtil;
+import com.kym.common.annotation.SysLog;
+import com.kym.service.admin.SystemLogService;
+import com.kym.common.utils.HttpContextUtils;
+import com.kym.common.utils.IDGenerator;
+import com.kym.common.utils.IPUtils;
+import com.kym.entity.admin.SystemLog;
+import com.google.gson.Gson;
+import jakarta.servlet.http.HttpServletRequest;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.lang.reflect.Method;
+
+
+/**
+ * 系统日志,切面处理类
+ *
+ * @author skyline
+ */
+@Aspect
+@Component
+public class SysLogAspect {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(SysLogAspect.class);
+
+    @Autowired
+    private SystemLogService systemLogService;
+
+    IDGenerator idGenerator;
+
+    SysLogAspect() {
+        this.idGenerator = new IDGenerator();
+    }
+
+    /**
+     * 切点
+     */
+    @Pointcut("@annotation(com.kym.common.annotation.SysLog)")
+    public void logPointCut() {
+    }
+
+    @Around("logPointCut()")
+    Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
+        var startTime = System.currentTimeMillis();
+        Object result = joinPoint.proceed();
+        var executeTime = System.currentTimeMillis() - startTime;
+        saveSysLog(joinPoint, executeTime);
+        return result;
+    }
+
+
+    private void saveSysLog(ProceedingJoinPoint joinPoint, long executeTime) {
+        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+        Method method = signature.getMethod();
+
+        SystemLog systemLog = new SystemLog();
+        systemLog.setId(idGenerator.nextId());
+        SysLog syslog = method.getAnnotation(SysLog.class);
+        if (syslog != null) {
+            //注解上的描述
+            systemLog.setOperation(syslog.value());
+        }
+
+        //请求的方法名
+        String className = joinPoint.getTarget().getClass().getName();
+        String methodName = signature.getName();
+        systemLog.setMethod(className + "." + methodName + "()");
+        //请求的参数
+        Object[] args = joinPoint.getArgs();
+        String params = new Gson().toJson(args);
+        systemLog.setRequestParam(params);
+        //获取request
+        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
+        //设置IP地址
+        systemLog.setIp(IPUtils.getIpAddr(request));
+        //用户名、公司id、后台用户id
+        systemLog.setUserId(StpUtil.getSession().getLong("userId"));
+        systemLog.setCompanyId(StpUtil.getSession().getLong("companyId"));
+        systemLog.setUsername(StpUtil.getSession().getString("username"));
+        systemLog.setExecuteTime(executeTime);
+
+        //保存系统日志
+        LOGGER.info(syslog.toString());
+        systemLogService.save(systemLog);
+    }
+
+
+}

+ 27 - 0
admin/src/main/java/com/kym/admin/config/SaTokenConfigure.java

@@ -0,0 +1,27 @@
+package com.kym.admin.config;
+
+import cn.dev33.satoken.interceptor.SaInterceptor;
+import cn.dev33.satoken.stp.StpUtil;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * @author skyline
+ * @description 权限校验
+ * @date 2023-07-11 21:49
+ */
+@Configuration
+public class SaTokenConfigure implements WebMvcConfigurer {
+    // 注册拦截器
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        // 注册 Sa-Token 拦截器,校验规则为 StpUtil.checkLogin() 登录校验。
+        registry.addInterceptor(new SaInterceptor(handle -> StpUtil.checkLogin()))
+                .addPathPatterns("/**")
+                // login接口不鉴权
+                .excludePathPatterns("/charge/admin-user/login");
+    }
+    // TODO: 2023-07-11 具体功能权限校验后续开发
+
+}

+ 32 - 0
admin/src/main/java/com/kym/admin/controller/AdminUserController.java

@@ -0,0 +1,32 @@
+package com.kym.admin.controller;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.kym.common.R;
+import com.kym.service.admin.AdminUserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 用户表 前端控制器
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-11
+ */
+@RestController
+@RequestMapping("/charge/admin-user")
+public class AdminUserController {
+
+    @Autowired
+    private AdminUserService adminUserService;
+
+    @PostMapping("login")
+    R adminLogin(@RequestBody JSONObject json) {
+        return adminUserService.login(json.getString("username"), json.getString("password"));
+    }
+
+}

+ 18 - 0
admin/src/main/java/com/kym/admin/controller/AdminUserRoleController.java

@@ -0,0 +1,18 @@
+package com.kym.admin.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 管理平台用户角色表 前端控制器
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-12
+ */
+@RestController
+@RequestMapping("/charge/admin-user-role")
+public class AdminUserRoleController {
+
+}

+ 18 - 0
admin/src/main/java/com/kym/admin/controller/CompanyController.java

@@ -0,0 +1,18 @@
+package com.kym.admin.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 公司表 前端控制器
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-12
+ */
+@RestController
+@RequestMapping("/charge/company")
+public class CompanyController {
+
+}

+ 18 - 0
admin/src/main/java/com/kym/admin/controller/PermissionController.java

@@ -0,0 +1,18 @@
+package com.kym.admin.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 权限表 前端控制器
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-12
+ */
+@RestController
+@RequestMapping("/charge/permission")
+public class PermissionController {
+
+}

+ 18 - 0
admin/src/main/java/com/kym/admin/controller/RoleController.java

@@ -0,0 +1,18 @@
+package com.kym.admin.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 角色表 前端控制器
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-12
+ */
+@RestController
+@RequestMapping("/charge/role")
+public class RoleController {
+
+}

+ 18 - 0
admin/src/main/java/com/kym/admin/controller/RolePermissionController.java

@@ -0,0 +1,18 @@
+package com.kym.admin.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 角色权限表 前端控制器
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-12
+ */
+@RestController
+@RequestMapping("/charge/role-permission")
+public class RolePermissionController {
+
+}

+ 18 - 0
admin/src/main/java/com/kym/admin/controller/StationController.java

@@ -0,0 +1,18 @@
+package com.kym.admin.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-06-27
+ */
+@RestController
+@RequestMapping("/charge/station")
+public class StationController {
+
+}

+ 18 - 0
admin/src/main/java/com/kym/admin/controller/SystemLogController.java

@@ -0,0 +1,18 @@
+package com.kym.admin.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 系统操作日志表 前端控制器
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-10
+ */
+@RestController
+@RequestMapping("/charge/system-log")
+public class SystemLogController {
+
+}

+ 31 - 0
admin/src/main/java/com/kym/admin/utils/HttpContextUtils.java

@@ -0,0 +1,31 @@
+package com.kym.common.utils;
+
+import jakarta.servlet.http.HttpServletRequest;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import java.util.Objects;
+
+
+/**
+ * http context 工具
+ *
+ * @author skyline
+ */
+public class HttpContextUtils {
+
+    public static HttpServletRequest getHttpServletRequest() {
+        return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
+    }
+
+    public static String getDomain() {
+        HttpServletRequest request = getHttpServletRequest();
+        StringBuffer url = request.getRequestURL();
+        return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
+    }
+
+    public static String getOrigin() {
+        HttpServletRequest request = getHttpServletRequest();
+        return request.getHeader("Origin");
+    }
+}

+ 181 - 0
admin/src/main/java/com/kym/admin/utils/IDGenerator.java

@@ -0,0 +1,181 @@
+package com.kym.common.utils;
+
+import org.springframework.stereotype.Component;
+
+/**
+ * Twitter_Snowflake<br>
+ * SnowFlake的结构如下(每部分用-分开):<br>
+ * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 <br>
+ * 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0<br>
+ * 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截)
+ * 得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69<br>
+ * 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId<br>
+ * 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号<br>
+ * 加起来刚好64位,为一个Long型。<br>
+ * SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。
+ */
+@Component
+public class IDGenerator {
+
+
+    // ==============================Fields===========================================
+    /**
+     * 开始时间截 (2015-01-01)
+     */
+    private final long twepoch = 1420041600000L;
+
+    /**
+     * 机器id所占的位数
+     */
+    private final long workerIdBits = 5L;
+
+    /**
+     * 数据标识id所占的位数
+     */
+    private final long datacenterIdBits = 5L;
+
+    /**
+     * 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数)
+     */
+    private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
+
+    /**
+     * 支持的最大数据标识id,结果是31
+     */
+    private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
+
+    /**
+     * 序列在id中占的位数
+     */
+    private final long sequenceBits = 12L;
+
+    /**
+     * 机器ID向左移12位
+     */
+    private final long workerIdShift = sequenceBits;
+
+    /**
+     * 数据标识id向左移17位(12+5)
+     */
+    private final long datacenterIdShift = sequenceBits + workerIdBits;
+
+    /**
+     * 时间截向左移22位(5+5+12)
+     */
+    private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
+
+    /**
+     * 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095)
+     */
+    private final long sequenceMask = -1L ^ (-1L << sequenceBits);
+
+    /**
+     * 工作机器ID(0~31)
+     */
+    private long workerId;
+
+    /**
+     * 数据中心ID(0~31)
+     */
+    private long datacenterId;
+
+    /**
+     * 毫秒内序列(0~4095)
+     */
+    private long sequence = 0L;
+
+    /**
+     * 上次生成ID的时间截
+     */
+    private long lastTimestamp = -1L;
+
+    //==============================Constructors=====================================
+
+    /**
+     * 构造函数
+     *
+     * @param workerId     工作ID (0~31)
+     * @param datacenterId 数据中心ID (0~31)
+     */
+    public IDGenerator(long workerId, long datacenterId) {
+        if (workerId > maxWorkerId || workerId < 0) {
+            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
+        }
+        if (datacenterId > maxDatacenterId || datacenterId < 0) {
+            throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
+        }
+        this.workerId = workerId;
+        this.datacenterId = datacenterId;
+    }
+
+    /**
+     * 默认workerId、datacenterId为0L
+     */
+    public IDGenerator() {
+        this.workerId = 0L;
+        this.datacenterId = 0L;
+    }
+
+    // ==============================Methods==========================================
+
+    /**
+     * 获得下一个ID (该方法是线程安全的)
+     *
+     * @return SnowflakeId
+     */
+    public synchronized long nextId() {
+        long timestamp = timeGen();
+
+        //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
+        if (timestamp < lastTimestamp) {
+            throw new RuntimeException(
+                    String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
+        }
+
+        //如果是同一时间生成的,则进行毫秒内序列
+        if (lastTimestamp == timestamp) {
+            sequence = (sequence + 1) & sequenceMask;
+            //毫秒内序列溢出
+            if (sequence == 0) {
+                //阻塞到下一个毫秒,获得新的时间戳
+                timestamp = tilNextMillis(lastTimestamp);
+            }
+        }
+        //时间戳改变,毫秒内序列重置
+        else {
+            sequence = 0L;
+        }
+
+        //上次生成ID的时间截
+        lastTimestamp = timestamp;
+
+        //移位并通过或运算拼到一起组成64位的ID
+        return ((timestamp - twepoch) << timestampLeftShift) //
+                | (datacenterId << datacenterIdShift) //
+                | (workerId << workerIdShift) //
+                | sequence;
+    }
+
+    /**
+     * 阻塞到下一个毫秒,直到获得新的时间戳
+     *
+     * @param lastTimestamp 上次生成ID的时间截
+     * @return 当前时间戳
+     */
+    protected long tilNextMillis(long lastTimestamp) {
+        long timestamp = timeGen();
+        while (timestamp <= lastTimestamp) {
+            timestamp = timeGen();
+        }
+        return timestamp;
+    }
+
+    /**
+     * 返回以毫秒为单位的当前时间
+     *
+     * @return 当前时间(毫秒)
+     */
+    protected long timeGen() {
+        return System.currentTimeMillis();
+    }
+}

+ 56 - 0
admin/src/main/java/com/kym/admin/utils/IPUtils.java

@@ -0,0 +1,56 @@
+package com.kym.common.utils;
+
+import com.alibaba.druid.util.StringUtils;
+import jakarta.servlet.http.HttpServletRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * IP地址
+ *
+ * @author skyline
+ */
+public class IPUtils {
+    private static Logger logger = LoggerFactory.getLogger(IPUtils.class);
+
+    /**
+     * 获取IP地址
+     * <p>
+     * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
+     * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
+     */
+    public static String getIpAddr(HttpServletRequest request) {
+        String ip = null;
+        try {
+            ip = request.getHeader("x-forwarded-for");
+            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
+                ip = request.getHeader("Proxy-Client-IP");
+            }
+            if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+                ip = request.getHeader("WL-Proxy-Client-IP");
+            }
+            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
+                ip = request.getHeader("HTTP_CLIENT_IP");
+            }
+            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
+                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+            }
+            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
+                ip = request.getRemoteAddr();
+            }
+        } catch (Exception e) {
+            logger.error("IPUtils ERROR ", e);
+        }
+
+//        //使用代理,则获取第一个IP地址
+//        if(StringUtils.isEmpty(ip) && ip.length() > 15) {
+//			if(ip.indexOf(",") > 0) {
+//				ip = ip.substring(0, ip.indexOf(","));
+//			}
+//		}
+
+        return ip;
+    }
+
+}

+ 99 - 0
admin/src/main/java/com/kym/admin/utils/MybatisPlusGeneratorForAdmin.java

@@ -0,0 +1,99 @@
+package com.kym.admin.utils;
+
+import com.baomidou.mybatisplus.generator.FastAutoGenerator;
+import com.baomidou.mybatisplus.generator.config.OutputFile;
+import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
+
+import java.util.Map;
+
+/**
+ * mybatis-plus-generator代码生成
+ *
+ * @author skyline
+ */
+public class MybatisPlusGeneratorForAdmin {
+
+    public static void main(String[] args) {
+        // 指定数据源
+        FastAutoGenerator.create("jdbc:mysql://localhost:3306/charge_admin", "root", "root")
+                .globalConfig(builder -> {
+                    builder.author("skyline")
+                            // 指定输出目录
+                            //.outputDir("D://Java Project/charge/admin/src/main/java")
+                            .disableOpenDir();
+                })
+                .packageConfig(builder -> {
+                    // 设置父包名
+                    builder
+                            //.parent("com.kym.admin")
+                            // 设置父包模块名
+                            .entity("com.kym.entity.admin")
+                            .service("com.kym.service.admin")
+                            .serviceImpl("com.kym.service.admin.impl")
+                            .mapper("com.kym.mapper.admin")
+                            .xml("mapper.xml")
+                            .controller("com.kym.admin.controller")
+                            // 设置mapperXml生成路径
+                            .pathInfo(Map.of(
+                                    OutputFile.entity, "D://Java Project/charge/entity/src/main/java/com/kym/entity/admin",
+                                    OutputFile.service, "D://Java Project/charge/admin/src/main/java/com/kym/admin/service",
+                                    OutputFile.serviceImpl, "D://Java Project/charge/admin/src/main/java/com/kym/admin/service/impl",
+                                    OutputFile.mapper, "D://Java Project/charge/admin/src/main/java/com/kym/admin/mapper",
+                                    OutputFile.controller, "D://Java Project/charge/admin/src/main/java/com/kym/admin/controller",
+                                    OutputFile.xml, "D://Java Project/charge/admin/src/main/resources/mappers"
+
+                            ));
+                })
+
+                .strategyConfig(builder -> {
+                    // 设置需要生成的表名
+                    builder.addInclude(
+//                                    "t_user",
+//                                    "t_account",
+//                                    "t_station",
+//                                    "t_charge_order",
+//                                    "t_system_log",
+                                    "t_collection"
+                            )
+                            // 设置过滤表前缀
+                            .addTablePrefix("t_");
+
+                    // entity配置
+                    builder.entityBuilder()
+                            .enableFileOverride()
+                            .enableLombok();
+
+                    // controller配置
+                    builder.controllerBuilder()
+                            .enableFileOverride()
+                            .enableRestStyle()
+                            .enableHyphenStyle()
+//                            .superClass(BaseController.class)
+                            .formatFileName("%sController");
+
+                    // service配置
+                    builder.serviceBuilder()
+                            .enableFileOverride()
+                            .formatServiceFileName("%sService")
+                            .formatServiceImplFileName("%sServiceImpl");
+
+                    // mapper配置
+                    builder.mapperBuilder()
+                            .enableFileOverride()
+                            .enableBaseResultMap()
+                            .enableBaseColumnList()
+                            .formatMapperFileName("%sMapper")
+                            .formatXmlFileName("%sMapper")
+                            .build();
+
+
+                    builder.build();
+
+                })
+
+                // 使用Freemarker引擎模板,默认的是Velocity引擎模板
+                .templateEngine(new FreemarkerTemplateEngine())
+                .execute();
+    }
+
+}

+ 96 - 0
admin/src/main/java/com/kym/admin/utils/MybatisPlusGeneratorForMiniApp.java

@@ -0,0 +1,96 @@
+package com.kym.admin.utils;
+
+import com.baomidou.mybatisplus.generator.FastAutoGenerator;
+import com.baomidou.mybatisplus.generator.config.OutputFile;
+import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
+
+import java.util.Map;
+
+/**
+ * mybatis-plus-generator代码生成
+ *
+ * @author skyline
+ */
+public class MybatisPlusGeneratorForMiniApp {
+
+    public static void main(String[] args) {
+        // 指定数据源
+        FastAutoGenerator.create("jdbc:mysql://localhost:3306/charge_app", "root", "root")
+                .globalConfig(builder -> {
+                    builder.author("skyline")
+                            // 指定输出目录
+                            .disableOpenDir();
+                })
+                .packageConfig(builder -> {
+                    // 设置父包名
+                    builder
+                            // 设置父包模块名
+                            .entity("com.kym.entity.miniapp")
+                            .service("com.kym.miniapp.service")
+                            .serviceImpl("com.kym.service.miniapp.impl")
+                            .mapper("com.kym.mapper.miniapp")
+                            .xml("mapper.xml")
+                            .controller("com.kym.miniapp.controller")
+                            // 设置mapperXml生成路径
+                            .pathInfo(Map.of(
+                                    OutputFile.entity, "D://Java Project/charge/entity/src/main/java/com/kym/entity/miniapp",
+                                    OutputFile.service, "D://Java Project/charge/miniapp/src/main/java/com/kym/miniapp/service",
+                                    OutputFile.serviceImpl, "D://Java Project/charge/miniapp/src/main/java/com/kym/miniapp/service/impl",
+                                    OutputFile.mapper, "D://Java Project/charge/miniapp/src/main/java/com/kym/miniapp/mapper",
+                                    OutputFile.controller, "D://Java Project/charge/miniapp/src/main/java/com/kym/miniapp/controller",
+                                    OutputFile.xml, "D://Java Project/charge/miniapp/src/main/resources/mappers"
+
+                            ));
+                })
+
+                .strategyConfig(builder -> {
+                    // 设置需要生成的表名
+                    builder.addInclude(
+//                                    "t_user",
+//                                    "t_account",
+//                                    "t_charge_order",
+//                                    "t_collection",
+                            "t_wallet_detail"
+                            )
+                            // 设置过滤表前缀
+                            .addTablePrefix("t_");
+
+                    // entity配置
+                    builder.entityBuilder()
+                            .enableFileOverride()
+                            .enableLombok();
+
+                    // controller配置
+                    builder.controllerBuilder()
+                            .enableFileOverride()
+                            .enableRestStyle()
+                            .enableHyphenStyle()
+//                            .superClass(BaseController.class)
+                            .formatFileName("%sController");
+
+                    // service配置
+                    builder.serviceBuilder()
+                            .enableFileOverride()
+                            .formatServiceFileName("%sService")
+                            .formatServiceImplFileName("%sServiceImpl");
+
+                    // mapper配置
+                    builder.mapperBuilder()
+                            .enableFileOverride()
+                            .enableBaseResultMap()
+                            .enableBaseColumnList()
+                            .formatMapperFileName("%sMapper")
+                            .formatXmlFileName("%sMapper")
+                            .build();
+
+
+                    builder.build();
+
+                })
+
+                // 使用Freemarker引擎模板,默认的是Velocity引擎模板
+                .templateEngine(new FreemarkerTemplateEngine())
+                .execute();
+    }
+
+}

+ 60 - 0
admin/src/main/resources/application.yml

@@ -0,0 +1,60 @@
+spring:
+  application:
+    name: miniapp
+  datasource:
+    url: jdbc:mysql://localhost:3306/charge_admin
+    username: root
+    password: root
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    name: charge-datasource
+  main:
+    allow-circular-references: true
+
+#mybatis:
+#  mapper-locations: classpath:mappers/*.xml
+#  type-aliases-package: com.kym.charge.entity
+#  configuration:
+#    map-underscore-to-camel-case: true #下划线转驼峰
+server:
+  port: 9000
+# PageHelper
+pagehelper:
+  propertyName: propertyValue
+  reasonable: false
+  defaultCount: true # 分页插件默认参数支持 default-count 形式,自定义扩展的参数,必须大小写一致
+mybatis-plus:
+  mapper-locations:  classpath:mappers/admin/*.xml
+  type-aliases-package: com.kym.entity.admin
+
+sa-token:
+  # jwt秘钥
+  jwt-secret-key: 12345678
+  # token 名称(同时也是 cookie 名称)
+  token-name: satoken
+  # token 有效期(单位:秒) 默认30分钟,-1 代表永久有效
+  timeout: 1800
+  # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
+  active-timeout: -1
+  # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录)
+  is-concurrent: true
+  # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token)
+  is-share: true
+  # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)
+  token-style: uuid
+  # 是否输出操作日志
+  is-log: true
+
+# EN+充电配置
+en-plus:
+  # 运营商ID
+  operator-id: MA5HJNDG1
+  # 运营商密钥
+  operator-secret: c7fd9b753a9f434e
+  # 消息密钥
+  data-secret: 5cb7e12da198420a
+  # 消息密钥初始化向量
+  data-secret-iv: 8a6ac88326bc4d3f
+  # 签名密钥
+  sig-secret: 2365b20f69e44817
+  # 最小充电余额(分)
+  charge-min-amount: 200

+ 49 - 0
admin/src/main/resources/generatorConfig.xml

@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE generatorConfiguration
+        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
+        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
+<generatorConfiguration>
+    <!--数据库驱动-->
+    <classPathEntry
+            location="D:\Apache\repository\mysql\mysql-connector-java\8.0.29\mysql-connector-java-8.0.29.jar"/>
+    <context id="mysql" targetRuntime="MyBatis3">
+        <!--是否忽略注释的生成 true -->
+        <commentGenerator>
+            <!-- 这个元素用来去除指定生成的注释中是否包含生成的日期 false:表示包含 -->
+            <!-- 如果生成日期,会造成即使修改一个字段,整个实体类所有属性都会发生变化,不利于版本控制,所以
+            设置为true -->
+            <property name="suppressDate" value="true"/>
+            <!-- 是否去除自动生成的注释 true:是 : false:否 -->
+            <property name="suppressAllComments" value="true"/>
+        </commentGenerator>
+        <!--数据库链接地址账号密码-->
+        <!--数据库链接URL,用户名、密码 -->
+        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
+                        connectionURL="jdbc:mysql://localhost:3306/charge_admin"
+                        userId="root"
+                        password="root">
+        </jdbcConnection>
+        <!--生成Model类存放位置 entity-->
+        <javaModelGenerator targetPackage="com.kym.charge.entity" targetProject="./src/main/java">
+            <!--是否合并-->
+            <property name="enableSubPackages" value="true"/>
+            <!--去除空格-->
+            <property name="trimStrings" value="true"/>
+        </javaModelGenerator>
+        <!--生成映射文件存放位置-->
+        <sqlMapGenerator targetPackage="mappers" targetProject="./src/main/resources">
+            <!--是否合并-->
+            <property name="enableSubPackages" value="true"/>
+        </sqlMapGenerator>
+        <!--生成Dao接口存放位置-->
+        <javaClientGenerator type="XMLMAPPER" targetPackage="com.kym.charge.mapper" targetProject="./src/main/java">
+            <!--是否合并-->
+            <property name="enableSubPackages" value="true"/>
+        </javaClientGenerator>
+        <!--生成对应表及类名-->
+        <table tableName="t_user" domainObjectName="User"></table>
+        <table tableName="t_account" domainObjectName="Account"></table>
+        <table tableName="t_charge_order" domainObjectName="ChargeOrder"></table>
+        <table tableName="t_station" domainObjectName="Station"></table>
+    </context>
+</generatorConfiguration>

+ 201 - 0
admin/src/main/resources/logback-spring.xml

@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE configuration>
+<configuration>
+    <!--引用默认日志配置-->
+    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
+    <!--使用默认的控制台日志输出实现-->
+    <include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
+    <!--应用名称-->
+    <springProperty scope="context" name="APP_NAME" source="spring.application.name" defaultValue="springBoot"/>
+    <!--日志文件保存路径-->
+    <property name="LOG_FILE_PATH" value="D:/Java Project/logs/admin"/>
+<!--    <property name="LOG_FILE_PATH" value="opt/logs/admin"/>   -->
+    <!--LogStash访问host-->
+    <!--    <springProperty name="LOG_STASH_HOST" scope="context" source="logstash.host" defaultValue="localhost"/>-->
+    <!--是否开启LogStash插件内部日志-->
+    <!--    <springProperty name="ENABLE_INNER_LOG" scope="context" source="logstash.enableInnerLog" defaultValue="false"/>-->
+
+    <!--DEBUG日志输出到文件-->
+    <appender name="FILE_DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!--输出DEBUG以上级别日志-->
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>DEBUG</level>
+        </filter>
+        <encoder>
+            <!--设置为默认的文件日志格式-->
+            <pattern>${FILE_LOG_PATTERN}</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <!--设置文件命名格式-->
+            <fileNamePattern>${LOG_FILE_PATH}/debug/${APP_NAME}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
+            <!--设置日志文件大小,超过就重新生成文件,默认10M-->
+            <maxFileSize>${LOG_FILE_MAX_SIZE:-10MB}</maxFileSize>
+            <!--日志文件保留天数,默认30天-->
+            <maxHistory>${LOG_FILE_MAX_HISTORY:-30}</maxHistory>
+        </rollingPolicy>
+    </appender>
+
+    <!--ERROR日志输出到文件-->
+    <appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!--只输出ERROR级别的日志-->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>ERROR</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+        <encoder>
+            <!--设置为默认的文件日志格式-->
+            <pattern>${FILE_LOG_PATTERN}</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <!--设置文件命名格式-->
+            <fileNamePattern>${LOG_FILE_PATH}/error/${APP_NAME}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
+            <!--设置日志文件大小,超过就重新生成文件,默认10M-->
+            <maxFileSize>${LOG_FILE_MAX_SIZE:-10MB}</maxFileSize>
+            <!--日志文件保留天数,默认30天-->
+            <maxHistory>${LOG_FILE_MAX_HISTORY:-30}</maxHistory>
+        </rollingPolicy>
+    </appender>
+
+    <!--DEBUG日志输出到LogStash-->
+<!--   <appender name="LOG_STASH_DEBUG" class="net.logstash.logback.appender.LogstashTcpSocketAppender">-->
+<!--        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">-->
+<!--            <level>DEBUG</level>-->
+<!--        </filter>-->
+<!--        <destination>${LOG_STASH_HOST}:4560</destination>-->
+<!--        <addDefaultStatusListener>${ENABLE_INNER_LOG}</addDefaultStatusListener>-->
+<!--        <encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">-->
+<!--            <providers>-->
+<!--                <timestamp>-->
+<!--                    <timeZone>Asia/Shanghai</timeZone>-->
+<!--                </timestamp>-->
+<!--                &lt;!&ndash;自定义日志输出格式&ndash;&gt;-->
+<!--                <pattern>-->
+<!--                    <pattern>-->
+<!--                        {-->
+<!--                        "project": "mall",-->
+<!--                        "level": "%level",-->
+<!--                        "service": "${APP_NAME:-}",-->
+<!--                        "pid": "${PID:-}",-->
+<!--                        "thread": "%thread",-->
+<!--                        "class": "%logger",-->
+<!--                        "message": "%message",-->
+<!--                        "stack_trace": "%exception{20}"-->
+<!--                        }-->
+<!--                    </pattern>-->
+<!--                </pattern>-->
+<!--            </providers>-->
+<!--        </encoder>-->
+<!--    </appender>-->
+
+    <!--ERROR日志输出到LogStash-->
+<!--    <appender name="LOG_STASH_ERROR" class="net.logstash.logback.appender.LogstashTcpSocketAppender">-->
+<!--        <filter class="ch.qos.logback.classic.filter.LevelFilter">-->
+<!--            <level>ERROR</level>-->
+<!--            <onMatch>ACCEPT</onMatch>-->
+<!--            <onMismatch>DENY</onMismatch>-->
+<!--        </filter>-->
+<!--        <destination>${LOG_STASH_HOST}:4561</destination>-->
+<!--        <addDefaultStatusListener>${ENABLE_INNER_LOG}</addDefaultStatusListener>-->
+<!--        <encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">-->
+<!--            <providers>-->
+<!--                <timestamp>-->
+<!--                    <timeZone>Asia/Shanghai</timeZone>-->
+<!--                </timestamp>-->
+<!--                &lt;!&ndash;自定义日志输出格式&ndash;&gt;-->
+<!--                <pattern>-->
+<!--                    <pattern>-->
+<!--                        {-->
+<!--                        "project": "mall",-->
+<!--                        "level": "%level",-->
+<!--                        "service": "${APP_NAME:-}",-->
+<!--                        "pid": "${PID:-}",-->
+<!--                        "thread": "%thread",-->
+<!--                        "class": "%logger",-->
+<!--                        "message": "%message",-->
+<!--                        "stack_trace": "%exception{20}"-->
+<!--                        }-->
+<!--                    </pattern>-->
+<!--                </pattern>-->
+<!--            </providers>-->
+<!--        </encoder>-->
+<!--    </appender>-->
+
+    <!--业务日志输出到LogStash-->
+<!--    <appender name="LOG_STASH_BUSINESS" class="net.logstash.logback.appender.LogstashTcpSocketAppender">-->
+<!--        <destination>${LOG_STASH_HOST}:4562</destination>-->
+<!--        <addDefaultStatusListener>${ENABLE_INNER_LOG}</addDefaultStatusListener>-->
+<!--        <encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">-->
+<!--            <providers>-->
+<!--                <timestamp>-->
+<!--                    <timeZone>Asia/Shanghai</timeZone>-->
+<!--                </timestamp>-->
+<!--                &lt;!&ndash;自定义日志输出格式&ndash;&gt;-->
+<!--                <pattern>-->
+<!--                    <pattern>-->
+<!--                        {-->
+<!--                        "project": "mall",-->
+<!--                        "level": "%level",-->
+<!--                        "service": "${APP_NAME:-}",-->
+<!--                        "pid": "${PID:-}",-->
+<!--                        "thread": "%thread",-->
+<!--                        "class": "%logger",-->
+<!--                        "message": "%message",-->
+<!--                        "stack_trace": "%exception{20}"-->
+<!--                        }-->
+<!--                    </pattern>-->
+<!--                </pattern>-->
+<!--            </providers>-->
+<!--        </encoder>-->
+<!--    </appender>-->
+
+    <!--接口访问记录日志输出到LogStash-->
+<!--    <appender name="LOG_STASH_RECORD" class="net.logstash.logback.appender.LogstashTcpSocketAppender">-->
+<!--        <destination>${LOG_STASH_HOST}:4563</destination>-->
+<!--        <addDefaultStatusListener>${ENABLE_INNER_LOG}</addDefaultStatusListener>-->
+<!--        <encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">-->
+<!--            <providers>-->
+<!--                <timestamp>-->
+<!--                    <timeZone>Asia/Shanghai</timeZone>-->
+<!--                </timestamp>-->
+<!--                &lt;!&ndash;自定义日志输出格式&ndash;&gt;-->
+<!--                <pattern>-->
+<!--                    <pattern>-->
+<!--                        {-->
+<!--                        "project": "mall",-->
+<!--                        "level": "%level",-->
+<!--                        "service": "${APP_NAME:-}",-->
+<!--                        "class": "%logger",-->
+<!--                        "message": "%message"-->
+<!--                        }-->
+<!--                    </pattern>-->
+<!--                </pattern>-->
+<!--            </providers>-->
+<!--        </encoder>-->
+<!--    </appender>-->
+
+    <!--控制框架输出日志-->
+    <logger name="org.slf4j" level="INFO"/>
+    <logger name="springfox" level="INFO"/>
+    <logger name="io.swagger" level="INFO"/>
+    <logger name="org.springframework" level="INFO"/>
+    <logger name="org.hibernate.validator" level="INFO"/>
+
+    <root level="DEBUG">
+        <appender-ref ref="CONSOLE"/>
+        <appender-ref ref="FILE_DEBUG"/>
+        <appender-ref ref="FILE_ERROR"/>
+<!--        <appender-ref ref="LOG_STASH_DEBUG"/>-->
+<!--        <appender-ref ref="LOG_STASH_ERROR"/>-->
+    </root>
+
+<!--    <logger name="com.kym.charge.aspect.com.kym.common.SysLogAspect" level="DEBUG">-->
+<!--        <appender-ref ref="LOG_STASH_RECORD"/>-->
+<!--    </logger>-->
+
+<!--    <logger name="com.kym.charge" level="DEBUG">-->
+<!--        <appender-ref ref="LOG_STASH_BUSINESS"/>-->
+<!--    </logger>-->
+</configuration>

+ 25 - 0
admin/src/main/resources/mappers/AdminUserMapper.xml

@@ -0,0 +1,25 @@
+<?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.kym.mapper.admin.AdminUserMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.kym.entity.admin.AdminUser">
+        <id column="id" property="id" />
+        <result column="company_id" property="companyId" />
+        <result column="username" property="username" />
+        <result column="password" property="password" />
+        <result column="nickname" property="nickname" />
+        <result column="mobile_phone" property="mobilePhone" />
+        <result column="avatar" property="avatar" />
+        <result column="status" property="status" />
+        <result column="create_time" property="createTime" />
+        <result column="update_time" property="updateTime" />
+        <result column="last_login_time" property="lastLoginTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, company_id, username, password, nickname, mobile_phone, avatar, status, create_time, update_time, last_login_time
+    </sql>
+
+</mapper>

+ 20 - 0
admin/src/main/resources/mappers/AdminUserRoleMapper.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.kym.mapper.admin.AdminUserRoleMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.kym.entity.admin.AdminUserRole">
+        <id column="id" property="id" />
+        <result column="company_id" property="companyId" />
+        <result column="admin_user_id" property="adminUserId" />
+        <result column="role_id" property="roleId" />
+        <result column="create_time" property="createTime" />
+        <result column="update_time" property="updateTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, company_id, admin_user_id, role_id, create_time, update_time
+    </sql>
+
+</mapper>

+ 21 - 0
admin/src/main/resources/mappers/CompanyMapper.xml

@@ -0,0 +1,21 @@
+<?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.kym.mapper.admin.CompanyMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.kym.entity.admin.Company">
+        <id column="id" property="id" />
+        <result column="company_name" property="companyName" />
+        <result column="super_admin_id" property="superAdminId" />
+        <result column="super_admin_name" property="superAdminName" />
+        <result column="status" property="status" />
+        <result column="create_time" property="createTime" />
+        <result column="update_time" property="updateTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, company_name, super_admin_id, super_admin_name, status, create_time, update_time
+    </sql>
+
+</mapper>

+ 21 - 0
admin/src/main/resources/mappers/PermissionMapper.xml

@@ -0,0 +1,21 @@
+<?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.kym.mapper.admin.PermissionMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.kym.entity.admin.Permission">
+        <id column="id" property="id" />
+        <result column="company_id" property="companyId" />
+        <result column="parent_id" property="parentId" />
+        <result column="permission_name" property="permissionName" />
+        <result column="permission_desc" property="permissionDesc" />
+        <result column="create_time" property="createTime" />
+        <result column="update_time" property="updateTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, company_id, parent_id, permission_name, permission_desc, create_time, update_time
+    </sql>
+
+</mapper>

+ 21 - 0
admin/src/main/resources/mappers/RoleMapper.xml

@@ -0,0 +1,21 @@
+<?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.kym.mapper.admin.RoleMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.kym.entity.admin.Role">
+        <id column="id" property="id" />
+        <result column="company_id" property="companyId" />
+        <result column="parent_id" property="parentId" />
+        <result column="role_name" property="roleName" />
+        <result column="role_desc" property="roleDesc" />
+        <result column="create_time" property="createTime" />
+        <result column="update_time" property="updateTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, company_id, parent_id, role_name, role_desc, create_time, update_time
+    </sql>
+
+</mapper>

+ 20 - 0
admin/src/main/resources/mappers/RolePermissionMapper.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.kym.mapper.admin.RolePermissionMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.kym.entity.admin.RolePermission">
+        <id column="id" property="id" />
+        <result column="company_id" property="companyId" />
+        <result column="role_id" property="roleId" />
+        <result column="permission_id" property="permissionId" />
+        <result column="create_time" property="createTime" />
+        <result column="update_time" property="updateTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, company_id, role_id, permission_id, create_time, update_time
+    </sql>
+
+</mapper>

+ 22 - 0
admin/src/main/resources/mappers/StationMapper.xml

@@ -0,0 +1,22 @@
+<?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.kym.mapper.admin.StationMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.kym.entity.admin.Station">
+        <id column="id" property="id" />
+        <result column="station_name" property="stationName" />
+        <result column="station_type" property="stationType" />
+        <result column="station_location" property="stationLocation" />
+        <result column="parking_fee" property="parkingFee" />
+        <result column="parking_num" property="parkingNum" />
+        <result column="create_time" property="createTime" />
+        <result column="update_time" property="updateTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, station_name, station_type, station_location, parking_fee, parking_num, create_time, update_time
+    </sql>
+
+</mapper>

+ 25 - 0
admin/src/main/resources/mappers/SystemLogMapper.xml

@@ -0,0 +1,25 @@
+<?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.kym.mapper.admin.SystemLogMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.kym.entity.admin.SystemLog">
+        <id column="id" property="id" />
+        <result column="company_id" property="companyId" />
+        <result column="user_id" property="userId" />
+        <result column="username" property="username" />
+        <result column="ip" property="ip" />
+        <result column="operation" property="operation" />
+        <result column="method" property="method" />
+        <result column="request_param" property="requestParam" />
+        <result column="execute_time" property="executeTime" />
+        <result column="create_time" property="createTime" />
+        <result column="update_time" property="updateTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, company_id, user_id, username, ip, operation, method, request_param, execute_time, create_time, update_time
+    </sql>
+
+</mapper>

+ 8 - 0
admin/src/main/resources/templates/application.properties

@@ -0,0 +1,8 @@
+spring.datasource.name=testdatasource
+spring.datasource.url=jdbc:mysql://localhost:3306/skyline 
+spring.datasource.username=root
+spring.datasource.password=root
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
+
+mybatis.mapper-locations=classpath:mappers/*.xml
+mybatis.type-aliases-package=com.kym.charge.entity

+ 38 - 0
common/.gitignore

@@ -0,0 +1,38 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.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

+ 63 - 0
common/pom.xml

@@ -0,0 +1,63 @@
+<?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>
+    <parent>
+        <groupId>com.kym</groupId>
+        <artifactId>charge</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>common</artifactId>
+
+    <properties>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.kym</groupId>
+            <artifactId>entity</artifactId>
+            <version>0.0.1-SNAPSHOT</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>3.5.3.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+            <version>4.11.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.8.16</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-cache</artifactId>
+        </dependency>
+
+        <!--lettuce 依赖commons-pool-->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-pool2</artifactId>
+        </dependency>
+
+    </dependencies>
+
+</project>

+ 51 - 0
common/src/main/java/com/kym/common/Assert.java

@@ -0,0 +1,51 @@
+package com.kym.common;
+
+import com.kym.common.exception.BaseException;
+
+/**
+ * @author skyline
+ * @description 断言
+ * @date 2023-07-02 15:06
+ */
+public interface Assert {
+    /**
+     * 创建异常
+     *
+     * @param args
+     * @return
+     */
+    BaseException baseException(Object... args);
+
+    /**
+     * 创建异常
+     *
+     * @param t
+     * @param args
+     * @return
+     */
+    BaseException baseException(Throwable t, Object... args);
+
+    /**
+     * <p>断言对象<code>obj</code>非空。如果对象<code>obj</code>为空,则抛出异常
+     *
+     * @param obj 待判断对象
+     */
+    default void assertNotNull(Object obj) {
+        if (obj == null) {
+            throw baseException();
+        }
+    }
+
+    /**
+     * <p>断言对象<code>obj</code>非空。如果对象<code>obj</code>为空,则抛出异常
+     * <p>异常信息<code>message</code>支持传递参数方式,避免在判断之前进行字符串拼接操作
+     *
+     * @param obj  待判断对象
+     * @param args message占位符对应的参数列表
+     */
+    default void assertNotNull(Object obj, Object... args) {
+        if (obj == null) {
+            throw baseException(args);
+        }
+    }
+}

+ 51 - 0
common/src/main/java/com/kym/common/R.java

@@ -0,0 +1,51 @@
+package com.kym.common;
+
+import com.kym.common.constant.ResponseEnum;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 返回信息封装
+ *
+ * @param <T>
+ * @author skyline
+ */
+@NoArgsConstructor
+@AllArgsConstructor
+@Data
+public class R<T> implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private Integer code;
+    private String message;
+    private T data;
+
+    public R(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public static R success() {
+        return new R<>(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMessage());
+    }
+
+    public static <T> R<T> success(T data) {
+        return new R<T>(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMessage(), data);
+    }
+
+    public static R failed() {
+        return new R<>(ResponseEnum.FAILED.getCode(), ResponseEnum.FAILED.getMessage());
+    }
+
+    public static R failed(Integer code, String message) {
+        return new R<>(code, message);
+    }
+
+    public static R failed(ResponseEnum responseEnum) {
+        return new R<>(responseEnum.getCode(), responseEnum.getMessage());
+    }
+
+}

+ 15 - 0
common/src/main/java/com/kym/common/annotation/SysLog.java

@@ -0,0 +1,15 @@
+package com.kym.common.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 系统日志注解
+ *
+ * @author skyline
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface SysLog {
+    String value() default "";
+}

+ 29 - 0
common/src/main/java/com/kym/common/config/Properties.java

@@ -0,0 +1,29 @@
+package com.kym.common.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author skyline
+ * @description 微信支付配置类
+ * @date 2023-07-22 23:09
+ */
+@Data
+@Configuration
+@ConfigurationProperties(prefix = "wechat.payment")
+public class Properties {
+
+    private String appId;
+
+    private String appSecret;
+
+    private String mchId;
+
+    private String mchKey;
+
+    private String notifyUrl;
+
+    private String keyPath;
+
+}

+ 31 - 0
common/src/main/java/com/kym/common/config/WechatPaymentConfig.java

@@ -0,0 +1,31 @@
+package com.kym.common.config;
+
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author skyline
+ * @description
+ * @date 2023-07-22 23:11
+ */
+@Configuration
+public class WechatPaymentConfig {
+/*    @Autowired
+    private WechatPaymentProperties properties;
+
+    @Bean
+    public WxMaConfig wxMaConfig() {
+        WxMaInMemoryConfig config = new WxMaInMemoryConfig();
+        config.setAppid(properties.getAppId());
+        config.setSecret(properties.getAppSecret());
+        return config;
+    }
+
+
+    @Bean
+    public WxMaService wxMaService(WxMaConfig maConfig) {
+        WxMaService service = new WxMaServiceImpl();
+        service.setWxMaConfig(maConfig);
+        return service;
+    }*/
+
+}

+ 21 - 0
common/src/main/java/com/kym/common/config/WxMiniAppConfig.java

@@ -0,0 +1,21 @@
+package com.kym.common.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author skyline
+ * @description 微信支付小程序
+ * @date 2023-07-22 23:09
+ */
+@Data
+@Configuration
+@ConfigurationProperties(prefix = "wechat.miniapp")
+public class WxMiniAppConfig {
+
+    private String appId;
+
+    private String secret;
+
+}

+ 12 - 0
common/src/main/java/com/kym/common/constant/IResponseCode.java

@@ -0,0 +1,12 @@
+package com.kym.common.constant;
+
+/**
+ * @author skyline
+ * @description
+ * @date 2023-07-08 10:34
+ */
+public interface IResponseCode {
+    Integer getCode();
+
+    String getMessage();
+}

+ 42 - 0
common/src/main/java/com/kym/common/constant/ResponseEnum.java

@@ -0,0 +1,42 @@
+package com.kym.common.constant;
+
+import com.kym.common.exception.BusinessExceptionAssert;
+import lombok.Getter;
+
+/**
+ * 返回码信息
+ *
+ * @author skyline
+ */
+@Getter
+public enum ResponseEnum implements BusinessExceptionAssert {
+    SUCCESS(200, "ok"),
+    FAILED(500, "failed"),
+
+    HTTP_STATUS_200(200, "ok"),
+    HTTP_STATUS_400(400, "request error"),
+    HTTP_STATUS_401(401, "no authentication"),
+    HTTP_STATUS_403(403, "no authorities"),
+    HTTP_STATUS_500(500, "server error"),
+
+
+    // 微信小程序
+    WX_MP_LOGIN_ERROR(301, "微信登录异常"),
+
+
+    // 登录
+    LOGIN_FAILED(10001, "用户名或密码错误"),
+
+
+    // EN+
+    EN_PLUS_API_EXCEPTION(90000,"接口数据异常"),
+    EN_PLUS_QUERY_TOKEN_ERROR(90001, "TOKEN获取异常");
+
+    private final Integer code;
+    private final String message;
+
+    ResponseEnum(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+}

+ 13 - 0
common/src/main/java/com/kym/common/enums/Api.java

@@ -0,0 +1,13 @@
+package com.kym.common.enums;
+
+import org.springframework.web.bind.annotation.RequestMethod;
+
+/**
+ * @author skyline
+ * @description
+ * @date 2023-07-08 10:34
+ */
+public interface Api {
+    String getApi();
+    RequestMethod getRequestMethod();
+}

+ 36 - 0
common/src/main/java/com/kym/common/enums/EnPlusApi.java

@@ -0,0 +1,36 @@
+package com.kym.common.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+
+/**
+ * @author skyline
+ * @description EN+接口
+ * @date 2023-07-29 12:33
+ */
+@AllArgsConstructor
+@Getter
+public enum EnPlusApi implements Api {
+
+
+    // 认证-获取token
+    EN_PLUS_QUERY_TOKEN(Constants.DOMAIN + "query_token", RequestMethod.POST),
+
+    // 站点
+    EN_PLUS_QUERY_STATION_INFO(Constants.DOMAIN + "query_stations_info", RequestMethod.POST),
+    EN_PLUS_QUERY_STATION_STATUS(Constants.DOMAIN + "query_station_status", RequestMethod.POST),
+
+    //微信
+    WX_MP_GET_PHONE("", RequestMethod.POST),
+    WX_GET_ACCESS_TOKEN("", RequestMethod.POST);
+
+    private final String api;
+    private final RequestMethod requestMethod;
+
+    private static class Constants {
+        private static final String DOMAIN = "https://api.en-plus.cn:8080/Charge/evcs/v1//MA5HJNDG1/";
+    }
+
+}

+ 24 - 0
common/src/main/java/com/kym/common/enums/WxApi.java

@@ -0,0 +1,24 @@
+package com.kym.common.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+/**
+ * @author skyline
+ * @description 微信接口
+ * @date 2023-07-23 14:33
+ */
+@AllArgsConstructor
+@Getter
+public enum WxApi implements Api{
+
+    // 微信小程序登录
+    WX_MP_LOGIN("https://api.weixin.qq.com/sns/jscode2session?grant_type=authorization_code", RequestMethod.GET),
+    WX_MP_GET_PHONE("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=ACCESS_TOKEN", RequestMethod.POST),
+    WX_GET_ACCESS_TOKEN("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential", RequestMethod.GET);
+
+    private final String api;
+    private final RequestMethod requestMethod;
+
+}

+ 35 - 0
common/src/main/java/com/kym/common/exception/BaseException.java

@@ -0,0 +1,35 @@
+package com.kym.common.exception;
+
+import com.kym.common.constant.IResponseCode;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author skyline
+ * @description 自定义异常
+ * @date 2023-07-02 15:08
+ */
+@AllArgsConstructor
+@Getter
+public class BaseException extends RuntimeException {
+    Integer code;
+    String message;
+
+    BaseException(IResponseCode responseEnum) {
+        this.code = responseEnum.getCode();
+        this.message = responseEnum.getMessage();
+    }
+
+    BaseException(IResponseCode responseEnum, Object[] args, String message) {
+        this.code = responseEnum.getCode();
+        this.message = message;
+        // TODO: 2023-07-04 args处理
+    }
+
+    BaseException(IResponseCode responseEnum, Object[] args, String message, Throwable cause) {
+        this.code = responseEnum.getCode();
+        this.message = message;
+        // TODO: 2023-07-04 args cause 处理 
+    }
+
+}

+ 26 - 0
common/src/main/java/com/kym/common/exception/BusinessException.java

@@ -0,0 +1,26 @@
+package com.kym.common.exception;
+
+import com.kym.common.constant.IResponseCode;
+
+/**
+ * @author skyline
+ * @description 业务异常
+ * @date 2023-07-04 15:44
+ */
+public class BusinessException extends com.kym.common.exception.BaseException {
+
+    private static final long serialVersionUID = 1L;
+
+    public BusinessException(IResponseCode responseEnum) {
+        super(responseEnum);
+    }
+
+    public BusinessException(IResponseCode responseEnum, Object[] args, String message) {
+        super(responseEnum, args, message);
+    }
+
+    public BusinessException(IResponseCode responseEnum, Object[] args, String message, Throwable cause) {
+        super(responseEnum, args, message, cause);
+    }
+}
+

+ 25 - 0
common/src/main/java/com/kym/common/exception/BusinessExceptionAssert.java

@@ -0,0 +1,25 @@
+package com.kym.common.exception;
+
+import com.kym.common.Assert;
+import com.kym.common.constant.IResponseCode;
+
+import java.text.MessageFormat;
+
+/**
+ * @author skyline
+ * @description 业务异常断言
+ * @date 2023-07-08 10:30
+ */
+public interface BusinessExceptionAssert extends IResponseCode, Assert {
+    @Override
+    default BaseException baseException(Object... args) {
+        String msg = MessageFormat.format(this.getMessage(), args);
+        return new BusinessException(this, args, msg);
+    }
+
+    @Override
+    default BaseException baseException(Throwable t, Object... args) {
+        String msg = MessageFormat.format(this.getMessage(), args);
+        return new BusinessException(this, args, msg, t);
+    }
+}

+ 83 - 0
common/src/main/java/com/kym/common/handler/GlobalExceptionHandler.java

@@ -0,0 +1,83 @@
+package com.kym.common.handler;
+
+import cn.dev33.satoken.exception.NotLoginException;
+import com.kym.common.R;
+import com.kym.common.exception.BaseException;
+import com.kym.common.exception.BusinessException;
+import org.apache.ibatis.jdbc.Null;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import static com.kym.common.constant.ResponseEnum.LOGIN_FAILED;
+
+/**
+ * 全局异常处理
+ *
+ * @author skyline
+ */
+@RestControllerAdvice
+public class GlobalExceptionHandler {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class);
+
+    /**
+     * 业务异常
+     *
+     * @param e 异常
+     * @return 异常结果
+     */
+    @ExceptionHandler(value = BusinessException.class)
+    @ResponseBody
+    public R handleBusinessException(BaseException e) {
+        return R.failed(e.getCode(), e.getMessage());
+    }
+
+    /**
+     * 自定义异常
+     *
+     * @param e 异常
+     * @return 异常结果
+     */
+    @ExceptionHandler(value = BaseException.class)
+    @ResponseBody
+    public R<Null> handleBaseException(BaseException e) {
+
+
+        return R.failed();
+    }
+
+    /**
+     * 登录异常
+     *
+     * @param e 异常
+     * @return 异常结果
+     */
+    @ExceptionHandler(value = NotLoginException.class)
+    @ResponseBody
+    public R handleLoginException(NotLoginException e) {
+        LOGGER.error("登录异常", e);
+        var message = "";
+        if (e.getType().equals(NotLoginException.NOT_TOKEN)) {
+            message = NotLoginException.NOT_TOKEN_MESSAGE;
+        } else if (e.getType().equals(NotLoginException.INVALID_TOKEN)) {
+            message = NotLoginException.INVALID_TOKEN_MESSAGE;
+        } else if (e.getType().equals(NotLoginException.TOKEN_TIMEOUT)) {
+            message = NotLoginException.TOKEN_TIMEOUT_MESSAGE;
+        } else if (e.getType().equals(NotLoginException.BE_REPLACED)) {
+            message = NotLoginException.BE_REPLACED_MESSAGE;
+        } else if (e.getType().equals(NotLoginException.KICK_OUT)) {
+            message = NotLoginException.KICK_OUT_MESSAGE;
+        } else if (e.getType().equals(NotLoginException.TOKEN_FREEZE)) {
+            message = NotLoginException.TOKEN_FREEZE_MESSAGE;
+        } else if (e.getType().equals(NotLoginException.NO_PREFIX)) {
+            message = NotLoginException.NO_PREFIX_MESSAGE;
+        } else {
+            message = NotLoginException.DEFAULT_MESSAGE;
+        }
+        return R.failed(LOGIN_FAILED.getCode(), message);
+    }
+
+}

+ 45 - 0
common/src/main/java/com/kym/common/handler/ResponseResultHandler.java

@@ -0,0 +1,45 @@
+package com.kym.common.handler;
+
+import com.kym.common.R;
+import org.springframework.core.MethodParameter;
+import org.springframework.http.MediaType;
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
+
+/**
+ * 返回信息处理
+ *
+ * @author skyline
+ */
+@RestControllerAdvice
+public class ResponseResultHandler implements ResponseBodyAdvice {
+
+
+    /**
+     * 判断是否执行beforeBodyWrite
+     *
+     * @param returnType    the return type
+     * @param converterType the selected converter type
+     * @return
+     */
+    @Override
+    public boolean supports(MethodParameter returnType, Class converterType) {
+        return true;
+    }
+
+    @Override
+    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
+                                  Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
+
+        if (body instanceof R<?>) {
+            return body;
+        } else if (body == null) {
+            return R.success();
+        } else {
+            return R.success(body);
+        }
+        // 失败返回在公共异常处理中
+    }
+}

+ 148 - 0
common/src/main/java/com/kym/common/utils/AESUtil.java

@@ -0,0 +1,148 @@
+package com.kym.common.utils;
+
+
+import jakarta.annotation.PostConstruct;
+import org.apache.tomcat.util.codec.binary.Base64;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.SecureRandom;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * @author skyline
+ * @description AES加解密工具
+ * @date 2023-07-30 01:41
+ */
+@Component
+public class AESUtil {
+
+    //编码方式
+    public static final String CODE_TYPE = "UTF-8";
+    //AES:加密方式   CBC:工作模式   PKCS5Padding:填充模式
+    private static final String CBC_PKCS5_PADDING = "AES/CBC/PKCS5Padding";
+    private static final String AES = "AES";
+
+
+    private static String operatorId;
+    private static String operatorSecret;
+    private static String dataSecret;
+    private static String dataSecretIV;
+    private static String sigSecret;
+    @Autowired
+    Environment environment;
+
+    /**
+     * AES 加密操作
+     *
+     * @param content 待加密内容
+     * @return 返回Base64转码后的加密数据
+     */
+    public static String encrypt(String content) {
+
+        if (content == null || "".equals(content)) {
+            return content;
+        }
+
+        try {
+            /*
+             * 新建一个密码编译器的实例,由三部分构成,用"/"分隔,分别代表如下
+             * 1. 加密的类型(如AES,DES,RC2等)
+             * 2. 模式(AES中包含ECB,CBC,CFB,CTR,CTS等)
+             * 3. 补码方式(包含nopadding/PKCS5Padding等等)
+             * 依据这三个参数可以创建很多种加密方式
+             */
+            Cipher cipher = Cipher.getInstance(CBC_PKCS5_PADDING);
+
+            //偏移量
+            IvParameterSpec zeroIv = new IvParameterSpec(dataSecretIV.getBytes(CODE_TYPE));
+
+            byte[] byteContent = content.getBytes(CODE_TYPE);
+
+            //使用加密秘钥
+            SecretKeySpec skeySpec = new SecretKeySpec(dataSecret.getBytes(CODE_TYPE), AES);
+            //SecretKeySpec skeySpec = getSecretKey(key);
+
+            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, zeroIv);// 初始化为加密模式的密码器
+
+            byte[] result = cipher.doFinal(byteContent);// 加密
+
+            return Base64.encodeBase64String(result);//通过Base64转码返回
+        } catch (Exception ex) {
+            Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
+        }
+
+        return null;
+
+    }
+
+    /**
+     * AES 解密操作
+     *
+     * @param content
+     * @return
+     */
+    public static String decrypt(String content) {
+        if (content == null || "".equals(content)) {
+            return content;
+        }
+
+        try {
+            //实例化
+            Cipher cipher = Cipher.getInstance(CBC_PKCS5_PADDING);
+            IvParameterSpec zeroIv = new IvParameterSpec(dataSecretIV.getBytes(CODE_TYPE));
+
+            SecretKeySpec skeySpec = new SecretKeySpec(dataSecret.getBytes(CODE_TYPE), AES);
+            //SecretKeySpec skeySpec = getSecretKey(key);
+            cipher.init(Cipher.DECRYPT_MODE, skeySpec, zeroIv);
+
+            byte[] result = cipher.doFinal(Base64.decodeBase64(content));
+
+            return new String(result, CODE_TYPE);
+        } catch (Exception ex) {
+            Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
+        }
+
+        return null;
+    }
+
+    /**
+     * 生成加密秘钥
+     *
+     * @return
+     */
+    private static SecretKeySpec getSecretKey(final String key) {
+        //返回生成指定算法密钥生成器的 KeyGenerator 对象
+        KeyGenerator kg;
+        try {
+            kg = KeyGenerator.getInstance(AES);
+            //AES 要求密钥长度为 128
+            kg.init(128, new SecureRandom(key.getBytes()));
+            //生成一个密钥
+            SecretKey secretKey = kg.generateKey();
+            // 转换为AES专用密钥
+            return new SecretKeySpec(secretKey.getEncoded(), AES);
+        } catch (Exception ex) {
+            Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
+        }
+        return null;
+    }
+
+    @PostConstruct//初始化调用
+    public void init() {
+        operatorId = environment.getProperty("en-plus.operator-id");
+        operatorSecret = environment.getProperty("en-plus.operator-secret");
+        dataSecret = environment.getProperty("en-plus.data-secret");
+        dataSecretIV = environment.getProperty("en-plus.data-secret-iv");
+        sigSecret = environment.getProperty("en-plus.sig-secret");
+    }
+
+
+}

+ 31 - 0
common/src/main/java/com/kym/common/utils/HttpContextUtils.java

@@ -0,0 +1,31 @@
+package com.kym.common.utils;
+
+import jakarta.servlet.http.HttpServletRequest;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import java.util.Objects;
+
+
+/**
+ * http context 工具
+ *
+ * @author skyline
+ */
+public class HttpContextUtils {
+
+    public static HttpServletRequest getHttpServletRequest() {
+        return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
+    }
+
+    public static String getDomain() {
+        HttpServletRequest request = getHttpServletRequest();
+        StringBuffer url = request.getRequestURL();
+        return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
+    }
+
+    public static String getOrigin() {
+        HttpServletRequest request = getHttpServletRequest();
+        return request.getHeader("Origin");
+    }
+}

+ 168 - 0
common/src/main/java/com/kym/common/utils/HttpUtil.java

@@ -0,0 +1,168 @@
+package com.kym.common.utils;
+
+import com.alibaba.fastjson2.JSONObject;
+import okhttp3.*;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * @author skyline
+ * @description http工具
+ * @date 2023-07-23 16:31
+ */
+@Component
+public class HttpUtil {
+
+    public static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
+    static OkHttpClient HTTP_CLIENT = new OkHttpClient.Builder().build();
+
+
+    public static String get(String url) {
+        Request request = new Request.Builder()
+                .get()
+                .url(url)
+                .build();
+        return synchronizedCall(request);
+    }
+
+    /**
+     * Get请求
+     *
+     * @param url
+     * @param params
+     * @return
+     */
+    public static JSONObject getJson(String url, Map<String, String> params) {
+        var urlBuilder = HttpUrl.parse(url).newBuilder();
+        params.forEach(urlBuilder::addQueryParameter);
+        Request request = new Request.Builder()
+                .get()
+                .url(urlBuilder.build())
+                .build();
+
+        return parseJson(synchronizedCall(request));
+    }
+
+    public static <T> T get(String url, Class<T> clz) {
+        return parse(get(url), clz);
+    }
+
+    public static String post(String url, String json) {
+        RequestBody requestBody = RequestBody.create(json, JSON);
+        Request request = new Request.Builder()
+                .post(requestBody)
+                .url(url)
+                .build();
+
+        return synchronizedCall(request);
+    }
+
+    public static String post(String url, String json, Headers headers) {
+        RequestBody requestBody = RequestBody.create(json, JSON);
+        Request request = new Request.Builder()
+                .headers(headers)
+                .post(requestBody)
+                .url(url)
+                .build();
+
+        return synchronizedCall(request);
+    }
+
+    public static <T> T post(String url, Map params, Class<T> clz) {
+
+        RequestBody requestBody = RequestBody.create(JSON, JSONObject.toJSONString(params));
+        Request request = new Request.Builder()
+                .post(requestBody)
+                .url(url)
+                .build();
+
+        return parse(synchronizedCall(request), clz);
+    }
+
+    public static <T> T post(String url, String params, Headers headers, Class<T> clz) {
+
+        RequestBody requestBody = RequestBody.create(JSON, params);
+        Request request = new Request.Builder()
+                .headers(headers)
+                .post(requestBody)
+                .url(url)
+                .build();
+
+        return parse(synchronizedCall(request), clz);
+    }
+
+
+    public static <T> T post(String url, String json, Class<T> clz) {
+        return parse(post(url, json), clz);
+    }
+
+    public static String put(String url, String json) {
+        RequestBody body = RequestBody.create(JSON, json);
+
+        Request request = new Request.Builder()
+                .url(url)
+                .put(body)
+                .build();
+
+        return synchronizedCall(request);
+    }
+
+    public static String put(String url) {
+        return put(url, "");
+    }
+
+
+    public static <T> T put(String url, String json, Class<T> clz) {
+        return parse(put(url, json), clz);
+    }
+
+
+    public static String delete(String url, String json) {
+        RequestBody body = RequestBody.create(JSON, json);
+
+        Request request = new Request.Builder()
+                .url(url)
+                .delete(body)
+                .build();
+        return synchronizedCall(request);
+    }
+
+    public static String delete(String url) {
+        return delete(url, "");
+    }
+
+    public static <T> T delete(String url, Class<T> clz) {
+        return parse(
+                delete(url, ""),
+                clz
+        );
+    }
+
+    public static <T> T delete(String url, String json, Class<T> clz) {
+        return parse(delete(url, json), clz);
+    }
+
+    private static String synchronizedCall(Request request) {
+        try (Response response = HTTP_CLIENT.newCall(request).execute()) {
+            return response.body().string();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static <T> T synchronizedCall(Request request, Class<T> clz) {
+        return parse(synchronizedCall(request), clz);
+    }
+
+    public static <T> T parse(String json, Class<T> clz) {
+        return JSONObject.parseObject(json, clz);
+    }
+
+    public static JSONObject parseJson(String json) {
+        return JSONObject.parseObject(json);
+    }
+
+
+}

+ 181 - 0
common/src/main/java/com/kym/common/utils/IDGenerator.java

@@ -0,0 +1,181 @@
+package com.kym.common.utils;
+
+import org.springframework.stereotype.Component;
+
+/**
+ * Twitter_Snowflake<br>
+ * SnowFlake的结构如下(每部分用-分开):<br>
+ * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 <br>
+ * 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0<br>
+ * 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截)
+ * 得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69<br>
+ * 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId<br>
+ * 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号<br>
+ * 加起来刚好64位,为一个Long型。<br>
+ * SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。
+ */
+@Component
+public class IDGenerator {
+
+
+    // ==============================Fields===========================================
+    /**
+     * 开始时间截 (2015-01-01)
+     */
+    private final long twepoch = 1420041600000L;
+
+    /**
+     * 机器id所占的位数
+     */
+    private final long workerIdBits = 5L;
+
+    /**
+     * 数据标识id所占的位数
+     */
+    private final long datacenterIdBits = 5L;
+
+    /**
+     * 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数)
+     */
+    private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
+
+    /**
+     * 支持的最大数据标识id,结果是31
+     */
+    private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
+
+    /**
+     * 序列在id中占的位数
+     */
+    private final long sequenceBits = 12L;
+
+    /**
+     * 机器ID向左移12位
+     */
+    private final long workerIdShift = sequenceBits;
+
+    /**
+     * 数据标识id向左移17位(12+5)
+     */
+    private final long datacenterIdShift = sequenceBits + workerIdBits;
+
+    /**
+     * 时间截向左移22位(5+5+12)
+     */
+    private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
+
+    /**
+     * 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095)
+     */
+    private final long sequenceMask = -1L ^ (-1L << sequenceBits);
+
+    /**
+     * 工作机器ID(0~31)
+     */
+    private long workerId;
+
+    /**
+     * 数据中心ID(0~31)
+     */
+    private long datacenterId;
+
+    /**
+     * 毫秒内序列(0~4095)
+     */
+    private long sequence = 0L;
+
+    /**
+     * 上次生成ID的时间截
+     */
+    private long lastTimestamp = -1L;
+
+    //==============================Constructors=====================================
+
+    /**
+     * 构造函数
+     *
+     * @param workerId     工作ID (0~31)
+     * @param datacenterId 数据中心ID (0~31)
+     */
+    public IDGenerator(long workerId, long datacenterId) {
+        if (workerId > maxWorkerId || workerId < 0) {
+            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
+        }
+        if (datacenterId > maxDatacenterId || datacenterId < 0) {
+            throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
+        }
+        this.workerId = workerId;
+        this.datacenterId = datacenterId;
+    }
+
+    /**
+     * 默认workerId、datacenterId为0L
+     */
+    public IDGenerator() {
+        this.workerId = 0L;
+        this.datacenterId = 0L;
+    }
+
+    // ==============================Methods==========================================
+
+    /**
+     * 获得下一个ID (该方法是线程安全的)
+     *
+     * @return SnowflakeId
+     */
+    public synchronized long nextId() {
+        long timestamp = timeGen();
+
+        //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
+        if (timestamp < lastTimestamp) {
+            throw new RuntimeException(
+                    String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
+        }
+
+        //如果是同一时间生成的,则进行毫秒内序列
+        if (lastTimestamp == timestamp) {
+            sequence = (sequence + 1) & sequenceMask;
+            //毫秒内序列溢出
+            if (sequence == 0) {
+                //阻塞到下一个毫秒,获得新的时间戳
+                timestamp = tilNextMillis(lastTimestamp);
+            }
+        }
+        //时间戳改变,毫秒内序列重置
+        else {
+            sequence = 0L;
+        }
+
+        //上次生成ID的时间截
+        lastTimestamp = timestamp;
+
+        //移位并通过或运算拼到一起组成64位的ID
+        return ((timestamp - twepoch) << timestampLeftShift) //
+                | (datacenterId << datacenterIdShift) //
+                | (workerId << workerIdShift) //
+                | sequence;
+    }
+
+    /**
+     * 阻塞到下一个毫秒,直到获得新的时间戳
+     *
+     * @param lastTimestamp 上次生成ID的时间截
+     * @return 当前时间戳
+     */
+    protected long tilNextMillis(long lastTimestamp) {
+        long timestamp = timeGen();
+        while (timestamp <= lastTimestamp) {
+            timestamp = timeGen();
+        }
+        return timestamp;
+    }
+
+    /**
+     * 返回以毫秒为单位的当前时间
+     *
+     * @return 当前时间(毫秒)
+     */
+    protected long timeGen() {
+        return System.currentTimeMillis();
+    }
+}

+ 56 - 0
common/src/main/java/com/kym/common/utils/IPUtils.java

@@ -0,0 +1,56 @@
+package com.kym.common.utils;
+
+import com.alibaba.druid.util.StringUtils;
+import jakarta.servlet.http.HttpServletRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * IP地址
+ *
+ * @author skyline
+ */
+public class IPUtils {
+    private static Logger logger = LoggerFactory.getLogger(IPUtils.class);
+
+    /**
+     * 获取IP地址
+     * <p>
+     * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
+     * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
+     */
+    public static String getIpAddr(HttpServletRequest request) {
+        String ip = null;
+        try {
+            ip = request.getHeader("x-forwarded-for");
+            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
+                ip = request.getHeader("Proxy-Client-IP");
+            }
+            if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+                ip = request.getHeader("WL-Proxy-Client-IP");
+            }
+            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
+                ip = request.getHeader("HTTP_CLIENT_IP");
+            }
+            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
+                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+            }
+            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
+                ip = request.getRemoteAddr();
+            }
+        } catch (Exception e) {
+            logger.error("IPUtils ERROR ", e);
+        }
+
+//        //使用代理,则获取第一个IP地址
+//        if(StringUtils.isEmpty(ip) && ip.length() > 15) {
+//			if(ip.indexOf(",") > 0) {
+//				ip = ip.substring(0, ip.indexOf(","));
+//			}
+//		}
+
+        return ip;
+    }
+
+}

+ 89 - 0
common/src/main/java/com/kym/common/utils/MybatisPlusGenerator.java

@@ -0,0 +1,89 @@
+package com.kym.common.utils;
+
+import com.baomidou.mybatisplus.generator.FastAutoGenerator;
+import com.baomidou.mybatisplus.generator.config.OutputFile;
+import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
+
+import java.util.Collections;
+
+/**
+ * mybatis-plus-generator代码生成
+ *
+ * @author skyline
+ */
+public class MybatisPlusGenerator {
+
+    public static void main(String[] args) {
+        // 指定数据源
+        FastAutoGenerator.create("jdbc:mysql://localhost:3306/charge_admin", "root", "root")
+                .globalConfig(builder -> {
+                    builder.author("skyline")
+                            // 指定输出目录
+                            .outputDir("D://Java Project/charge/src/main/java");
+                })
+                .packageConfig(builder -> {
+                    // 设置父包名
+                    builder.parent("com.kym")
+                            // 设置父包模块名
+                            .moduleName("charge")
+                            .entity("entity")
+                            .service("service")
+                            .serviceImpl("service.impl")
+                            .mapper("mapper")
+                            .xml("mapper.xml")
+                            .controller("controller")
+                            // 设置mapperXml生成路径
+                            .pathInfo(Collections.singletonMap(OutputFile.xml, "D://Java Project/charge/src/main/resources/mappers"));
+                })
+
+                .strategyConfig(builder -> {
+                    // 设置需要生成的表名
+                    builder.addInclude(
+//                                    "t_user",
+//                                    "t_account",
+//                                    "t_station",
+//                                    "t_charge_order",
+                                    "t_system_log"
+                            )
+                            // 设置过滤表前缀
+                            .addTablePrefix("t_");
+
+                    // entity配置
+                    builder.entityBuilder()
+                            .enableFileOverride()
+                            .enableLombok();
+
+                    // controller配置
+                    builder.controllerBuilder()
+                            .enableFileOverride()
+                            .enableRestStyle()
+                            .enableHyphenStyle()
+//                            .superClass(BaseController.class)
+                            .formatFileName("%sController");
+
+                    // service配置
+                    builder.serviceBuilder()
+                            .enableFileOverride()
+                            .formatServiceFileName("%sService")
+                            .formatServiceImplFileName("%sServiceImpl");
+
+                    // mapper配置
+                    builder.mapperBuilder()
+                            .enableFileOverride()
+                            .enableBaseResultMap()
+                            .enableBaseColumnList()
+                            .formatMapperFileName("%sMapper")
+                            .formatXmlFileName("%sMapper")
+                            .build();
+
+
+                    builder.build();
+
+                })
+
+                // 使用Freemarker引擎模板,默认的是Velocity引擎模板
+                .templateEngine(new FreemarkerTemplateEngine())
+                .execute();
+    }
+
+}

+ 20 - 0
entity/pom.xml

@@ -0,0 +1,20 @@
+<?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>
+    <parent>
+        <groupId>com.kym</groupId>
+        <artifactId>charge</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>entity</artifactId>
+
+    <properties>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+</project>

+ 70 - 0
entity/src/main/java/com/kym/entity/admin/AdminUser.java

@@ -0,0 +1,70 @@
+package com.kym.entity.admin;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 用户表
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-11
+ */
+@Getter
+@Setter
+@TableName("t_admin_user")
+public class AdminUser implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    /**
+     * 公司id
+     */
+    private Long companyId;
+
+    /**
+     * 用户名
+     */
+    private String username;
+
+    /**
+     * 密码
+     */
+    private String password;
+
+    /**
+     * 昵称
+     */
+    private String nickname;
+
+    /**
+     * 手机号
+     */
+    private String mobilePhone;
+
+    /**
+     * 头像
+     */
+    private String avatar;
+
+    /**
+     * 0:禁用 1:启用
+     */
+    private Byte status;
+
+    private LocalDateTime createTime;
+
+    private LocalDateTime updateTime;
+
+    /**
+     * 最后登录时间
+     */
+    private LocalDateTime lastLoginTime;
+}

+ 51 - 0
entity/src/main/java/com/kym/entity/admin/AdminUserRole.java

@@ -0,0 +1,51 @@
+package com.kym.entity.admin;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 管理平台用户角色表
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-12
+ */
+@Getter
+@Setter
+@TableName("t_admin_user_role")
+public class AdminUserRole implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    /**
+     * 公司id
+     */
+    private Long companyId;
+
+    /**
+     * 管理平台用户id
+     */
+    private Long adminUserId;
+
+    /**
+     * 角色id
+     */
+    private Long roleId;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+}

+ 59 - 0
entity/src/main/java/com/kym/entity/admin/ChargeOrder.java

@@ -0,0 +1,59 @@
+package com.kym.entity.admin;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-06-27
+ */
+@Getter
+@Setter
+@TableName("t_charge_order")
+public class ChargeOrder implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Integer id;
+
+    private Integer userId;
+
+    private Integer stationId;
+
+    private String startChargeSeq;
+
+    private String connectorId;
+
+    private LocalDateTime startTime;
+
+    private LocalDateTime endTime;
+
+    private BigDecimal totalPower;
+
+    private BigDecimal totalCost;
+
+    private BigDecimal elecBill;
+
+    private BigDecimal serviceFee;
+
+    private Byte stopReason;
+
+    private Byte sumPeriod;
+
+    private String chargeDetail;
+
+    private Byte chargeStatus;
+
+    private LocalDateTime createTime;
+
+    private LocalDateTime updateTime;
+}

+ 50 - 0
entity/src/main/java/com/kym/entity/admin/Company.java

@@ -0,0 +1,50 @@
+package com.kym.entity.admin;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 公司表
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-12
+ */
+@Getter
+@Setter
+@TableName("t_company")
+public class Company implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    /**
+     * 公司名
+     */
+    private String companyName;
+
+    /**
+     * 超管id
+     */
+    private Long superAdminId;
+
+    /**
+     * 超管用户名
+     */
+    private String superAdminName;
+
+    /**
+     * 0:禁用 1:启用
+     */
+    private Byte status;
+
+    private LocalDateTime createTime;
+
+    private LocalDateTime updateTime;
+}

+ 56 - 0
entity/src/main/java/com/kym/entity/admin/Permission.java

@@ -0,0 +1,56 @@
+package com.kym.entity.admin;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 权限表
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-12
+ */
+@Getter
+@Setter
+@TableName("t_permission")
+public class Permission implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    /**
+     * 公司id
+     */
+    private Long companyId;
+
+    /**
+     * 父权限id
+     */
+    private Long parentId;
+
+    /**
+     * 权限名
+     */
+    private String permissionName;
+
+    /**
+     * 权限描述
+     */
+    private String permissionDesc;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+}

+ 56 - 0
entity/src/main/java/com/kym/entity/admin/Role.java

@@ -0,0 +1,56 @@
+package com.kym.entity.admin;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 角色表
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-12
+ */
+@Getter
+@Setter
+@TableName("t_role")
+public class Role implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    /**
+     * 公司id
+     */
+    private Long companyId;
+
+    /**
+     * 父角色id
+     */
+    private Long parentId;
+
+    /**
+     * 角色名
+     */
+    private String roleName;
+
+    /**
+     * 角色描述
+     */
+    private String roleDesc;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+}

+ 51 - 0
entity/src/main/java/com/kym/entity/admin/RolePermission.java

@@ -0,0 +1,51 @@
+package com.kym.entity.admin;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 角色权限表
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-12
+ */
+@Getter
+@Setter
+@TableName("t_role_permission")
+public class RolePermission implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    /**
+     * 公司id
+     */
+    private Long companyId;
+
+    /**
+     * 角色id
+     */
+    private Long roleId;
+
+    /**
+     * 权限id
+     */
+    private Long permissionId;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+}

+ 55 - 0
entity/src/main/java/com/kym/entity/admin/Station.java

@@ -0,0 +1,55 @@
+package com.kym.entity.admin;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-06-27
+ */
+@Getter
+@Setter
+@TableName("t_station")
+public class Station implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Integer id;
+
+    /**
+     * 站点名称
+     */
+    private String stationName;
+
+    /**
+     * 类型: 0慢充 1快充
+     */
+    private String stationType;
+
+    /**
+     * 充电桩位置
+     */
+    private byte[] stationLocation;
+
+    /**
+     * 停车费
+     */
+    private String parkingFee;
+
+    /**
+     * 充电车位数量
+     */
+    private Integer parkingNum;
+
+    private LocalDateTime createTime;
+
+    private LocalDateTime updateTime;
+}

+ 76 - 0
entity/src/main/java/com/kym/entity/admin/SystemLog.java

@@ -0,0 +1,76 @@
+package com.kym.entity.admin;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 系统操作日志表
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-10
+ */
+@Getter
+@Setter
+@TableName("t_system_log")
+public class SystemLog implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    /**
+     * 公司id
+     */
+    private Long companyId;
+
+    /**
+     * 用户id
+     */
+    private Long userId;
+
+    /**
+     * 操作人
+     */
+    private String username;
+
+    /**
+     * ip
+     */
+    private String ip;
+
+    /**
+     * 操作名
+     */
+    private String operation;
+
+    /**
+     * 方法
+     */
+    private String method;
+
+    /**
+     * 请求参数
+     */
+    private String requestParam;
+
+    /**
+     * 执行时长
+     */
+    private Long executeTime;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+}

+ 10 - 0
entity/src/main/java/com/kym/entity/common/RedisKeys.java

@@ -0,0 +1,10 @@
+package com.kym.entity.common;
+
+/**
+ * @author skyline
+ * @description
+ * @date 2023-07-31 18:26
+ */
+public interface RedisKeys {
+    String EN_PLUS_TOKEN = "EN_PLUS_TOKEN";
+}

+ 62 - 0
entity/src/main/java/com/kym/entity/enplus/ConnectorInfo.java

@@ -0,0 +1,62 @@
+package com.kym.entity.enplus;
+
+import lombok.Data;
+
+/**
+ * @author skyline
+ * @description 充电设备接口信息
+ * @date 2023-07-31 15:30
+ */
+@Data
+public class ConnectorInfo {
+    /**
+     * 充电设备接口编码
+     */
+    private String ConnectorID;
+    /**
+     * 充电设备接口名称
+     */
+    private String ConnectorName;
+    /**
+     * 充电设备接口类型
+     * 1:家用插座(模式2)
+     * 2:交流接口插座(模式3,连接方式B)
+     * 3:交流接口插头(带枪线,模式3,连接方式C)
+     * 4:直流接口枪头(带枪线,模式4)
+     * 5:无线充电桩
+     * 6:其他
+     */
+    private int ConnectorType;
+
+    /**
+     * 额定电压上限(V)
+     */
+    private int VoltageUpperLimits;
+
+    /**
+     * 额定电压下限(V)
+     */
+    private int VoltageLowerLimits;
+    /**
+     * 额定电流(A)
+     */
+    private int Current;
+
+    /**
+     * 额定功率(KW)
+     */
+    private int Power;
+
+    /**
+     * 停车场车位编号
+     */
+    private String ParkNo;
+    /**
+     * 国家标准
+     * 1:2011
+     * 2:2015
+     */
+    private int NationalStandard;
+
+
+}

+ 23 - 0
entity/src/main/java/com/kym/entity/enplus/ConnectorStatsInfo.java

@@ -0,0 +1,23 @@
+package com.kym.entity.enplus;
+
+import lombok.Data;
+
+/**
+ * @author skyline
+ * @description 充电设备接口统计信息
+ * @date 2023-07-31 16:15
+ */
+@Data
+public class ConnectorStatsInfo {
+
+    /**
+     * 充电设备接口编码
+     * 充电设备接口编码,同一运营商内唯一
+     */
+    private String ConnectorID;
+    /**
+     * 充电设备接口累计电量(kWh,精度0.1)
+     */
+    private float ConnectorElectricity;
+
+}

+ 40 - 0
entity/src/main/java/com/kym/entity/enplus/ConnectorStatusInfo.java

@@ -0,0 +1,40 @@
+package com.kym.entity.enplus;
+
+import lombok.Data;
+
+/**
+ * @author skyline
+ * @description
+ * @date 2023-07-31 15:40
+ */
+@Data
+public class ConnectorStatusInfo {
+    /**
+     * 充电设备接口编码
+     */
+    private String ConnectorID;
+    /**
+     * 充个设备接口状态
+     * 0:离网
+     * 1:空闲
+     * 2:占用(未充电)
+     * 3:占用(充电中)
+     * 4:占用(预约锁定)
+     * 255:故障
+     */
+    private int Status;
+    /**
+     * 车位状态
+     * 0:未知
+     * 10:空闲
+     * 50:占用
+     */
+    private int ParkStatus;
+    /**
+     * 地锁状态
+     * 0:未知
+     * 10:已解锁
+     * 50:已上锁
+     */
+    private int LockStatus;
+}

+ 39 - 0
entity/src/main/java/com/kym/entity/enplus/EnRespQueryToken.java

@@ -0,0 +1,39 @@
+package com.kym.entity.enplus;
+
+import lombok.Data;
+
+/**
+ * @author skyline
+ * @description query_token 返回值
+ * @date 2023-07-31 11:32
+ */
+@Data
+public class EnRespQueryToken {
+    /**
+     * 运营商ID
+     */
+    private String OperatorID;
+    /**
+     * 成功状态
+     * 0:成功
+     * 1:失败
+     */
+    private int SuccStat;
+    /**
+     * 全局唯一凭证
+     */
+    private String AccessToken;
+    /**
+     * 凭证有效期(秒)
+     */
+    private int TokenAvailableTime;
+    /**
+     * 失败原因:
+     * 0:无
+     * 1:无此运营商
+     * 2:密钥错误
+     * 3~99:自定义
+     */
+    private String FailReason;
+
+}

+ 16 - 0
entity/src/main/java/com/kym/entity/enplus/EnResponse.java

@@ -0,0 +1,16 @@
+package com.kym.entity.enplus;
+
+import lombok.Data;
+
+/**
+ * @author skyline
+ * @description en+接口返回数据
+ * @date 2023-07-31 11:59
+ */
+@Data
+public class EnResponse {
+    private int Ret;
+    private String Msg;
+    private String Data;
+    private String Sig;
+}

+ 55 - 0
entity/src/main/java/com/kym/entity/enplus/EquipmentInfo.java

@@ -0,0 +1,55 @@
+package com.kym.entity.enplus;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author skyline
+ * @description 充电设备信息
+ * @date 2023-07-31 15:21
+ */
+@Data
+public class EquipmentInfo {
+
+    /**
+     * 设备编码
+     */
+    private String EquipmentID;
+
+    /**
+     * 设备生产商组织机构代码
+     */
+    private String ManufacturerID;
+
+    /**
+     * 设备生产商名称
+     */
+    private String ManufacturerName;
+
+    /**
+     * 设备型号
+     */
+    private String EquipmentModel;
+
+    /**
+     * 设备生产日期(YYYY-MM-DD)
+     */
+    private String ProductionDate;
+
+    /**
+     * 设备类型
+     * 1:直流设备
+     * 2:交流设备
+     * 3:交直流一体设备
+     * 4:无线设备
+     * 5:其他
+     */
+    private int EquipmentType;
+
+    /**
+     * 充电设备接口信息列表
+     */
+    private List<ConnectorInfo> ConnectorInfos;
+
+}

+ 25 - 0
entity/src/main/java/com/kym/entity/enplus/EquipmentStatsInfo.java

@@ -0,0 +1,25 @@
+package com.kym.entity.enplus;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author skyline
+ * @description 充电设备统计信息
+ * @date 2023-07-31 16:10
+ */
+@Data
+public class EquipmentStatsInfo {
+    /**
+     * 设备编码
+     * 设备唯一编码,对同一运营商,保证唯一
+     */
+    private String EquipmentID;
+    /**
+     * 充电设别接口累计电量
+     */
+    private float EquipmentElectricity;
+    private List<ConnectorStatsInfo> ConnectorStatsInfos;
+
+}

+ 150 - 0
entity/src/main/java/com/kym/entity/enplus/StationInfo.java

@@ -0,0 +1,150 @@
+package com.kym.entity.enplus;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author skyline
+ * @description 充电站信息
+ * @date 2023-07-31 14:55
+ */
+@Data
+public class StationInfo {
+
+
+    /**
+     * 充电站ID
+     */
+    private String StationID;
+    /**
+     * 运营商ID
+     */
+    private String OperatorID;
+    /**
+     * 设备所属方ID
+     */
+    private String EquipmentOwnerID;
+    /**
+     * 充电站名称
+     */
+    private String StationName;
+    /**
+     * 充电站国家代码
+     */
+    private String CountryCode;
+    /**
+     * 充电站省市辖区码
+     */
+    private String AreaCode;
+    /**
+     * 详细地址(50字符)
+     */
+    private String Address;
+    /**
+     * 站点电话
+     */
+    private String StationTel;
+    /**
+     * 服务电话
+     */
+    private String ServiceTel;
+    /**
+     * 站点类型
+     * 1:公共
+     * 50:个人
+     * 100:公交(专用)
+     * 101:环卫(专用)
+     * 102:物流(专用)
+     * 103:出租车(专用)
+     * 255:其他
+     */
+    private int StationType;
+    /**
+     * 站点状态
+     * 0:未知
+     * 1:建设中
+     * 5:关闭下线
+     * 6:维护中
+     * 50:正常使用
+     */
+    private int StationStatus;
+    /**
+     * 车位数量
+     */
+    private int ParkNums;
+    /**
+     * 经度
+     */
+    private float StationLng;
+    /**
+     * 纬度
+     */
+    private float StationLat;
+    /**
+     * 站点引导(100字符)
+     */
+    private String SiteGuide;
+    /**
+     * 建设场所
+     * 1:居民区
+     * 2:公共机构
+     * 3:企事业单位
+     * 4:写字楼
+     * 5:工业园区
+     * 6:交通枢纽
+     * 7:大型问题设施
+     * 8:城市绿地
+     * 9:大型建筑配建停车场
+     * 10:路边停车位
+     * 11:城际高速服务区
+     * 255:其他
+     */
+    private int Construction;
+    /**
+     * 站点照片
+     */
+    private String[] Pictures;
+    /**
+     * 使用车型描述
+     */
+    private String MatchCars;
+    /**
+     * 车位楼层及数量描述
+     */
+    private String ParkInfo;
+    /**
+     * 营业时间描述
+     */
+    private String BusineHours;
+    /**
+     * 充电电费率
+     */
+    private String ElectricityFee;
+    /**
+     * 服务费率
+     */
+    private String ServiceFee;
+    /**
+     * 停车费
+     */
+    private String ParkFee;
+    /**
+     * 支付方式
+     */
+    private String Payment;
+    /**
+     * 是否支持预约
+     * 0:不支持
+     * 1:支持
+     */
+    private int SupportOrder;
+    /**
+     * 备注
+     */
+    private String Remark;
+    /**
+     * 充电设备信息列表
+     */
+    private List<EquipmentInfo> EquipmentInfos;
+}

+ 36 - 0
entity/src/main/java/com/kym/entity/enplus/StationStatsInfo.java

@@ -0,0 +1,36 @@
+package com.kym.entity.enplus;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author skyline
+ * @description 充电桩统计信息
+ * @date 2023-07-31 16:02
+ */
+@Data
+public class StationStatsInfo {
+    /**
+     * 充电站ID
+     */
+    private String StationID;
+    /**
+     * 统计开始时间(yyyy-MM-dd)
+     */
+    private String StartTime;
+    /**
+     * 统计结束时间(yyyy-MM-dd)
+     */
+    private String EndTime;
+    /**
+     * 充电站累积电量(kWh,精度0.1)
+     */
+    private float StationElectricity;
+
+    /**
+     * 充电设备统计信息列表
+     */
+    private List<EquipmentStatsInfo> EquipmentStatsInfos;
+
+}

+ 24 - 0
entity/src/main/java/com/kym/entity/enplus/StationStatusInfo.java

@@ -0,0 +1,24 @@
+package com.kym.entity.enplus;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author skyline
+ * @description
+ * @date 2023-07-31 16:00
+ */
+@Data
+public class StationStatusInfo {
+    /**
+     * 充电站ID(20字符,运营商自定义的唯一编码,不足长度在前方补0)
+     */
+    private String StationID;
+
+    /**
+     * 充电设备接口状态列表
+     */
+    private List<ConnectorStatusInfo> ConnectorStatusInfos;
+
+}

+ 49 - 0
entity/src/main/java/com/kym/entity/miniapp/Account.java

@@ -0,0 +1,49 @@
+package com.kym.entity.miniapp;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 用户账户表
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-26
+ */
+@Getter
+@Setter
+@TableName("t_account")
+public class Account implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    /**
+     * 用户id
+     */
+    private Long userId;
+
+    /**
+     * 余额
+     */
+    private Long balance;
+
+    /**
+     * 冻结金额
+     */
+    private Long frozenAmount;
+
+    /**
+     * 状态: 0禁用 1启用
+     */
+    private Integer status;
+
+    private LocalDateTime createTime;
+
+    private LocalDateTime updateTime;
+}

+ 96 - 0
entity/src/main/java/com/kym/entity/miniapp/Cars.java

@@ -0,0 +1,96 @@
+package com.kym.entity.miniapp;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 车辆表
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-26
+ */
+@Getter
+@Setter
+@TableName("t_cars")
+public class Cars implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    /**
+     * 车辆所有人
+     */
+    private Long userId;
+
+    /**
+     * 车牌号码
+     */
+    private Long plateNo;
+
+    /**
+     * 车辆类型
+     */
+    private String vehicleType;
+
+    /**
+     * 住址
+     */
+    private String address;
+
+    /**
+     * 车辆识别号
+     */
+    private String vin;
+
+    /**
+     * 车辆使用性质
+     */
+    private String useCharacter;
+
+    /**
+     * 品牌型号
+     */
+    private String model;
+
+    /**
+     * 发动机编号
+     */
+    private String engineNo;
+
+    /**
+     * 注册时间
+     */
+    private LocalDate registerDate;
+
+    /**
+     * 是否默认
+     */
+    private Boolean isDefult;
+
+    /**
+     * 是否删除
+     */
+    private Boolean isDelete;
+
+    /**
+     * 发证时间
+     */
+    private LocalDate issueDate;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+}

+ 59 - 0
entity/src/main/java/com/kym/entity/miniapp/ChargeOrder.java

@@ -0,0 +1,59 @@
+package com.kym.entity.miniapp;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-06-27
+ */
+@Getter
+@Setter
+@TableName("t_charge_order")
+public class ChargeOrder implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Integer id;
+
+    private Integer userId;
+
+    private Integer stationId;
+
+    private String startChargeSeq;
+
+    private String connectorId;
+
+    private LocalDateTime startTime;
+
+    private LocalDateTime endTime;
+
+    private BigDecimal totalPower;
+
+    private BigDecimal totalCost;
+
+    private BigDecimal elecBill;
+
+    private BigDecimal serviceFee;
+
+    private Byte stopReason;
+
+    private Byte sumPeriod;
+
+    private String chargeDetail;
+
+    private Byte chargeStatus;
+
+    private LocalDateTime createTime;
+
+    private LocalDateTime updateTime;
+}

+ 50 - 0
entity/src/main/java/com/kym/entity/miniapp/Collect.java

@@ -0,0 +1,50 @@
+package com.kym.entity.miniapp;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 收藏表
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-31
+ */
+@Getter
+@Setter
+@TableName("t_collect")
+public class Collect implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    /**
+     * 用户id
+     */
+    private Long userId;
+
+    /**
+     * 站点id
+     */
+    private Long stationId;
+
+    /**
+     * 状态: 0-不显示 1-显示
+     */
+    private Byte status;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+}

+ 79 - 0
entity/src/main/java/com/kym/entity/miniapp/User.java

@@ -0,0 +1,79 @@
+package com.kym.entity.miniapp;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 用户表
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-26
+ */
+@Getter
+@Setter
+@TableName("t_user")
+public class User implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    /**
+     * 微信openid
+     */
+    private String openid;
+
+    /**
+     * 微信unionid
+     */
+    private String unionid;
+
+    /**
+     * 用户名
+     */
+    private String username;
+
+    /**
+     * 密码
+     */
+    private String password;
+
+    /**
+     * 性别:0-女 1-男
+     */
+    private Byte gender;
+
+    /**
+     * 昵称
+     */
+    private String nickname;
+
+    /**
+     * 手机号
+     */
+    private String mobilePhone;
+
+    /**
+     * 头像
+     */
+    private String avatar;
+
+    /**
+     * 0:禁用 1:启用
+     */
+    private Byte status;
+
+    private LocalDateTime createTime;
+
+    private LocalDateTime updateTime;
+
+    /**
+     * 最后登录时间
+     */
+    private LocalDateTime lastLoginTime;
+}

+ 86 - 0
entity/src/main/java/com/kym/entity/miniapp/WalletDetail.java

@@ -0,0 +1,86 @@
+package com.kym.entity.miniapp;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 用户账户表
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-22
+ */
+@Getter
+@Setter
+@TableName("t_wallet_detail")
+public class WalletDetail implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    /**
+     * 用户id
+     */
+    private Long userId;
+
+    /**
+     * 交易类型:1-充值2-提现3-消费
+     */
+    private Byte type;
+
+    /**
+     * 币种
+     */
+    private String current;
+
+    /**
+     * 订单id
+     */
+    private Long orderId;
+
+    /**
+     * 金额
+     */
+    private BigDecimal amount;
+
+    /**
+     * 手续费
+     */
+    private BigDecimal commission;
+
+    /**
+     * 交易id type为1是pay_log的id,type为3是charge_order的id
+     */
+    private Long transactionId;
+
+    /**
+     * 交易发起时间
+     */
+    private LocalDateTime transactionTime;
+
+    /**
+     * 明细状态:0-待确认1-已确认2-已取消
+     */
+    private Byte status;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+}

+ 31 - 0
entity/src/main/java/com/kym/entity/miniapp/WxPhoneNum.java

@@ -0,0 +1,31 @@
+package com.kym.entity.miniapp;
+
+import lombok.Data;
+
+/**
+ * @author skyline
+ * @description
+ * @date 2023-07-26 17:11
+ */
+@Data
+public class WxPhoneNum {
+    public Integer errcode;
+    public String errmsg;
+    public PhoneInfo phone_info;
+    public WaterMark watermark;
+
+    @Data
+    public class PhoneInfo {
+        String phoneNumber;
+        String purePhoneNumber;
+        String countryCode;
+    }
+
+
+    @Data
+    public class WaterMark {
+        Integer timestamp;
+        String appid;
+    }
+
+}

+ 19 - 0
entity/src/main/java/com/kym/entity/miniapp/vo/vo/UserVo.java

@@ -0,0 +1,19 @@
+package com.kym.entity.miniapp.vo.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+
+@Data
+public class UserVo implements Serializable {
+    private static final long serialVersionUID = 1L;
+    public Long id;
+    public String username;
+    public String nickname;
+    public String mobilePhone;
+    public String defaultPlateNo;
+    public Integer status;
+    public String vin;
+
+}

+ 38 - 0
mapper/.gitignore

@@ -0,0 +1,38 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.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

+ 28 - 0
mapper/pom.xml

@@ -0,0 +1,28 @@
+<?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>
+    <parent>
+        <groupId>com.kym</groupId>
+        <artifactId>charge</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>mapper</artifactId>
+
+    <properties>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.kym</groupId>
+            <artifactId>entity</artifactId>
+            <version>0.0.1-SNAPSHOT</version>
+        </dependency>
+    </dependencies>
+
+</project>

+ 16 - 0
mapper/src/main/java/com/kym/mapper/admin/AdminUserMapper.java

@@ -0,0 +1,16 @@
+package com.kym.mapper.admin;
+
+import com.kym.entity.admin.AdminUser;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 用户表 Mapper 接口
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-11
+ */
+public interface AdminUserMapper extends BaseMapper<AdminUser> {
+
+}

+ 16 - 0
mapper/src/main/java/com/kym/mapper/admin/AdminUserRoleMapper.java

@@ -0,0 +1,16 @@
+package com.kym.mapper.admin;
+
+import com.kym.entity.admin.AdminUserRole;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 管理平台用户角色表 Mapper 接口
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-12
+ */
+public interface AdminUserRoleMapper extends BaseMapper<AdminUserRole> {
+
+}

+ 16 - 0
mapper/src/main/java/com/kym/mapper/admin/CompanyMapper.java

@@ -0,0 +1,16 @@
+package com.kym.mapper.admin;
+
+import com.kym.entity.admin.Company;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 公司表 Mapper 接口
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-12
+ */
+public interface CompanyMapper extends BaseMapper<Company> {
+
+}

+ 16 - 0
mapper/src/main/java/com/kym/mapper/admin/PermissionMapper.java

@@ -0,0 +1,16 @@
+package com.kym.mapper.admin;
+
+import com.kym.entity.admin.Permission;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 权限表 Mapper 接口
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-12
+ */
+public interface PermissionMapper extends BaseMapper<Permission> {
+
+}

+ 16 - 0
mapper/src/main/java/com/kym/mapper/admin/RoleMapper.java

@@ -0,0 +1,16 @@
+package com.kym.mapper.admin;
+
+import com.kym.entity.admin.Role;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 角色表 Mapper 接口
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-12
+ */
+public interface RoleMapper extends BaseMapper<Role> {
+
+}

+ 16 - 0
mapper/src/main/java/com/kym/mapper/admin/RolePermissionMapper.java

@@ -0,0 +1,16 @@
+package com.kym.mapper.admin;
+
+import com.kym.entity.admin.RolePermission;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 角色权限表 Mapper 接口
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-12
+ */
+public interface RolePermissionMapper extends BaseMapper<RolePermission> {
+
+}

+ 16 - 0
mapper/src/main/java/com/kym/mapper/admin/StationMapper.java

@@ -0,0 +1,16 @@
+package com.kym.mapper.admin;
+
+import com.kym.entity.admin.Station;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-06-27
+ */
+public interface StationMapper extends BaseMapper<Station> {
+
+}

+ 16 - 0
mapper/src/main/java/com/kym/mapper/admin/SystemLogMapper.java

@@ -0,0 +1,16 @@
+package com.kym.mapper.admin;
+
+import com.kym.entity.admin.SystemLog;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 系统操作日志表 Mapper 接口
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-10
+ */
+public interface SystemLogMapper extends BaseMapper<SystemLog> {
+
+}

+ 16 - 0
mapper/src/main/java/com/kym/mapper/miniapp/AccountMapper.java

@@ -0,0 +1,16 @@
+package com.kym.mapper.miniapp;
+
+import com.kym.entity.miniapp.Account;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 用户账户表 Mapper 接口
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-26
+ */
+public interface AccountMapper extends BaseMapper<Account> {
+
+}

+ 16 - 0
mapper/src/main/java/com/kym/mapper/miniapp/CarsMapper.java

@@ -0,0 +1,16 @@
+package com.kym.mapper.miniapp;
+
+import com.kym.entity.miniapp.Cars;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 车辆表 Mapper 接口
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-26
+ */
+public interface CarsMapper extends BaseMapper<Cars> {
+
+}

+ 16 - 0
mapper/src/main/java/com/kym/mapper/miniapp/ChargeOrderMapper.java

@@ -0,0 +1,16 @@
+package com.kym.mapper.miniapp;
+
+import com.kym.entity.admin.ChargeOrder;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-06-27
+ */
+public interface ChargeOrderMapper extends BaseMapper<ChargeOrder> {
+
+}

+ 16 - 0
mapper/src/main/java/com/kym/mapper/miniapp/CollectMapper.java

@@ -0,0 +1,16 @@
+package com.kym.mapper.miniapp;
+
+import com.kym.entity.miniapp.Collect;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 收藏表 Mapper 接口
+ * </p>
+ *
+ * @author skyline
+ * @since 2023-07-27
+ */
+public interface CollectMapper extends BaseMapper<Collect> {
+
+}

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.