Merge remote-tracking branch 'origin/main'

This commit is contained in:
袁红川 2025-04-19 13:59:03 +08:00
commit 53690f68f5
65 changed files with 603 additions and 217 deletions

View File

@ -1,57 +0,0 @@
---
description:
globs:
alwaysApply: true
---
您是Java编程、Spring Boot、Spring Framework、Maven、JUnit和相关Java技术方面的专家。
代码风格和结构
-使用准确的Spring Boot示例编写干净、高效且文档齐全的Java代码。
-在整个代码中使用Spring Boot最佳实践和约定。
-在创建Web服务时实施RESTful API设计模式。
-按照camelCase约定使用描述性方法和变量名。
-构建Spring Boot应用程序控制器、服务、存储库、模型、配置。
Spring Boot规范
-使用Spring Boot启动器进行快速项目设置和依赖管理。
-正确使用注释(例如@SpringBootApplication、@RestController、@Service
-有效利用Spring Boot的自动配置功能。
-使用@ControlllerAddge和@ExceptionHandler实施正确的异常处理。
命名约定
-将PascalCase用于类名例如UserController、OrderService
-将camelCase用于方法和变量名例如findUserById、isOrderValid
-将ALL_CAPS用于常量例如MAX_RETRY_ATTEMPTS、DEFAULT_PAGE_SIZE
Java和Spring Boot用法
-在适用的情况下使用Java21或更高版本的功能例如记录、密封类、模式匹配
-利用Spring Boot 3.x功能和最佳实践。
-在适用的情况下将Spring Data JPA用于数据库操作。
-使用Bean验证例如@Valid、自定义验证器实现正确的验证。
配置和属性
-使用application.properties或application.yml进行配置。
-使用Spring Profiles实现environment-specific配置。
-使用@ConfigurationProperties进行类型安全的配置属性。依赖注入和IoC
-使用构造函数注入而不是字段注入以获得更好的可测试性。
-利用Spring的IoC容器来管理bean生命周期。
测试
-使用JUnit 5和Spring Boot Test编写单元测试。
-使用@SpringBootTest实现集成测试。
-使用@DataJpaTest进行存储库层测试。性能和可扩展性
-使用Spring Cache抽象实现缓存策略。-使用@Async进行异步处理进行非阻塞操作。
-实施适当的数据库索引和查询优化。
日志记录和监控
-使用SLF4J和Logback进行日志记录。
-实施适当的日志级别ERROR、WARN、INFO、DEBUG
-使用Spring Boot Actuator进行应用程序监控和指标。
API文档
-使用Springdoc OpenAPI以前的Swagger进行API留档。
数据访问和ORM
-使用mybatis plus进行数据库操作。
-实现适当的实体关系和级联。
构建和部署
-使用Maven进行依赖管理和构建流程。
-为不同的环境(开发、测试、产品)实施适当的配置文件。
遵循以下最佳实践:
-RESTful API设计正确使用HTTP方法、状态代码等
-微服务架构(如果适用)。
-使用Spring的@Async进行异步处理.
所有生成的代码都需要加上java注释注意父级maven依赖,尽量使用lombok的getter和setter
工程依赖的包使用的版本号都使用父项目中定义的版本,如果父项目不存在则空

41
.gitignore vendored Normal file
View File

@ -0,0 +1,41 @@
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/
/weight-loss-camp-service-api/target/
/.vscode/
/.idea/
/logs/
/.idea
/.vscode
/logs
/.cursor

8
.idea/.gitignore generated vendored
View File

@ -1,8 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

15
.idea/compiler.xml generated
View File

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="weight-loss-camp-api-base" />
<module name="weight-loss-camp-api-data" />
<module name="weight-loss-camp-service-api" />
</profile>
</annotationProcessing>
</component>
</project>

13
.idea/encodings.xml generated
View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/weight-loss-camp-api-base/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/weight-loss-camp-api-base/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/weight-loss-camp-api-data/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/weight-loss-camp-api-data/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/weight-loss-camp-service-api/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/weight-loss-camp-service-api/src/main/resources" charset="UTF-8" />
</component>
</project>

7
.idea/gradle.xml generated
View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="parallelModelFetch" value="true" />
</component>
</project>

View File

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="central" />
<option name="url" value="https://maven.aliyun.com/nexus/content/groups/public" />
</remote-repository>
<remote-repository>
<option name="id" value="yqz" />
<option name="name" value="yqz" />
<option name="url" value="https://packages.aliyun.com/605daee3fde602776f082f49/maven/yqz" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="snapshots" />
<option name="name" value="snapshots" />
<option name="url" value="https://maven.aliyun.com/nexus/content/groups/public" />
</remote-repository>
</component>
</project>

12
.idea/misc.xml generated
View File

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="17" project-jdk-type="JavaSDK" />
</project>

6
.idea/vcs.xml generated
View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

22
.vscode/launch.json vendored
View File

@ -1,22 +0,0 @@
{
// 使 IntelliSense
//
// 访: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "java",
"name": "Current File",
"request": "launch",
"mainClass": "${file}"
},
{
"type": "java",
"name": "service-api",
"request": "launch",
"mainClass": "com.wjbl.weightlosscamp.service.api.WeightLossCampServiceApiApplication",
"projectName": "weight-loss-camp-service-api",
"vmArgs": "-Dfile.encoding=UTF-8"
}
]
}

22
.vscode/settings.json vendored
View File

@ -1,22 +0,0 @@
{
"maven.view": "hierarchical",
"java.configuration.updateBuildConfiguration": "automatic",
"cSpell.words": [
"Appender",
"Appenders",
"baomidou",
"Hikari",
"ibatis",
"jdbc",
"jsqlparser",
"mybatis",
"Nacos",
"projectlombok",
"springframework",
"wjbl",
"xiaoymin",
"zaxxer"
],
"java.compile.nullAnalysis.mode": "automatic",
"java.format.settings.url": ".vscode/java-formatter.xml"
}

View File

@ -26,6 +26,7 @@
<module>weight-loss-camp-api-base</module>
<module>weight-loss-camp-api-data</module>
<module>weight-loss-camp-service-api</module>
<module>weight-loss-camp-work-api</module>
</modules>
<dependencyManagement>

10
readme.md Normal file
View File

@ -0,0 +1,10 @@
## weight-loss-camp-api-base
基础功能服务
## weight-loss-camp-api-data
数据库连接服务
## weight-loss-camp-service-api
基础服务接口
## weight-loss-camp-work-api
工作端api

View File

@ -55,5 +55,20 @@
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,4 +1,4 @@
package com.wjbl.weightlosscamp.service.api.controller;
package com.wjbl.weightlosscamp.service.api.module.camp.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@ -9,8 +9,8 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wjbl.weightlosscamp.api.base.core.ApiResult;
import com.wjbl.weightlosscamp.api.base.core.IdParam;
import com.wjbl.weightlosscamp.api.base.core.PageParam;
import com.wjbl.weightlosscamp.service.api.dto.CampInfoDTO;
import com.wjbl.weightlosscamp.service.api.service.CampInfoService;
import com.wjbl.weightlosscamp.service.api.module.camp.dto.CampInfoDTO;
import com.wjbl.weightlosscamp.service.api.module.camp.service.CampInfoService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;

View File

@ -1,4 +1,4 @@
package com.wjbl.weightlosscamp.service.api.dto;
package com.wjbl.weightlosscamp.service.api.module.camp.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;

View File

@ -1,4 +1,4 @@
package com.wjbl.weightlosscamp.service.api.dto;
package com.wjbl.weightlosscamp.service.api.module.camp.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;

View File

@ -1,4 +1,4 @@
package com.wjbl.weightlosscamp.service.api.entity;
package com.wjbl.weightlosscamp.service.api.module.camp.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.wjbl.weightlosscamp.api.base.entity.BaseEntity;

View File

@ -1,4 +1,4 @@
package com.wjbl.weightlosscamp.service.api.entity;
package com.wjbl.weightlosscamp.service.api.module.camp.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.wjbl.weightlosscamp.api.base.entity.BaseEntity;

View File

@ -1,4 +1,4 @@
package com.wjbl.weightlosscamp.service.api.entity;
package com.wjbl.weightlosscamp.service.api.module.camp.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.wjbl.weightlosscamp.api.base.entity.BaseEntity;

View File

@ -1,4 +1,4 @@
package com.wjbl.weightlosscamp.service.api.entity;
package com.wjbl.weightlosscamp.service.api.module.camp.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.wjbl.weightlosscamp.api.base.entity.BaseEntity;

View File

@ -1,7 +1,7 @@
package com.wjbl.weightlosscamp.service.api.mapper;
package com.wjbl.weightlosscamp.service.api.module.camp.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wjbl.weightlosscamp.service.api.entity.CampClassroomImage;
import com.wjbl.weightlosscamp.service.api.module.camp.entity.CampClassroomImage;
import org.apache.ibatis.annotations.Mapper;
/**

View File

@ -1,7 +1,7 @@
package com.wjbl.weightlosscamp.service.api.mapper;
package com.wjbl.weightlosscamp.service.api.module.camp.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wjbl.weightlosscamp.service.api.entity.CampClassroom;
import com.wjbl.weightlosscamp.service.api.module.camp.entity.CampClassroom;
import org.apache.ibatis.annotations.Mapper;
/**

View File

@ -1,7 +1,7 @@
package com.wjbl.weightlosscamp.service.api.mapper;
package com.wjbl.weightlosscamp.service.api.module.camp.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wjbl.weightlosscamp.service.api.entity.CampImage;
import com.wjbl.weightlosscamp.service.api.module.camp.entity.CampImage;
import org.apache.ibatis.annotations.Mapper;
/**

View File

@ -1,7 +1,7 @@
package com.wjbl.weightlosscamp.service.api.mapper;
package com.wjbl.weightlosscamp.service.api.module.camp.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wjbl.weightlosscamp.service.api.entity.CampInfo;
import com.wjbl.weightlosscamp.service.api.module.camp.entity.CampInfo;
import org.apache.ibatis.annotations.Mapper;
/**

View File

@ -1,12 +1,12 @@
package com.wjbl.weightlosscamp.service.api.service;
package com.wjbl.weightlosscamp.service.api.module.camp.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.wjbl.weightlosscamp.api.base.core.ApiResult;
import com.wjbl.weightlosscamp.api.base.core.IdParam;
import com.wjbl.weightlosscamp.api.base.core.PageParam;
import com.wjbl.weightlosscamp.service.api.dto.CampInfoDTO;
import com.wjbl.weightlosscamp.service.api.entity.CampInfo;
import com.wjbl.weightlosscamp.service.api.module.camp.dto.CampInfoDTO;
import com.wjbl.weightlosscamp.service.api.module.camp.entity.CampInfo;
/**
* 营地信息服务接口

View File

@ -1,4 +1,4 @@
package com.wjbl.weightlosscamp.service.api.service.impl;
package com.wjbl.weightlosscamp.service.api.module.camp.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -6,10 +6,10 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wjbl.weightlosscamp.api.base.core.ApiResult;
import com.wjbl.weightlosscamp.api.base.core.IdParam;
import com.wjbl.weightlosscamp.api.base.core.PageParam;
import com.wjbl.weightlosscamp.service.api.dto.CampInfoDTO;
import com.wjbl.weightlosscamp.service.api.entity.CampInfo;
import com.wjbl.weightlosscamp.service.api.mapper.CampInfoMapper;
import com.wjbl.weightlosscamp.service.api.service.CampInfoService;
import com.wjbl.weightlosscamp.service.api.module.camp.dto.CampInfoDTO;
import com.wjbl.weightlosscamp.service.api.module.camp.entity.CampInfo;
import com.wjbl.weightlosscamp.service.api.module.camp.mapper.CampInfoMapper;
import com.wjbl.weightlosscamp.service.api.module.camp.service.CampInfoService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

View File

@ -0,0 +1,79 @@
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.wjbl.weightlosscamp.api.base.entity.BaseEntity;
import java.io.File;
import java.util.Arrays;
import java.util.List;
public class Gen {
public static void main(String[] args) {
List<String> tableNameList = Arrays.asList(
"qywx_approve_template_config"
);
gen("jfxly", "root", "123456", tableNameList, "com.wjbl.weightlosscamp.service.api.module.sys");
}
public static void gen(String dbName, String userName, String pwd, List<String> tableNameList, String basePackage) {
String path = System.getProperty("user.dir");
System.out.println(path);
//E:\project\data_process\zhudehao\src\main\java
String url = "jdbc:mysql://localhost:3307/" + dbName + "?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai";
String username = userName;
String password = pwd;
FastAutoGenerator.create(url, username, password)
.globalConfig(builder -> {
builder.author("kevin") // 设置作者
.commentDate("yyyy-MM-dd")
.outputDir(path + File.separator + "weight-loss-camp-service-api" + "\\src\\main\\java")
.disableOpenDir()
.enableSpringdoc()
.dateType(DateType.ONLY_DATE)
//.enableSpringdoc()
; // 指定输出目录
}).packageConfig(builder -> {
builder.parent(basePackage);
}).strategyConfig(builder -> {
builder
.addTablePrefix("tb_")
.addInclude(tableNameList)
.entityBuilder()
.enableFileOverride()
.enableLombok()
//enableTableFieldAnnotation()
.versionColumnName("revision")
.logicDeleteColumnName("deleted")
.superClass(BaseEntity.class)
.addSuperEntityColumns("id", "tenant_id", "created_by_id", "created_by", "created_time", "updated_by", "updated_by_id", "updated_time", "deleted", "revision")
.addIgnoreColumns("dev_remark")
//.enableActiveRecord()
.idType(IdType.ASSIGN_ID)
.controllerBuilder()
//.enableFileOverride()
.enableRestStyle()
.serviceBuilder()
.enableFileOverride()
.formatServiceFileName("%sService")
.formatServiceImplFileName("%sServiceImp")
.mapperBuilder()
.enableMapperAnnotation()
.enableBaseResultMap()
.enableBaseColumnList()
.enableFileOverride()
;
})
.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板默认的是Velocity引擎模板
.execute();
}
}

View File

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.wjbl</groupId>
<artifactId>weight-loss-camp</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>weight-loss-camp-work-api</artifactId>
<packaging>jar</packaging>
<description>营地服务应用API</description>
<dependencies>
<!-- 内部依赖 -->
<dependency>
<groupId>com.wjbl</groupId>
<artifactId>weight-loss-camp-api-base</artifactId>
<version>${project.version}</version>
</dependency>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Cloud OpenFeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- Spring Cloud LoadBalancer -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- Spring Cloud Alibaba Nacos Discovery -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Knife4j -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
</dependency>
<!-- Sa-Token -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot3-starter</artifactId>
<version>1.37.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,21 @@
package com.wjbl.weightlosscamp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* 营地工作服务API启动类
*
* @author generated
*/
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class WorkApiApplication {
public static void main(String[] args) {
SpringApplication.run(WorkApiApplication.class, args);
}
}

View File

@ -0,0 +1,25 @@
package com.wjbl.weightlosscamp.service.api.client;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* 服务Feign客户端
* 使用OpenFeign调用service-api服务
*
* @author generated
*/
@FeignClient(name = "weight-loss-camp-service-api", path = "/service-api")
public interface ServiceFeignClient {
/**
* 示例方法根据ID获取数据
*
* @param id 数据ID
* @return 返回数据字符串
*/
@GetMapping("/example/{id}")
String getExampleDataById(@PathVariable("id") Long id);
}

View File

@ -0,0 +1,149 @@
package com.wjbl.weightlosscamp.service.api.config;
import com.wjbl.weightlosscamp.api.base.constant.WebParamConstant;
import feign.Logger;
import feign.RequestInterceptor;
import feign.Response;
import feign.codec.Decoder;
import feign.codec.Encoder;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Map;
import java.util.UUID;
/**
* Feign配置类
*
* @author generated
*/
@Slf4j
@Configuration
public class FeignConfig {
/**
* 配置Feign日志级别
*/
@Bean
public Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
/**
* 请求拦截器添加traceId用于链路追踪
*/
@Bean
public RequestInterceptor requestInterceptor() {
return requestTemplate -> {
// 添加请求唯一标识
// 设置序列号
String seq = MDC.get(WebParamConstant.SEQ);
if (seq == null || seq.isEmpty()) {
seq = UUID.randomUUID().toString();
}
// 记录请求信息
String method = requestTemplate.method();
String url = requestTemplate.url();
Map<String, Collection<String>> headers = requestTemplate.headers();
StringBuilder requestLog = new StringBuilder();
requestLog.append("\n================================ Feign请求开始 ================================\n");
requestLog.append("请求方式: ").append(method).append("\n");
requestLog.append("请求地址: ").append(url).append("\n");
requestLog.append("请求头: ").append(headers).append("\n");
// 获取请求体
if (requestTemplate.body() != null) {
String bodyStr = new String(requestTemplate.body(), StandardCharsets.UTF_8);
requestLog.append("请求参数: ").append(bodyStr).append("\n");
}
log.info(requestLog.toString());
};
}
/**
* 自定义Feign编码器记录请求参数
*/
@Bean
public Encoder loggingEncoder(Encoder defaultEncoder) {
return (object, bodyType, template) -> {
defaultEncoder.encode(object, bodyType, template);
if (object != null) {
log.info("请求参数对象: {}", object);
}
};
}
/**
* 自定义Feign解码器记录响应结果
*/
@Bean
public Decoder loggingDecoder(Decoder defaultDecoder) {
return (response, type) -> {
long startTime = System.currentTimeMillis();
// 克隆响应因为响应体只能读取一次
Response clonedResponse = cloneResponse(response);
try {
// 记录响应信息
String responseBody = getResponseBody(clonedResponse);
StringBuilder responseLog = new StringBuilder();
responseLog.append("\n================================ Feign响应结果 ================================\n");
responseLog.append("响应状态: ").append(clonedResponse.status()).append("\n");
responseLog.append("响应头: ").append(clonedResponse.headers()).append("\n");
responseLog.append("响应体: ").append(responseBody).append("\n");
responseLog.append("处理时间: ").append(System.currentTimeMillis() - startTime).append("ms\n");
responseLog.append("================================ Feign请求结束 ================================\n");
log.info(responseLog.toString());
// 使用原始响应解码
return defaultDecoder.decode(response, type);
} catch (Exception e) {
log.error("记录Feign响应日志失败", e);
return defaultDecoder.decode(response, type);
}
};
}
/**
* 克隆响应对象
*/
private Response cloneResponse(Response response) {
return Response.builder()
.status(response.status())
.reason(response.reason())
.headers(response.headers())
.body(response.body())
.request(response.request())
.build();
}
/**
* 获取响应体内容
*/
private String getResponseBody(Response response) {
if (response.body() == null) {
return "(空响应体)";
}
try {
byte[] bodyData = feign.Util.toByteArray(response.body().asInputStream());
return new String(bodyData, StandardCharsets.UTF_8);
} catch (IOException e) {
log.error("读取响应体失败", e);
return "(响应体读取失败)";
}
}
}

View File

@ -0,0 +1,16 @@
package com.wjbl.weightlosscamp.service.api.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* Web配置类
*
* @author generated
*/
@Configuration
public class WebConfig implements WebMvcConfigurer {
// Web相关配置如拦截器资源处理器等
}

View File

@ -0,0 +1,47 @@
package com.wjbl.weightlosscamp.service.api.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.wjbl.weightlosscamp.service.api.client.ServiceFeignClient;
import lombok.extern.slf4j.Slf4j;
/**
* 示例控制器
*
* @author generated
*/
@Slf4j
@RestController
@RequestMapping("/example")
public class ExampleController {
@Autowired
private ServiceFeignClient serviceFeignClient;
/**
* 示例方法通过Feign调用服务API
*
* @param id 数据ID
* @return 返回数据字符串
*/
@GetMapping("/{id}")
public String getExample(@PathVariable Long id) {
log.info("接收到获取示例数据请求, id={}", id);
return serviceFeignClient.getExampleDataById(id);
}
/**
* 健康检查接口
*
* @return 返回健康状态
*/
@GetMapping("/health")
public String health() {
return "work-api服务运行正常!";
}
}

View File

@ -0,0 +1,48 @@
server:
port: 9001
servlet:
context-path: /work-api
spring:
application:
name: weight-loss-camp-work-api
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3307/kevin?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: 123456
cloud:
nacos:
discovery:
server-addr: 60.205.225.2:8848
group: weight-loss-camp
# OpenFeign配置
openfeign:
client:
config:
default:
connectTimeout: 5000
readTimeout: 5000
loggerLevel: FULL
# 日志配置
logging:
level:
com.wjbl.weight.loss.camp.service.api.apiservice: DEBUG
# Knife4j配置
knife4j:
enable: true
setting:
language: zh-CN
# Sa-Token配置
sa-token:
token-name: Authorization
token-prefix: Bearer
timeout: 2592000
active-timeout: -1
is-concurrent: true
is-share: false
token-style: uuid
is-log: true

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30">
<Properties>
<Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{TraceId}] %-5level %logger{36} - %msg%n</Property>
<Property name="LOG_FILE_PATH">logs/weight-loss-camp-work-api</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${LOG_PATTERN}" />
</Console>
<RollingFile name="FileAppender" fileName="${LOG_FILE_PATH}/application.log" filePattern="${LOG_FILE_PATH}/application-%d{yyyy-MM-dd}-%i.log">
<PatternLayout pattern="${LOG_PATTERN}" />
<Policies>
<TimeBasedTriggeringPolicy interval="1" />
<SizeBasedTriggeringPolicy size="10MB" />
</Policies>
<DefaultRolloverStrategy max="10" />
</RollingFile>
<RollingFile name="ErrorFileAppender" fileName="${LOG_FILE_PATH}/error.log" filePattern="${LOG_FILE_PATH}/error-%d{yyyy-MM-dd}-%i.log">
<PatternLayout pattern="${LOG_PATTERN}" />
<Policies>
<TimeBasedTriggeringPolicy interval="1" />
<SizeBasedTriggeringPolicy size="10MB" />
</Policies>
<DefaultRolloverStrategy max="10" />
<Filters>
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY" />
</Filters>
</RollingFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console" />
<AppenderRef ref="FileAppender" />
<AppenderRef ref="ErrorFileAppender" />
</Root>
<Logger name="com.wjbl.weight-loss-camp" level="debug" additivity="false">
<AppenderRef ref="Console" />
<AppenderRef ref="FileAppender" />
<AppenderRef ref="ErrorFileAppender" />
</Logger>
</Loggers>
</Configuration>