fix: 确保项目可以启动
This commit is contained in:
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"permissions": {
|
|
||||||
"allow": [
|
|
||||||
"Bash(cat:*)",
|
|
||||||
"Bash(find ./aioj-backend-common -path \"*common-log*pom.xml\" -exec cat {} ;)"
|
|
||||||
],
|
|
||||||
"deny": [],
|
|
||||||
"ask": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
2
.idea/CoolRequestCommonStatePersistent.xml
generated
2
.idea/CoolRequestCommonStatePersistent.xml
generated
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="CoolRequestCommonStatePersistent">
|
<component name="CoolRequestCommonStatePersistent">
|
||||||
<option name="searchCache" value="/*" />
|
<option name="searchCache" value="AIOJAdminA" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
6
.idea/copilot.data.migration.agent.xml
generated
Normal file
6
.idea/copilot.data.migration.agent.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="AgentMigrationStateService">
|
||||||
|
<option name="migrationStatus" value="COMPLETED" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
250
CLAUDE.md
250
CLAUDE.md
@@ -4,83 +4,193 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|||||||
|
|
||||||
## Project Overview
|
## Project Overview
|
||||||
|
|
||||||
This is an AI-integrated OJ (Online Judge) judging system with a microservices architecture. The system allows users to submit code for programming problems, which is then judged automatically. It also includes AI features to assist with problem-solving and code evaluation.
|
This is a microservices-based Online Judge (OJ) system with AI integration called AIOJ (AI Online Judge). It's built with Spring Boot 3.5.7 and Spring Cloud 2025.0.0, following a modular Maven multi-module architecture.
|
||||||
|
|
||||||
## Architecture
|
## Common Development Commands
|
||||||
|
|
||||||
The project follows a microservices architecture pattern built with Spring Boot and Spring Cloud Alibaba:
|
|
||||||
|
|
||||||
### Core Modules:
|
|
||||||
|
|
||||||
1. **aioj-backend-common**: Common utilities and dependencies shared across all modules.
|
|
||||||
2. **aioj-backend-gateway**: API gateway that routes requests to the appropriate microservices.
|
|
||||||
3. **aioj-backend-judge-service**: Handles code submission, compilation, and judging processes.
|
|
||||||
4. **aioj-backend-user-service**: Manages user accounts, authentication, and authorization.
|
|
||||||
5. **aioj-backend-question-service**: Manages programming problems and test cases.
|
|
||||||
6. **aioj-backend-ai-service**: Provides AI-assisted features such as code analysis and problem-solving.
|
|
||||||
7. **aioj-backend-auth**: Manages authentication and token issuance.
|
|
||||||
8. **aioj-backend-upms**: User Management System for administrative operations.
|
|
||||||
|
|
||||||
## Database
|
|
||||||
|
|
||||||
The system uses SQL databases. Database scripts can be found in the `db/` directory.
|
|
||||||
|
|
||||||
## Build System
|
|
||||||
|
|
||||||
The project uses Maven for build and dependency management.
|
|
||||||
|
|
||||||
### Common Commands:
|
|
||||||
|
|
||||||
- Compile the entire project:
|
|
||||||
```bash
|
|
||||||
mvn clean compile
|
|
||||||
```
|
|
||||||
|
|
||||||
- Compile a specific module:
|
|
||||||
```bash
|
|
||||||
mvn clean compile -pl <module-name>
|
|
||||||
```
|
|
||||||
|
|
||||||
- Package the entire project:
|
|
||||||
```bash
|
|
||||||
mvn clean package
|
|
||||||
```
|
|
||||||
|
|
||||||
- Package a specific module:
|
|
||||||
```bash
|
|
||||||
mvn clean package -pl <module-name>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Development
|
|
||||||
|
|
||||||
### Environment Profiles
|
|
||||||
|
|
||||||
The project supports different environments (dev, test, prod) with corresponding configuration files:
|
|
||||||
|
|
||||||
- Development: application-dev.yml
|
|
||||||
- Test: application-test.yml
|
|
||||||
- Production: application-prod.yml
|
|
||||||
|
|
||||||
### Running a Service
|
|
||||||
|
|
||||||
To run a specific microservice, use the Spring Boot Maven plugin:
|
|
||||||
|
|
||||||
|
### Building the Project
|
||||||
```bash
|
```bash
|
||||||
cd <module-name>
|
# Build entire project
|
||||||
|
mvn clean install
|
||||||
|
|
||||||
|
# Build with specific environment profile
|
||||||
|
mvn clean install -P dev # Development (default)
|
||||||
|
mvn clean install -P test # Testing
|
||||||
|
mvn clean install -P prod # Production
|
||||||
|
|
||||||
|
# Format code according to Spring standards
|
||||||
|
mvn spring-javaformat:apply
|
||||||
|
|
||||||
|
# Build Docker images using Jib
|
||||||
|
mvn clean package jib:build
|
||||||
|
|
||||||
|
# Or use Maven wrapper
|
||||||
|
./mvnw clean install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Running Services
|
||||||
|
Each service runs on different ports:
|
||||||
|
- Gateway: 8085
|
||||||
|
- Other services: configured via Nacos
|
||||||
|
|
||||||
|
Run individual services from their respective directories:
|
||||||
|
```bash
|
||||||
|
cd aioj-backend-gateway
|
||||||
mvn spring-boot:run
|
mvn spring-boot:run
|
||||||
|
|
||||||
|
# Or with specific profile
|
||||||
|
mvn spring-boot:run -Dspring.profiles.active=dev
|
||||||
```
|
```
|
||||||
|
|
||||||
Or run the built JAR file:
|
### Database Setup
|
||||||
|
1. Create databases using the provided script:
|
||||||
```bash
|
```bash
|
||||||
cd <module-name>/target
|
mysql -u root -p < db/create_db.sql
|
||||||
java -jar <module-name>-<version>.jar
|
```
|
||||||
|
This creates three databases: `aioj_dev`, `aioj_test`, and `aioj_prod`
|
||||||
|
|
||||||
|
## Architecture Overview
|
||||||
|
|
||||||
|
### Microservices Architecture
|
||||||
|
The system consists of seven main services:
|
||||||
|
|
||||||
|
1. **aioj-backend-gateway** (Port 8085)
|
||||||
|
- API Gateway using Spring Cloud Gateway
|
||||||
|
- Routes requests to appropriate services
|
||||||
|
- Built with WebFlux for reactive programming
|
||||||
|
|
||||||
|
2. **aioj-backend-auth**
|
||||||
|
- OAuth2 authentication and authorization service
|
||||||
|
- Manages user credentials and tokens
|
||||||
|
|
||||||
|
3. **aioj-backend-user-service**
|
||||||
|
- User management and profiles
|
||||||
|
- Handles registration, login, profile updates
|
||||||
|
- Integrates with Redis for session management
|
||||||
|
|
||||||
|
4. **aioj-backend-question-service**
|
||||||
|
- Problem/question management
|
||||||
|
- Handles problem storage and retrieval
|
||||||
|
|
||||||
|
5. **aioj-backend-judge-service**
|
||||||
|
- Core OJ functionality for code execution
|
||||||
|
- Supports multiple programming languages
|
||||||
|
|
||||||
|
6. **aioj-backend-ai-service**
|
||||||
|
- AI integration for enhanced features
|
||||||
|
- Code analysis and automated feedback
|
||||||
|
|
||||||
|
7. **aioj-backend-upms** (User Permission Management System)
|
||||||
|
- Role-based access control
|
||||||
|
- Permission management
|
||||||
|
|
||||||
|
### Common Modules
|
||||||
|
- **aioj-backend-common**: Shared utilities with sub-modules:
|
||||||
|
- `core`: Core utilities and configurations
|
||||||
|
- `log`: Custom logging implementation
|
||||||
|
- `starter`: Auto-configuration starters
|
||||||
|
- `mybatis`: Database access layer
|
||||||
|
- `feign`: HTTP client for service communication
|
||||||
|
- `bom`: Bill of Materials for dependency management
|
||||||
|
|
||||||
|
## Technology Stack
|
||||||
|
|
||||||
|
### Core Technologies
|
||||||
|
- **Java 17**
|
||||||
|
- **Spring Boot 3.5.7**
|
||||||
|
- **Spring Cloud 2025.0.0**
|
||||||
|
- **Spring Cloud Alibaba 2025.0.0.0**
|
||||||
|
- **Maven** for build management
|
||||||
|
|
||||||
|
### Database & Persistence
|
||||||
|
- **MySQL 9.4.0** as primary database
|
||||||
|
- **MyBatis-Plus 3.5.14** for ORM
|
||||||
|
- **Redis** for caching and session management
|
||||||
|
|
||||||
|
### Cloud & Infrastructure
|
||||||
|
- **Nacos** for service discovery and configuration (server: 10.0.0.10:8848)
|
||||||
|
- **Spring Cloud Gateway** for API routing
|
||||||
|
- **Docker** with Jib plugin for containerization
|
||||||
|
- **Sentinel** for circuit breaking
|
||||||
|
|
||||||
|
### Security
|
||||||
|
- **Spring Security 6.5.6** with OAuth2
|
||||||
|
- JWT token-based authentication
|
||||||
|
- Role-based access control
|
||||||
|
|
||||||
|
### API Documentation
|
||||||
|
- **Knife4j** (OpenAPI 3) integrated across services
|
||||||
|
|
||||||
|
## Configuration Management
|
||||||
|
|
||||||
|
### Environment-Specific Configuration
|
||||||
|
Three environments are supported:
|
||||||
|
- `dev` (development, default)
|
||||||
|
- `test` (testing)
|
||||||
|
- `prod` (production)
|
||||||
|
|
||||||
|
Configuration files:
|
||||||
|
- `bootstrap.yml` - Nacos service discovery configuration
|
||||||
|
- `application.yml` - Main application configuration
|
||||||
|
- `application-{env}.yml` - Environment-specific settings
|
||||||
|
|
||||||
|
### Nacos Integration
|
||||||
|
All services use Nacos for:
|
||||||
|
- Service discovery
|
||||||
|
- Configuration management
|
||||||
|
- Centralized properties management
|
||||||
|
|
||||||
|
Default Nacos configuration:
|
||||||
|
```yaml
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
discovery:
|
||||||
|
server-addr: 10.0.0.10:8848
|
||||||
|
username: nacos
|
||||||
|
password: nacos
|
||||||
```
|
```
|
||||||
|
|
||||||
## Technologies Used
|
## Database Schema
|
||||||
|
|
||||||
- **Java 17**: Programming language
|
### Environment Databases
|
||||||
- **Spring Boot 3.5.7**: Framework for building microservices
|
- Development: `aioj_dev`
|
||||||
- **Spring Cloud Alibaba 2025.0.0.0**: Microservices ecosystem
|
- Testing: `aioj_test`
|
||||||
- **Maven**: Build tool
|
- Production: `aioj_prod`
|
||||||
- **Lombok**: Java library to reduce boilerplate code
|
|
||||||
|
All databases use UTF-8 character set with `utf8mb4_general_ci` collation.
|
||||||
|
|
||||||
|
## Development Guidelines
|
||||||
|
|
||||||
|
### Code Formatting
|
||||||
|
- Uses Spring JavaFormat plugin for consistent code style
|
||||||
|
- IDE plugin available: https://repo1.maven.org/maven2/io/spring/javaformat/spring-javaformat-intellij-idea-plugin
|
||||||
|
- Run `mvn spring-javaformat:apply` before commits
|
||||||
|
|
||||||
|
### Docker Integration
|
||||||
|
- Jib plugin configured for container builds
|
||||||
|
- Target registry: `10.0.0.3/aioj/{service-name}:{version}`
|
||||||
|
- JVM memory configured: -Xms512m -Xmx512m
|
||||||
|
|
||||||
|
### Service Communication
|
||||||
|
- Uses OpenFeign for inter-service communication
|
||||||
|
- Load balancing with Spring Cloud LoadBalancer
|
||||||
|
- Circuit breaking with Sentinel
|
||||||
|
|
||||||
|
### Logging
|
||||||
|
- Custom logging implementation in `aioj-backend-common-log`
|
||||||
|
- Integrates with Spring Security for context logging
|
||||||
|
- Uses Hutool utilities for enhanced logging
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
- Spring Boot Test framework included
|
||||||
|
- Spring Security Test for authentication testing
|
||||||
|
- Test structure is evolving - check individual modules for test coverage
|
||||||
|
|
||||||
|
## Important Notes
|
||||||
|
|
||||||
|
1. **Service Dependencies**: Services depend on Nacos for discovery - ensure Nacos is running before starting services
|
||||||
|
2. **Database Setup**: Run the database creation script before first run
|
||||||
|
3. **Port Configuration**: Gateway runs on 8085, other services are dynamically registered
|
||||||
|
4. **Environment Profiles**: Default is `dev` - use appropriate profiles for different environments
|
||||||
|
5. **Configuration Management**: Most configuration is externalized to Nacos - check Nacos for service-specific settings
|
||||||
@@ -19,40 +19,51 @@
|
|||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<!-- 核心模块 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.meowrain</groupId>
|
||||||
|
<artifactId>aioj-backend-common-core</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.meowrain</groupId>
|
||||||
|
<artifactId>aioj-backend-common-feign</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- spring cloud发现服务-->
|
<!-- 工具类 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-crypto</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Spring Cloud服务发现 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.alibaba.cloud</groupId>
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- OAuth2 Client -->
|
|
||||||
|
<!-- Web -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- OAuth2 & Spring Security -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-oauth2-client</artifactId>
|
<artifactId>spring-boot-starter-oauth2-client</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- Spring Security -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-security</artifactId>
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<!-- JWT -->
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-devtools</artifactId>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<!--JWT-->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.jsonwebtoken</groupId>
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
<artifactId>jjwt-api</artifactId>
|
<artifactId>jjwt-api</artifactId>
|
||||||
@@ -70,37 +81,42 @@
|
|||||||
<version>0.13.0</version>
|
<version>0.13.0</version>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/com.github.xiaoymin/knife4j-openapi3-jakarta-spring-boot-starter -->
|
|
||||||
<dependency>
|
<!-- Feign客户端 -->
|
||||||
<groupId>com.github.xiaoymin</groupId>
|
|
||||||
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<!--
|
|
||||||
引用通用模块
|
|
||||||
-->
|
|
||||||
<dependency>
|
|
||||||
<groupId>cn.meowrain</groupId>
|
|
||||||
<artifactId>aioj-backend-common-starter</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
<!--引入openfeign-->
|
|
||||||
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.cloud</groupId>
|
<groupId>org.springframework.cloud</groupId>
|
||||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||||
<version>4.3.0</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.cloud</groupId>
|
<groupId>org.springframework.cloud</groupId>
|
||||||
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||||
<version>4.3.0</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 引入redis,存储refreshToken-->
|
<!-- Redis用于存储refreshToken -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- API文档 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.xiaoymin</groupId>
|
||||||
|
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 开发工具 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-devtools</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 测试 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
@@ -13,6 +13,6 @@ public interface UserClient {
|
|||||||
Result<UserAuthRespDTO> getUserByUserName(@RequestParam("userAccount") String userAccount);
|
Result<UserAuthRespDTO> getUserByUserName(@RequestParam("userAccount") String userAccount);
|
||||||
|
|
||||||
@GetMapping("/inner/get-by-userid")
|
@GetMapping("/inner/get-by-userid")
|
||||||
public Result<UserAuthRespDTO> getUserById(@RequestParam("userId") String userid);
|
public Result<UserAuthRespDTO> getUserById(@RequestParam("userId") String userId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,9 @@ package cn.meowrain.aioj.backend.auth.controller;
|
|||||||
import cn.meowrain.aioj.backend.auth.dto.req.UserLoginRequestDTO;
|
import cn.meowrain.aioj.backend.auth.dto.req.UserLoginRequestDTO;
|
||||||
import cn.meowrain.aioj.backend.auth.dto.resp.UserLoginResponseDTO;
|
import cn.meowrain.aioj.backend.auth.dto.resp.UserLoginResponseDTO;
|
||||||
import cn.meowrain.aioj.backend.auth.service.AuthService;
|
import cn.meowrain.aioj.backend.auth.service.AuthService;
|
||||||
import cn.meowrain.aioj.backend.framework.web.Results;
|
|
||||||
import cn.meowrain.aioj.backend.framework.web.Result;
|
import cn.meowrain.aioj.backend.framework.core.web.Result;
|
||||||
|
import cn.meowrain.aioj.backend.framework.core.web.Results;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@@ -33,4 +34,16 @@ public class AuthController {
|
|||||||
return Results.success(userLoginResponseDTO.getAccessToken());
|
return Results.success(userLoginResponseDTO.getAccessToken());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/validate")
|
||||||
|
public Result<Boolean> validate(@RequestHeader(value = "Authorization", required = false) String authorization) {
|
||||||
|
// 从Authorization头中提取Bearer token
|
||||||
|
String token = null;
|
||||||
|
if (authorization != null && authorization.startsWith("Bearer ")) {
|
||||||
|
token = authorization.substring(7);
|
||||||
|
}
|
||||||
|
|
||||||
|
Boolean isValid = authService.validateToken(token);
|
||||||
|
return Results.success(isValid);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ package cn.meowrain.aioj.backend.auth.dto.chains;
|
|||||||
|
|
||||||
import cn.meowrain.aioj.backend.auth.common.enums.ChainMarkEnums;
|
import cn.meowrain.aioj.backend.auth.common.enums.ChainMarkEnums;
|
||||||
import cn.meowrain.aioj.backend.auth.dto.req.UserLoginRequestDTO;
|
import cn.meowrain.aioj.backend.auth.dto.req.UserLoginRequestDTO;
|
||||||
import cn.meowrain.aioj.backend.framework.designpattern.chains.AbstractChianHandler;
|
|
||||||
import cn.meowrain.aioj.backend.framework.errorcode.ErrorCode;
|
import cn.meowrain.aioj.backend.framework.core.designpattern.chains.AbstractChianHandler;
|
||||||
import cn.meowrain.aioj.backend.framework.exception.ClientException;
|
import cn.meowrain.aioj.backend.framework.core.errorcode.ErrorCode;
|
||||||
|
import cn.meowrain.aioj.backend.framework.core.exception.ClientException;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|||||||
@@ -19,4 +19,11 @@ public interface AuthService {
|
|||||||
*/
|
*/
|
||||||
UserLoginResponseDTO refreshToken(String refreshToken);
|
UserLoginResponseDTO refreshToken(String refreshToken);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证token的有效性
|
||||||
|
* @param accessToken 访问令牌
|
||||||
|
* @return token是否有效
|
||||||
|
*/
|
||||||
|
Boolean validateToken(String accessToken);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,23 +39,37 @@ public class AuthServiceImpl implements AuthService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserLoginResponseDTO userLogin(UserLoginRequestDTO requestParam) {
|
public UserLoginResponseDTO userLogin(UserLoginRequestDTO requestParam) {
|
||||||
|
log.info("用户登录请求: userAccount={}", requestParam.getUserAccount());
|
||||||
|
|
||||||
// 1.校验
|
// 1.校验
|
||||||
userLoginRequestParamVerifyContext.handler(ChainMarkEnums.USER_LOGIN_REQ_PARAM_VERIFY.getMarkName(),
|
userLoginRequestParamVerifyContext.handler(ChainMarkEnums.USER_LOGIN_REQ_PARAM_VERIFY.getMarkName(),
|
||||||
requestParam);
|
requestParam);
|
||||||
|
|
||||||
// 如果调用user-service失败,那么就说明是系统内部错误
|
// 如果调用user-service失败,那么就说明是系统内部错误
|
||||||
|
log.info("正在调用user-service查询用户信息...");
|
||||||
Result<UserAuthRespDTO> userResp = userClient.getUserByUserName(requestParam.getUserAccount());
|
Result<UserAuthRespDTO> userResp = userClient.getUserByUserName(requestParam.getUserAccount());
|
||||||
|
|
||||||
if (userResp.isFail()) {
|
if (userResp.isFail()) {
|
||||||
log.error("调用user-service返回失败:{}", userResp.getMessage());
|
log.error("调用user-service返回失败:{}", userResp.getMessage());
|
||||||
throw new ServiceException(ErrorCode.SYSTEM_ERROR);
|
throw new ServiceException(ErrorCode.SYSTEM_ERROR);
|
||||||
}
|
}
|
||||||
UserAuthRespDTO user = userResp.getData();
|
|
||||||
|
|
||||||
if (ObjectUtil.isNull(user) || !BCrypt.checkpw(requestParam.getUserPassword(), user.getUserPassword())) {
|
UserAuthRespDTO user = userResp.getData();
|
||||||
throw new ServiceException("用户不存在或者密码错误", ErrorCode.NOT_LOGIN_ERROR);
|
if (user == null) {
|
||||||
|
log.warn("用户不存在: {}", requestParam.getUserAccount());
|
||||||
|
throw new ServiceException("用户不存在或密码错误", ErrorCode.NOT_LOGIN_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!BCrypt.checkpw(requestParam.getUserPassword(), user.getUserPassword())) {
|
||||||
|
log.warn("密码错误: {}", requestParam.getUserAccount());
|
||||||
|
throw new ServiceException("用户不存在或密码错误", ErrorCode.NOT_LOGIN_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
// 生成 JWT
|
// 生成 JWT
|
||||||
|
log.info("正在生成JWT token...");
|
||||||
String accessToken = jwtUtil.generateAccessToken(user);
|
String accessToken = jwtUtil.generateAccessToken(user);
|
||||||
String refreshToken = jwtUtil.generateRefreshToken(user.getId());
|
String refreshToken = jwtUtil.generateRefreshToken(user.getId());
|
||||||
|
|
||||||
UserLoginResponseDTO resp = new UserLoginResponseDTO();
|
UserLoginResponseDTO resp = new UserLoginResponseDTO();
|
||||||
resp.setId(user.getId());
|
resp.setId(user.getId());
|
||||||
resp.setUserAccount(user.getUserAccount());
|
resp.setUserAccount(user.getUserAccount());
|
||||||
@@ -66,6 +80,8 @@ public class AuthServiceImpl implements AuthService {
|
|||||||
stringRedisTemplate.opsForValue()
|
stringRedisTemplate.opsForValue()
|
||||||
.set(String.format(RedisKeyConstants.REFRESH_TOKEN_KEY_PREFIX, user.getId()), refreshToken,
|
.set(String.format(RedisKeyConstants.REFRESH_TOKEN_KEY_PREFIX, user.getId()), refreshToken,
|
||||||
jwtPropertiesConfiguration.getRefreshExpire(), TimeUnit.MILLISECONDS);
|
jwtPropertiesConfiguration.getRefreshExpire(), TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
|
log.info("用户登录成功: userId={}, userAccount={}", user.getId(), user.getUserAccount());
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,4 +122,46 @@ public class AuthServiceImpl implements AuthService {
|
|||||||
return userLoginResponseDTO;
|
return userLoginResponseDTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证token的有效性
|
||||||
|
* @param accessToken 访问令牌
|
||||||
|
* @return token是否有效
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Boolean validateToken(String accessToken) {
|
||||||
|
try {
|
||||||
|
// 1. 检查token格式
|
||||||
|
if (accessToken == null || accessToken.trim().isEmpty()) {
|
||||||
|
log.warn("Access token is null or empty");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 验证token签名和过期时间
|
||||||
|
if (!jwtUtil.isTokenValid(accessToken)) {
|
||||||
|
log.warn("Access token is invalid or expired");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 解析token获取用户信息
|
||||||
|
String userId = jwtUtil.parseClaims(accessToken).getSubject();
|
||||||
|
if (userId == null) {
|
||||||
|
log.warn("Access token does not contain valid user id");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 验证用户是否存在(可选,增加安全性)
|
||||||
|
Result<UserAuthRespDTO> userResult = userClient.getUserById(userId);
|
||||||
|
if (userResult.isFail() || userResult.getData() == null) {
|
||||||
|
log.warn("User not found for id: {}", userId);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug("Access token validation successful for user: {}", userId);
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error validating access token", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,11 +18,6 @@
|
|||||||
<spring-cloud-gateway.version>4.3.2</spring-cloud-gateway.version>
|
<spring-cloud-gateway.version>4.3.2</spring-cloud-gateway.version>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
|
||||||
<groupId>cn.meowrain</groupId>
|
|
||||||
<artifactId>aioj-backend-common-starter</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||||
@@ -66,5 +61,27 @@
|
|||||||
<artifactId>spring-cloud-starter-bootstrap</artifactId>
|
<artifactId>spring-cloud-starter-bootstrap</artifactId>
|
||||||
<version>4.3.0</version>
|
<version>4.3.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.meowrain</groupId>
|
||||||
|
<artifactId>aioj-backend-common-core</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<exclusions>
|
||||||
|
<!-- 🚫 必须排除:Spring MVC 核心 -->
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<!-- 🚫 必须排除:Servlet API (Gateway用不到) -->
|
||||||
|
<exclusion>
|
||||||
|
<groupId>jakarta.servlet</groupId>
|
||||||
|
<artifactId>jakarta.servlet-api</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<!-- 🚫 必须排除:Spring WebMVC -->
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-webmvc</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package cn.meowrain.aioj.backend.gateway.config;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.reactive.function.client.WebClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网关配置类
|
||||||
|
*/
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
@EnableConfigurationProperties(GatewayPropertiesConfiguration.class)
|
||||||
|
public class GatewayConfiguration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WebClient Bean,用于服务间调用
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public WebClient.Builder webClientBuilder() {
|
||||||
|
return WebClient.builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,7 +2,12 @@ package cn.meowrain.aioj.backend.gateway.config;
|
|||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
@ConfigurationProperties(prefix = GatewayPropertiesConfiguration.PREFIX)
|
@ConfigurationProperties(prefix = GatewayPropertiesConfiguration.PREFIX)
|
||||||
@Data
|
@Data
|
||||||
public class GatewayPropertiesConfiguration {
|
public class GatewayPropertiesConfiguration {
|
||||||
@@ -10,8 +15,9 @@ public class GatewayPropertiesConfiguration {
|
|||||||
public static final String PREFIX = "aioj-backend-gateway";
|
public static final String PREFIX = "aioj-backend-gateway";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 白名单放行
|
* 白名单放行路径
|
||||||
|
* 支持Ant风格路径匹配,如 /api/v1/question/**
|
||||||
*/
|
*/
|
||||||
private String[] whiteList;
|
private List<String> whiteList = new ArrayList<>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +1,169 @@
|
|||||||
package cn.meowrain.aioj.backend.gateway.filter;
|
package cn.meowrain.aioj.backend.gateway.filter;
|
||||||
|
|
||||||
|
import cn.meowrain.aioj.backend.framework.core.errorcode.ErrorCode;
|
||||||
|
import cn.meowrain.aioj.backend.framework.core.exception.RemoteException;
|
||||||
|
import cn.meowrain.aioj.backend.framework.core.web.Result;
|
||||||
|
import cn.meowrain.aioj.backend.framework.core.web.Results;
|
||||||
|
import cn.meowrain.aioj.backend.gateway.config.GatewayPropertiesConfiguration;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||||
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
|
import org.springframework.core.io.buffer.DataBuffer;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||||
|
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||||
|
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.AntPathMatcher;
|
||||||
import org.springframework.web.reactive.function.client.WebClient;
|
import org.springframework.web.reactive.function.client.WebClient;
|
||||||
import org.springframework.web.server.ServerWebExchange;
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class AuthGlobalFilter implements GlobalFilter, Ordered {
|
public class AuthGlobalFilter implements GlobalFilter, Ordered {
|
||||||
|
|
||||||
private final WebClient.Builder webClientBuilder;
|
private final WebClient.Builder webClientBuilder;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private GatewayPropertiesConfiguration gatewayPropertiesConfiguration;
|
||||||
|
|
||||||
|
private final AntPathMatcher antPathMatcher = new AntPathMatcher();
|
||||||
|
|
||||||
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 不需要认证的路径
|
||||||
|
*/
|
||||||
|
private static final String[] DEFAULT_WHITE_LIST = {
|
||||||
|
"/api/v1/auth/login",
|
||||||
|
"/api/v1/auth/register",
|
||||||
|
"/api/v1/auth/refresh",
|
||||||
|
"/api/v1/user/info"
|
||||||
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||||
return null;
|
ServerHttpRequest request = exchange.getRequest();
|
||||||
|
String path = request.getURI().getPath();
|
||||||
|
|
||||||
|
log.info("Auth filter processing request: {}", path);
|
||||||
|
|
||||||
|
// 检查是否在白名单中
|
||||||
|
if (isWhiteListPath(path)) {
|
||||||
|
log.info("Path {} is in whitelist, skip authentication", path);
|
||||||
|
return chain.filter(exchange);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取Authorization头
|
||||||
|
String authHeader = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
|
||||||
|
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
|
||||||
|
log.warn("No valid authorization header found for path: {}", path);
|
||||||
|
return handleUnauthorized(exchange);
|
||||||
|
}
|
||||||
|
|
||||||
|
String token = authHeader.substring(7);
|
||||||
|
|
||||||
|
// 调用auth服务验证token
|
||||||
|
return validateToken(token)
|
||||||
|
.flatMap(isValid -> {
|
||||||
|
if (isValid) {
|
||||||
|
log.info("Token validation successful for path: {}", path);
|
||||||
|
return chain.filter(exchange);
|
||||||
|
} else {
|
||||||
|
log.warn("Token validation failed for path: {}", path);
|
||||||
|
return handleUnauthorized(exchange);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.onErrorResume(throwable -> {
|
||||||
|
log.error("Token validation error for path: {}", path, throwable);
|
||||||
|
return handleUnauthorized(exchange);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查路径是否在白名单中
|
||||||
|
*/
|
||||||
|
private boolean isWhiteListPath(String path) {
|
||||||
|
// 先检查默认白名单
|
||||||
|
for (String whitePath : DEFAULT_WHITE_LIST) {
|
||||||
|
if (antPathMatcher.match(whitePath, path)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查配置文件中的白名单
|
||||||
|
if (gatewayPropertiesConfiguration.getWhiteList() != null && !gatewayPropertiesConfiguration.getWhiteList().isEmpty()) {
|
||||||
|
for (String whitePath : gatewayPropertiesConfiguration.getWhiteList()) {
|
||||||
|
if (antPathMatcher.match(whitePath, path)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调用auth服务验证token
|
||||||
|
*/
|
||||||
|
private Mono<Boolean> validateToken(String token) {
|
||||||
|
return webClientBuilder.build()
|
||||||
|
.post()
|
||||||
|
.uri("lb://auth-service/api/v1/auth/validate")
|
||||||
|
.header(HttpHeaders.AUTHORIZATION, "Bearer " + token)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.retrieve()
|
||||||
|
.bodyToMono(String.class)
|
||||||
|
.map(response -> {
|
||||||
|
try {
|
||||||
|
// 解析响应,判断是否有效
|
||||||
|
Result result = objectMapper.readValue(response, Result.class);
|
||||||
|
return Objects.equals(result.getCode(), Result.SUCCESS_CODE);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
log.error("Failed to parse auth response", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.defaultIfEmpty(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理未授权的请求
|
||||||
|
*/
|
||||||
|
private Mono<Void> handleUnauthorized(ServerWebExchange exchange) {
|
||||||
|
ServerHttpResponse response = exchange.getResponse();
|
||||||
|
response.setStatusCode(HttpStatus.UNAUTHORIZED);
|
||||||
|
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
|
||||||
|
Result<Void> result = Results.failure(new RemoteException(ErrorCode.NO_AUTH_ERROR));
|
||||||
|
String responseBody;
|
||||||
|
try {
|
||||||
|
responseBody = objectMapper.writeValueAsString(result);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
responseBody = "{\"code\":401,\"message\":\"Unauthorized\",\"data\":null}";
|
||||||
|
}
|
||||||
|
|
||||||
|
DataBuffer buffer = response.bufferFactory().wrap(responseBody.getBytes(StandardCharsets.UTF_8));
|
||||||
|
return response.writeWith(Mono.just(buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getOrder() {
|
public int getOrder() {
|
||||||
return 0;
|
// 设置较高的优先级,确保在其他过滤器之前执行
|
||||||
|
return -100;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,13 +7,28 @@ spring:
|
|||||||
webflux:
|
webflux:
|
||||||
routes:
|
routes:
|
||||||
- id: auth-service
|
- id: auth-service
|
||||||
uri: lb://auth-service
|
uri: lb://auth-service/api
|
||||||
predicates:
|
predicates:
|
||||||
- Path=/api/v1/auth/**
|
- Path=/api/v1/auth/**
|
||||||
- id: user-service
|
- id: user-service
|
||||||
uri: lb://user-service
|
uri: lb://user-service/api
|
||||||
predicates:
|
predicates:
|
||||||
- Path=/api/v1/user/**
|
- Path=/api/v1/user/**
|
||||||
|
|
||||||
|
aioj-backend-gateway:
|
||||||
|
# 白名单配置
|
||||||
|
white-list:
|
||||||
|
- /api/v1/auth/login
|
||||||
|
- /api/v1/auth/register
|
||||||
|
- /api/v1/auth/refresh
|
||||||
|
- /api/v1/user/info
|
||||||
|
- /api/v1/question/list
|
||||||
|
- /api/v1/question/detail/**
|
||||||
|
- /actuator/health
|
||||||
|
- /swagger-ui/**
|
||||||
|
- /v3/api-docs/**
|
||||||
|
- /swagger-resources/**
|
||||||
|
|
||||||
aioj:
|
aioj:
|
||||||
log:
|
log:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|||||||
@@ -34,10 +34,5 @@
|
|||||||
<artifactId>aioj-backend-common-feign</artifactId>
|
<artifactId>aioj-backend-common-feign</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>cn.meowrain</groupId>
|
|
||||||
<artifactId>aioj-backend-upms-api</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
@@ -28,5 +28,9 @@
|
|||||||
<artifactId>aioj-backend-upms-api</artifactId>
|
<artifactId>aioj-backend-upms-api</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
spring:
|
||||||
|
data:
|
||||||
|
redis:
|
||||||
|
host: 10.0.0.10
|
||||||
|
port: 6379
|
||||||
|
password: 123456
|
||||||
|
datasource:
|
||||||
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
url: jdbc:mysql://10.0.0.10/aioj_dev
|
||||||
|
username: root
|
||||||
|
password: root
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
discovery:
|
||||||
|
enabled: true
|
||||||
|
register-enabled: true
|
||||||
|
server-addr: 10.0.0.10:8848
|
||||||
|
username: nacos
|
||||||
|
password: nacos
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
spring:
|
||||||
|
data:
|
||||||
|
redis:
|
||||||
|
host: 10.0.0.10
|
||||||
|
port: 6379
|
||||||
|
password: 123456
|
||||||
|
datasource:
|
||||||
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
url: jdbc:mysql://10.0.0.10/aioj_prod
|
||||||
|
username: root
|
||||||
|
password: root
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
spring:
|
||||||
|
data:
|
||||||
|
redis:
|
||||||
|
host: 10.0.0.10
|
||||||
|
port: 6379
|
||||||
|
password: 123456
|
||||||
|
datasource:
|
||||||
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
url: jdbc:mysql://10.0.0.10/aioj_test
|
||||||
|
username: root
|
||||||
|
password: 123456
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: user-service
|
||||||
|
profiles:
|
||||||
|
active: @env@
|
||||||
|
server:
|
||||||
|
port: 10012
|
||||||
|
servlet:
|
||||||
|
context-path: /api
|
||||||
|
springdoc:
|
||||||
|
api-docs:
|
||||||
|
enabled: true
|
||||||
|
path: /v3/api-docs
|
||||||
|
default-flat-param-object: true
|
||||||
|
swagger-ui:
|
||||||
|
path: /swagger-ui.html
|
||||||
|
tags-sorter: alpha
|
||||||
|
operations-sorter: alpha
|
||||||
|
group-configs:
|
||||||
|
- group: 'default'
|
||||||
|
paths-to-match: '/**'
|
||||||
|
packages-to-scan: cn.meowrain.aioj.backend.userservice.controller
|
||||||
|
knife4j:
|
||||||
|
basic:
|
||||||
|
enable: true
|
||||||
|
setting:
|
||||||
|
language: zh_cn
|
||||||
|
mybatis-plus:
|
||||||
|
configuration:
|
||||||
|
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||||
|
mapper-locations: classpath*:/mapper/**/*.xml
|
||||||
|
aioj:
|
||||||
|
log:
|
||||||
|
enabled: true
|
||||||
|
max-length: 20000
|
||||||
Reference in New Issue
Block a user