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

@@ -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