feat:修复已知问题,提升系统稳定性

This commit is contained in:
njydsz
2024-09-25 11:38:06 +08:00
parent bbed2aadbc
commit 8d094e48ac
493 changed files with 5108 additions and 22521 deletions

View File

@@ -2,90 +2,228 @@
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo</artifactId>
<name>remi-demo</name>
<packaging>pom</packaging>
<description>瑞米平台-快速开发服务</description>
<parent>
<groupId>ai.remi.top.cloud</groupId>
<artifactId>remi-cloud</artifactId>
<version>3.1.1</version>
<version>3.1.0</version>
</parent>
<properties>
<!--jdk-->
<java.version>17</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<!--UFT-->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<!-- 打包上传到私服, 需要和配置文件中的server节点配合使用 -->
<distributionManagement>
<repository>
<id>maven-releases</id>
<name>release</name>
<url>https://repository.njydsz.com/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>maven-snapshots</id>
<name>snapshot</name>
<url>https://repository.njydsz.com/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<modules>
<module>remi-demo-domain</module>
<module>remi-demo-infra</module>
<module>remi-demo-server</module>
<module>remi-demo-job</module>
<module>remi-demo-app</module>
<module>remi-demo-web</module>
<module>remi-demo-api</module>
<module>remi-demo-web</module>
</modules>
<dependencyManagement>
<dependencies>
<!-- SpringBoot 依赖配置 -->
<dependency>
<artifactId>spring-boot-dependencies</artifactId>
<groupId>org.springframework.boot</groupId>
<scope>import</scope>
<type>pom</type>
<version>${spring-boot.version}</version>
</dependency>
<!-- SpringCloud 微服务 -->
<dependency>
<artifactId>spring-cloud-dependencies</artifactId>
<groupId>org.springframework.cloud</groupId>
<scope>import</scope>
<type>pom</type>
<version>${spring-cloud.version}</version>
</dependency>
<!-- SpringCloud Alibaba 微服务 -->
<dependency>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<groupId>com.alibaba.cloud</groupId>
<scope>import</scope>
<type>pom</type>
<version>${spring-cloud-alibaba.version}</version>
</dependency>
<!--内部服务依赖开始-->
<!--remi-comm-->
<dependency>
<artifactId>remi-comm</artifactId>
<groupId>ai.remi.top.comm</groupId>
<version>${remi-comm.version}</version>
</dependency>
<dependency>
<artifactId>remi-comm-core</artifactId>
<groupId>ai.remi.top.comm</groupId>
<version>${remi-comm.version}</version>
</dependency>
<dependency>
<artifactId>remi-comm-redis</artifactId>
<groupId>ai.remi.top.comm</groupId>
<version>${remi-comm.version}</version>
</dependency>
<dependency>
<artifactId>remi-comm-jdbc</artifactId>
<groupId>ai.remi.top.comm</groupId>
<version>${remi-comm.version}</version>
</dependency>
<dependency>
<artifactId>remi-comm-domain</artifactId>
<groupId>ai.remi.top.comm</groupId>
<version>${remi-comm.version}</version>
</dependency>
<dependency>
<artifactId>remi-comm-exception</artifactId>
<groupId>ai.remi.top.comm</groupId>
<version>${remi-comm.version}</version>
</dependency>
<dependency>
<artifactId>remi-comm-feign</artifactId>
<groupId>ai.remi.top.comm</groupId>
<version>${remi-comm.version}</version>
</dependency>
<dependency>
<artifactId>remi-comm-job</artifactId>
<groupId>ai.remi.top.comm</groupId>
<version>${remi-comm.version}</version>
</dependency>
<dependency>
<artifactId>remi-comm-log</artifactId>
<groupId>ai.remi.top.comm</groupId>
<version>${remi-comm.version}</version>
</dependency>
<dependency>
<artifactId>remi-comm-swagger</artifactId>
<groupId>ai.remi.top.comm</groupId>
<version>${remi-comm.version}</version>
</dependency>
<dependency>
<artifactId>remi-comm-thread</artifactId>
<groupId>ai.remi.top.comm</groupId>
<version>${remi-comm.version}</version>
</dependency>
<dependency>
<artifactId>remi-comm-util</artifactId>
<groupId>ai.remi.top.comm</groupId>
<version>${remi-comm.version}</version>
</dependency>
<dependency>
<artifactId>remi-comm-auth</artifactId>
<groupId>ai.remi.top.comm</groupId>
<version>${remi-comm.version}</version>
</dependency>
<dependency>
<artifactId>remi-comm-safe</artifactId>
<groupId>ai.remi.top.comm</groupId>
<version>${remi-comm.version}</version>
</dependency>
<dependency>
<artifactId>remi-comm-web</artifactId>
<groupId>ai.remi.top.comm</groupId>
<version>${remi-comm.version}</version>
</dependency>
<!--remi-demo-->
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo</artifactId>
<version>${remi.version}</version>
<version>${remi-demo.version}</version>
</dependency>
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo-domain</artifactId>
<version>${remi.version}</version>
<version>${remi-demo.version}</version>
</dependency>
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo-infra</artifactId>
<version>${remi.version}</version>
<version>${remi-demo.version}</version>
</dependency>
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo-server</artifactId>
<version>${remi.version}</version>
<version>${remi-demo.version}</version>
</dependency>
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo-job</artifactId>
<version>${remi.version}</version>
<version>${remi-demo.version}</version>
</dependency>
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo-api</artifactId>
<version>${remi.version}</version>
<version>${remi-demo.version}</version>
</dependency>
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo-app</artifactId>
<version>${remi.version}</version>
<version>${remi-demo.version}</version>
</dependency>
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo-web</artifactId>
<version>${remi.version}</version>
<version>${remi-demo.version}</version>
</dependency>
<!--内部服务依赖结束-->
</dependencies>
</dependencyManagement>
<!-- 打包上传到私服, 需要和配置文件中的server节点配合使用 -->
<distributionManagement>
<repository>
<id>maven-releases</id>
<name>release</name>
<url>https://remi.njydsz.com/repository/remi-top-releases/</url>
</repository>
<snapshotRepository>
<id>maven-snapshots</id>
<name>snapshot</name>
<url>https://remi.njydsz.com/repository/remi-top-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<repositories>
<repository>
<id>public</id>
<name>remi nexus</name>
<url>https://remi.njydsz.com/repository/remi-top</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<name>remi nexus</name>
<url>https://remi.njydsz.com/repository/remi-top</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>

View File

@@ -7,34 +7,20 @@
<description>remi-demo-api</description>
<parent>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo</artifactId>
<version>3.1.1</version>
<version>3.1.0</version>
</parent>
<!-- 打包上传到私服, 需要和配置文件中的server节点配合使用 -->
<distributionManagement>
<repository>
<id>maven-releases</id>
<name>release</name>
<url>https://repository.njydsz.com/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>maven-snapshots</id>
<name>snapshot</name>
<url>https://repository.njydsz.com/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<dependencies>
<!--remi-comm-feign-->
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.comm</groupId>
<artifactId>remi-comm-feign</artifactId>
</dependency>
<!--remi-demo-domain-->
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo-domain</artifactId>
</dependency>
<!--servlet-api-->

View File

@@ -0,0 +1,29 @@
package ai.remi.boot.api.client;
import ai.remi.comm.core.result.ResultBean;
import ai.remi.comm.feign.aspect.FeignAutoConfiguration;
import ai.remi.boot.api.factory.IamClientFactory;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@FeignClient(value = "remi-boot-web", configuration = FeignAutoConfiguration.class, fallbackFactory = IamClientFactory.class)
public interface IamClientApi {
@Operation(summary = "保存日志")
@PostMapping("/logRecord/add")
ResultBean<Boolean> addLogRecord(@RequestBody @Validated LogRecordPostDTO logRecordDTO);
@Operation(summary = "查询用户全局配置")
@PostMapping(value = "/config/getUserConfigs")
ResultBean<List<ConfigVO>> getUserConfigs();
@Operation(summary = "查询应用全局配置")
@PostMapping(value = "/config/getAppConfigs")
ResultBean<List<ConfigVO>> getAppConfigs(@RequestParam("appId") String appId, @RequestParam("confType") Integer confType);
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.api.factory;
import ai.remi.boot.api.client.IamClientApi;
import ai.remi.boot.api.fallback.IamClientFallback;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
@Component
public class IamClientFactory implements FallbackFactory<IamClientApi> {
@Override
public IamClientApi create(Throwable cause) {
IamClientFallback fallback = new IamClientFallback();
fallback.setCause(cause);
return fallback;
}
}

View File

@@ -0,0 +1,33 @@
package ai.remi.boot.api.fallback;
import ai.remi.comm.core.result.ResultBean;
import ai.remi.boot.api.client.IamClientApi;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
@Slf4j
public class IamClientFallback implements IamClientApi {
@Setter
private Throwable cause;
@Override
public ResultBean<Boolean> addLogRecord(LogRecordPostDTO logRecordDTO) {
log.error("addLogRecord = {}", cause.getMessage());
return null;
}
@Override
public ResultBean<List<ConfigVO>> getUserConfigs() {
log.error("getUserConfigs = {}", cause.getMessage());
return null;
}
@Override
public ResultBean<List<ConfigVO>> getAppConfigs(String appId, Integer confType) {
log.error("getAppConfigs = {}", cause.getMessage());
return null;
}
}

View File

@@ -1,14 +0,0 @@
package ai.remi.demo.api.client;
import ai.remi.demo.api.factory.FeignClientFactory;
import ai.remi.comm.feign.aspect.FeignAutoConfiguration;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(value = "remi-demo-web", configuration = FeignAutoConfiguration.class, fallbackFactory = FeignClientFactory.class)
public interface FeignClientApi {
@GetMapping("/books/findByBooksId")
String findById(@RequestParam("booksId") int booksId);
}

View File

@@ -1,18 +0,0 @@
package ai.remi.demo.api.factory;
import ai.remi.demo.api.client.FeignClientApi;
import ai.remi.demo.api.fallback.FeignClientFallback;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
@Component
public class FeignClientFactory implements FallbackFactory<FeignClientApi> {
@Override
public FeignClientApi create(Throwable cause) {
FeignClientFallback fallback = new FeignClientFallback();
fallback.setCause(cause);
return fallback;
}
}

View File

@@ -1,17 +0,0 @@
package ai.remi.demo.api.fallback;
import ai.remi.demo.api.client.FeignClientApi;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class FeignClientFallback implements FeignClientApi {
@Setter
private Throwable cause;
@Override
public String findById(int goodsId) {
log.error("findById = {}", cause.getMessage());
return null;
}
}

View File

@@ -7,25 +7,11 @@
<description>remi-demo-app</description>
<parent>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo</artifactId>
<version>3.1.1</version>
<version>3.1.0</version>
</parent>
<!-- 打包上传到私服, 需要和配置文件中的server节点配合使用 -->
<distributionManagement>
<repository>
<id>maven-releases</id>
<name>release</name>
<url>https://repository.njydsz.com/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>maven-snapshots</id>
<name>snapshot</name>
<url>https://repository.njydsz.com/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<dependencies>
<!--spring-boot-->
<dependency>
@@ -71,22 +57,29 @@
<!--remi-comm-feign-->
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.comm</groupId>
<artifactId>remi-comm-feign</artifactId>
</dependency>
<!--remi-demo-job-->
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<artifactId>remi-demo-job</artifactId>
</dependency>
<!--引入内部模块-->
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo-job</artifactId>
</dependency>
<dependency>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo-server</artifactId>
</dependency>
<!--slf4j-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
</dependency>
</dependencies>
<build>

View File

@@ -1,4 +1,4 @@
package ai.remi.demo.app;
package ai.remi.boot.app;
import ai.remi.comm.feign.annotation.EnableRemiFeignClients;
import org.springframework.boot.SpringApplication;
@@ -8,7 +8,7 @@ import org.springframework.context.annotation.EnableMBeanExport;
import org.springframework.jmx.support.RegistrationPolicy;
import org.springframework.transaction.annotation.EnableTransactionManagement;
//@Enableremitem
//@Enablestartdistem
//@EnableLogRecord
@EnableDiscoveryClient
@EnableRemiFeignClients
@@ -22,7 +22,7 @@ public class Application {
SpringApplication.run(Application.class, args);
System.out.println("(♥◠‿◠)ノ゙ Remi Cloud App 启动成功 ლ(´ڡ`ლ)゙ ");
System.out.println("(♥◠‿◠)ノ゙ Remi IAM App 启动成功 ლ(´ڡ`ლ)゙ ");
}

View File

@@ -1,12 +1,12 @@
# 服务端口号
server:
port: 8081
port: 12801
spring:
application:
name: remi-bpm-web
name: remi-boot-app
profiles:
active: dev
active: local
cloud:
# nacos
nacos:
@@ -15,9 +15,9 @@ spring:
password: nacos
discovery:
# 配置中心的地址
server-addr: ${NACOS_HOST:192.168.31.18}:${NACOS_PORT:8848}
server-addr: ${NACOS_HOST:192.168.1.31}:${NACOS_PORT:8848}
#命名空间
namespace: ${SERVICE_NAME_SPACE_NAME:dev}
namespace: ${spring.profiles.active:dev}
# 配置文件的环境
group: ${SERVICE_DISCOVERY_GROUP_NAME:dev}
# 配置中心
@@ -39,7 +39,7 @@ spring:
# 共享配置
shared-configs:
# Data Id 的默认完整格式为: ${prefix}-${spring.profile.active}.${file-extension}。
- dataId: remi-cloud-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
- dataId: application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
group: ${spring.cloud.nacos.discovery.group}
#是否自动刷新
refresh: true
refresh: true

View File

@@ -10,15 +10,15 @@ VOLUME /temp
#ADD 将app.jar文件将拷贝到容器中,默认拷贝到根路径下
#也可以直接写成ADD app.jar /app.jar 或者 ADD app.jar /
ADD remi-demo-app-3.1.1.jar remi-demo-app.jar
ADD startdistem-web-1.0.0.jar startdistem-web.jar
#修改app.jar这个文件的访问时间和修改时间为当前时间,而不会修改文件的内容。
RUN bash -c "touch /remi-demo-app.jar"
RUN bash -c "touch /startdistem-web.jar"
#ENTRYPOINT 应用启动命令 参数设定
#由于tomcat的session id的生成主要通过java.security.SecureRandom生成随机数来实现,导致启动过程很慢
#通过-Djava.security.egd=file:/dev/./urandom参数可以加快随机数产生过程
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/remi-demo-app.jar"]
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/startdistem-web.jar"]
#EXPOSE 容器暴露端口
EXPOSE 8081
EXPOSE 18080

View File

@@ -1,5 +1,5 @@
```shell
sh ./docker_deploy.sh
docker logs -f remi-demo-app
docker logs -f startdistem-web
```

View File

@@ -1,7 +1,7 @@
docker stop remi-demo-app
docker rm -f remi-demo-app
docker rmi remi-demo-app
docker build -t remi-demo-app .
docker stop startdistem-web
docker rm -f startdistem-web
docker rmi startdistem-web
docker build -t startdistem-web .
docker images
docker run --restart=always -t -dit -p 8081:8081 -e TZ="Asia/Shanghai" --name remi-demo-app remi-demo-app
docker run --restart=always -t -dit -p 18080:18080 -e TZ="Asia/Shanghai" --name startdistem-web startdistem-web
docker ps

View File

@@ -1,152 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为INFO,则低于INFO级别的信息都不会输出 -->
<!-- scan:默认值为true,当此属性设置为true时,配置文件如果发生改变,将会被重新加载 -->
<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:默认值为false。当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。 -->
<contextName>logback</contextName>
<!--application.yml 传递参数,不能使用logback 自带的<property>标签 -->
<springProperty scope="context" name="logDir" source="logback.logDir"/>
<springProperty scope="context" name="appName" source="spring.application.name"/>
<springProperty scope="context" name="logDir" source="logback.logDir"/>
<springProperty scope="context" name="fileType" source="logback.fileType"/>
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex"
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx"
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!--输出到控制台-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
<!-- 控制台日志输出格式 -->
<!-- 日期 [线程] [class类]-[日志级别] log内容 -->
<property name="LOG_PATTERN_CONSOLE" value="%blue(%d{yyyy-MM-dd HH:mm:ss,SSS}) [%cyan(%t)] [%yellow(%c)]-[%highlight(%p)], %m%n" />
<!-- 文件日志输出格式 -->
<property name="LOG_PATTERN_FILE" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} --> %msg%n" />
<!--- 设置控制台日志 -->
<appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<charset>UTF-8</charset>
<pattern>${LOG_PATTERN_CONSOLE}</pattern>
</encoder>
</appender>
<!-- debug日志输出文件 -->
<appender name="debug_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logDir}/debug.log</file>
<!-- 设置日志文件 -->
<appender name="fileLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${LOG_PATTERN_FILE}</pattern>
</encoder>
<!-- 总文件日志 -->
<file>${logDir}/${appName}.${fileType}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天对日志归档 -->
<fileNamePattern>${logDir}/%d{yyyy-MM-dd}/debug-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
<!-- 每天的文件日志 -->
<fileNamePattern>${logDir}/${appName}-%d{yyyy-MM-dd}.${fileType}</fileNamePattern>
<!-- 日志文件保存7天,超过7天的自动删除 -->
<maxHistory>30</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>500MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger [%file : %line] - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- info日志输出文件 -->
<appender name="info_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logDir}/info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天对日志归档 -->
<fileNamePattern>${logDir}/%d{yyyy-MM-dd}/info-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
<maxHistory>30</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>500MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger [%file : %line] - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- warn日志输出文件 -->
<appender name="warn_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logDir}/warn.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天对日志归档 -->
<fileNamePattern>${logDir}/%d{yyyy-MM-dd}/warn-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
<maxHistory>30</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>500MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger [%file : %line] - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- error日志输出文件 -->
<appender name="error_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logDir}/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天对日志归档 -->
<fileNamePattern>${logDir}/%d{yyyy-MM-dd}/error-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
<maxHistory>30</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>500MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger [%file : %line] - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!--全量日志-->
<appender name="detail_file" class="ch.qos.logback.core.rolling.RollingFileAppender" additivity="false">
<File>${logDir}/${appName}.log</File>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger [%file : %line] - %msg%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${logDir}/%d{yyyy-MM-dd}/${appName}-%d{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
</appender>
<!--开发环境:打印控制台-->
<springProfile name="dev">
<logger name="ai.remi" level="debug"/>
</springProfile>
<springProfile name="!dev">
<logger name="ai.remi" level="info"/>
</springProfile>
<!-- Level: FATAL 0 ERROR 3 WARN 4 INFO 6 DEBUG 7 -->
<root>
<level value="info"/>
<appender-ref ref="console"/>
<appender-ref ref="debug_file"/>
<appender-ref ref="info_file"/>
<appender-ref ref="warn_file"/>
<appender-ref ref="error_file"/>
<appender-ref ref="detail_file"/>
<!-- 设置日志级别,及需要记录日志的类 -->
<root level="INFO">
<appender-ref ref="consoleLog" />
<appender-ref ref="fileLog" />
</root>
</configuration>

View File

@@ -7,34 +7,20 @@
<description>remi-demo-domain</description>
<parent>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo</artifactId>
<version>3.1.1</version>
<version>3.1.0</version>
</parent>
<!-- 打包上传到私服, 需要和配置文件中的server节点配合使用 -->
<distributionManagement>
<repository>
<id>maven-releases</id>
<name>release</name>
<url>https://repository.njydsz.com/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>maven-snapshots</id>
<name>snapshot</name>
<url>https://repository.njydsz.com/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<dependencies>
<!--remi-comm-domain-->
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.comm</groupId>
<artifactId>remi-comm-domain</artifactId>
</dependency>
<!--remi-comm-swagger-->
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.comm</groupId>
<artifactId>remi-comm-swagger</artifactId>
</dependency>
<!-- Lombok -->

View File

@@ -1,4 +1,4 @@
package ai.remi.demo.domain.constant;
package ai.remi.boot.domain.constant;
/**
* 单点登录基础常量

View File

@@ -0,0 +1,56 @@
package ai.remi.boot.domain.converter;
import ai.remi.boot.domain.dto.post.UserPostDTO;
import ai.remi.boot.domain.dto.put.UserPutDTO;
import ai.remi.boot.domain.entity.User;
import ai.remi.boot.domain.query.UserQuery;
import ai.remi.boot.domain.vo.UserVO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 用户表 UserConverter转换接口
*/
@Mapper
public interface UserConverter {
UserConverter INSTANT = Mappers.getMapper(UserConverter.class);
@Mapping(target = "id", ignore = true)
@Mapping(target = "deleted", ignore = true)
@Mapping(target = "revision", ignore = true)
@Mapping(target = "deptTenantId", ignore = true)
@Mapping(target = "companyTenantId", ignore = true)
@Mapping(target = "createdBy", ignore = true)
@Mapping(target = "createdAt", ignore = true)
@Mapping(target = "updatedBy", ignore = true)
@Mapping(target = "updatedAt", ignore = true)
User postDtoToEntity(UserPostDTO userDTO);
@Mapping(target = "deleted", ignore = true)
@Mapping(target = "revision", ignore = true)
@Mapping(target = "deptTenantId", ignore = true)
@Mapping(target = "companyTenantId", ignore = true)
@Mapping(target = "createdBy", ignore = true)
@Mapping(target = "createdAt", ignore = true)
@Mapping(target = "updatedBy", ignore = true)
@Mapping(target = "updatedAt", ignore = true)
User putDtoToEntity(UserPutDTO userDTO);
@Mapping(target = "deleted", ignore = true)
@Mapping(target = "revision", ignore = true)
@Mapping(target = "deptTenantId", ignore = true)
@Mapping(target = "companyTenantId", ignore = true)
@Mapping(target = "createdBy", ignore = true)
@Mapping(target = "createdAt", ignore = true)
@Mapping(target = "updatedBy", ignore = true)
@Mapping(target = "updatedAt", ignore = true)
User queryToEntity(UserQuery userQuery);
UserVO entityToVO(User user);
}

View File

@@ -0,0 +1,195 @@
package ai.remi.boot.domain.dto.post;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 用户表 UserDTO对象
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ToString(callSuper = true)
@Schema(description = "用户表")
public class UserPostDTO implements Serializable {
private static final long serialVersionUID = -48342054464737753L;
/**
* 所属公司ID
*/
@Schema(description = "所属公司ID")
private String companyId;
/**
* 所属公司编码
*/
@Schema(description = "所属公司编码")
private String companyCode;
/**
* 所属部门ID
*/
@Schema(description = "所属部门ID")
private String deptId;
/**
* 所属部门编码
*/
@Schema(description = "所属部门编码")
private String deptCode;
/**
* 用户编码/员工工号
*/
@Schema(description = "用户编码/员工工号")
private String userCode;
/**
* 用户名称
*/
@Schema(description = "用户名称")
private String userName;
/**
* 用户英文名称
*/
@Schema(description = "用户英文名称")
private String userNameEn;
/**
* 用户首名(东方为姓,西方为名)
*/
@Schema(description = "用户首名(东方为姓,西方为名)")
private String firstName;
/**
* 用户中名(欧美人常用)
*/
@Schema(description = "用户中名(欧美人常用)")
private String middleName;
/**
* 用户末名(东方为名,西方为姓)
*/
@Schema(description = "用户末名(东方为名,西方为姓)")
private String lastName;
/**
* 用户昵称/别号
*/
@Schema(description = "用户昵称/别号")
private String nickName;
/**
* 登录账号
*/
@Schema(description = "登录账号")
private String loginName;
/**
* 登录密码
*/
@Schema(description = "登录密码")
private String password;
/**
* 职位ID
*/
@Schema(description = "职位ID")
private String positionId;
/**
* 职位编码
*/
@Schema(description = "职位编码")
private String positionCode;
/**
* 职级ID
*/
@Schema(description = "职级ID")
private String rankId;
/**
* 职级编码
*/
@Schema(description = "职级编码")
private String rankCode;
/**
* 用户描述
*/
@Schema(description = "用户描述")
private String userRemark;
/**
* 出生日期
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Schema(description = "出生日期")
private LocalDate birthday;
/**
* 证件号码
*/
@Schema(description = "证件号码")
private String identity;
/**
* 电话号码
*/
@Schema(description = "电话号码")
private String phone;
/**
* 电子邮箱
*/
@Schema(description = "电子邮箱")
private String email;
/**
* 用户性别(0女性 1男性)
*/
@Schema(description = "用户性别(0女性 1男性)")
private Integer sex;
/**
* 头像地址
*/
@Schema(description = "头像地址")
private String headPic;
/**
* 最后登录IP
*/
@Schema(description = "最后登录IP")
private String loginIp;
/**
* 最后登录时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Schema(description = "最后登录时间")
private LocalDateTime loginDate;
/**
* 是否启用(0停用 1启用)
*/
@Schema(description = "是否启用(0停用 1启用)")
private Integer status;
}

View File

@@ -0,0 +1,201 @@
package ai.remi.boot.domain.dto.put;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 用户表 UserDTO对象
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ToString(callSuper = true)
@Schema(description = "用户表")
public class UserPutDTO implements Serializable {
private static final long serialVersionUID = -67424143626189045L;
/**
* ID
*/
@Schema(description = "ID")
private String id;
/**
* 所属公司ID
*/
@Schema(description = "所属公司ID")
private String companyId;
/**
* 所属公司编码
*/
@Schema(description = "所属公司编码")
private String companyCode;
/**
* 所属部门ID
*/
@Schema(description = "所属部门ID")
private String deptId;
/**
* 所属部门编码
*/
@Schema(description = "所属部门编码")
private String deptCode;
/**
* 用户编码/员工工号
*/
@Schema(description = "用户编码/员工工号")
private String userCode;
/**
* 用户名称
*/
@Schema(description = "用户名称")
private String userName;
/**
* 用户英文名称
*/
@Schema(description = "用户英文名称")
private String userNameEn;
/**
* 用户首名(东方为姓,西方为名)
*/
@Schema(description = "用户首名(东方为姓,西方为名)")
private String firstName;
/**
* 用户中名(欧美人常用)
*/
@Schema(description = "用户中名(欧美人常用)")
private String middleName;
/**
* 用户末名(东方为名,西方为姓)
*/
@Schema(description = "用户末名(东方为名,西方为姓)")
private String lastName;
/**
* 用户昵称/别号
*/
@Schema(description = "用户昵称/别号")
private String nickName;
/**
* 登录账号
*/
@Schema(description = "登录账号")
private String loginName;
/**
* 登录密码
*/
@Schema(description = "登录密码")
private String password;
/**
* 职位ID
*/
@Schema(description = "职位ID")
private String positionId;
/**
* 职位编码
*/
@Schema(description = "职位编码")
private String positionCode;
/**
* 职级ID
*/
@Schema(description = "职级ID")
private String rankId;
/**
* 职级编码
*/
@Schema(description = "职级编码")
private String rankCode;
/**
* 用户描述
*/
@Schema(description = "用户描述")
private String userRemark;
/**
* 出生日期
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Schema(description = "出生日期")
private LocalDate birthday;
/**
* 证件号码
*/
@Schema(description = "证件号码")
private String identity;
/**
* 电话号码
*/
@Schema(description = "电话号码")
private String phone;
/**
* 电子邮箱
*/
@Schema(description = "电子邮箱")
private String email;
/**
* 用户性别(0女性 1男性)
*/
@Schema(description = "用户性别(0女性 1男性)")
private Integer sex;
/**
* 头像地址
*/
@Schema(description = "头像地址")
private String headPic;
/**
* 最后登录IP
*/
@Schema(description = "最后登录IP")
private String loginIp;
/**
* 最后登录时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Schema(description = "最后登录时间")
private LocalDateTime loginDate;
/**
* 是否启用(0停用 1启用)
*/
@Schema(description = "是否启用(0停用 1启用)")
private Integer status;
}

View File

@@ -0,0 +1,123 @@
package ai.remi.boot.domain.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import ai.remi.comm.domain.entity.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 用户表 UserDTO对象
*/
@Data
@SuperBuilder
@AllArgsConstructor
@NoArgsConstructor
@TableName("remi_user")
public class User extends BaseEntity {
/**
* 用户编码/员工工号
*/
private String userCode;
/**
* 登录账号
*/
private String loginName;
/**
* 用户名称
*/
private String userName;
/**
* 用户英文名称
*/
private String userNameEn;
/**
* 用户首名(东方为姓,西方为名)
*/
private String firstName;
/**
* 用户中名(欧美人常用)
*/
private String middleName;
/**
* 用户末名(东方为名,西方为姓)
*/
private String lastName;
/**
* 用户昵称/别号
*/
private String nickName;
/**
* 用户描述
*/
private String userRemark;
/**
* 登录密码
*/
private String password;
/**
* 出生日期
*/
private LocalDate birthday;
/**
* 证件号码
*/
private String identity;
/**
* 电话号码
*/
private String phone;
/**
* 电子邮箱
*/
private String email;
/**
* 用户性别(0女性 1男性)
*/
private Integer sex;
/**
* 头像地址
*/
private String headPic;
/**
* 最后登录IP
*/
private String loginIp;
/**
* 最后登录时间
*/
private LocalDateTime loginDate;
/**
* 是否启用(0停用 1启用)
*/
private Integer status;
}

View File

@@ -0,0 +1,39 @@
package ai.remi.boot.domain.enums;
import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* Redis key枚举类
*
* @author dianjiu
* @date 2021-12-7 16:10:35
*/
@Getter
@AllArgsConstructor
public enum SsoCacheEnum {
/**
* 客户登录token,24小时失效 1:{} = customerId 2:{} = token 使用方式 RedisKeysEnum.CUSTOMER_LOGIN_TOKEN.getKey(customerId,token)
*/
APP_CODE("remi-saas-iam:app-code:{}:{}"),
USER_INFO("remi-saas-iam:user-info:{}"),
TICKET("remi-saas-iam:ticket:{}"),
AUTH_CODE("remi-saas-iam:auth-code:{}"),
ACCESS_TOKEN("remi-saas-iam:access-token:{}"),
REFRESH_TOKEN("remi-saas-iam:refresh-token:{}");
/**
* redis key
*/
private String key;
/**
* key失效时间,单位秒
*/
//private Long expireAt;
public String getKey(String... key) {
return StrUtil.format(this.key, key);
}
}

View File

@@ -0,0 +1,177 @@
package ai.remi.boot.domain.query;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 用户表 UserQuery对象
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ToString(callSuper = true)
@Schema(description = "用户表")
public class UserQuery implements Serializable {
private static final long serialVersionUID = 441095565282363416L;
/**
* ID
*/
@Schema(description = "ID")
private String id;
/**
* 用户编码/员工工号
*/
@Schema(description = "用户编码/员工工号")
private String userCode;
/**
* 所属公司ID
*/
@Schema(description = "所属公司ID")
private String companyId;
/**
* 所属公司编码
*/
@Schema(description = "所属公司编码")
private String companyCode;
/**
* 所属部门ID
*/
@Schema(description = "所属部门ID")
private String deptId;
/**
* 所属部门编码
*/
@Schema(description = "所属部门编码")
private String deptCode;
/**
* 登录账号
*/
@Schema(description = "登录账号")
private String loginName;
/**
* 用户名称
*/
@Schema(description = "用户名称")
private String userName;
/**
* 用户英文名称
*/
@Schema(description = "用户英文名称")
private String userNameEn;
/**
* 用户首名(东方为姓,西方为名)
*/
@Schema(description = "用户首名(东方为姓,西方为名)")
private String firstName;
/**
* 用户中名(欧美人常用)
*/
@Schema(description = "用户中名(欧美人常用)")
private String middleName;
/**
* 用户末名(东方为名,西方为姓)
*/
@Schema(description = "用户末名(东方为名,西方为姓)")
private String lastName;
/**
* 用户昵称/别号
*/
@Schema(description = "用户昵称/别号")
private String nickName;
/**
* 用户描述
*/
@Schema(description = "用户描述")
private String userRemark;
/**
* 登录密码
*/
@Schema(description = "登录密码")
private String password;
/**
* 出生日期
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Schema(description = "出生日期")
private LocalDate birthday;
/**
* 证件号码
*/
@Schema(description = "证件号码")
private String identity;
/**
* 电话号码
*/
@Schema(description = "电话号码")
private String phone;
/**
* 电子邮箱
*/
@Schema(description = "电子邮箱")
private String email;
/**
* 用户性别(0女性 1男性)
*/
@Schema(description = "用户性别(0女性 1男性)")
private Integer sex;
/**
* 头像地址
*/
@Schema(description = "头像地址")
private String headPic;
/**
* 最后登录IP
*/
@Schema(description = "最后登录IP")
private String loginIp;
/**
* 最后登录时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Schema(description = "最后登录时间")
private LocalDateTime loginDate;
/**
* 是否启用(0停用 1启用)
*/
@Schema(description = "是否启用(0停用 1启用)")
private Integer status;
}

View File

@@ -0,0 +1,131 @@
package ai.remi.boot.domain.tree;
import com.fasterxml.jackson.annotation.JsonFormat;
import ai.remi.comm.domain.tree.TreeNode;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* @author Remi
* @email startdis@dianjiukeji.cn
* @desc 部门表 DeptVO对象
*/
@Data
@SuperBuilder
@AllArgsConstructor
@NoArgsConstructor
@ToString(callSuper = true)
@Schema(description = "业务组织")
public class GroupTree extends TreeNode<GroupTree> implements Serializable {
private static final long serialVersionUID = 505874294590378764L;
/**
* ID
*/
@Schema(description = "ID")
private String id;
/**
* 父菜单ID
*/
@Schema(description = "父菜单ID")
private String parentId;
/**
* 应用ID
*/
@Schema(description = "应用ID")
private String appId;
/**
* 应用编码
*/
@Schema(description = "应用编码")
private String appCode;
/**
* 用户组编码
*/
@Schema(description = "用户组编码")
private String groupCode;
/**
* 用户组名称
*/
@Schema(description = "用户组名称")
private String groupName;
/**
* 用户组英文名称
*/
@Schema(description = "用户组英文名称")
private String groupNameEn;
/**
* 用户组描述
*/
@Schema(description = "用户组描述")
private String groupRemark;
/**
* 用户组英文描述
*/
@Schema(description = "用户组英文描述")
private String groupRemarkEn;
/**
* 显示顺序
*/
@Schema(description = "显示顺序")
private Integer sort;
/**
* 是否启用(0停用 1启用)
*/
@Schema(description = "是否启用(0停用 1启用)")
private Integer status;
/**
* 是否删除(0正常 1删除)
*/
@Schema(description = "是否删除(0正常 1删除)")
private Integer deleted;
/**
* 乐观锁
*/
@Schema(description = "乐观锁")
private Integer revision;
/**
* 部门租户ID
*/
@Schema(description = "部门租户ID")
private String deptTenantId;
/**
* 公司租户ID
*/
@Schema(description = "公司租户ID")
private String companyTenantId;
/**
* 创建人
*/
@Schema(description = "创建人")
private String createdBy;
/**
* 创建时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Schema(description = "创建时间")
private LocalDateTime createdAt;
/**
* 更新人
*/
@Schema(description = "更新人")
private String updatedBy;
/**
* 更新时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Schema(description = "更新时间")
private LocalDateTime updatedAt;
}

View File

@@ -0,0 +1,294 @@
package ai.remi.boot.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 用户表 UserVO对象
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ToString(callSuper = true)
@Schema(description = "用户表")
public class UserVO implements Serializable {
private static final long serialVersionUID = -23942899880966373L;
/**
* ID
*/
@Schema(description = "ID")
private String id;
/**
* 用户编码/员工工号
*/
@Schema(description = "用户编码/员工工号")
private String userCode;
/**
* 所属公司ID
*/
@Schema(description = "所属公司ID")
private String companyId;
/**
* 所属公司编码
*/
@Schema(description = "所属公司编码")
private String companyCode;
/**
* 所属部门ID
*/
@Schema(description = "所属部门ID")
private String deptId;
/**
* 所属部门编码
*/
@Schema(description = "所属部门编码")
private String deptCode;
/**
* 用户名称
*/
@Schema(description = "用户名称")
private String userName;
/**
* 用户英文名称
*/
@Schema(description = "用户英文名称")
private String userNameEn;
/**
* 用户首名(东方为姓,西方为名)
*/
@Schema(description = "用户首名(东方为姓,西方为名)")
private String firstName;
/**
* 用户中名(欧美人常用)
*/
@Schema(description = "用户中名(欧美人常用)")
private String middleName;
/**
* 用户末名(东方为名,西方为姓)
*/
@Schema(description = "用户末名(东方为名,西方为姓)")
private String lastName;
/**
* 用户昵称/别号
*/
@Schema(description = "用户昵称/别号")
private String nickName;
/**
* 登录账号
*/
@Schema(description = "登录账号")
private String loginName;
/**
* 登录密码
*/
@Schema(description = "登录密码")
private String password;
/**
* 职位ID
*/
@Schema(description = "职位ID")
private String positionId;
/**
* 职位编码
*/
@Schema(description = "职位编码")
private String positionCode;
/**
* 职位名称
*/
@Schema(description = "职位名称")
private String positionName;
/**
* 岗位英文名称
*/
@Schema(description = "职位英文名称")
private String positionNameEn;
/**
* 职级ID
*/
@Schema(description = "职级ID")
private String rankId;
/**
* 职级编码
*/
@Schema(description = "职级编码")
private String rankCode;
/**
* 职级名称
*/
@Schema(description = "职级名称")
private String rankName;
/**
* 职级英文名称
*/
@Schema(description = "职级英文名称")
private String rankNameEn;
/**
* 用户描述
*/
@Schema(description = "用户描述")
private String userRemark;
/**
* 出生日期
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@Schema(description = "出生日期")
private LocalDate birthday;
/**
* 证件号码
*/
@Schema(description = "证件号码")
private String identity;
/**
* 电话号码
*/
@Schema(description = "电话号码")
private String phone;
/**
* 电子邮箱
*/
@Schema(description = "电子邮箱")
private String email;
/**
* 用户性别(0女性 1男性)
*/
@Schema(description = "用户性别(0女性 1男性)")
private Integer sex;
/**
* 头像地址
*/
@Schema(description = "头像地址")
private String headPic;
/**
* 最后登录IP
*/
@Schema(description = "最后登录IP")
private String loginIp;
/**
* 用户角色集合
*/
@Schema(description = "用户角色集合")
private List<RoleVO> userRoles;
/**
* 用户菜单集合
*/
@Schema(description = "用户菜单集合")
private List<AppMenuVO> userMenus;
/**
* 应用的全局配置
*/
@Schema(description = "用户全局配置")
private List<ConfigVO> appConfigs;
/**
* 最后登录时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Schema(description = "最后登录时间")
private LocalDateTime loginDate;
/**
* 是否启用(0停用 1启用)
*/
@Schema(description = "是否启用(0停用 1启用)")
private Integer status;
/**
* 是否删除(0正常 1删除)
*/
@Schema(description = "是否删除(0正常 1删除)")
private Integer deleted;
/**
* 乐观锁
*/
@Schema(description = "乐观锁")
private Long revision;
/**
* 部门租户ID
*/
@Schema(description = "部门租户ID")
private String deptTenantId;
/**
* 公司租户ID
*/
@Schema(description = "公司租户ID")
private String companyTenantId;
/**
* 创建人
*/
@Schema(description = "创建人")
private String createdBy;
/**
* 创建时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Schema(description = "创建时间")
private LocalDateTime createdAt;
/**
* 更新人
*/
@Schema(description = "更新人")
private String updatedBy;
/**
* 更新时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Schema(description = "更新时间")
private LocalDateTime updatedAt;
}

View File

@@ -7,35 +7,30 @@
<description>remi-demo-infra</description>
<parent>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo</artifactId>
<version>3.1.1</version>
<version>3.1.0</version>
</parent>
<!-- 打包上传到私服, 需要和配置文件中的server节点配合使用 -->
<distributionManagement>
<repository>
<id>maven-releases</id>
<name>release</name>
<url>https://repository.njydsz.com/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>maven-snapshots</id>
<name>snapshot</name>
<url>https://repository.njydsz.com/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<dependencies>
<!--remi-comm-jdbc-->
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.comm</groupId>
<artifactId>remi-comm-jdbc</artifactId>
</dependency>
<!--remi-demo-domain-->
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo-domain</artifactId>
</dependency>
<!--slf4j-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,143 @@
package ai.remi.boot.infra.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import ai.remi.boot.domain.entity.User;
import ai.remi.boot.domain.query.UserQuery;
import ai.remi.boot.domain.vo.UserVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 用户表(User)数据层
*/
@Mapper
public interface UserMapper extends BaseMapper<User> {
@Select("SELECT " +
" u.*, " +
" up.position_id, " +
" up.position_code, " +
" up.rank_id, " +
" up.rank_code, " +
" du.dept_id, " +
" du.dept_code, " +
" cd.company_id, " +
" cd.company_code " +
"FROM " +
" iam_user u, " +
" iam_user_post up, " +
" iam_dept_user du, " +
" iam_company_dept cd " +
"WHERE " +
" u.id = du.user_id " +
" and u.user_code = du.user_code " +
" and u.id = up.user_id " +
" and u.user_code = up.user_code " +
" and du.dept_id = cd.dept_id " +
" and du.dept_code = cd.dept_code " +
" and u.id = #{id}")
UserVO selectOneById(String id);
@Select("<script>" +
"select " +
" u.*, " +
" du.dept_id, " +
" du.dept_code, " +
" cd.company_id, " +
" cd.company_code " +
"from " +
" iam_user u, " +
" iam_dept_user du, " +
" iam_company_dept cd " +
"where " +
" u.id = du.user_id " +
" and u.user_code = du.user_code " +
" and du.dept_id = cd.dept_id " +
" and du.dept_code = cd.dept_code " +
" <if test=\"userQuery.companyId != null and userQuery.companyId != '' \" >" +
" and cd.company_id = #{userQuery.companyId} " +
" </if>" +
" <if test=\"userQuery.companyCode != null and userQuery.companyCode != '' \" >" +
" and cd.company_code = #{userQuery.companyCode} " +
" </if>" +
" <if test=\"userQuery.deptId != null and userQuery.deptId != '' \" >" +
" and cd.dept_id = #{userQuery.deptId} " +
" </if>" +
" <if test=\"userQuery.deptCode != null and userQuery.deptCode != '' \" >" +
" and cd.dept_code = #{userQuery.deptCode} " +
" </if>" +
"</script>")
List<UserVO> selectListByUser(@Param("userQuery") UserQuery userQuery);
@Select("<script>" +
"select " +
" u.*, " +
" up.position_id, " +
" up.position_code, " +
" up.rank_id, " +
" up.rank_code, " +
" du.dept_id, " +
" du.dept_code, " +
" cd.company_id, " +
" cd.company_code " +
"from " +
" iam_user u, " +
" iam_user_post up, " +
" iam_dept_user du, " +
" iam_company_dept cd " +
"where " +
" u.id = du.user_id " +
" and u.user_code = du.user_code " +
" and u.id = up.user_id " +
" and u.user_code = up.user_code " +
" and du.dept_id = cd.dept_id " +
" and du.dept_code = cd.dept_code " +
" <if test=\"userQuery.companyId != null and userQuery.companyId != '' \" >" +
" and cd.company_id = #{userQuery.companyId} " +
" </if>" +
" <if test=\"userQuery.companyCode != null and userQuery.companyCode != '' \" >" +
" and cd.company_code = #{userQuery.companyCode} " +
" </if>" +
" <if test=\"userQuery.deptId != null and userQuery.deptId != '' \" >" +
" and cd.dept_id = #{userQuery.deptId} " +
" </if>" +
" <if test=\"userQuery.deptCode != null and userQuery.deptCode != '' \" >" +
" and cd.dept_code = #{userQuery.deptCode} " +
" </if>" +
" limit #{pageNum},#{pageSize}" +
"</script>")
List<UserVO> selectPageByUser(@Param("pageNum") Integer pageNum, @Param("pageSize") Integer pageSize, @Param("userQuery") UserQuery userQuery);
@Select("<script>" +
"select " +
" count(u.id) as total " +
"from " +
" iam_user u, " +
" iam_dept_user du, " +
" iam_company_dept cd " +
"where " +
" u.id = du.user_id " +
" and u.user_code = du.user_code " +
" and du.dept_id = cd.dept_id " +
" and du.dept_code = cd.dept_code " +
" <if test=\"userQuery.companyId != null and userQuery.companyId != '' \" >" +
" and cd.company_id = #{userQuery.companyId} " +
" </if>" +
" <if test=\"userQuery.companyCode != null and userQuery.companyCode != '' \" >" +
" and cd.company_code = #{userQuery.companyCode} " +
" </if>" +
" <if test=\"userQuery.deptId != null and userQuery.deptId != '' \" >" +
" and cd.dept_id = #{userQuery.deptId} " +
" </if>" +
" <if test=\"userQuery.deptCode != null and userQuery.deptCode != '' \" >" +
" and cd.dept_code = #{userQuery.deptCode} " +
" </if>" +
"</script>")
Long selectCountByUser(@Param("userQuery") UserQuery userQuery);
}

View File

@@ -9,7 +9,7 @@ xxl-job:
# 执行器
executor:
# 执行器AppName
appname: remi-demo-job
appname: remi-ids-job
# 执行器注册地址
address:
# 执行器IP
@@ -17,7 +17,7 @@ xxl-job:
# 执行器端口号
port:
# 执行器运行日志文件存储磁盘路径
logPath: /app/logs/remi-demo-job
logPath: /app/logs/remi-ids-job
# 执行器日志文件保存天数
logRetentionDays: 30
```

View File

@@ -7,36 +7,31 @@
<description>remi-demo-job</description>
<parent>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo</artifactId>
<version>3.1.1</version>
<version>3.1.0</version>
</parent>
<!-- 打包上传到私服, 需要和配置文件中的server节点配合使用 -->
<distributionManagement>
<repository>
<id>maven-releases</id>
<name>release</name>
<url>https://repository.njydsz.com/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>maven-snapshots</id>
<name>snapshot</name>
<url>https://repository.njydsz.com/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<dependencies>
<!--remi-comm-job-->
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.comm</groupId>
<artifactId>remi-comm-job</artifactId>
</dependency>
<!--remi-demo-server-->
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo-server</artifactId>
</dependency>
<!--slf4j-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -1,4 +1,4 @@
package ai.remi.demo.job.handler;
package ai.remi.boot.job.handler;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.context.XxlJobHelper;

View File

@@ -7,52 +7,43 @@
<description>remi-demo-server</description>
<parent>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo</artifactId>
<version>3.1.1</version>
<version>3.1.0</version>
</parent>
<!-- 打包上传到私服, 需要和配置文件中的server节点配合使用 -->
<distributionManagement>
<repository>
<id>maven-releases</id>
<name>release</name>
<url>https://repository.njydsz.com/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>maven-snapshots</id>
<name>snapshot</name>
<url>https://repository.njydsz.com/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<dependencies>
<!--remi-demo-infra-->
<!--瑞米公共模块-->
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<artifactId>remi-demo-infra</artifactId>
</dependency>
<!--启迪公共模块-->
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.comm</groupId>
<artifactId>remi-comm-exception</artifactId>
</dependency>
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<artifactId>remi-comm-minio</artifactId>
</dependency>
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.comm</groupId>
<artifactId>remi-comm-redis</artifactId>
</dependency>
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.comm</groupId>
<artifactId>remi-comm-thread</artifactId>
</dependency>
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.comm</groupId>
<artifactId>remi-comm-util</artifactId>
</dependency>
<!--remi-demo-infra-->
<dependency>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo-infra</artifactId>
</dependency>
<!--slf4j-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
</dependency>
</dependencies>

View File

@@ -1,4 +1,4 @@
package ai.remi.demo.server.exception;
package ai.remi.boot.server.exception;
import ai.remi.comm.exception.enums.ExceptionCode;
import lombok.AllArgsConstructor;
@@ -6,7 +6,7 @@ import lombok.Getter;
@AllArgsConstructor
@Getter
public enum BpmExceptionCode implements ExceptionCode {
public enum IamExceptionCode implements ExceptionCode {
/**
* 业务异常code

View File

@@ -0,0 +1,22 @@
package ai.remi.boot.server.exception;
import ai.remi.comm.exception.custom.BusinessException;
public class IamServiceException extends BusinessException {
public IamServiceException(String code, String message) {
super(code, message);
}
public IamServiceException(String code, Throwable cause) {
super(code, cause);
}
public IamServiceException(String code, String message, Throwable cause) {
super(code, message, cause);
}
public IamServiceException(String code, String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(code, message, cause, enableSuppression, writableStackTrace);
}
}

View File

@@ -0,0 +1,19 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.User;
import ai.remi.boot.domain.vo.UserVO;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 用户表(User)服务定义层
*/
public interface UserService extends IService<User> {
UserVO getLoginById(String id);
UserVO getUserById(String id);
User login(String username, String password);
}

View File

@@ -0,0 +1,176 @@
package ai.remi.boot.server.service.impl;
import ai.remi.boot.domain.entity.*;
import ai.remi.boot.domain.vo.UserVO;
import ai.remi.boot.infra.mapper.UserMapper;
import ai.remi.boot.server.service.*;
import ai.remi.comm.domain.tree.TreeBuild;
import ai.remi.comm.util.bean.BeanCopyUtils;
import ai.remi.comm.util.collection.CollectionUtils;
import ai.remi.comm.util.object.ObjectUtils;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 用户表(User)服务实现层
*/
@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Resource
private UserMapper userMapper;
@Resource
private RoleService roleService;
@Resource
private UserRoleService userRoleService;
@Resource
private DeptUserService deptUserService;
@Resource
private CompanyDeptService companyDeptService;
@Resource
private CordRoleService cordRoleService;
@Resource
private UserPostService userPostService;
@Resource
private PostRoleService postRoleService;
@Resource
private GroupUserService groupUserService;
@Resource
private GroupRoleService groupRoleService;
@Resource
private RoleMenuService roleMenuService;
@Resource
private MenuMapper menuMapper;
@Resource
private ConfigService configService;
@Override
public UserVO getLoginById(String id) {
UserVO userVO = userMapper.selectOneById(id);
// 获取用户角色
List<RoleVO> userRoles = getUserRoles(id);
userVO.setUserRoles(userRoles);
// 获取用户菜单
List<AppMenuVO> userMenus = getUserMenus(userRoles);
userVO.setUserMenus(userMenus);
// 用户全局配置
List<Config> list = configService.list(Wrappers.<Config>lambdaQuery().eq(Config::getConfType, 1).eq(Config::getBindId, id));
userVO.setAppConfigs(BeanCopyUtils.coverList(list, ConfigVO.class));
return userVO;
}
@Override
public UserVO getUserById(String id) {
UserVO userVO = userMapper.selectOneById(id);
// 获取用户角色
List<RoleVO> userRoles = getUserRoles(id);
userVO.setUserRoles(userRoles);
// 获取用户菜单
//List<AppMenuVO> userMenus = getUserMenus(userRoles);
//userVO.setUserMenus(userMenus);
return userVO;
}
@Override
public User login(String username, String password) {
Wrapper<User> queryWrapper = Wrappers.<User>lambdaQuery().eq(User::getLoginName, username).eq(User::getPassword, password).eq(User::getStatus, 1).last("limit 1");
User user = userMapper.selectOne(queryWrapper);
return user;
}
private List<AppMenuVO> getUserMenus(List<RoleVO> userRoles) {
List<AppMenuVO> list = new ArrayList<>();
// 获取用户所有的菜单
List<RoleMenu> roleMenus = roleMenuService.list(Wrappers.<RoleMenu>lambdaQuery().in(RoleMenu::getRoleId, userRoles.stream().map(a -> a.getId()).collect(Collectors.toList())));
// 查询出所有菜单信息
List<MenuTree> menuTrees = menuMapper.selectMenuInIds(roleMenus.stream().map(a -> a.getMenuId()).collect(Collectors.toList()), 1);
Map<String, List<MenuTree>> collect = menuTrees.stream().collect(Collectors.groupingBy(menuTree -> menuTree.getAppId()));
collect.forEach((key, value) -> {
AppMenuVO appMenuVO = new AppMenuVO();
appMenuVO.setAppId(key);
if (CollectionUtils.isNotEmpty(value)) {
appMenuVO.setAppCode(value.get(0).getAppCode());
String rootId = "0";
// 创建树形结构并返回
TreeBuild treeBuild = new TreeBuild(rootId, value);
appMenuVO.setMenuTree(treeBuild.buildTree());
}
list.add(appMenuVO);
});
return list;
}
private List<RoleVO> getUserRoles(String userId) {
List<RoleVO> list = new ArrayList<>();
// 1、基础角色
List<UserRole> userRoles = userRoleService.list(Wrappers.<UserRole>lambdaQuery().eq(UserRole::getUserId, userId));
if (CollectionUtils.isNotEmpty(userRoles)) {
for (UserRole userRole : userRoles) {
Role one = roleService.getOne(Wrappers.<Role>lambdaQuery().eq(Role::getId, userRole.getRoleId()).eq(Role::getRoleType, 1).last("limit 1"));
list.add(RoleConverter.INSTANT.entityToVO(one));
}
}
// 组织角色
// 所在部门角色
DeptUser deptUser = deptUserService.getOne(Wrappers.<DeptUser>lambdaQuery().eq(DeptUser::getUserId, userId).last("limit 1"));
List<CordRole> deptRoles = cordRoleService.list(Wrappers.<CordRole>lambdaQuery().eq(CordRole::getCordId, deptUser.getDeptId()).eq(CordRole::getCordType, 2));
if (CollectionUtils.isNotEmpty(deptRoles)) {
for (CordRole cordRole : deptRoles) {
Role one = roleService.getOne(Wrappers.<Role>lambdaQuery().eq(Role::getId, cordRole.getRoleId()).eq(Role::getRoleType, 2).last("limit 1"));
list.add(RoleConverter.INSTANT.entityToVO(one));
}
}
// 所在公司角色
CompanyDept companyDept = companyDeptService.getOne(Wrappers.<CompanyDept>lambdaQuery().eq(CompanyDept::getDeptId, deptUser.getDeptId()).last("limit 1"));
List<CordRole> companyRoles = new ArrayList<>();
if (ObjectUtils.isNotEmpty(companyDept)) {
companyRoles = cordRoleService.list(Wrappers.<CordRole>lambdaQuery().eq(CordRole::getCordId, companyDept.getCompanyId()).eq(CordRole::getCordType, 1));
}
if (CollectionUtils.isNotEmpty(companyRoles)) {
for (CordRole cordRole : companyRoles) {
Role one = roleService.getOne(Wrappers.<Role>lambdaQuery().eq(Role::getId, cordRole.getRoleId()).eq(Role::getRoleType, 2).last("limit 1"));
list.add(RoleConverter.INSTANT.entityToVO(one));
}
}
// 业务角色
UserPost userPost = userPostService.getOne(Wrappers.<UserPost>lambdaQuery().eq(UserPost::getUserId, userId).last("limit 1"));
List<PostRole> postRoles = new ArrayList<>();
if (ObjectUtils.isNotEmpty(userPost)) {
postRoles = postRoleService.list(Wrappers.<PostRole>lambdaQuery().eq(PostRole::getPostId, userPost.getPositionId()));
}
if (CollectionUtils.isNotEmpty(postRoles)) {
for (PostRole postRole : postRoles) {
Role one = roleService.getOne(Wrappers.<Role>lambdaQuery().eq(Role::getId, postRole.getRoleId()).eq(Role::getRoleType, 3).last("limit 1"));
list.add(RoleConverter.INSTANT.entityToVO(one));
}
}
// 用户组角色
List<GroupUser> groupUsers = groupUserService.list(Wrappers.<GroupUser>lambdaQuery().eq(GroupUser::getUserId, userId));
List<GroupRole> groupRoles = new ArrayList<>();
if (CollectionUtils.isNotEmpty(groupUsers)) {
groupRoles = groupRoleService.list(Wrappers.<GroupRole>lambdaQuery().in(GroupRole::getGroupId, groupUsers.stream().map(a -> a.getGroupId()).collect(Collectors.toList())));
}
if (CollectionUtils.isNotEmpty(groupRoles)) {
for (GroupRole groupRole : groupRoles) {
Role one = roleService.getOne(Wrappers.<Role>lambdaQuery().eq(Role::getId, groupRole.getRoleId()).eq(Role::getRoleType, 4).last("limit 1"));
list.add(RoleConverter.INSTANT.entityToVO(one));
}
}
// 角色集合去重返回
if (CollectionUtils.isNotEmpty(list)) {
return list.stream().distinct().collect(Collectors.toList());
}
return list;
}
}

View File

@@ -0,0 +1,178 @@
package ai.remi.boot.server.util;
import ai.remi.comm.exception.util.MessageUtils;
import ai.remi.comm.redis.service.RedisService;
import ai.remi.comm.util.asserts.AssertUtils;
import ai.remi.comm.util.id.RandomUtils;
import ai.remi.comm.util.id.UUIDUtils;
import ai.remi.comm.util.security.AesUtils;
import ai.remi.boot.domain.enums.SsoCacheEnum;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.util.Arrays;
;
/**
* @author DianJiu
* @date 2021/12/8
* @Description 随机产生唯一的app_key和app_secret
*/
@Component
public class AppUtils {
@Resource
private RedisService redisService;
public static RedisService redisUtils;
@PostConstruct
public void init() {
redisUtils = this.redisService;
}
private final static String[] chars = new String[]{"a", "b", "c", "d", "e", "f",
"g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
"t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I",
"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
"W", "X", "Y", "Z"};
/**
* 最大重试次数
*/
public static final int MAX_RETRY_COUNT = 10;
/**
* 最大重试记录
*/
public static int maxCount = 0;
/**
* 生成规则 年份后两位【2位】 + 1年内第几天【3位】 + 随机数【5位】
* 理论上来说,一百年内不会重复
* 注意:1.前五位保证每天生成的id不重复,后五位会在redis缓存 set集合中进行碰撞校验,
* 2.请保证每天0时清除缓存,保证缓存中的短id数量较少提高性能,减少内存浪费
*/
public static String getAppCode() {
String year = String.valueOf(LocalDateTime.now().getYear()).substring(2);
String day = String.valueOf(LocalDateTime.now().getDayOfYear());
if (day.length() < 3) {
StringBuilder sb = new StringBuilder();
for (int i = day.length(); i < 3; i++) {
sb.append("0");
}
day = sb.append(day).toString();
}
String code = year + day;
int count = 0;
boolean exists = true;
while (exists) {
if (count > maxCount) {
maxCount = count;
}
String random = RandomUtils.generateNumberString(10 - code.length());
exists = redisUtils.sSet(SsoCacheEnum.APP_CODE.getKey(code, random), code + random) == 0L;
code = code + random;
count++;
AssertUtils.isFalse(count >= MAX_RETRY_COUNT, MessageUtils.getMessage("app.code.error"));
}
return code;
}
/**
* @Description: <p>
* 短8位UUID思想其实借鉴微博短域名的生成方式,但是其重复概率过高,而且每次生成4个,需要随即选取一个。
* 本算法利用62个可打印字符,通过随机生成32位UUID,由于UUID都为十六进制,所以将UUID分成8组,每4个为一组,然后通过模62操作,结果作为索引取出字符,
* 这样重复率大大降低。
* 经测试,在生成一千万个数据也没有出现重复,完全满足大部分需求。
* </p>
* @author DianJiu
* @date 2019/8/27 16:16
*/
public static String getAppKey() {
StringBuffer shortBuffer = new StringBuffer();
String uuid = UUIDUtils.simpleUuid();
for (int i = 0; i < 8; i++) {
String str = uuid.substring(i * 4, i * 4 + 4);
int x = Integer.parseInt(str, 16);
shortBuffer.append(chars[x % 0x3E]);
}
return shortBuffer.toString().toLowerCase();
}
/**
* <p>
* 通过appId和内置关键词生成APP Secret
* </P>
*
* @author DianJiu
* @date 2019/8/27 16:32
*/
public static String getAppSecret() {
return AesUtils.initHexKey();
}
public static Boolean validate(String appKey,String appSecret) {
return appSecret.equals(getAppSecret(appKey));
}
/**
* <p>
* 通过appId和内置关键词生成APP Secret
* </P>
*
* @author DianJiu
* @date 2019/8/27 16:32
*/
public static String getAppSecret(String appKey) {
try {
String[] array = new String[]{appKey};
StringBuffer sb = new StringBuffer();
// 字符串排序
Arrays.sort(array);
for (int i = 0; i < array.length; i++) {
sb.append(array[i]);
}
String str = sb.toString();
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(str.getBytes());
byte[] digest = md.digest();
StringBuffer hexstr = new StringBuffer();
String shaHex = "";
for (int i = 0; i < digest.length; i++) {
shaHex = Integer.toHexString(digest[i] & 0xFF);
if (shaHex.length() < 2) {
hexstr.append(0);
}
hexstr.append(shaHex);
}
return hexstr.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new RuntimeException();
}
}
public static void main(String[] args) {
//for (int i = 0; i < 10000; i++) {
// getAppCode();
//}
//System.out.println("最大碰撞次数为=>" + AppUtils.maxCount);
//String appCode = getAppCode();
String appKey = getAppKey();
String appSecret = getAppSecret(appKey);
//System.out.println("appCode: " + appCode);
System.out.println("appKey: " + appKey);
System.out.println("appSecret: " + appSecret);
}
}

View File

@@ -0,0 +1,21 @@
package ai.remi.boot.server.util;
import ai.remi.comm.util.security.Base64Utils;
import ai.remi.comm.util.string.StringUtils;
import org.springframework.util.DigestUtils;
import java.nio.charset.StandardCharsets;
public class AuthUtils {
public static String getAuthCode(String appKey, String state) {
String encode = Base64Utils.encode(appKey + state);
if (StringUtils.isNotBlank(encode)) {
return DigestUtils.md5DigestAsHex(encode.getBytes(StandardCharsets.UTF_8));
}
return "";
}
public static void main(String[] args) {
System.out.println(getAuthCode("AB123CE","123456"));
}
}

View File

@@ -1,22 +0,0 @@
package ai.remi.demo.server.exception;
import ai.remi.comm.exception.custom.BusinessException;
public class BpmServiceException extends BusinessException {
public BpmServiceException(String code, String message) {
super(code, message);
}
public BpmServiceException(String code, Throwable cause) {
super(code, cause);
}
public BpmServiceException(String code, String message, Throwable cause) {
super(code, message, cause);
}
public BpmServiceException(String code, String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(code, message, cause, enableSuppression, writableStackTrace);
}
}

View File

@@ -7,26 +7,11 @@
<description>remi-demo-web</description>
<parent>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo</artifactId>
<version>3.1.1</version>
<version>3.1.0</version>
</parent>
<!-- 打包上传到私服, 需要和配置文件中的server节点配合使用 -->
<distributionManagement>
<repository>
<id>maven-releases</id>
<name>release</name>
<url>https://repository.njydsz.com/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>maven-snapshots</id>
<name>snapshot</name>
<url>https://repository.njydsz.com/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<dependencies>
<!--spring-boot-->
<dependency>
@@ -35,15 +20,17 @@
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<artifactId>slf4j-simple</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--logging-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<!--spring-cloud-->
@@ -84,33 +71,34 @@
<!--remi-comm-web-->
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.comm</groupId>
<artifactId>remi-comm-web</artifactId>
</dependency>
<!--remi-comm-log-->
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<!--<dependency>
<groupId>ai.remi.top.comm</groupId>
<artifactId>remi-comm-log</artifactId>
</dependency>
</dependency>-->
<!--remi-ids-server-->
<!--remi-demo-server-->
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo-server</artifactId>
</dependency>
<!--remi-ids-job-->
<!--remi-demo-job-->
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo-job</artifactId>
</dependency>
<!--remi-ids-api-->
<dependency>
<groupId>ai.remi.top.cloud</groupId>
<groupId>ai.remi.top.demo</groupId>
<artifactId>remi-demo-api</artifactId>
</dependency>
</dependencies>
<build>

View File

@@ -1,4 +1,4 @@
package ai.remi.demo.web;
package ai.remi.boot.web;
import ai.remi.comm.feign.annotation.EnableRemiFeignClients;
import org.springframework.boot.SpringApplication;
@@ -10,7 +10,7 @@ import org.springframework.jmx.support.RegistrationPolicy;
/**
* 系统服务启动程序
*/
//@EnableLogRecord
//@EnableLogRecord
@EnableDiscoveryClient
@EnableRemiFeignClients
@SpringBootApplication(scanBasePackages = "ai.remi")
@@ -18,10 +18,11 @@ import org.springframework.jmx.support.RegistrationPolicy;
public class Application {
public static void main(String[] args) {
//System.setProperty("cfg.env","local");
SpringApplication.run(Application.class, args);
System.out.println("(♥◠‿◠)ノ゙ Sdt Boot Web Startup Completed! ლ(´ڡ`ლ)゙ ");
System.out.println("(♥◠‿◠)ノ゙ Remi Demo Web Startup Completed! ლ(´ڡ`ლ)゙ ");
}

View File

@@ -0,0 +1,202 @@
package ai.remi.boot.web.controller;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import ai.remi.comm.core.result.PagerBean;
import ai.remi.comm.core.result.ResultBean;
import ai.remi.comm.domain.query.PageQuery;
import ai.remi.comm.exception.util.MessageUtils;
import ai.remi.comm.redis.service.RedisService;
import ai.remi.comm.util.asserts.AssertUtils;
import ai.remi.comm.util.collection.CollectionUtils;
import ai.remi.comm.util.id.SnowflakeUtils;
import ai.remi.boot.domain.converter.UserConverter;
import ai.remi.boot.domain.dto.post.UserPostDTO;
import ai.remi.boot.domain.dto.put.UserPutDTO;
import ai.remi.boot.domain.entity.User;
import ai.remi.boot.domain.enums.SsoCacheEnum;
import ai.remi.boot.domain.query.UserQuery;
import ai.remi.boot.domain.vo.UserVO;
import ai.remi.boot.infra.mapper.UserMapper;
import ai.remi.boot.server.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import java.util.List;
import java.util.Map;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 用户表(User)控制层
*/
@Validated
@RestController
@Tag(name = "用户管理")
@RequestMapping("user")
public class UserController {
/**
* 服务对象
*/
@Resource
private RedisService redisService;
@Resource
private UserService userService;
@Resource
private UserMapper userMapper;
@Resource
private DeptUserService deptUserService;
@Resource
private UserPostService userPostService;
/**
* 通过主键查询单条数据
*
* @param id 主键
* @return 单条数据
*/
@GetMapping("{id}")
@Operation(summary = "通过userId获取用户信息")
public ResultBean<UserVO> get(@PathVariable @Validated @NotBlank(message = "ID不能为空") String id) {
UserVO userVO = userService.getUserById(id);
return ResultBean.success(userVO);
}
/**
* 通过主键查询单条数据
*
* @param token 主键
* @return 单条数据
*/
@GetMapping("token/{token}")
@Operation(summary = "通过Token获取用户信息")
public ResultBean<UserVO> getUserByToken(@PathVariable @Validated @NotBlank(message = "Token不能为空") String token) throws Exception {
Map<Object, Object> hmget = redisService.hmget(SsoCacheEnum.USER_INFO.getKey(token));
AssertUtils.isTrue(CollectionUtils.isNotEmpty(hmget), MessageUtils.getMessage("check.userinfo.token.error"));
return ResultBean.success(BeanUtil.toBean(hmget, UserVO.class));
}
/**
* 通过实体不为空的属性作为筛选条件查询对象列表
*
* @param userQuery 实例对象
* @return 对象列表
*/
@PostMapping(value = "/list")
@Operation(summary = "查询所有")
public ResultBean<List<UserVO>> list(@RequestBody UserQuery userQuery) {
//执行分页查询
List<UserVO> listResult = userMapper.selectListByUser(userQuery);
return ResultBean.success(listResult);
}
/**
* 分页查询所有数据
*
* @param pageQuery 分页对象
* @param userQuery 查询实体
* @return 分页对象
*/
@PostMapping(value = "/page")
@Operation(summary = "分页查询")
public ResultBean<PagerBean<UserVO>> page(PageQuery pageQuery, UserQuery userQuery) {
//查询总条数
Long total = userMapper.selectCountByUser(userQuery);
//执行分页查询
List<UserVO> userVOS = userMapper.selectPageByUser(pageQuery.getPageNum() - 1, pageQuery.getPageSize(), userQuery);
PagerBean<UserVO> pageBean = new PagerBean<>(total, Long.valueOf(pageQuery.getPageNum()), Long.valueOf(pageQuery.getPageSize()), userVOS);
return ResultBean.success(pageBean);
}
/**
* 新增数据
*
* @param userDTO 实体对象
* @return 新增结果
*/
@PostMapping("/add")
@Operation(summary = "新增数据")
//@LogRecord(content = "录入用户信息", businessType = BusinessType.INSERT)
@Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
public ResultBean<Boolean> insert(@RequestBody @Validated UserPostDTO userDTO) {
//处理格式转换
User user = UserConverter.INSTANT.postDtoToEntity(userDTO);
user.setId(SnowflakeUtils.getInstance().nextIdStr());
//保存部门用户中间表
DeptUser deptUser = DeptUser.builder()
.deptId(userDTO.getDeptId())
.deptCode(userDTO.getDeptCode())
.userId(user.getId()).userCode(user.getUserCode()).build();
deptUserService.save(deptUser);
// 保存用户职位职级(即岗位)
UserPost userPost = UserPost.builder()
.positionId(userDTO.getPositionId()).positionCode(userDTO.getPositionCode())
.rankId(userDTO.getRankId()).rankCode(userDTO.getRankCode())
.userId(user.getId()).userCode(user.getUserCode()).build();
userPostService.save(userPost);
//执行用户信息保存
return ResultBean.success(userService.save(user));
}
/**
* 修改数据
*
* @param userDTO 实体对象
* @return 修改结果
*/
@PutMapping("/update")
@Operation(summary = "修改数据")
//@LogRecord(content = "更新用户信息", businessType = BusinessType.UPDATE)
@Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
public ResultBean<Boolean> update(@RequestBody @Validated UserPutDTO userDTO) {
//处理格式转换
User user = UserConverter.INSTANT.putDtoToEntity(userDTO);
//保存公司部门中间表
DeptUser deptUser = DeptUser.builder()
.deptId(userDTO.getDeptId())
.deptCode(userDTO.getDeptCode())
.userId(user.getId()).userCode(user.getUserCode()).build();
deptUserService.saveOrUpdate(deptUser, Wrappers.<DeptUser>lambdaUpdate().eq(DeptUser::getUserId, userDTO.getId()));
// 保存用户职位职级(即岗位)
UserPost userPost = UserPost.builder()
.positionId(userDTO.getPositionId()).positionCode(userDTO.getPositionCode())
.rankId(userDTO.getRankId()).rankCode(userDTO.getRankCode())
.userId(user.getId()).userCode(user.getUserCode()).build();
userPostService.saveOrUpdate(userPost, Wrappers.<UserPost>lambdaUpdate().eq(UserPost::getUserId, userDTO.getId()));
//执行数据更新
return ResultBean.success(userService.updateById(user));
}
/**
* 删除数据
*
* @param ids 主键结合
* @return 删除结果
*/
@DeleteMapping("/delete")
@Operation(summary = "删除数据")
//@LogRecord(content = "删除用户信息", businessType = BusinessType.DELETE)
@Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
public ResultBean<Boolean> delete(@RequestParam("ids") List<String> ids) {
for (String id : ids) {
// 删除部门用户中间表
LambdaQueryWrapper<DeptUser> deptUserQuery = Wrappers.lambdaQuery(DeptUser.class).eq(DeptUser::getUserId, id);
deptUserService.remove(deptUserQuery);
// 删除用户岗位中间表
LambdaQueryWrapper<UserPost> userPostQuery = Wrappers.lambdaQuery(UserPost.class).eq(UserPost::getUserId, id);
userPostService.remove(userPostQuery);
}
return ResultBean.success(userService.removeByIds(ids));
}
}

View File

@@ -7,6 +7,7 @@ spring:
name: remi-demo-web
profiles:
active: dev
#active: sit
cloud:
# nacos
nacos:
@@ -15,11 +16,14 @@ spring:
password: nacos
discovery:
# 配置中心的地址
server-addr: ${NACOS_HOST:192.168.31.204}:${NACOS_PORT:8848}
#server-addr: ${NACOS_HOST:192.168.31.18}:${NACOS_PORT:8848}
server-addr: ${NACOS_HOST:192.168.31.200}:${NACOS_PORT:30888}
#命名空间
namespace: ${SERVICE_NAME_SPACE_NAME:dev}
#namespace: ${SERVICE_NAME_SPACE_NAME:sit}
# 配置文件的环境
group: ${SERVICE_DISCOVERY_GROUP_NAME:dev}
#group: ${SERVICE_DISCOVERY_GROUP_NAME:sit}
# 配置中心
config:
# 配置中心的地址
@@ -42,4 +46,7 @@ spring:
- dataId: remi-cloud-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
group: ${spring.cloud.nacos.discovery.group}
#是否自动刷新
refresh: true
refresh: true

View File

@@ -3,14 +3,12 @@
# Author: DianJiu
# 指定基础镜像,这是分阶段构建的前期阶段
FROM harbor.njydsz.com/library/jdk:17 as builder
# 维护者
MAINTAINER DianJiu <dianjiuxyz@gmail.com>
#VOLUME:挂载目录
VOLUME /temp
#ADD 将app.jar文件将拷贝到容器中,默认拷贝到根路径下
#也可以直接写成ADD app.jar /app.jar 或者 ADD app.jar /
ADD remi-demo-web-3.1.1.jar remi-demo-web.jar
ADD remi-demo-web-3.1.0.jar remi-demo-web.jar
#修改app.jar这个文件的访问时间和修改时间为当前时间,而不会修改文件的内容。
RUN bash -c "touch /remi-demo-web.jar"
@@ -21,4 +19,4 @@ RUN bash -c "touch /remi-demo-web.jar"
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/remi-demo-web.jar"]
#EXPOSE 容器暴露端口
EXPOSE 8080
EXPOSE 1010

View File

@@ -1,5 +1,7 @@
## 如果基于Docker部署项目 直接运行如下脚本即可
```shell
sh ./docker_deploy.sh
docker logs -f remi-demo-web
```
```

View File

@@ -1,7 +1,12 @@
docker stop remi-demo-web
docker rm -f remi-demo-web
docker rmi remi-demo-web
#先删除原有的镜像
docker images | grep remi-demo-web | awk '{print $3}' | xargs docker rmi -f
docker build -t remi-demo-web .
docker images
docker run --restart=always -t -dit -p 8080:8080 -e TZ="Asia/Shanghai" --name remi-demo-web remi-demo-web
docker ps
docker images | grep remi-demo-web
#把新镜像推送到私服
docker login -uadmin -pRemi123 harbor.******.com
docker tag remi-demo-web harbor.******.com/remi-top/remi-demo-web:3.1.0
docker tag remi-demo-web harbor.******.com/remi-top/remi-demo-web
docker push harbor.******.com/remi-top/remi-demo-web:3.1.0
docker push harbor.******.com/remi-top/remi-demo-web
#基于Docker启动容器
docker run --restart=always -t -dit -p 1010:1010 --name remi-demo-web harbor.******.com/remi-top/remi-demo-web

View File

@@ -5,6 +5,22 @@ not.logged.in=not logged in or token is invalid
#****************************????****************************
system.error=System error
assert.error=Verify error
add.dept.error=The same department already exists?
delete.dept.error=There are sub-dept or user under the current dept that have not been removed?
delete.company.error=There are sub-company or dept under the current company that have not been removed?
only.support.code.error=Only the authorization code method is supported
check.app.secret.error=Verify the appSecret is exceptional
check.auth.code.error=The code is incorrect or out of date
check.userinfo.token.error=The Token is incorrect or out of date
check.ticket.error=No ticket exist, please log in again
app.code.error=Generate an AppCode that collides more than 10 times, please regenerate it
add.menu.error=The same menu already exists?
add.groupUser.error=The same user {0} already exists?
add.roleUser.error=The same user {0} already exists?
add.roleCord.error=The same cord {0} already exists?
add.rolePost.error=The same post {0} already exists?
add.roleGroup.error=The same group {0} already exists?
check.login.error=The username or password is wrong, please check and try again!
#****************************????****************************
other.system.error=Other system error
call.feign.error=Call feign error

View File

@@ -6,6 +6,22 @@ not.logged.in=未登录或Token失效
#****************************系统异常****************************
system.error=系统异常
assert.error=校验失败
add.dept.error=当前公司下已存在相同部门,请检查部门名称和部门编码!
delete.dept.error=当前部门下有子部门或员工未移除,不允许直接被删除!
delete.company.error=当前公司下有子子公司或部门未移除,不允许直接被删除!
only.support.code.error=仅支持授权码方式
check.app.secret.error=校验appSecret异常
check.auth.code.error=code有误或已过期
check.userinfo.token.error=token有误或已过期
check.ticket.error=不存在凭证,请重新登陆
app.code.error=尝试生成AppCode发生碰撞超过10次,请重新生成!
add.menu.error=当前应用下已存在相同菜单,请检查菜单名称和菜单编码!
add.groupUser.error=当前用户组下已存在该用户,请检查用户:{0}!
add.roleUser.error=当前角色下已存在该用户,请检查用户:{0}!
add.roleCord.error=当前角色下已存在该组织,请检查组织:{0}!
add.rolePost.error=当前角色下已存在该岗位,请检查岗位:{0}!
add.roleGroup.error=当前角色下已存在该用户组,请检查用户组:{0}!
check.login.error=用户名或密码错误,请检查后重试!
#****************************三方异常****************************
other.system.error=三方系统异常
call.feign.error=调用Feign异常

View File

@@ -0,0 +1,22 @@
# Docker image for springboot application
# VERSION 0.0.1
# Author: DianJiu
# 指定基础镜像,这是分阶段构建的前期阶段
FROM harbor.njydsz.com/library/jdk:17 as builder
#VOLUME:挂载目录
VOLUME /temp
#ADD 将app.jar文件将拷贝到容器中,默认拷贝到根路径下
#也可以直接写成ADD app.jar /app.jar 或者 ADD app.jar /
ADD remi-demo-web-3.1.0.jar remi-demo-web.jar
#修改app.jar这个文件的访问时间和修改时间为当前时间,而不会修改文件的内容。
RUN bash -c "touch /remi-demo-web.jar"
#ENTRYPOINT 应用启动命令 参数设定
#由于tomcat的session id的生成主要通过java.security.SecureRandom生成随机数来实现,导致启动过程很慢
#通过-Djava.security.egd=file:/dev/./urandom参数可以加快随机数产生过程
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/remi-demo-web.jar"]
#EXPOSE 容器暴露端口
EXPOSE 1010

View File

@@ -0,0 +1,13 @@
## 如果基于K8S部署项目 直接运行如下脚本即可
```shell
sh ./docker_deploy.sh
sh ./k8s_deploy.sh
kubectl get pods -n remi-top
kubectl describe pod remi-demo-web -n remi-top
kubectl get deployment remi-demo-web -n remi-top -o yaml
```

View File

@@ -0,0 +1,69 @@
## Service
apiVersion: v1
kind: Service
metadata:
name: remi-demo-web
labels:
app: remi-demo-web
spec:
type: NodePort
ports:
- name: remi-demo-web
port: 1010
protocol: TCP
targetPort: 1010
nodePort: 30010
selector:
app: remi-demo-web
---
## Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: remi-demo-web
labels:
app: remi-demo-web
spec:
replicas: 2
selector:
matchLabels:
app: remi-demo-web
template:
metadata:
labels:
app: remi-demo-web
spec:
containers:
- image: harbor.******.com/remi-top/remi-demo-web
imagePullPolicy: Always
name: remi-demo-web
ports:
- containerPort: 1010
protocol: TCP
env:
- name: NACOS_HOST
value: 192.168.31.200
- name: NACOS_PORT
value: "30888"
- name: NAME_SPACE
value: dev
- name: GROUP_NAME
value: dev
- name: spring.application.name
value: remi-sys-web
- name: spring.profiles.active
value: dev
resources:
limits:
cpu: "1"
memory: "500Mi"
requests:
cpu: "0.2"
memory: "200Mi"
volumeMounts:
- name: logs
mountPath: /logs
volumes:
- name: logs
persistentVolumeClaim:
claimName: remi-log

View File

@@ -0,0 +1,10 @@
#先删除原有的镜像
docker images | grep remi-demo-web | awk '{print $3}' | xargs docker rmi -f
docker build -t remi-demo-web .
docker images | grep remi-demo-web
#把新镜像推送到私服
docker login -uadmin -pRemi123 harbor.******.com
docker tag remi-demo-web harbor.******.com/remi-top/remi-demo-web:3.1.0
docker tag remi-demo-web harbor.******.com/remi-top/remi-demo-web
docker push harbor.******.com/remi-top/remi-demo-web:3.1.0
docker push harbor.******.com/remi-top/remi-demo-web

View File

@@ -0,0 +1,5 @@
#先删除原有的Pod
kubectl delete deployment remi-demo-web -n remi-top --grace-period=0 --force
kubectl delete svc remi-demo-web -n remi-top
#启动新的Pod
kubectl create -f remi-demo-web.yaml -n remi-top