diff --git a/ebike-gateway/src/main/resources/application-dev.yml b/ebike-gateway/src/main/resources/application-dev.yml
index d4a7c92..0e1cfe1 100644
--- a/ebike-gateway/src/main/resources/application-dev.yml
+++ b/ebike-gateway/src/main/resources/application-dev.yml
@@ -40,6 +40,12 @@ spring:
- Path=/operations/**
filters:
- StripPrefix=1
+ - id: ebike-user
+ uri: lb://ebike-user
+ predicates:
+ - Path=/user/**
+ filters:
+ - StripPrefix=1
data:
# redis配置
diff --git a/ebike-operations/src/main/docker/Dockerfile b/ebike-operations/src/main/docker/Dockerfile
index 5caf8dd..f46d084 100644
--- a/ebike-operations/src/main/docker/Dockerfile
+++ b/ebike-operations/src/main/docker/Dockerfile
@@ -11,11 +11,11 @@ ADD ebike-operations-0.0.1-SNAPSHOT.jar /ebike-operations.jar
ENV JAVA_OPTS="-Xms512m -Xmx1024m"
# 暴露应用端口(与application.yml配置一致)
-EXPOSE 10012
+EXPOSE 10013
# 健康检查配置
HEALTHCHECK --interval=30s --timeout=3s \
- CMD curl -f http://localhost:10012/actuator/health || exit 1
+ CMD curl -f http://localhost:10013/actuator/health || exit 1
# 容器启动命令
ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar ebike-operations.jar"]
diff --git a/ebike-user/pom.xml b/ebike-user/pom.xml
new file mode 100644
index 0000000..4555a4f
--- /dev/null
+++ b/ebike-user/pom.xml
@@ -0,0 +1,192 @@
+
+
+ 4.0.0
+
+ com.cdzy
+ ebike-plus
+ 0.0.1-SNAPSHOT
+
+
+ ebike-user
+ 0.0.1-SNAPSHOT
+ ebike-user
+ ebike-user
+ jar
+
+
+ 17
+ ebike_plus
+
+
+
+
+
+ com.cdzy
+ ebike-common
+ 0.0.1-SNAPSHOT
+
+
+
+ com.cdzy
+ ebike-feign
+ 0.0.1-SNAPSHOT
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+
+ com.mybatis-flex
+ mybatis-flex-spring-boot3-starter
+ ${mybatis-flex.version}
+
+
+
+ com.mybatis-flex
+ mybatis-flex-processor
+ ${mybatis-flex.version}
+
+
+
+
+ io.minio
+ minio
+ ${minio.version}
+
+
+
+
+ org.postgresql
+ postgresql
+ 42.7.7
+
+
+
+
+ net.postgis
+ postgis-jdbc
+ 2025.1.0
+
+
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-alibaba-nacos-discovery
+ ${nacos.version}
+
+
+
+
+ cn.dev33
+ sa-token-spring-boot3-starter
+ ${satoken.version}
+
+
+
+
+ cn.dev33
+ sa-token-redis-jackson
+ ${satoken.version}
+
+
+
+
+ org.apache.commons
+ commons-pool2
+
+
+
+ org.projectlombok
+ lombok
+ ${org.projectlombok.version}
+
+
+
+ com.zaxxer
+ HikariCP
+ ${HikariCP.version}
+
+
+
+ cn.hutool
+ hutool-core
+ ${hutool.version}
+
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+
+
+
+
+
+ dev
+
+ dev
+
+ true
+
+
+
+
+
+
+ prod
+
+ prod
+
+
+
+
+ test
+
+ test
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${boot.version}
+
+
+
+ repackage
+
+
+
+
+
+ com.spotify
+ docker-maven-plugin
+ 1.2.2
+
+
+ http://192.168.2.226:2375
+ ${docker.image.prefix}/${project.artifactId}
+ src/main/docker
+
+
+ /
+ ${project.build.directory}
+ ${project.build.finalName}.jar
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ebike-user/src/main/docker/Dockerfile b/ebike-user/src/main/docker/Dockerfile
new file mode 100644
index 0000000..af2700e
--- /dev/null
+++ b/ebike-user/src/main/docker/Dockerfile
@@ -0,0 +1,21 @@
+
+# 使用官方Eclipse Temurin镜像作为基础镜像(JDK17兼容Spring Boot 3.x)
+FROM eclipse-temurin:17-jdk-jammy
+
+VOLUME /opt/docker-images
+
+ADD ebike-user-0.0.1-SNAPSHOT.jar /ebike-user.jar
+
+
+# 设置JVM参数(根据实际需求调整)
+ENV JAVA_OPTS="-Xms512m -Xmx1024m"
+
+# 暴露应用端口(与application.yml配置一致)
+EXPOSE 10014
+
+# 健康检查配置
+HEALTHCHECK --interval=30s --timeout=3s \
+ CMD curl -f http://localhost:10014/actuator/health || exit 1
+
+# 容器启动命令
+ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar ebike-user.jar"]
diff --git a/ebike-user/src/main/java/com/cdzy/user/EbikeUserApplication.java b/ebike-user/src/main/java/com/cdzy/user/EbikeUserApplication.java
new file mode 100644
index 0000000..82b0301
--- /dev/null
+++ b/ebike-user/src/main/java/com/cdzy/user/EbikeUserApplication.java
@@ -0,0 +1,13 @@
+package com.cdzy.user;
+
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class EbikeUserApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(EbikeUserApplication.class, args);
+ }
+}
\ No newline at end of file
diff --git a/ebike-user/src/main/java/com/cdzy/user/component/CustomHealthIndicator.java b/ebike-user/src/main/java/com/cdzy/user/component/CustomHealthIndicator.java
new file mode 100644
index 0000000..4eab05d
--- /dev/null
+++ b/ebike-user/src/main/java/com/cdzy/user/component/CustomHealthIndicator.java
@@ -0,0 +1,25 @@
+package com.cdzy.user.component;
+
+import org.springframework.boot.actuate.health.Health;
+import org.springframework.boot.actuate.health.HealthIndicator;
+import org.springframework.stereotype.Component;
+
+@Component
+public class CustomHealthIndicator implements HealthIndicator {
+
+ @Override
+ public Health health() {
+ // 内存使用情况检查逻辑
+ Runtime runtime = Runtime.getRuntime();
+ double usedMem = (runtime.totalMemory() - runtime.freeMemory()) / 1024.0 / 1024 / 1024;
+ double maxMem = runtime.maxMemory() / 1024.0 / 1024 / 1024;
+ double ratio = usedMem / maxMem * 100;
+
+ return Health.up()
+ .withDetail("memoryUsed(GB)", String.format("%.2f", usedMem))
+ .withDetail("memoryMax(GB)", String.format("%.2f", maxMem))
+ .withDetail("utilization", String.format("%.2f%%", ratio))
+ .build();
+// return Health.up().withDetail("service", "available").build();
+ }
+}
diff --git a/ebike-user/src/main/java/com/cdzy/user/component/MyTenantFactory.java b/ebike-user/src/main/java/com/cdzy/user/component/MyTenantFactory.java
new file mode 100644
index 0000000..8068b85
--- /dev/null
+++ b/ebike-user/src/main/java/com/cdzy/user/component/MyTenantFactory.java
@@ -0,0 +1,21 @@
+package com.cdzy.user.component;
+
+import cn.dev33.satoken.stp.StpUtil;
+import com.mybatisflex.core.tenant.TenantFactory;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+
+public class MyTenantFactory implements TenantFactory {
+
+ public Object[] getTenantIds() {
+ if (StpUtil.isLogin()) {
+ RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
+ Object attribute = attributes.getAttribute("tenantId", RequestAttributes.SCOPE_REQUEST);
+ if (attribute != null) {
+ Long tenantId = Long.valueOf(attribute.toString());
+ return new Object[]{tenantId};
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/ebike-user/src/main/java/com/cdzy/user/component/TenantInterceptor.java b/ebike-user/src/main/java/com/cdzy/user/component/TenantInterceptor.java
new file mode 100644
index 0000000..90e6350
--- /dev/null
+++ b/ebike-user/src/main/java/com/cdzy/user/component/TenantInterceptor.java
@@ -0,0 +1,43 @@
+package com.cdzy.user.component;
+
+import cn.dev33.satoken.stp.StpUtil;
+import com.cdzy.common.model.response.CommonStaffInfo;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import java.util.TimeZone;
+
+
+public class TenantInterceptor implements HandlerInterceptor {
+
+ @Override
+ public boolean preHandle(@NotNull HttpServletRequest request
+ , @NotNull HttpServletResponse response, @NotNull Object handler) {
+
+ boolean login = StpUtil.isLogin();
+ if (login) {
+ Long tenantId = getTenantIdByReuqest(request);
+ request.setAttribute("tenantId", tenantId);
+ return true;
+ }
+ return true;
+ }
+
+ Long getTenantIdByReuqest(HttpServletRequest request) {
+ String token = request.getHeader("Authorization");
+ String id = (String) StpUtil.getLoginIdByToken(token);
+ Object object = StpUtil.getSessionByLoginId(id).get(id);
+ ObjectMapper objectMapper = new ObjectMapper()
+ .registerModule(new JavaTimeModule())
+ .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
+ .setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+ CommonStaffInfo staffInfo = objectMapper.convertValue(object, CommonStaffInfo.class);
+ return staffInfo.getOperatorId();
+ }
+
+}
\ No newline at end of file
diff --git a/ebike-user/src/main/java/com/cdzy/user/config/GlobalExceptionHandler.java b/ebike-user/src/main/java/com/cdzy/user/config/GlobalExceptionHandler.java
new file mode 100644
index 0000000..46dd40b
--- /dev/null
+++ b/ebike-user/src/main/java/com/cdzy/user/config/GlobalExceptionHandler.java
@@ -0,0 +1,121 @@
+package com.cdzy.user.config;
+
+import cn.dev33.satoken.exception.NotLoginException;
+import com.alibaba.nacos.shaded.com.google.gson.JsonSyntaxException;
+import com.cdzy.common.model.response.JsonResult;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.validation.ConstraintViolationException;
+import jakarta.validation.UnexpectedTypeException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.converter.HttpMessageConversionException;
+import org.springframework.http.converter.HttpMessageNotReadableException;
+import org.springframework.jdbc.BadSqlGrammarException;
+import org.springframework.validation.BindException;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import java.sql.SQLSyntaxErrorException;
+
+/**
+ * 全局异常处理
+ * @author attiya
+ * @since 2023-6-14
+ *
+ */
+@RestControllerAdvice(annotations = RestController.class)
+@Slf4j
+public class GlobalExceptionHandler {
+
+ @ExceptionHandler(NotLoginException.class)
+ public JsonResult> bindExceptionHandler(NotLoginException e) {
+ log.error(e.toString());
+ return JsonResult.failed(e.getMessage());
+ }
+
+ @ExceptionHandler(BindException.class)
+ public JsonResult> bindExceptionHandler(BindException e) {
+ log.error(e.toString());
+ return JsonResult.failed(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
+ }
+
+ @ExceptionHandler(MethodArgumentNotValidException.class)
+ public JsonResult> bindExceptionHandler(MethodArgumentNotValidException e) {
+ log.error(e.toString());
+ String message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
+ return JsonResult.failed(message);
+ }
+
+ @ResponseBody
+ @ExceptionHandler
+ public JsonResult> exp(HttpServletRequest request, JsonSyntaxException e) {
+ log.error(request.getServletPath(), e);
+ return JsonResult.failed("数据格式化错误");
+ }
+
+ @ResponseBody
+ @ExceptionHandler
+ public JsonResult> exp(HttpServletRequest request, SQLSyntaxErrorException e) {
+// LogFactory.getLog(super.getClass()).error(e.getMessage(), e);
+ log.error(request.getServletPath(), e);
+ return JsonResult.failed("系统错误");
+ }
+
+ @ResponseBody
+ @ExceptionHandler
+ public JsonResult> exp(HttpServletRequest request, BadSqlGrammarException e) {
+// LogFactory.getLog(super.getClass()).error(e.getMessage(), e);
+ log.error(request.getServletPath(), e);
+ return JsonResult.failed("系统错误");
+ }
+
+ @ResponseBody
+ @ExceptionHandler
+ public JsonResult> exp(HttpServletRequest request, NumberFormatException e) {
+// LogFactory.getLog(super.getClass()).error(e.getMessage(), e);
+ log.error(request.getServletPath(), e);
+ return JsonResult.failed(e.getMessage());
+ }
+
+ @ResponseBody
+ @ExceptionHandler
+ public JsonResult> exp(HttpServletRequest request, HttpMessageNotReadableException e) {
+ log.error(request.getServletPath(), e);
+ return JsonResult.failed("请输入指定格式的参数");
+ }
+
+ @ResponseBody
+ @ExceptionHandler
+ public JsonResult> exp(HttpServletRequest request, UnexpectedTypeException e) {
+// e.printStackTrace();
+ log.error(request.getServletPath());
+ return JsonResult.failed(e.getMessage());
+ }
+
+ @ExceptionHandler({ConstraintViolationException.class})
+ @ResponseBody
+ public JsonResult> handleMethodArgumentNotValidException(HttpServletRequest request, ConstraintViolationException e) {
+// e.printStackTrace();
+ log.error(request.getServletPath(), e);
+ String[] msgs = e.getMessage().split(":");
+ return JsonResult.failed(msgs[msgs.length - 1].trim());
+ }
+
+ @ResponseBody
+ @ExceptionHandler
+ public JsonResult> exp(HttpServletRequest request, HttpMessageConversionException e) {
+ log.error(request.getServletPath(), e);
+ return JsonResult.failed(e.getMessage());
+ }
+
+ @ResponseBody
+ @ExceptionHandler
+ public JsonResult> exp(HttpServletRequest request, Exception e) {
+// LogFactory.getLog(super.getClass()).error(e.getMessage(), e);
+ log.error(request.getServletPath(), e);
+ return JsonResult.failed(e.getMessage());
+ }
+
+}
diff --git a/ebike-user/src/main/java/com/cdzy/user/config/JacksonConfig.java b/ebike-user/src/main/java/com/cdzy/user/config/JacksonConfig.java
new file mode 100644
index 0000000..8a22396
--- /dev/null
+++ b/ebike-user/src/main/java/com/cdzy/user/config/JacksonConfig.java
@@ -0,0 +1,55 @@
+package com.cdzy.user.config;
+
+import cn.hutool.core.date.DatePattern;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.util.Locale;
+import java.util.TimeZone;
+
+/**
+ * 日期类型数据处理配置
+ * @author attiya
+ * @since 2024-11-04
+ **/
+@Configuration
+public class JacksonConfig {
+
+ public static JavaTimeModule buildJavaTimeModule() {
+ JavaTimeModule javaTimeModule = new JavaTimeModule();
+ javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DatePattern.NORM_TIME_FORMATTER));
+ javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DatePattern.NORM_DATE_FORMATTER));
+ javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DatePattern.NORM_DATETIME_FORMATTER));
+
+ javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DatePattern.NORM_TIME_FORMATTER));
+ javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DatePattern.NORM_DATE_FORMATTER));
+ javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DatePattern.NORM_DATETIME_FORMATTER));
+ return javaTimeModule;
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public Jackson2ObjectMapperBuilderCustomizer customizer() {
+ return builder -> {
+ builder.locale(Locale.CHINA);
+ builder.timeZone(TimeZone.getTimeZone(ZoneId.systemDefault()));
+ builder.simpleDateFormat(DatePattern.NORM_DATETIME_PATTERN);
+ builder.serializerByType(Long.class, ToStringSerializer.instance);
+ builder.modules(buildJavaTimeModule());
+ };
+ }
+}
\ No newline at end of file
diff --git a/ebike-user/src/main/java/com/cdzy/user/config/MyBatisFlexConfiguration.java b/ebike-user/src/main/java/com/cdzy/user/config/MyBatisFlexConfiguration.java
new file mode 100644
index 0000000..83dcf14
--- /dev/null
+++ b/ebike-user/src/main/java/com/cdzy/user/config/MyBatisFlexConfiguration.java
@@ -0,0 +1,41 @@
+package com.cdzy.user.config;
+
+import com.mybatisflex.annotation.KeyType;
+import com.mybatisflex.core.FlexGlobalConfig;
+import com.mybatisflex.core.audit.AuditManager;
+import com.mybatisflex.core.dialect.DbType;
+import com.mybatisflex.core.dialect.DialectFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author attiya
+ */
+@Configuration
+public class MyBatisFlexConfiguration {
+
+ private static final Logger logger = LoggerFactory
+ .getLogger("mybatis-flex-sql:");
+
+
+ public MyBatisFlexConfiguration() {
+ //开启审计功能
+ AuditManager.setAuditEnable(true);
+
+ //设置 SQL 审计收集器
+ AuditManager.setMessageCollector(auditMessage ->
+ logger.info("{},{}ms", auditMessage.getFullSql()
+ , auditMessage.getElapsedTime())
+ );
+
+ //全局ID生成策略配置
+ FlexGlobalConfig.KeyConfig keyConfig = new FlexGlobalConfig.KeyConfig();
+ keyConfig.setKeyType(KeyType.Generator);
+ keyConfig.setValue("snowFlakeId");
+ keyConfig.setBefore(true);
+ FlexGlobalConfig.getDefaultConfig().setKeyConfig(keyConfig);
+
+ DialectFactory.registerDialect(DbType.MYSQL,new PermissionDialect());
+ }
+}
\ No newline at end of file
diff --git a/ebike-user/src/main/java/com/cdzy/user/config/PermissionDialect.java b/ebike-user/src/main/java/com/cdzy/user/config/PermissionDialect.java
new file mode 100644
index 0000000..bf9527b
--- /dev/null
+++ b/ebike-user/src/main/java/com/cdzy/user/config/PermissionDialect.java
@@ -0,0 +1,24 @@
+package com.cdzy.user.config;
+
+import com.mybatisflex.core.dialect.impl.CommonsDialectImpl;
+import com.mybatisflex.core.query.CPI;
+import com.mybatisflex.core.query.QueryTable;
+import com.mybatisflex.core.query.QueryWrapper;
+
+import java.util.List;
+
+/**
+ * @author attiya
+ * @since 2025-03-14
+ */
+public class PermissionDialect extends CommonsDialectImpl {
+
+ @Override
+ public String forSelectByQuery(QueryWrapper queryWrapper) {
+
+ //用于严重table是否需要添加数据权限查询条件
+ List tables = CPI.getQueryTables(queryWrapper);
+ //获取当前用户信息,为 queryWrapper 添加额外的条件
+ return super.buildSelectSql(queryWrapper);
+ }
+}
diff --git a/ebike-user/src/main/java/com/cdzy/user/config/WebConfig.java b/ebike-user/src/main/java/com/cdzy/user/config/WebConfig.java
new file mode 100644
index 0000000..9dc0ecf
--- /dev/null
+++ b/ebike-user/src/main/java/com/cdzy/user/config/WebConfig.java
@@ -0,0 +1,23 @@
+package com.cdzy.user.config;
+
+import com.cdzy.user.component.MyTenantFactory;
+import com.cdzy.user.component.TenantInterceptor;
+import com.mybatisflex.core.tenant.TenantFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class WebConfig implements WebMvcConfigurer {
+
+ @Bean
+ public TenantFactory tenantFactory(){
+ return new MyTenantFactory();
+ }
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(new TenantInterceptor());
+ }
+}
\ No newline at end of file
diff --git a/ebike-user/src/main/resources/application-dev.yml b/ebike-user/src/main/resources/application-dev.yml
new file mode 100644
index 0000000..33c1212
--- /dev/null
+++ b/ebike-user/src/main/resources/application-dev.yml
@@ -0,0 +1,90 @@
+server:
+ port: 10014
+spring:
+ application:
+ name: ebike-user
+ cloud:
+ nacos:
+ server-addr: 127.0.0.1:8848 # nacos
+ username: nacos
+ password: nacos
+ sql:
+ init:
+ platform: postgis
+ mode: never
+ schema-locations: classpath:db/init.sql
+ data-locations: classpath:db/data.sql
+ jackson:
+ serialization:
+ write-dates-as-timestamps: false
+ date-format: yyyy-MM-dd HH:mm:ss
+ time-zone: GMT+8
+ datasource:
+ url: jdbc:postgresql://47.109.71.130:5432/ebike_user?currentSchema=public&stringtype=unspecified
+ username: root
+ password: 970529
+ driver-class-name: org.postgresql.Driver
+ hikari:
+ ## 最小空闲连接数量
+ minimum-idle: 5
+ ## 空闲连接存活最大时间,默认600000(10分钟)
+ idle-timeout: 180000
+ ## 连接池最大连接数,默认是10
+ maximum-pool-size: 10
+ ## 数据库连接超时时间,默认30秒,即30000
+ connection-timeout: 30000
+ connection-test-query: SELECT 1
+ ##此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
+ max-lifetime: 1800000
+ data:
+ # redis配置
+ redis:
+ # Redis数据库索引(默认为0)
+ database: 1
+ # Redis服务器地址
+ host: 192.168.2.226
+ # Redis服务器连接端口
+ port: 6379
+ # Redis服务器连接密码(默认为空)
+ # password:
+ # 连接超时时间
+ lettuce:
+ pool:
+ # 连接池最大连接数
+ max-active: 200
+ # 连接池最大阻塞等待时间(使用负值表示没有限制)
+ max-wait: -1ms
+ # 连接池中的最大空闲连接
+ max-idle: 10
+ # 连接池中的最小空闲连接
+ min-idle: 0
+
+mybatis-flex:
+ mapper-locations: classpath:mapper/*.xml
+############## Sa-Token 配置 (文档: https://sa-token.cc) ##############
+sa-token:
+ # token 名称(同时也是 cookie 名称)
+ token-name: Authorization
+ # token 有效期(单位:秒) 默认30天,-1 代表永久有效
+ timeout: 2592000
+ # 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: random-32
+ # 是否输出操作日志
+ is-log: true
+
+management:
+ endpoints:
+ web:
+ exposure:
+ include: health,info
+ endpoint:
+ health:
+ show-details: always
+
+
diff --git a/ebike-user/src/main/resources/application-prod.yml b/ebike-user/src/main/resources/application-prod.yml
new file mode 100644
index 0000000..473a0f4
diff --git a/ebike-user/src/main/resources/application-test.yml b/ebike-user/src/main/resources/application-test.yml
new file mode 100644
index 0000000..473a0f4
diff --git a/ebike-user/src/main/resources/application.yml b/ebike-user/src/main/resources/application.yml
new file mode 100644
index 0000000..030c324
--- /dev/null
+++ b/ebike-user/src/main/resources/application.yml
@@ -0,0 +1,3 @@
+spring:
+ profiles:
+ active: @profile.active@
\ No newline at end of file
diff --git a/ebike-user/src/main/resources/db/data.sql b/ebike-user/src/main/resources/db/data.sql
new file mode 100644
index 0000000..473a0f4
diff --git a/ebike-user/src/main/resources/db/init.sql b/ebike-user/src/main/resources/db/init.sql
new file mode 100644
index 0000000..473a0f4
diff --git a/pom.xml b/pom.xml
index a62ab24..fe4f08a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -18,6 +18,7 @@
ebike-gather
ebike-staff
ebike-operations
+ ebike-user