init: 初始化项目
This commit is contained in:
commit
bbb638c28a
39
.gitignore
vendored
Normal file
39
.gitignore
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
HELP.md
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
application-local.yml
|
||||
*.log
|
||||
|
||||
rebel.xml
|
||||
.flattened-pom.xml
|
||||
9
README.md
Normal file
9
README.md
Normal file
@ -0,0 +1,9 @@
|
||||
Riven-瑞雯
|
||||
--------------------------
|
||||
|
||||
## 能力
|
||||
* 钉钉/企微 组织人员同步
|
||||
|
||||
## 本地运行参数
|
||||
* 系统环境变量
|
||||
server.port=8080;spring.datasource.url=jdbc:mysql://116.63.13.181:3311/pudge-dev?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&serverTimezone=Asia/Shanghai&useSSL=true&verifyServerCertificate=false&rewriteBatchedStatements=true;CUSTOM_ENV=dev
|
||||
2
RELEASE.md
Normal file
2
RELEASE.md
Normal file
@ -0,0 +1,2 @@
|
||||
# 发布记录
|
||||
|
||||
103
pom.xml
Normal file
103
pom.xml
Normal file
@ -0,0 +1,103 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>cn.axzo.infra</groupId>
|
||||
<artifactId>axzo-parent</artifactId>
|
||||
<version>2.4.13.5</version>
|
||||
</parent>
|
||||
|
||||
<groupId>cn.axzo</groupId>
|
||||
<artifactId>riven</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>${revision}</version>
|
||||
<name>riven</name>
|
||||
|
||||
<properties>
|
||||
<axzo-bom.version>2.0.0-SNAPSHOT</axzo-bom.version>
|
||||
<axzo-dependencies.version>2.0.0-SNAPSHOT</axzo-dependencies.version>
|
||||
<lombok.version>1.18.22</lombok.version>
|
||||
<mapstruct.version>1.4.2.Final</mapstruct.version>
|
||||
<revision>2.0.0-SNAPSHOT</revision>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
<module>riven-server</module>
|
||||
<module>riven-api</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!-- 导入axzo通用api依赖 -->
|
||||
<dependency>
|
||||
<groupId>cn.axzo.infra</groupId>
|
||||
<artifactId>axzo-bom</artifactId>
|
||||
<version>${axzo-bom.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.axzo.infra</groupId>
|
||||
<artifactId>axzo-dependencies</artifactId>
|
||||
<version>${axzo-dependencies.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- for test -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- maven-compiler-plugin 插件,解决 Lombok + MapStruct 组合 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</path>
|
||||
<path>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-processor</artifactId>
|
||||
<version>${mapstruct.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>axzo</id>
|
||||
<name>axzo repository</name>
|
||||
<url>https://nexus.axzo.cn/repository/axzo/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
</project>
|
||||
22
riven-api/pom.xml
Normal file
22
riven-api/pom.xml
Normal file
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<artifactId>riven</artifactId>
|
||||
<groupId>cn.axzo</groupId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>riven-api</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>riven-api</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cn.axzo.framework</groupId>
|
||||
<artifactId>axzo-consumer-spring-cloud-starter</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@ -0,0 +1,33 @@
|
||||
package cn.axzo.riven.client.feign;
|
||||
|
||||
import cn.axzo.framework.domain.page.PageQO;
|
||||
import cn.axzo.framework.domain.web.result.ApiPageResult;
|
||||
import cn.axzo.framework.domain.web.result.ApiResult;
|
||||
import cn.axzo.riven.client.model.NewUserReq;
|
||||
import cn.axzo.riven.client.model.UpdateUserReq;
|
||||
import cn.axzo.riven.client.model.UserRes;
|
||||
import cn.azxo.framework.common.model.CommonResponse;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2022/9/17
|
||||
* @Description:
|
||||
*/
|
||||
@FeignClient(name = "riven", url = "http://localhost:8899", fallbackFactory = MicroArchetypeFallbackFactory.class)
|
||||
public interface MicroArchetypeApi {
|
||||
|
||||
@PostMapping(value = "/api/v1/users", consumes = APPLICATION_JSON_VALUE)
|
||||
CommonResponse<UserRes> createUser(@RequestBody NewUserReq req);
|
||||
|
||||
@PutMapping(value = "/api/v2/users/{id}", consumes = APPLICATION_JSON_VALUE)
|
||||
ApiResult<UserRes> updateUser(@PathVariable("id") Long id, @RequestBody UpdateUserReq req);
|
||||
|
||||
@GetMapping(value = "/api/v2/users")
|
||||
ApiPageResult<UserRes> fetchUsers(@RequestParam Map<String, Object> query, PageQO page);
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
package cn.axzo.riven.client.feign;
|
||||
|
||||
import cn.axzo.framework.client.feign.FeignFallback;
|
||||
import cn.axzo.framework.domain.page.PageQO;
|
||||
import cn.axzo.framework.domain.web.result.ApiPageResult;
|
||||
import cn.axzo.framework.domain.web.result.ApiResult;
|
||||
import cn.axzo.riven.client.model.NewUserReq;
|
||||
import cn.axzo.riven.client.model.UpdateUserReq;
|
||||
import cn.axzo.riven.client.model.UserRes;
|
||||
import cn.azxo.framework.common.model.CommonResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2022/9/17
|
||||
* @Description:
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class MicroArchetypeApiFallback implements MicroArchetypeApi {
|
||||
|
||||
private final FeignFallback fallback;
|
||||
|
||||
/**
|
||||
* 老项目迁移使用
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public CommonResponse<UserRes> createUser(NewUserReq req) {
|
||||
log.error("[riven-api] createUser fallback", fallback.getCause());
|
||||
return CommonResponse.error("创建用户失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 新项目推荐使用
|
||||
*/
|
||||
@Override
|
||||
public ApiResult<UserRes> updateUser(Long id, UpdateUserReq req) {
|
||||
log.error("[riven-api] updateUser fallback", fallback.getCause());
|
||||
return fallback.resp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiPageResult<UserRes> fetchUsers(Map<String, Object> query, PageQO page) {
|
||||
log.error("[riven-api] fetchUsers fallback", fallback.getCause());
|
||||
return fallback.pageResp();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package cn.axzo.riven.client.feign;
|
||||
|
||||
import cn.axzo.framework.client.feign.FeignFallback;
|
||||
import cn.axzo.framework.domain.web.code.IRespCode;
|
||||
import cn.axzo.framework.domain.web.code.RespCode;
|
||||
import feign.hystrix.FallbackFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class MicroArchetypeFallbackFactory implements FallbackFactory<MicroArchetypeApiFallback> {
|
||||
|
||||
// TODO: 2022/11/3 100-调整为具体的项目编号,XXX-调整为项目名
|
||||
private final IRespCode respCode = new RespCode("100" + "91001", "XXX服务不可用");
|
||||
|
||||
@Override
|
||||
public MicroArchetypeApiFallback create(Throwable cause) {
|
||||
return new MicroArchetypeApiFallback(new FeignFallback(cause, respCode));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package cn.axzo.riven.client.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2022/9/2
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
public class NewUserReq {
|
||||
|
||||
@NotBlank(message = "名称不能为空")
|
||||
private String name;
|
||||
|
||||
@NotNull
|
||||
private Integer sex;
|
||||
|
||||
private Integer age;
|
||||
|
||||
private String phone;
|
||||
|
||||
private String email;
|
||||
|
||||
private String address;
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package cn.axzo.riven.client.model;
|
||||
|
||||
import cn.axzo.framework.context.client.IQueryMap;
|
||||
import cn.axzo.framework.context.client.QueryMap;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class QueryUserReq implements IQueryMap {
|
||||
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String phone;
|
||||
|
||||
private String email;
|
||||
|
||||
@Override
|
||||
public void append(QueryMap.Builder builder) {
|
||||
builder.put("id", id).put("name", name).put("phone", phone).put("email", email);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package cn.axzo.riven.client.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class UpdateUserReq {
|
||||
|
||||
private String name;
|
||||
|
||||
private Integer sex;
|
||||
|
||||
private Integer age;
|
||||
|
||||
private String phone;
|
||||
|
||||
private String email;
|
||||
|
||||
private String address;
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package cn.axzo.riven.client.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class UserRes {
|
||||
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
private Integer sex;
|
||||
|
||||
private Integer age;
|
||||
|
||||
private String phone;
|
||||
|
||||
private String email;
|
||||
|
||||
private String address;
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package cn.axzo.maven.archetype.client;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* Unit test for simple App.
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
public class AppTest {
|
||||
|
||||
}
|
||||
66
riven-server/pom.xml
Normal file
66
riven-server/pom.xml
Normal file
@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>riven</artifactId>
|
||||
<groupId>cn.axzo</groupId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>riven-server</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>riven-server</name>
|
||||
|
||||
<properties>
|
||||
<!--不打包发布server模块-->
|
||||
<maven.test.skip>true</maven.test.skip>
|
||||
<maven.deploy.skip>true</maven.deploy.skip>
|
||||
<maven.deploy.skip>true</maven.deploy.skip>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cn.axzo</groupId>
|
||||
<artifactId>riven-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.axzo.framework</groupId>
|
||||
<artifactId>axzo-web-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.axzo.framework</groupId>
|
||||
<artifactId>axzo-spring-cloud-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.axzo.framework</groupId>
|
||||
<artifactId>axzo-consumer-spring-cloud-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.axzo.framework</groupId>
|
||||
<artifactId>axzo-processor-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<!--mybatis-plus-->
|
||||
<dependency>
|
||||
<groupId>cn.axzo.framework</groupId>
|
||||
<artifactId>axzo-mybatisplus-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.axzo.framework</groupId>
|
||||
<artifactId>axzo-logger-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
36
riven-server/src/main/java/cn/axzo/riven/Application.java
Normal file
36
riven-server/src/main/java/cn/axzo/riven/Application.java
Normal file
@ -0,0 +1,36 @@
|
||||
package cn.axzo.riven;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
@Slf4j
|
||||
@MapperScan(value = {"cn.axzo.riven.repository.mapper"})
|
||||
@SpringBootApplication(scanBasePackages = "cn.axzo")
|
||||
public class Application {
|
||||
public static void main(String[] args) {
|
||||
ConfigurableApplicationContext run = SpringApplication.run(Application.class, args);
|
||||
Environment env = run.getEnvironment();
|
||||
log.info(
|
||||
"--------------------------------------------------------------------------------------------------------------------\n" +
|
||||
"Application 【{}】 is running on 【{}】 environment!\n" +
|
||||
"Api Local: \thttp://127.0.0.1:{}\n" +
|
||||
"Mysql: \t{}\t username:{}\n" +
|
||||
"Redis: \t{}:{}\t database:{}\n" +
|
||||
"RabbitMQ: \t{}\t username:{}",
|
||||
env.getProperty("spring.application.name"),
|
||||
env.getProperty("spring.profiles.active"),
|
||||
env.getProperty("server.port"),
|
||||
env.getProperty("spring.datasource.url"),
|
||||
env.getProperty("spring.datasource.username"),
|
||||
env.getProperty("spring.redis.host"),
|
||||
env.getProperty("spring.redis.port"),
|
||||
env.getProperty("spring.redis.database"),
|
||||
env.getProperty("spring.rabbitmq.addresses"),
|
||||
env.getProperty("spring.rabbitmq.username") +
|
||||
"\n----------------------------------------------------------");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package cn.axzo.riven.common.enums;
|
||||
|
||||
import cn.axzo.framework.domain.web.code.IProjectRespCode;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2022/9/5
|
||||
* @Description: 响应码规范:一共8位,取值范围0~9,3位项目编号(首位不能为0)+2位模块编号+3位自定义编号
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ErrorCode implements IProjectRespCode {
|
||||
|
||||
USER_NOT_EXISTS("01001", "用户不存在,id=%s"),
|
||||
USER_PHONE_EMAIL_IS_NULL("01002", "电话和邮箱不能都为空");
|
||||
|
||||
private String code;
|
||||
private String message;
|
||||
|
||||
@Override
|
||||
public String getProjectCode() {
|
||||
// 根据不同项目进行项目编码调整,可联系框架组获取项目编号(首位不能为0)
|
||||
return "100";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,88 @@
|
||||
package cn.axzo.riven.common.enums;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2022/9/5
|
||||
* @Description:
|
||||
*/
|
||||
public enum ResultCode {
|
||||
/**
|
||||
* 成功 [GET]
|
||||
*/
|
||||
SUCCESS(200),
|
||||
/**
|
||||
* [POST/PUT/PATCH] 用户新建或修改数据成功
|
||||
*/
|
||||
CREATED(201),
|
||||
/**
|
||||
* [*] 标识一个请求已经进入后台排队 (异步任务)
|
||||
*/
|
||||
ACCEPTED(202),
|
||||
/**
|
||||
* [DELETE]: 用户删除数据成功
|
||||
*/
|
||||
NO_CONTENT(204),
|
||||
/**
|
||||
* [POST/PUT/PATCH] 用户发出的请求有错误, 服务器没有进行新建或修改数据的操作, 该操作是幂等的.
|
||||
*/
|
||||
FAIL(400),
|
||||
/**
|
||||
* [*] 标识没有权限 (令牌、用户名、密码错误)
|
||||
*/
|
||||
UNAUTHORIZED(401),
|
||||
/**
|
||||
* [*] 标识用户得到授权(与401错误相对), 但是访问是被禁止的
|
||||
*/
|
||||
FORBIDDEN(403),
|
||||
/**
|
||||
* [*] 用户发出的请求针对的是不存在的记录, 服务器没有进行操作
|
||||
*/
|
||||
NOT_FOUND(404),
|
||||
/**
|
||||
* [GET] 用户请求的格式不可得 (比如用户请求JSON格式, 但是只有XML格式)
|
||||
*/
|
||||
NOT_ACCEPTABLE(406),
|
||||
/**
|
||||
* [GET] 用户请求的资源被永久删除, 且不会再得到
|
||||
*/
|
||||
GONE(410),
|
||||
/**
|
||||
* [POST/PUT/PATCH] 当创建一个对象时, 发生一个验证错误646
|
||||
*/
|
||||
UNPROCESSABLE_ENTITY(422),
|
||||
/**
|
||||
* 服务器内部错误
|
||||
*/
|
||||
INTERNAL_SERVER_ERROR(9999),
|
||||
/**
|
||||
* 通用业务异常
|
||||
*/
|
||||
SERVICE_EXCEPTION_ERROR(9998),
|
||||
|
||||
/**
|
||||
* ####业务的响应码####
|
||||
* 按业务依次划分 :
|
||||
* 一共6位, 第6位是业务代码 第1-5位响应码, 按业务不同码不同
|
||||
* #100000 全局级别
|
||||
*/
|
||||
|
||||
/**
|
||||
* 100001 当前用户被强制下线
|
||||
*/
|
||||
CUSTOM_100001(100001),
|
||||
/**
|
||||
* 确认弹窗响应码
|
||||
*/
|
||||
CUSTOM_100002(100002);
|
||||
|
||||
public int code;
|
||||
|
||||
ResultCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
package cn.axzo.riven.common.util;
|
||||
@ -0,0 +1,173 @@
|
||||
package cn.axzo.riven.config;
|
||||
|
||||
import cn.axzo.framework.domain.ServiceException;
|
||||
import cn.azxo.framework.common.constatns.Constants;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import feign.RequestInterceptor;
|
||||
import feign.RequestTemplate;
|
||||
import feign.Target.HardCodedTarget;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.MDC;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2023/8/29 14:50
|
||||
* @Description:
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class FeignConfiguration implements RequestInterceptor {
|
||||
|
||||
@Autowired
|
||||
private Environment environment;
|
||||
|
||||
private static final String FEIGN_URL_REGEX = "http://([A-Za-z-|_]+)(:[1-9]\\d{1,4}[/]?$)?";
|
||||
private static final String LOCAL_HOST = "localhost";
|
||||
private static final String DEV_HOST = "http://dev-app.axzo.cn/";
|
||||
private static final String TEST_HOST = "http://test-api.axzo.cn/";
|
||||
private static final String TEST1_HOST = "http://test1-api.axzo.cn/";
|
||||
private static final String PRE_HOST = "http://pre-api.axzo.cn/";
|
||||
private static final String PRE_NEW_HOST = "http://pre-new-api.axzo.cn/";
|
||||
private static final String UAT_HOST = "http://uat-api.axzo.cn/";
|
||||
private static final List<String> HOSTS = Lists
|
||||
.newArrayList(LOCAL_HOST, DEV_HOST, TEST_HOST, TEST1_HOST, PRE_HOST, PRE_NEW_HOST, UAT_HOST);
|
||||
|
||||
private static String POD_NAMESPACE;
|
||||
|
||||
static {
|
||||
Map<String, String> env = System.getenv();
|
||||
if (env != null) {
|
||||
POD_NAMESPACE = env.get("MY_POD_NAMESPACE");
|
||||
}
|
||||
log.info("init FeignConfig, POD_NAMESPACE value is {}", POD_NAMESPACE);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public void apply(RequestTemplate requestTemplate) {
|
||||
// POD_NAMESPACE为空 说明服务没有运行在rancher中则进行url替换;POD_NAMESPACE不为空时服务间通过Istio通信则不需要替换url
|
||||
if (POD_NAMESPACE == null) {
|
||||
HardCodedTarget<?> target = (HardCodedTarget<?>) requestTemplate.feignTarget();
|
||||
Field field = ReflectUtil.getField(target.getClass(), "url");
|
||||
field.setAccessible(true);
|
||||
String url = (String) field.get(target);
|
||||
// 如需要调用开发者本地启动的xxx服务,传入到toLocalServiceNames
|
||||
List<String> toLocalServiceNames = Lists.newArrayList("");
|
||||
String convertUrl = convertUrl(url, toLocalServiceNames);
|
||||
field.set(target, convertService(convertUrl));
|
||||
target.apply(requestTemplate);
|
||||
}
|
||||
requestTemplate.header(Constants.CTX_LOG_ID_MDC, MDC.get(Constants.CTX_LOG_ID_MDC));
|
||||
requestTemplate.header("X-SERVER-NAME", environment.getProperty("spring.application.name"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 某些服务URL需要特殊处理
|
||||
*/
|
||||
private String convertService(String url) {
|
||||
if (url.contains("data-collection")) {
|
||||
return url.replaceAll("data-collection", "dataCollection");
|
||||
} else if (url.contains("iot-hub")) {
|
||||
return url.replaceAll("iot-hub", "iotHub");
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将feign api中的url替换为其他环境
|
||||
*/
|
||||
private String convertUrl(String url, List<String> toLocalServiceNames) {
|
||||
// 已经替换过的 不再进行替换了
|
||||
if (HOSTS.stream().anyMatch(url::contains)) {
|
||||
return url;
|
||||
}
|
||||
String convertUrl = toLocalHost(url, toLocalServiceNames);
|
||||
if (!convertUrl.equals(url)) {
|
||||
return convertUrl;
|
||||
}
|
||||
// 环境为空或为生产环境,不替换
|
||||
String profile = environment.getProperty("spring.profiles.active");
|
||||
if (profile == null) {
|
||||
return url;
|
||||
}
|
||||
|
||||
// 调用profile对应环境的服务
|
||||
switch (profile.toLowerCase()) {
|
||||
case "local":
|
||||
return toLocalHost(url);
|
||||
case "dev":
|
||||
return toRemoteHost(url, DEV_HOST);
|
||||
case "test":
|
||||
return toRemoteHost(url, TEST_HOST);
|
||||
case "test1":
|
||||
return toRemoteHost(url, TEST1_HOST);
|
||||
case "pre":
|
||||
return toRemoteHost(url, PRE_HOST);
|
||||
case "pre-new":
|
||||
return toRemoteHost(url, PRE_NEW_HOST);
|
||||
case "uat":
|
||||
return toRemoteHost(url, UAT_HOST);
|
||||
default:
|
||||
throw new ServiceException("不支持该环境的feign api调用!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用本地启动的服务
|
||||
*
|
||||
* @param url 原url
|
||||
* @param toLocalServiceNames 需要切换到本地的服务名
|
||||
*/
|
||||
private static String toLocalHost(String url, List<String> toLocalServiceNames) {
|
||||
if (CollectionUtils.isEmpty(toLocalServiceNames)) {
|
||||
return url;
|
||||
}
|
||||
if (toLocalServiceNames.stream().anyMatch(o -> StringUtils.isNotBlank(o) && url.contains(o))) {
|
||||
return toLocalHost(url);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用本地启动的服务,如:http://apollo:11000 -> http://localhost:11000
|
||||
*/
|
||||
private static String toLocalHost(String url) {
|
||||
String serviceName = getServiceNameFromUrl(url);
|
||||
// 替换服务名为localhost
|
||||
return serviceName == null ? url : url.replaceAll(serviceName, LOCAL_HOST);
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用远程指定环境的服务,如:http://apollo:11000 -> http://dev-app.axzo.cn/apollo
|
||||
*/
|
||||
private static String toRemoteHost(String url, String host) {
|
||||
String serviceName = getServiceNameFromUrl(url);
|
||||
// 拼接远端host到url
|
||||
return serviceName == null ? url : host + serviceName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取url中的服务名
|
||||
*/
|
||||
private static String getServiceNameFromUrl(String url) {
|
||||
Pattern pattern = Pattern.compile(FEIGN_URL_REGEX);
|
||||
Matcher matcher = pattern.matcher(url);
|
||||
String serviceName = null;
|
||||
if (matcher.matches()) {
|
||||
serviceName = matcher.group(1);
|
||||
}
|
||||
return serviceName;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,259 @@
|
||||
package cn.axzo.riven.config.filter;
|
||||
|
||||
import cn.azxo.framework.common.constatns.Constants;
|
||||
import cn.azxo.framework.common.utils.LogUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONException;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
import com.google.common.base.Strings;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.skywalking.apm.toolkit.trace.Trace;
|
||||
import org.apache.skywalking.apm.toolkit.trace.TraceContext;
|
||||
import org.slf4j.MDC;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
import org.springframework.web.util.ContentCachingRequestWrapper;
|
||||
import org.springframework.web.util.ContentCachingResponseWrapper;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2022/12/6 14:48
|
||||
* @Description: Http接口日志记录
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class HttpTraceLogFilter extends OncePerRequestFilter implements Ordered {
|
||||
|
||||
private static final String X_REQUEST_ID = "x-request-id";
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Ordered.LOWEST_PRECEDENCE - 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Trace(operationName = "HttpTraceLogFilter")
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
|
||||
FilterChain filterChain) throws ServletException, IOException {
|
||||
String uri = request.getRequestURI();
|
||||
String contextPath = request.getContextPath();
|
||||
String url = uri.substring(contextPath.length());
|
||||
//swagger 跳过
|
||||
if (url.contains("api-docs") || url.contains("swagger") || url.contains("checkDeath")) {
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
//静态资源 跳过
|
||||
if (url.contains(".")) {
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
if (!(request instanceof ContentCachingRequestWrapper)) {
|
||||
request = new ContentCachingRequestWrapper(request);
|
||||
}
|
||||
if (!(response instanceof ContentCachingResponseWrapper)) {
|
||||
response = new ContentCachingResponseWrapper(response);
|
||||
}
|
||||
|
||||
String requestId = request.getHeader(X_REQUEST_ID);
|
||||
if (Strings.isNullOrEmpty(requestId)) {
|
||||
MDC.put(X_REQUEST_ID, getTraceId());
|
||||
} else {
|
||||
MDC.put(X_REQUEST_ID, requestId);
|
||||
}
|
||||
String ctxLogId = request.getHeader(Constants.CTX_LOG_ID_MDC);
|
||||
if (Strings.isNullOrEmpty(ctxLogId)) {
|
||||
MDC.put(Constants.CTX_LOG_ID_MDC, getTraceId());
|
||||
} else {
|
||||
MDC.put(Constants.CTX_LOG_ID_MDC, ctxLogId);
|
||||
}
|
||||
|
||||
// 获取请求参数
|
||||
String parameter = null;
|
||||
String requestContentType = request.getHeader(HttpHeaders.CONTENT_TYPE);
|
||||
if (requestContentType != null) {
|
||||
if (requestContentType.startsWith(MediaType.APPLICATION_JSON_VALUE)) {
|
||||
//Json
|
||||
WrappedHttpServletRequest requestWrapper = new WrappedHttpServletRequest(request);
|
||||
parameter = getRequestBody(requestWrapper);
|
||||
request = requestWrapper;
|
||||
} else if (requestContentType.startsWith(MediaType.APPLICATION_FORM_URLENCODED_VALUE)) {
|
||||
//普通表单提交
|
||||
parameter = JSON.toJSONString(request.getParameterMap());
|
||||
} else if (requestContentType.startsWith(MediaType.MULTIPART_FORM_DATA_VALUE)) {
|
||||
//文件表单提交
|
||||
parameter = JSON.toJSONString("文件类型");
|
||||
}
|
||||
} else if (url.startsWith("/api")) {
|
||||
if ("GET".equals(request.getMethod())) {
|
||||
parameter = JSON.toJSONString(request.getParameterMap());
|
||||
} else if ("POST".equals(request.getMethod())) {
|
||||
WrappedHttpServletRequest requestWrapper = new WrappedHttpServletRequest(request);
|
||||
parameter = getRequestBody(requestWrapper);
|
||||
request = requestWrapper;
|
||||
}
|
||||
} else if ("GET".equals(request.getMethod())) {
|
||||
parameter = JSON.toJSONString(request.getParameterMap());
|
||||
}
|
||||
|
||||
long requestTime = System.currentTimeMillis();
|
||||
try {
|
||||
filterChain.doFilter(request, response);
|
||||
} finally {
|
||||
response.setHeader(Constants.CTX_LOG_ID_MDC, MDC.get(Constants.CTX_LOG_ID_MDC));
|
||||
response.setHeader(X_REQUEST_ID, MDC.get(Constants.CTX_LOG_ID_MDC));
|
||||
|
||||
long latency = System.currentTimeMillis() - requestTime;
|
||||
String responseBody = null;
|
||||
int responseStatus = response.getStatus();
|
||||
String responseContentType = response.getContentType();
|
||||
//Json
|
||||
if (responseContentType != null && responseContentType
|
||||
.startsWith(MediaType.APPLICATION_JSON_VALUE)) {
|
||||
responseBody = getResponseBody(response);
|
||||
}
|
||||
//记录日志
|
||||
HttpTraceLog traceLog = new HttpTraceLog();
|
||||
traceLog.setRequestContentType(requestContentType);
|
||||
traceLog.setPath(url);
|
||||
traceLog.setMethod(request.getMethod());
|
||||
traceLog.setTimeTaken(latency);
|
||||
traceLog.setParameter(parameter);
|
||||
traceLog.setResponseContentType(responseContentType);
|
||||
traceLog.setStatus(responseStatus);
|
||||
traceLog.setResponseBody(responseBody);
|
||||
traceLog.setRequestHeaders(getRequestHeader(request));
|
||||
if (traceLog.getResponseCode() != null && traceLog.getResponseCode().equals(9999)) {
|
||||
LogUtil.error(LogUtil.ErrorLevel.P0, LogUtil.ErrorType.ERROR_BUSINESS, JSON.toJSONString(traceLog));
|
||||
} else if (traceLog.getResponseCode() != null && traceLog.getResponseCode().equals(9998)) {
|
||||
log.warn(JSON.toJSONString(traceLog));
|
||||
} else {
|
||||
log.info(JSON.toJSONString(traceLog));
|
||||
}
|
||||
updateResponse(response);
|
||||
// 清理链路id
|
||||
MDC.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private String getTraceId() {
|
||||
String contextTraceId = TraceContext.traceId();
|
||||
return Strings.isNullOrEmpty(contextTraceId)
|
||||
? UUID.randomUUID().toString().replaceAll("-", "") : contextTraceId;
|
||||
}
|
||||
|
||||
private String getRequestBody(WrappedHttpServletRequest request) throws IOException {
|
||||
// 获取请求参数
|
||||
return request.getRequestParams();
|
||||
}
|
||||
|
||||
@Trace(operationName = "HttpTraceLogFilter#getResponseBody")
|
||||
private String getResponseBody(HttpServletResponse response) {
|
||||
String responseBody = null;
|
||||
ContentCachingResponseWrapper wrapper = WebUtils
|
||||
.getNativeResponse(response, ContentCachingResponseWrapper.class);
|
||||
if (wrapper != null) {
|
||||
responseBody = new String(wrapper.getContentAsByteArray(), StandardCharsets.UTF_8);
|
||||
}
|
||||
return responseBody;
|
||||
}
|
||||
|
||||
public Map<String, String> getRequestHeader(HttpServletRequest request) {
|
||||
Map<String, String> ret = new HashMap<>();
|
||||
Enumeration<String> headerNames = request.getHeaderNames();
|
||||
while (headerNames.hasMoreElements()) {
|
||||
String headerName = headerNames.nextElement();
|
||||
ret.put(headerName, request.getHeader(headerName));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Trace(operationName = "HttpTraceLogFilter#updateResponse")
|
||||
private void updateResponse(HttpServletResponse response) throws IOException {
|
||||
ContentCachingResponseWrapper responseWrapper = WebUtils
|
||||
.getNativeResponse(response, ContentCachingResponseWrapper.class);
|
||||
Objects.requireNonNull(responseWrapper).copyBodyToResponse();
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
private static class HttpTraceLog {
|
||||
|
||||
/**
|
||||
* 路径
|
||||
*/
|
||||
private String path;
|
||||
/**
|
||||
* 参数
|
||||
*/
|
||||
@JSONField(jsonDirect = true)
|
||||
private String parameter;
|
||||
private String requestContentType;
|
||||
private String responseContentType;
|
||||
private String method;
|
||||
private Long timeTaken;
|
||||
private Integer status;
|
||||
/**
|
||||
* 业务Code
|
||||
*/
|
||||
private Integer responseCode;//业务返回码
|
||||
/**
|
||||
* 响应参数
|
||||
*/
|
||||
@JSONField(jsonDirect = true)
|
||||
private String responseBody;
|
||||
|
||||
@JSONField(jsonDirect = true)
|
||||
private Map<String, String> requestHeaders;
|
||||
|
||||
public String getParameter() {
|
||||
if (parameter == null) {
|
||||
return parameter;
|
||||
} else {
|
||||
return parameter.replaceAll("\n", "").replaceAll("\t", "").replaceAll("\r", "");
|
||||
}
|
||||
}
|
||||
|
||||
public String getResponseBody() {
|
||||
if (responseBody == null) {
|
||||
return responseBody;
|
||||
} else {
|
||||
return responseBody.replaceAll("\n", "").replaceAll("\t", "").replaceAll("\r", "");
|
||||
}
|
||||
}
|
||||
|
||||
public void setResponseBody(String responseBody) {
|
||||
if (StringUtils.isBlank(responseBody)) {
|
||||
return;
|
||||
}
|
||||
this.responseBody = responseBody;
|
||||
JSONObject responseJson = null;
|
||||
try {
|
||||
responseJson = JSONObject.parseObject(responseBody);
|
||||
this.responseCode = responseJson.getInteger("code");
|
||||
} catch (JSONException e) {
|
||||
log.debug("ResponseBody非JSON返回", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,91 @@
|
||||
package cn.axzo.riven.config.filter;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import javax.servlet.ReadListener;
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2022/12/6 14:56
|
||||
* @Description:
|
||||
*/
|
||||
public class WrappedHttpServletRequest extends HttpServletRequestWrapper {
|
||||
|
||||
private byte[] bytes;
|
||||
private WrappedServletInputStream wrappedServletInputStream;
|
||||
|
||||
public WrappedHttpServletRequest(HttpServletRequest request) throws IOException {
|
||||
super(request);
|
||||
// 读取输入流里的请求参数,并保存到bytes里
|
||||
bytes = IOUtils.toByteArray(request.getInputStream());
|
||||
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
|
||||
this.wrappedServletInputStream = new WrappedServletInputStream(byteArrayInputStream);
|
||||
// 很重要,把post参数重新写入请求流
|
||||
reWriteInputStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* 把参数重新写进请求里
|
||||
*/
|
||||
public void reWriteInputStream() {
|
||||
wrappedServletInputStream
|
||||
.setStream(new ByteArrayInputStream(bytes != null ? bytes : new byte[0]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletInputStream getInputStream() throws IOException {
|
||||
return wrappedServletInputStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedReader getReader() throws IOException {
|
||||
return new BufferedReader(new InputStreamReader(wrappedServletInputStream));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取post参数,可以自己再转为相应格式
|
||||
*/
|
||||
public String getRequestParams() throws IOException {
|
||||
return new String(bytes, this.getCharacterEncoding());
|
||||
}
|
||||
|
||||
private class WrappedServletInputStream extends ServletInputStream {
|
||||
|
||||
private InputStream stream;
|
||||
|
||||
public WrappedServletInputStream(InputStream stream) {
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
public void setStream(InputStream stream) {
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return stream.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinished() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReadListener(ReadListener readListener) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
package cn.axzo.riven.consumer;
|
||||
@ -0,0 +1,22 @@
|
||||
package cn.axzo.riven.controller;
|
||||
|
||||
import cn.axzo.framework.web.http.ApiResponse;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2022/11/25 18:00
|
||||
* @Description: 健康检查接口
|
||||
*/
|
||||
@RestController
|
||||
public class HealthCheckController {
|
||||
|
||||
/**
|
||||
* 探活
|
||||
*/
|
||||
@GetMapping("/checkDeath")
|
||||
public ApiResponse<String> checkDeath() {
|
||||
return ApiResponse.ok("ok");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
package cn.axzo.riven.controller.app;
|
||||
@ -0,0 +1,74 @@
|
||||
package cn.axzo.riven.controller.web;
|
||||
|
||||
import cn.axzo.riven.service.user.UserService;
|
||||
import cn.axzo.riven.service.dto.request.user.NewUserDTO;
|
||||
import cn.axzo.riven.service.dto.request.user.UpdateUserDTO;
|
||||
import cn.axzo.riven.service.dto.request.user.UserQO;
|
||||
import cn.axzo.riven.service.dto.response.user.UserVO;
|
||||
import cn.azxo.framework.common.model.CommonPageResponse;
|
||||
import cn.azxo.framework.common.model.CommonResponse;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2022/9/2
|
||||
* @Description:
|
||||
*/
|
||||
@Slf4j
|
||||
@Api(tags = "web-用户信息接口")
|
||||
@RequestMapping("/api/v1")
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
public class UserController {
|
||||
|
||||
private final UserService userService;
|
||||
|
||||
@ApiOperation(value = "创建用户")
|
||||
@PostMapping("/users")
|
||||
public CommonResponse<UserVO> createUser(@Valid @RequestBody NewUserDTO dto) {
|
||||
log.info("REST request to save user : {}", dto);
|
||||
// 校验入参
|
||||
dto.valid();
|
||||
UserVO result = userService.create(dto);
|
||||
return CommonResponse.success(result);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "修改用户")
|
||||
@PutMapping("/users/{id}")
|
||||
public CommonResponse<UserVO> updateUser(@ApiParam("用户ID") @PathVariable Long id,
|
||||
@Valid @RequestBody UpdateUserDTO dto) {
|
||||
log.info("REST request to update user : {}", dto);
|
||||
// 校验入参
|
||||
dto.valid();
|
||||
UserVO result = userService.update(id, dto);
|
||||
return CommonResponse.success(result);
|
||||
}
|
||||
|
||||
@ApiOperation("获取用户列表")
|
||||
@GetMapping("/users")
|
||||
public CommonResponse<CommonPageResponse<UserVO>> getUsers(@Valid UserQO userQO) {
|
||||
CommonPageResponse<UserVO> results = userService.queryByPage(userQO);
|
||||
return CommonResponse.success(results);
|
||||
}
|
||||
|
||||
@ApiOperation("获取用户详情")
|
||||
@GetMapping("/users/{id}")
|
||||
public CommonResponse getUser(@ApiParam("用户ID") @PathVariable Long id) {
|
||||
UserVO result = userService.getOne(id);
|
||||
return CommonResponse.success(result);
|
||||
}
|
||||
|
||||
@ApiOperation("删除用户")
|
||||
@DeleteMapping("/users/{id}")
|
||||
public CommonResponse deleteUser(@ApiParam("用户ID") @PathVariable Long id) {
|
||||
userService.delete(id);
|
||||
return CommonResponse.success();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,84 @@
|
||||
package cn.axzo.riven.controller.web;
|
||||
|
||||
import cn.axzo.framework.domain.page.PageQO;
|
||||
import cn.axzo.framework.domain.page.PageResp;
|
||||
import cn.axzo.framework.web.http.ApiResponse;
|
||||
import cn.axzo.framework.web.http.ApiPageResponse;
|
||||
import cn.axzo.riven.service.dto.request.user.NewUserDTO;
|
||||
import cn.axzo.riven.service.dto.request.user.UpdateUserDTO;
|
||||
import cn.axzo.riven.service.dto.request.user.UserQO1;
|
||||
import cn.axzo.riven.service.dto.response.user.UserRefVO;
|
||||
import cn.axzo.riven.service.dto.response.user.UserVO;
|
||||
import cn.axzo.riven.service.user.UserService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2022/10/28
|
||||
* @Description: 新项目搭建推荐方式
|
||||
*/
|
||||
@Slf4j
|
||||
@Api(tags = "web-用户信息接口")
|
||||
@RequestMapping("/api/v2")
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
public class UserResource {
|
||||
|
||||
private final UserService userService;
|
||||
|
||||
@ApiOperation(value = "创建用户")
|
||||
@PostMapping("/users")
|
||||
public ApiResponse<UserVO> createUser(@Valid @RequestBody NewUserDTO dto) {
|
||||
log.info("REST request to save user : {}", dto);
|
||||
// 校验入参
|
||||
dto.valid();
|
||||
UserVO result = userService.create(dto);
|
||||
return ApiResponse.ok(result);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "修改用户")
|
||||
@PutMapping("/users/{id}")
|
||||
public ApiResponse<UserVO> updateUser(@ApiParam("用户ID") @PathVariable Long id,
|
||||
@Valid @RequestBody UpdateUserDTO dto) {
|
||||
log.info("REST request to update user : {}", dto);
|
||||
// 校验入参
|
||||
dto.valid();
|
||||
UserVO result = userService.update(id, dto);
|
||||
return ApiResponse.ok(result);
|
||||
}
|
||||
|
||||
@ApiOperation("获取用户列表")
|
||||
@GetMapping("/users")
|
||||
public ApiPageResponse<UserVO> getUsers(@ModelAttribute UserQO1 userQo, PageQO page) {
|
||||
PageResp<UserVO> results = userService.find(userQo, page);
|
||||
return ApiPageResponse.ok(results);
|
||||
}
|
||||
|
||||
@ApiOperation("获取用户信息及地址列表")
|
||||
@GetMapping("/users/adress")
|
||||
public ApiPageResponse<UserRefVO> getUserAddress(@ModelAttribute UserQO1 userQo, PageQO page) {
|
||||
PageResp<UserRefVO> results = userService.queryUserAddress(userQo, page);
|
||||
return ApiPageResponse.ok(results);
|
||||
}
|
||||
|
||||
@ApiOperation("获取用户详情")
|
||||
@GetMapping("/users/{id}")
|
||||
public ApiResponse<UserVO> getUser(@ApiParam("用户ID") @PathVariable Long id) {
|
||||
UserVO result = userService.getOne(id);
|
||||
return ApiResponse.ok(result);
|
||||
}
|
||||
|
||||
@ApiOperation("删除用户")
|
||||
@DeleteMapping("/users/{id}")
|
||||
public ApiResponse deleteUser(@ApiParam("用户ID") @PathVariable Long id) {
|
||||
userService.delete(id);
|
||||
return ApiResponse.ok();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
package cn.axzo.riven.job;
|
||||
@ -0,0 +1,78 @@
|
||||
package cn.axzo.riven.repository;
|
||||
|
||||
import cn.axzo.framework.domain.page.PageQO;
|
||||
import cn.axzo.riven.repository.entity.address.AddressDO;
|
||||
import cn.axzo.riven.repository.entity.user.UserDO;
|
||||
import cn.axzo.riven.repository.entity.user.UserRefDO;
|
||||
import cn.axzo.riven.repository.mapper.UserMapper;
|
||||
import cn.axzo.riven.repository.mapper.UserReferenceMapper;
|
||||
import cn.axzo.riven.service.dto.request.user.UserQO;
|
||||
import cn.axzo.riven.service.dto.request.user.UserQO1;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.github.yulichang.toolkit.MPJWrappers;
|
||||
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2022/9/5
|
||||
* @Description:
|
||||
*/
|
||||
@Repository
|
||||
@RequiredArgsConstructor
|
||||
public class UserDao extends ServiceImpl<UserMapper, UserDO> {
|
||||
|
||||
private final UserMapper userMapper;
|
||||
|
||||
private final UserReferenceMapper userReferenceMapper;
|
||||
|
||||
public UserDO findById(Long id) {
|
||||
return userMapper.selectById(id);
|
||||
}
|
||||
|
||||
public void delete(Long id) {
|
||||
userMapper.deleteById(id);
|
||||
}
|
||||
|
||||
public IPage<UserDO> queryByPage(UserQO userQO) {
|
||||
return userMapper.selectPage(userQO.toPage(),
|
||||
Wrappers.lambdaQuery(UserDO.class)
|
||||
.eq(userQO.getId() != null, UserDO::getId, userQO.getId())
|
||||
.like(StringUtils.isNotBlank(userQO.getName()), UserDO::getName, userQO.getName())
|
||||
.like(StringUtils.isNotBlank(userQO.getPhone()), UserDO::getPhone, userQO.getPhone())
|
||||
.like(StringUtils.isNotBlank(userQO.getEmail()), UserDO::getEmail, userQO.getEmail())
|
||||
.orderByDesc(UserDO::getCreateAt)
|
||||
);
|
||||
}
|
||||
|
||||
public IPage<UserDO> find(UserQO1 userQO, PageQO page) {
|
||||
return userMapper.selectPage(page.toPage(),
|
||||
Wrappers.lambdaQuery(UserDO.class)
|
||||
.eq(userQO.getId() != null, UserDO::getId, userQO.getId())
|
||||
.like(StringUtils.isNotBlank(userQO.getName()), UserDO::getName, userQO.getName())
|
||||
.like(StringUtils.isNotBlank(userQO.getPhone()), UserDO::getPhone, userQO.getPhone())
|
||||
.like(StringUtils.isNotBlank(userQO.getEmail()), UserDO::getEmail, userQO.getEmail())
|
||||
.orderByDesc(UserDO::getCreateAt)
|
||||
);
|
||||
}
|
||||
|
||||
public IPage<UserRefDO> findUserAddress(UserQO1 userQO, PageQO page) {
|
||||
MPJLambdaWrapper<UserDO> wrapper = MPJWrappers.<UserDO>lambdaJoin()
|
||||
.selectAll(UserDO.class)
|
||||
.select(AddressDO::getProvince)
|
||||
.select(AddressDO::getCity)
|
||||
.select(AddressDO::getDistrict)
|
||||
.select(AddressDO::getStreet)
|
||||
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
|
||||
.eq(userQO.getId() != null, UserDO::getId, userQO.getId())
|
||||
.like(StringUtils.isNotBlank(userQO.getName()), UserDO::getName, userQO.getName())
|
||||
.like(StringUtils.isNotBlank(userQO.getPhone()), UserDO::getPhone, userQO.getPhone())
|
||||
.like(StringUtils.isNotBlank(userQO.getEmail()), UserDO::getEmail, userQO.getEmail())
|
||||
.orderByDesc(UserDO::getCreateAt);
|
||||
return userReferenceMapper.selectJoinPage(page.toPage(), UserRefDO.class, wrapper);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package cn.axzo.riven.repository.entity.address;
|
||||
|
||||
import cn.axzo.framework.data.mybatisplus.model.BaseEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2023/8/4 16:35
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
@TableName("b_address")
|
||||
public class AddressDO extends BaseEntity<AddressDO> {
|
||||
|
||||
private String province;
|
||||
|
||||
private String city;
|
||||
|
||||
private String district;
|
||||
|
||||
private String street;
|
||||
|
||||
private Long userId;
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
package cn.axzo.riven.repository.entity;
|
||||
@ -0,0 +1,27 @@
|
||||
package cn.axzo.riven.repository.entity.user;
|
||||
|
||||
import cn.axzo.framework.data.mybatisplus.model.BaseEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2022/9/5
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
@TableName("b_user")
|
||||
public class User extends BaseEntity<User> {
|
||||
|
||||
private String name;
|
||||
|
||||
private Integer sex;
|
||||
|
||||
private Integer age;
|
||||
|
||||
private String phone;
|
||||
|
||||
private String email;
|
||||
|
||||
private String address;
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package cn.axzo.riven.repository.entity.user;
|
||||
|
||||
import cn.axzo.framework.data.mybatisplus.model.BaseEntity;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2022/9/5
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
@TableName("b_user")
|
||||
public class UserDO extends BaseEntity<UserDO> {
|
||||
|
||||
private String name;
|
||||
|
||||
private Integer sex;
|
||||
|
||||
private Integer age;
|
||||
|
||||
private String phone;
|
||||
|
||||
private String email;
|
||||
|
||||
private String address;
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
package cn.axzo.riven.repository.entity.user;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2023/8/4 16:40
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
public class UserRefDO {
|
||||
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
private Integer sex;
|
||||
|
||||
private Integer age;
|
||||
|
||||
private String phone;
|
||||
|
||||
private String email;
|
||||
|
||||
private String province;
|
||||
|
||||
private String city;
|
||||
|
||||
private String district;
|
||||
|
||||
private String street;
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package cn.axzo.riven.repository.mapper;
|
||||
|
||||
import cn.axzo.riven.repository.entity.address.AddressDO;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2023/8/8 10:33
|
||||
* @Description:
|
||||
*/
|
||||
@Mapper
|
||||
public interface AddressMapper extends BaseMapper<AddressDO> {
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package cn.axzo.riven.repository.mapper;
|
||||
|
||||
import cn.axzo.riven.repository.entity.user.UserDO;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2022/9/5
|
||||
* @Description:
|
||||
*/
|
||||
@Mapper
|
||||
public interface UserMapper extends BaseMapper<UserDO> {
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package cn.axzo.riven.repository.mapper;
|
||||
|
||||
import cn.axzo.riven.repository.entity.user.UserDO;
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2023/8/4 16:49
|
||||
* @Description:
|
||||
*/
|
||||
@Mapper
|
||||
public interface UserReferenceMapper extends MPJBaseMapper<UserDO> {
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
package cn.axzo.riven.service.client;
|
||||
@ -0,0 +1,15 @@
|
||||
package cn.axzo.riven.service.converter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2022/9/5
|
||||
* @Description:
|
||||
*/
|
||||
public interface EntityConverter<V, E>{
|
||||
|
||||
V toVo(E var);
|
||||
|
||||
List<V> toVo(List<E> var);
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package cn.axzo.riven.service.converter;
|
||||
|
||||
import cn.axzo.riven.service.dto.request.user.NewUserDTO;
|
||||
import cn.axzo.riven.service.dto.request.user.UpdateUserDTO;
|
||||
import cn.axzo.riven.service.dto.response.user.UserVO;
|
||||
import cn.axzo.riven.repository.entity.user.UserDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.MappingTarget;
|
||||
|
||||
import static org.mapstruct.NullValueCheckStrategy.ALWAYS;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2022/9/2
|
||||
* @Description:
|
||||
*/
|
||||
@Mapper(
|
||||
componentModel = "spring",
|
||||
nullValueCheckStrategy = ALWAYS
|
||||
)
|
||||
public interface UserConverter extends EntityConverter<UserVO, UserDO> {
|
||||
|
||||
UserDO toEntity(NewUserDTO dto);
|
||||
|
||||
void updateEntity(UpdateUserDTO dto, @MappingTarget UserDO user);
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package cn.axzo.riven.service.converter;
|
||||
|
||||
import cn.axzo.riven.repository.entity.user.UserRefDO;
|
||||
import cn.axzo.riven.service.dto.response.user.UserRefVO;
|
||||
import org.mapstruct.Mapper;
|
||||
|
||||
import static org.mapstruct.NullValueCheckStrategy.ALWAYS;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2023/8/4 17:02
|
||||
* @Description:
|
||||
*/
|
||||
@Mapper(
|
||||
componentModel = "spring",
|
||||
nullValueCheckStrategy = ALWAYS
|
||||
)
|
||||
public interface UserRefConverter extends EntityConverter<UserRefVO, UserRefDO> {
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
package cn.axzo.riven.service.dto.request;
|
||||
@ -0,0 +1,41 @@
|
||||
package cn.axzo.riven.service.dto.request.user;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2022/9/2
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
public class NewUserDTO {
|
||||
|
||||
@ApiModelProperty(value = "名称", position = 1)
|
||||
@NotBlank(message = "名称不能为空")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "性别", position = 2)
|
||||
@NotNull
|
||||
private Integer sex;
|
||||
|
||||
@ApiModelProperty(value = "年龄", position = 3)
|
||||
private Integer age;
|
||||
|
||||
@ApiModelProperty(value = "电话", position = 4)
|
||||
private String phone;
|
||||
|
||||
@ApiModelProperty(value = "邮箱", position = 5)
|
||||
private String email;
|
||||
|
||||
public void valid() {
|
||||
// 电话和邮箱不能都为空
|
||||
if (StringUtils.isEmpty(phone) && StringUtils.isEmpty(email)) {
|
||||
throw new RuntimeException("电话和邮箱不能都为空");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
package cn.axzo.riven.service.dto.request.user;
|
||||
|
||||
import cn.axzo.framework.domain.web.ApiException;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import static cn.axzo.riven.common.enums.ErrorCode.USER_PHONE_EMAIL_IS_NULL;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2022/9/5
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
public class UpdateUserDTO {
|
||||
|
||||
@ApiModelProperty(value = "名称", position = 1)
|
||||
@NotBlank(message = "名称不能为空")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "性别", position = 2)
|
||||
@NotNull
|
||||
private Integer sex;
|
||||
|
||||
@ApiModelProperty(value = "年龄", position = 3)
|
||||
private Integer age;
|
||||
|
||||
@ApiModelProperty(value = "电话", position = 4)
|
||||
private String phone;
|
||||
|
||||
@ApiModelProperty(value = "邮箱", position = 5)
|
||||
private String email;
|
||||
|
||||
public void valid() {
|
||||
// 电话和邮箱不能都为空
|
||||
if (StringUtils.isEmpty(phone) && StringUtils.isEmpty(email)) {
|
||||
throw new ApiException(USER_PHONE_EMAIL_IS_NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package cn.axzo.riven.service.dto.request.user;
|
||||
|
||||
import cn.axzo.framework.domain.page.PageQO;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2022/9/5
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
public class UserQO extends PageQO {
|
||||
|
||||
@ApiParam("主键")
|
||||
private Long id;
|
||||
|
||||
@ApiParam("姓名")
|
||||
private String name;
|
||||
|
||||
@ApiParam("手机")
|
||||
private String phone;
|
||||
|
||||
@ApiParam("邮箱")
|
||||
private String email;
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package cn.axzo.riven.service.dto.request.user;
|
||||
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2022/9/5
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
public class UserQO1 {
|
||||
|
||||
@ApiParam("主键")
|
||||
private Long id;
|
||||
|
||||
@ApiParam("姓名")
|
||||
private String name;
|
||||
|
||||
@ApiParam("手机")
|
||||
private String phone;
|
||||
|
||||
@ApiParam("邮箱")
|
||||
private String email;
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
package cn.axzo.riven.service.dto.response;
|
||||
@ -0,0 +1,43 @@
|
||||
package cn.axzo.riven.service.dto.response.user;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2023/8/4 16:54
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
public class UserRefVO {
|
||||
|
||||
@ApiModelProperty(value = "id", position = 1)
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "名称", position = 2)
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "性别", position = 3)
|
||||
private Integer sex;
|
||||
|
||||
@ApiModelProperty(value = "年龄", position = 4)
|
||||
private Integer age;
|
||||
|
||||
@ApiModelProperty(value = "电话", position = 5)
|
||||
private String phone;
|
||||
|
||||
@ApiModelProperty(value = "邮箱", position = 6)
|
||||
private String email;
|
||||
|
||||
@ApiModelProperty(value = "省份", position = 7)
|
||||
private String province;
|
||||
|
||||
@ApiModelProperty(value = "城市", position = 8)
|
||||
private String city;
|
||||
|
||||
@ApiModelProperty(value = "区域", position = 9)
|
||||
private String district;
|
||||
|
||||
@ApiModelProperty(value = "街道", position = 10)
|
||||
private String street;
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package cn.axzo.riven.service.dto.response.user;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2022/9/2
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
public class UserVO {
|
||||
|
||||
@ApiModelProperty(value = "id", position = 1)
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "名称", position = 2)
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "性别", position = 3)
|
||||
private Integer sex;
|
||||
|
||||
@ApiModelProperty(value = "年龄", position = 4)
|
||||
private Integer age;
|
||||
|
||||
@ApiModelProperty(value = "电话", position = 5)
|
||||
private String phone;
|
||||
|
||||
@ApiModelProperty(value = "邮箱", position = 6)
|
||||
private String email;
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
package cn.axzo.riven.service.event;
|
||||
@ -0,0 +1,32 @@
|
||||
package cn.axzo.riven.service.user;
|
||||
|
||||
import cn.axzo.framework.domain.page.PageQO;
|
||||
import cn.axzo.framework.domain.page.PageResp;
|
||||
import cn.axzo.riven.service.dto.request.user.NewUserDTO;
|
||||
import cn.axzo.riven.service.dto.request.user.UpdateUserDTO;
|
||||
import cn.axzo.riven.service.dto.request.user.UserQO;
|
||||
import cn.axzo.riven.service.dto.request.user.UserQO1;
|
||||
import cn.axzo.riven.service.dto.response.user.UserRefVO;
|
||||
import cn.axzo.riven.service.dto.response.user.UserVO;
|
||||
import cn.azxo.framework.common.model.CommonPageResponse;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2022/9/2
|
||||
* @Description:
|
||||
*/
|
||||
public interface UserService {
|
||||
UserVO create(NewUserDTO dto);
|
||||
|
||||
UserVO update(Long id, UpdateUserDTO dto);
|
||||
|
||||
UserVO getOne(Long id);
|
||||
|
||||
void delete(Long id);
|
||||
|
||||
CommonPageResponse<UserVO> queryByPage(UserQO userQO);
|
||||
|
||||
PageResp<UserVO> find(UserQO1 userQo, PageQO page);
|
||||
|
||||
PageResp<UserRefVO> queryUserAddress(UserQO1 userQo, PageQO page);
|
||||
}
|
||||
@ -0,0 +1,94 @@
|
||||
package cn.axzo.riven.service.user.impl;
|
||||
|
||||
import cn.axzo.framework.domain.data.AssertUtil;
|
||||
import cn.axzo.framework.domain.page.PageQO;
|
||||
import cn.axzo.framework.domain.page.PageResp;
|
||||
import cn.axzo.riven.common.enums.ErrorCode;
|
||||
import cn.axzo.riven.repository.entity.user.UserDO;
|
||||
import cn.axzo.riven.repository.entity.user.UserRefDO;
|
||||
import cn.axzo.riven.service.converter.UserRefConverter;
|
||||
import cn.axzo.riven.service.dto.request.user.NewUserDTO;
|
||||
import cn.axzo.riven.service.dto.request.user.UpdateUserDTO;
|
||||
import cn.axzo.riven.service.dto.request.user.UserQO;
|
||||
import cn.axzo.riven.service.dto.request.user.UserQO1;
|
||||
import cn.axzo.riven.service.dto.response.user.UserRefVO;
|
||||
import cn.axzo.riven.service.dto.response.user.UserVO;
|
||||
import cn.axzo.riven.repository.UserDao;
|
||||
import cn.axzo.riven.service.user.UserService;
|
||||
import cn.axzo.riven.service.converter.UserConverter;
|
||||
import cn.azxo.framework.common.model.CommonPageResponse;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2022/9/2
|
||||
* @Description:
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class UserServiceImpl implements UserService {
|
||||
|
||||
private final UserConverter userConverter;
|
||||
|
||||
private final UserRefConverter userRefConverter;
|
||||
|
||||
private final UserDao userDao;
|
||||
|
||||
@Override
|
||||
public UserVO create(NewUserDTO dto) {
|
||||
UserDO user = userConverter.toEntity(dto);
|
||||
userDao.save(user);
|
||||
return userConverter.toVo(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserVO update(Long id, UpdateUserDTO dto) {
|
||||
UserDO user = userDao.findById(id);
|
||||
AssertUtil.notNull(user, ErrorCode.USER_NOT_EXISTS, id);
|
||||
/*if (user == null) {
|
||||
throw new ApiException(ErrorCode.USER_NOT_EXISTS, id);
|
||||
}*/
|
||||
userConverter.updateEntity(dto, user);
|
||||
return userConverter.toVo(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserVO getOne(Long id) {
|
||||
UserDO user = userDao.findById(id);
|
||||
return userConverter.toVo(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Long id) {
|
||||
userDao.delete(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonPageResponse<UserVO> queryByPage(UserQO userQo) {
|
||||
IPage<UserDO> page = userDao.queryByPage(userQo);
|
||||
List<UserDO> userList = page.getRecords();
|
||||
if (CollectionUtils.isEmpty(userList)) {
|
||||
return CommonPageResponse.zero(userQo.getPage(), userQo.getPageSize());
|
||||
}
|
||||
return new CommonPageResponse<>(page.getCurrent(), page.getSize(), page.getTotal(), userConverter.toVo(page.getRecords()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResp<UserVO> find(UserQO1 userQo, PageQO page) {
|
||||
IPage<UserDO> userPage = userDao.find(userQo, page);
|
||||
return PageResp.list(userPage, userConverter.toVo(userPage.getRecords()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResp<UserRefVO> queryUserAddress(UserQO1 userQo, PageQO page) {
|
||||
IPage<UserRefDO> userRefPage = userDao.findUserAddress(userQo, page);
|
||||
return PageResp.list(userRefPage, userRefConverter.toVo(userRefPage.getRecords()));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
package cn.axzo.riven.service.validator;
|
||||
44
riven-server/src/main/resources/bootstrap.yml
Normal file
44
riven-server/src/main/resources/bootstrap.yml
Normal file
@ -0,0 +1,44 @@
|
||||
spring:
|
||||
application:
|
||||
name: riven
|
||||
cloud:
|
||||
nacos:
|
||||
config:
|
||||
server-addr: ${NACOS_HOST:test-nacos.axzo.cn}:${NACOS_PORT:80}
|
||||
file-extension: yaml
|
||||
namespace: ${NACOS_NAMESPACE_ID:f82179f1-81a9-41a1-a489-4f9ab5660a6e}
|
||||
prefix: ${spring.application.name}
|
||||
profiles:
|
||||
active: ${NACOS_PROFILES_ACTIVE:test}
|
||||
main:
|
||||
allow-bean-definition-overriding: true
|
||||
|
||||
logging:
|
||||
level:
|
||||
com.alibaba.nacos.client.config.impl: WARN
|
||||
|
||||
management:
|
||||
endpoint:
|
||||
metrics:
|
||||
enabled: true
|
||||
prometheus:
|
||||
enabled: true
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: prometheus
|
||||
path-mapping:
|
||||
prometheus: metrics
|
||||
base-path: /
|
||||
metrics:
|
||||
tags:
|
||||
application: ${spring.application.name}
|
||||
export:
|
||||
prometheus:
|
||||
enabled: true
|
||||
server:
|
||||
port: 8081
|
||||
|
||||
resp:
|
||||
error-code:
|
||||
non-base-mapping: {"[*]": OK}
|
||||
10
riven-server/src/main/resources/logback-spring.xml
Normal file
10
riven-server/src/main/resources/logback-spring.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE xml>
|
||||
<configuration>
|
||||
<!-- 导入安心筑全局日志配置 -->
|
||||
<include resource="logback/logback-axzo.xml" />
|
||||
<!-- 覆盖开发环境日志配置 -->
|
||||
<springProfile name="local,dev">
|
||||
<logger name="cn.axzo" level="DEBUG" />
|
||||
</springProfile>
|
||||
</configuration>
|
||||
@ -0,0 +1,14 @@
|
||||
package cn.axzo.maven.archetype.server;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* Unit test for simple App.
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
public class AppTest {
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user