| @@ -1,2 +1,199 @@ | |||||
| # fuquanapi | |||||
| # 福泉WebAPI - 智能物流管理系统 | |||||
| ## 📋 项目简介 | |||||
| 基于SpringBoot的智能物流管理系统后端API,提供车辆管理、称重记录、供应商管理等核心功能,支持AK/SK签名认证。 | |||||
| ## ✨ 核心功能 | |||||
| - 🚛 **物流管理**: 车辆信息、转运记录、称重记录 | |||||
| - 👥 **用户管理**: 供应商、运输公司管理 | |||||
| - 📊 **数据管理**: 品种信息、供应关系、图片管理 | |||||
| - 🔐 **安全认证**: AK/SK签名验证、时间戳防重放 | |||||
| ## 🛠 技术栈 | |||||
| - **Spring Boot** 2.7.18 | |||||
| - **Spring Data JPA** | |||||
| - **SQL Server** | |||||
| - **Maven** | |||||
| - **Java 8+** | |||||
| ## 🚀 快速开始 | |||||
| ### 1. 环境要求 | |||||
| - JDK 1.8+ | |||||
| - Maven 3.6+ | |||||
| - SQL Server 2012+ | |||||
| ### 2. 配置数据库 | |||||
| ```yaml | |||||
| spring: | |||||
| datasource: | |||||
| url: jdbc:sqlserver://localhost:1433;databaseName=fuquan_db;encrypt=false;trustServerCertificate=true | |||||
| username: your_username | |||||
| password: your_password | |||||
| ``` | |||||
| ### 3. 配置API密钥 | |||||
| ```yaml | |||||
| api: | |||||
| client: | |||||
| ak: your_access_key_here | |||||
| sk: your_secret_key_here | |||||
| ``` | |||||
| ### 4. 启动应用 | |||||
| #### 方式一:Maven启动(开发环境) | |||||
| ```bash | |||||
| mvn spring-boot:run | |||||
| ``` | |||||
| #### 方式二:JAR包启动(生产环境) | |||||
| ```bash | |||||
| # 编译打包 | |||||
| mvn clean package | |||||
| # 快速启动 | |||||
| chmod +x run.sh | |||||
| ./run.sh | |||||
| # 或直接运行JAR | |||||
| java -jar target/webapi-0.0.1-SNAPSHOT.jar | |||||
| ``` | |||||
| #### 方式三:Linux服务部署 | |||||
| ```bash | |||||
| # 安装脚本 | |||||
| chmod +x install.sh | |||||
| ./install.sh | |||||
| # 启动服务 | |||||
| sudo systemctl start fuquan-webapi | |||||
| sudo systemctl enable fuquan-webapi | |||||
| # 查看状态 | |||||
| sudo systemctl status fuquan-webapi | |||||
| ``` | |||||
| 访问地址: `http://localhost:8806/fuquanapi` | |||||
| API文档: `http://localhost:8806/fuquanapi/swagger-ui.html` | |||||
| ## 🔐 安全认证 | |||||
| ### 请求头要求 | |||||
| ```http | |||||
| ak: your_access_key | |||||
| timestamp: 1640995200000 | |||||
| signature: calculated_signature | |||||
| ``` | |||||
| ### 签名计算 | |||||
| ```java | |||||
| // 签名 = MD5(ak + sk + timestamp) | |||||
| String signature = MD5(accessKey + secretKey + timestamp); | |||||
| ``` | |||||
| **注意**: 时间戳与服务器时间差不能超过10分钟 | |||||
| ## 📚 主要API | |||||
| ### 供应商管理 | |||||
| ```http | |||||
| POST /api/supplier/page/conditions | |||||
| ``` | |||||
| ### 运输公司管理 | |||||
| ```http | |||||
| POST /api/transport-company/page/conditions | |||||
| ``` | |||||
| ### 转运记录管理 | |||||
| ```http | |||||
| POST /api/transfer-record/page/conditions | |||||
| ``` | |||||
| ### 称重记录管理 | |||||
| ```http | |||||
| POST /api/weighing-record/page/conditions | |||||
| ``` | |||||
| ## 📁 项目结构 | |||||
| ``` | |||||
| src/main/java/com/example/webapi/ | |||||
| ├── controller/ # 控制器层 | |||||
| ├── service/ # 服务层 | |||||
| ├── repository/ # 数据访问层 | |||||
| ├── entity/ # 实体类 | |||||
| ├── dto/ # 数据传输对象 | |||||
| ├── interceptor/ # 拦截器 | |||||
| └── util/ # 工具类 | |||||
| ``` | |||||
| ## 🐧 Linux部署脚本 | |||||
| ### 脚本说明 | |||||
| | 脚本 | 用途 | 适用场景 | | |||||
| |------|------|----------| | |||||
| | `run.sh` | 快速启动 | 开发测试 | | |||||
| | `start.sh` | 完整管理 | 生产环境 | | |||||
| | `install.sh` | 自动安装 | 首次部署 | | |||||
| ### 使用示例 | |||||
| ```bash | |||||
| # 快速启动(开发环境) | |||||
| ./run.sh | |||||
| # 生产环境管理 | |||||
| ./start.sh start # 启动应用 | |||||
| ./start.sh stop # 停止应用 | |||||
| ./start.sh restart # 重启应用 | |||||
| ./start.sh status # 查看状态 | |||||
| ./start.sh logs # 查看日志 | |||||
| # 自动安装部署 | |||||
| ./install.sh | |||||
| ``` | |||||
| ### 系统服务管理 | |||||
| ```bash | |||||
| # 启动服务 | |||||
| sudo systemctl start fuquan-webapi | |||||
| # 停止服务 | |||||
| sudo systemctl stop fuquan-webapi | |||||
| # 重启服务 | |||||
| sudo systemctl restart fuquan-webapi | |||||
| # 查看状态 | |||||
| sudo systemctl status fuquan-webapi | |||||
| # 开机自启 | |||||
| sudo systemctl enable fuquan-webapi | |||||
| # 查看日志 | |||||
| sudo journalctl -u fuquan-webapi -f | |||||
| ``` | |||||
| ## 🐛 常见问题 | |||||
| 1. **数据库连接失败**: 检查数据库服务和连接配置 | |||||
| 2. **签名验证失败**: 确认AK/SK配置和时间戳格式 | |||||
| 3. **分页查询异常**: 验证分页参数和查询条件 | |||||
| 4. **端口被占用**: 修改配置文件中的端口号 | |||||
| 5. **权限不足**: 确保脚本有执行权限 `chmod +x *.sh` | |||||
| ## 📞 联系方式 | |||||
| - **项目地址**: [GitHub Repository] | |||||
| - **邮箱**: [your.email@example.com] | |||||
| --- | |||||
| **福泉WebAPI** - 让物流管理更智能! 🚀 | |||||
| @@ -0,0 +1,248 @@ | |||||
| #!/bin/bash | |||||
| # 福泉WebAPI 安装脚本 | |||||
| # 作者: Your Name | |||||
| # 版本: 1.0.0 | |||||
| # 颜色定义 | |||||
| RED='\033[0;31m' | |||||
| GREEN='\033[0;32m' | |||||
| YELLOW='\033[1;33m' | |||||
| BLUE='\033[0;34m' | |||||
| NC='\033[0m' | |||||
| print_message() { | |||||
| local color=$1 | |||||
| local message=$2 | |||||
| echo -e "${color}[$(date '+%Y-%m-%d %H:%M:%S')] $message${NC}" | |||||
| } | |||||
| # 检查是否为root用户 | |||||
| check_root() { | |||||
| if [ "$EUID" -eq 0 ]; then | |||||
| print_message $YELLOW "警告: 不建议使用root用户运行此脚本" | |||||
| read -p "是否继续? (y/N): " -n 1 -r | |||||
| echo | |||||
| if [[ ! $REPLY =~ ^[Yy]$ ]]; then | |||||
| exit 1 | |||||
| fi | |||||
| fi | |||||
| } | |||||
| # 检查系统类型 | |||||
| check_system() { | |||||
| if [[ "$OSTYPE" == "linux-gnu"* ]]; then | |||||
| print_message $GREEN "检测到Linux系统" | |||||
| else | |||||
| print_message $RED "此脚本仅支持Linux系统" | |||||
| exit 1 | |||||
| fi | |||||
| } | |||||
| # 检查Java环境 | |||||
| check_java() { | |||||
| if command -v java &> /dev/null; then | |||||
| JAVA_VERSION=$(java -version 2>&1 | head -n 1 | cut -d'"' -f2) | |||||
| print_message $GREEN "检测到Java版本: $JAVA_VERSION" | |||||
| return 0 | |||||
| else | |||||
| print_message $RED "未找到Java环境" | |||||
| return 1 | |||||
| fi | |||||
| } | |||||
| # 安装Java | |||||
| install_java() { | |||||
| print_message $BLUE "正在安装Java环境..." | |||||
| # 检测包管理器 | |||||
| if command -v apt-get &> /dev/null; then | |||||
| # Ubuntu/Debian | |||||
| sudo apt-get update | |||||
| sudo apt-get install -y openjdk-8-jdk | |||||
| elif command -v yum &> /dev/null; then | |||||
| # CentOS/RHEL | |||||
| sudo yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel | |||||
| elif command -v dnf &> /dev/null; then | |||||
| # Fedora | |||||
| sudo dnf install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel | |||||
| else | |||||
| print_message $RED "不支持的包管理器,请手动安装JDK 1.8+" | |||||
| exit 1 | |||||
| fi | |||||
| # 验证安装 | |||||
| if check_java; then | |||||
| print_message $GREEN "Java安装成功" | |||||
| else | |||||
| print_message $RED "Java安装失败" | |||||
| exit 1 | |||||
| fi | |||||
| } | |||||
| # 创建应用目录 | |||||
| create_app_dir() { | |||||
| APP_DIR="/opt/fuquan-webapi" | |||||
| if [ ! -d "$APP_DIR" ]; then | |||||
| sudo mkdir -p "$APP_DIR" | |||||
| print_message $BLUE "创建应用目录: $APP_DIR" | |||||
| fi | |||||
| # 设置权限 | |||||
| sudo chown -R $USER:$USER "$APP_DIR" | |||||
| print_message $GREEN "应用目录创建完成" | |||||
| } | |||||
| # 复制文件 | |||||
| copy_files() { | |||||
| APP_DIR="/opt/fuquan-webapi" | |||||
| # 复制JAR文件 | |||||
| if [ -f "webapi-0.0.1-SNAPSHOT.jar" ]; then | |||||
| cp webapi-0.0.1-SNAPSHOT.jar "$APP_DIR/" | |||||
| print_message $GREEN "JAR文件复制完成" | |||||
| else | |||||
| print_message $RED "未找到JAR文件,请先编译项目" | |||||
| exit 1 | |||||
| fi | |||||
| # 复制启动脚本 | |||||
| if [ -f "start.sh" ]; then | |||||
| cp start.sh "$APP_DIR/" | |||||
| chmod +x "$APP_DIR/start.sh" | |||||
| print_message $GREEN "启动脚本复制完成" | |||||
| fi | |||||
| # 创建配置文件 | |||||
| if [ ! -f "$APP_DIR/application.yml" ]; then | |||||
| cat > "$APP_DIR/application.yml" << EOF | |||||
| spring: | |||||
| datasource: | |||||
| url: jdbc:sqlserver://localhost:1433;databaseName=fuquan_db;encrypt=false;trustServerCertificate=true | |||||
| username: your_username | |||||
| password: your_password | |||||
| driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver | |||||
| jpa: | |||||
| hibernate: | |||||
| ddl-auto: update | |||||
| show-sql: false | |||||
| properties: | |||||
| hibernate: | |||||
| dialect: org.hibernate.dialect.SQLServer2012Dialect | |||||
| server: | |||||
| port: 8806 | |||||
| servlet: | |||||
| context-path: /fuquanapi | |||||
| api: | |||||
| client: | |||||
| ak: your_access_key_here | |||||
| sk: your_secret_key_here | |||||
| logging: | |||||
| level: | |||||
| com.example.webapi: INFO | |||||
| file: | |||||
| name: logs/app.log | |||||
| EOF | |||||
| print_message $GREEN "配置文件创建完成" | |||||
| fi | |||||
| } | |||||
| # 创建系统服务 | |||||
| create_service() { | |||||
| SERVICE_FILE="/etc/systemd/system/fuquan-webapi.service" | |||||
| if [ ! -f "$SERVICE_FILE" ]; then | |||||
| sudo tee "$SERVICE_FILE" > /dev/null << EOF | |||||
| [Unit] | |||||
| Description=福泉WebAPI服务 | |||||
| After=network.target | |||||
| [Service] | |||||
| Type=simple | |||||
| User=$USER | |||||
| WorkingDirectory=/opt/fuquan-webapi | |||||
| ExecStart=/opt/fuquan-webapi/start.sh start | |||||
| ExecStop=/opt/fuquan-webapi/start.sh stop | |||||
| Restart=always | |||||
| RestartSec=10 | |||||
| [Install] | |||||
| WantedBy=multi-user.target | |||||
| EOF | |||||
| print_message $GREEN "系统服务创建完成" | |||||
| # 重新加载systemd | |||||
| sudo systemctl daemon-reload | |||||
| print_message $BLUE "系统服务已注册" | |||||
| else | |||||
| print_message $YELLOW "系统服务已存在" | |||||
| fi | |||||
| } | |||||
| # 设置防火墙 | |||||
| setup_firewall() { | |||||
| print_message $BLUE "配置防火墙规则..." | |||||
| # 检测防火墙类型 | |||||
| if command -v ufw &> /dev/null; then | |||||
| # Ubuntu UFW | |||||
| sudo ufw allow 8806/tcp | |||||
| print_message $GREEN "UFW防火墙规则已添加" | |||||
| elif command -v firewall-cmd &> /dev/null; then | |||||
| # CentOS/RHEL firewalld | |||||
| sudo firewall-cmd --permanent --add-port=8806/tcp | |||||
| sudo firewall-cmd --reload | |||||
| print_message $GREEN "firewalld防火墙规则已添加" | |||||
| else | |||||
| print_message $YELLOW "未检测到防火墙,请手动开放8806端口" | |||||
| fi | |||||
| } | |||||
| # 显示安装完成信息 | |||||
| show_completion() { | |||||
| print_message $GREEN "==========================================" | |||||
| print_message $GREEN "福泉WebAPI 安装完成!" | |||||
| print_message $GREEN "==========================================" | |||||
| echo "" | |||||
| print_message $BLUE "应用目录: /opt/fuquan-webapi" | |||||
| print_message $BLUE "配置文件: /opt/fuquan-webapi/application.yml" | |||||
| print_message $BLUE "启动脚本: /opt/fuquan-webapi/start.sh" | |||||
| echo "" | |||||
| print_message $YELLOW "请编辑配置文件设置数据库连接信息:" | |||||
| print_message $YELLOW "sudo nano /opt/fuquan-webapi/application.yml" | |||||
| echo "" | |||||
| print_message $BLUE "启动服务:" | |||||
| print_message $BLUE "sudo systemctl start fuquan-webapi" | |||||
| print_message $BLUE "sudo systemctl enable fuquan-webapi" | |||||
| echo "" | |||||
| print_message $BLUE "查看服务状态:" | |||||
| print_message $BLUE "sudo systemctl status fuquan-webapi" | |||||
| echo "" | |||||
| print_message $GREEN "访问地址: http://localhost:8806/fuquanapi" | |||||
| print_message $GREEN "API文档: http://localhost:8806/fuquanapi/swagger-ui.html" | |||||
| } | |||||
| # 主函数 | |||||
| main() { | |||||
| print_message $BLUE "开始安装福泉WebAPI..." | |||||
| check_root | |||||
| check_system | |||||
| if ! check_java; then | |||||
| install_java | |||||
| fi | |||||
| create_app_dir | |||||
| copy_files | |||||
| create_service | |||||
| setup_firewall | |||||
| show_completion | |||||
| } | |||||
| # 执行主函数 | |||||
| main "$@" | |||||
| @@ -0,0 +1,92 @@ | |||||
| <?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> | |||||
| <groupId>com.example</groupId> | |||||
| <artifactId>webapi</artifactId> | |||||
| <version>1.0.0</version> | |||||
| <packaging>jar</packaging> | |||||
| <name>webapi</name> | |||||
| <description>SpringBoot WebAPI with Access Key/Secret Key Authentication</description> | |||||
| <parent> | |||||
| <groupId>org.springframework.boot</groupId> | |||||
| <artifactId>spring-boot-starter-parent</artifactId> | |||||
| <version>2.7.18</version> | |||||
| <relativePath/> | |||||
| </parent> | |||||
| <properties> | |||||
| <java.version>1.8</java.version> | |||||
| <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |||||
| <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | |||||
| </properties> | |||||
| <dependencies> | |||||
| <!-- Spring Boot Starter Web --> | |||||
| <dependency> | |||||
| <groupId>org.springframework.boot</groupId> | |||||
| <artifactId>spring-boot-starter-web</artifactId> | |||||
| </dependency> | |||||
| <!-- Spring Boot Starter Data JPA --> | |||||
| <dependency> | |||||
| <groupId>org.springframework.boot</groupId> | |||||
| <artifactId>spring-boot-starter-data-jpa</artifactId> | |||||
| </dependency> | |||||
| <!-- SQL Server JDBC Driver --> | |||||
| <dependency> | |||||
| <groupId>com.microsoft.sqlserver</groupId> | |||||
| <artifactId>mssql-jdbc</artifactId> | |||||
| <scope>runtime</scope> | |||||
| </dependency> | |||||
| <!-- Spring Boot Starter Validation --> | |||||
| <dependency> | |||||
| <groupId>org.springframework.boot</groupId> | |||||
| <artifactId>spring-boot-starter-validation</artifactId> | |||||
| </dependency> | |||||
| <!-- Lombok --> | |||||
| <dependency> | |||||
| <groupId>org.projectlombok</groupId> | |||||
| <artifactId>lombok</artifactId> | |||||
| <optional>true</optional> | |||||
| </dependency> | |||||
| <!-- Spring Boot Starter Test --> | |||||
| <dependency> | |||||
| <groupId>org.springframework.boot</groupId> | |||||
| <artifactId>spring-boot-starter-test</artifactId> | |||||
| <scope>test</scope> | |||||
| </dependency> | |||||
| <!-- Swagger3/Springfox 3.x 依赖 --> | |||||
| <dependency> | |||||
| <groupId>io.springfox</groupId> | |||||
| <artifactId>springfox-boot-starter</artifactId> | |||||
| <version>3.0.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> | |||||
| @@ -0,0 +1,48 @@ | |||||
| #!/bin/bash | |||||
| # 福泉WebAPI 快速启动脚本 | |||||
| # 简化版本,用于开发和测试环境 | |||||
| # 应用配置 | |||||
| JAR_FILE="webapi-0.0.1-SNAPSHOT.jar" | |||||
| PORT=8806 | |||||
| CONTEXT_PATH="/fuquanapi" | |||||
| # JVM配置 | |||||
| JVM_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC" | |||||
| JVM_OPTS="$JVM_OPTS -Dserver.port=$PORT" | |||||
| JVM_OPTS="$JVM_OPTS -Dserver.servlet.context-path=$CONTEXT_PATH" | |||||
| # 颜色 | |||||
| GREEN='\033[0;32m' | |||||
| RED='\033[0;31m' | |||||
| BLUE='\033[0;34m' | |||||
| NC='\033[0m' | |||||
| echo -e "${BLUE}福泉WebAPI 快速启动脚本${NC}" | |||||
| echo "================================" | |||||
| # 检查JAR文件 | |||||
| if [ ! -f "$JAR_FILE" ]; then | |||||
| echo -e "${RED}错误: 未找到JAR文件 $JAR_FILE${NC}" | |||||
| echo "请先编译项目: mvn clean package" | |||||
| exit 1 | |||||
| fi | |||||
| # 检查Java环境 | |||||
| if ! command -v java &> /dev/null; then | |||||
| echo -e "${RED}错误: 未找到Java环境${NC}" | |||||
| exit 1 | |||||
| fi | |||||
| echo -e "${GREEN}启动应用...${NC}" | |||||
| echo "JAR文件: $JAR_FILE" | |||||
| echo "端口: $PORT" | |||||
| echo "上下文路径: $CONTEXT_PATH" | |||||
| echo "" | |||||
| # 启动应用 | |||||
| java $JVM_OPTS -jar "$JAR_FILE" | |||||
| echo "" | |||||
| echo -e "${GREEN}应用已停止${NC}" | |||||
| @@ -0,0 +1,22 @@ | |||||
| package com.example.webapi; | |||||
| import org.springframework.boot.SpringApplication; | |||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | |||||
| /** | |||||
| * SpringBoot WebAPI 应用程序主类 | |||||
| * | |||||
| * @author Your Name | |||||
| * @version 1.0.0 | |||||
| */ | |||||
| @SpringBootApplication | |||||
| public class WebApiApplication { | |||||
| public static void main(String[] args) { | |||||
| SpringApplication.run(WebApiApplication.class, args); | |||||
| System.out.println("================================="); | |||||
| System.out.println("WebAPI 应用程序启动成功!"); | |||||
| System.out.println("访问地址: http://localhost:8080/api"); | |||||
| System.out.println("================================="); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,93 @@ | |||||
| package com.example.webapi.config; | |||||
| import org.springframework.context.annotation.Bean; | |||||
| import org.springframework.context.annotation.Configuration; | |||||
| import springfox.documentation.builders.ApiInfoBuilder; | |||||
| import springfox.documentation.builders.PathSelectors; | |||||
| import springfox.documentation.builders.RequestHandlerSelectors; | |||||
| import springfox.documentation.builders.RequestParameterBuilder; | |||||
| import springfox.documentation.schema.ScalarType; | |||||
| import springfox.documentation.service.ApiInfo; | |||||
| import springfox.documentation.service.Contact; | |||||
| import springfox.documentation.service.ParameterType; | |||||
| import springfox.documentation.service.RequestParameter; | |||||
| import springfox.documentation.spi.DocumentationType; | |||||
| import springfox.documentation.spring.web.plugins.Docket; | |||||
| import java.util.ArrayList; | |||||
| import java.util.List; | |||||
| /** | |||||
| * Swagger配置类 | |||||
| * 配置Swagger3文档,支持详细的请求参数和响应参数说明 | |||||
| */ | |||||
| @Configuration | |||||
| public class SwaggerConfig { | |||||
| @Bean | |||||
| public Docket api() { | |||||
| return new Docket(DocumentationType.OAS_30) | |||||
| .apiInfo(apiInfo()) | |||||
| .select() | |||||
| .apis(RequestHandlerSelectors.basePackage("com.example.webapi.controller")) | |||||
| .paths(PathSelectors.any()) | |||||
| .build() | |||||
| .globalRequestParameters(getGlobalRequestParameters()) | |||||
| // 以下设置对展示参数说明和返回值说明很重要 | |||||
| .useDefaultResponseMessages(false) // 不使用默认的响应消息 | |||||
| .forCodeGeneration(true) // 为代码生成优化 | |||||
| .pathMapping("/"); // 设置路径映射 | |||||
| } | |||||
| /** | |||||
| * API信息配置 | |||||
| */ | |||||
| private ApiInfo apiInfo() { | |||||
| return new ApiInfoBuilder() | |||||
| .title("福泉WebAPI接口文档") | |||||
| .description("提供福泉系统的所有接口说明,包括请求参数和响应数据的详细描述") | |||||
| .version("1.0.0") | |||||
| .contact(new Contact("开发团队", "http://www.example.com", "dev@example.com")) | |||||
| .build(); | |||||
| } | |||||
| /** | |||||
| * 获取全局请求参数 | |||||
| * 注意:在Swagger UI中这些参数设置为非必需,以便能够正常访问Swagger界面 | |||||
| * 实际API调用时,这些参数仍然需要通过拦截器进行验证 | |||||
| */ | |||||
| private List<RequestParameter> getGlobalRequestParameters() { | |||||
| List<RequestParameter> parameters = new ArrayList<>(); | |||||
| // AK (Access Key) - 在Swagger中设为非必需,便于测试 | |||||
| RequestParameter akParam = new RequestParameterBuilder() | |||||
| .name("ak") | |||||
| .description("访问密钥 (Access Key) - 必填") | |||||
| .in(ParameterType.HEADER.toString()) | |||||
| .required(false) // 改为false,让Swagger UI可以正常访问 | |||||
| .query(param -> param.model(model -> model.scalarModel(ScalarType.STRING))) | |||||
| .build(); | |||||
| parameters.add(akParam); | |||||
| // Timestamp - 在Swagger中设为非必需,便于测试 | |||||
| RequestParameter timestampParam = new RequestParameterBuilder() | |||||
| .name("timestamp") | |||||
| .description("时间戳 (毫秒) - 必填") | |||||
| .in(ParameterType.HEADER.toString()) | |||||
| .required(false) // 改为false,让Swagger UI可以正常访问 | |||||
| .query(param -> param.model(model -> model.scalarModel(ScalarType.STRING))) | |||||
| .build(); | |||||
| parameters.add(timestampParam); | |||||
| // Signature - 在Swagger中设为非必需,便于测试 | |||||
| RequestParameter signatureParam = new RequestParameterBuilder() | |||||
| .name("signature") | |||||
| .description("签名 (MD5(ak + sk + timestamp)) - 必填") | |||||
| .in(ParameterType.HEADER.toString()) | |||||
| .required(false) // 改为false,让Swagger UI可以正常访问 | |||||
| .query(param -> param.model(model -> model.scalarModel(ScalarType.STRING))) | |||||
| .build(); | |||||
| parameters.add(signatureParam); | |||||
| return parameters; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,75 @@ | |||||
| package com.example.webapi.config; | |||||
| import com.example.webapi.interceptor.SignatureInterceptor; | |||||
| import org.springframework.context.annotation.Bean; | |||||
| import org.springframework.context.annotation.Configuration; | |||||
| import org.springframework.web.cors.CorsConfiguration; | |||||
| import org.springframework.web.cors.CorsConfigurationSource; | |||||
| import org.springframework.web.cors.UrlBasedCorsConfigurationSource; | |||||
| import org.springframework.web.servlet.config.annotation.CorsRegistry; | |||||
| import org.springframework.web.servlet.config.annotation.InterceptorRegistry; | |||||
| import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | |||||
| import java.util.Arrays; | |||||
| /** | |||||
| * Web配置类 | |||||
| * | |||||
| * @author Your Name | |||||
| * @version 1.0.0 | |||||
| */ | |||||
| @Configuration | |||||
| public class WebConfig implements WebMvcConfigurer { | |||||
| private final SignatureInterceptor signatureInterceptor; | |||||
| public WebConfig(SignatureInterceptor signatureInterceptor) { | |||||
| this.signatureInterceptor = signatureInterceptor; | |||||
| } | |||||
| @Override | |||||
| public void addInterceptors(InterceptorRegistry registry) { | |||||
| // 添加签名验证拦截器,对所有API请求进行验证 | |||||
| registry.addInterceptor(signatureInterceptor) | |||||
| .addPathPatterns("/**") | |||||
| .excludePathPatterns( | |||||
| "/auth/register", | |||||
| "/public/**", | |||||
| "/test/**", | |||||
| // Swagger相关接口白名单 | |||||
| "/swagger-ui/**", | |||||
| "/v3/api-docs/**", | |||||
| "/swagger-resources/**", | |||||
| "/webjars/**" | |||||
| ); | |||||
| } | |||||
| @Override | |||||
| public void addCorsMappings(CorsRegistry registry) { | |||||
| registry.addMapping("/**") | |||||
| .allowedOriginPatterns("*") | |||||
| .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") | |||||
| .allowedHeaders("*") | |||||
| .allowCredentials(true) | |||||
| .maxAge(3600); | |||||
| } | |||||
| /** | |||||
| * CORS配置 | |||||
| * | |||||
| * @return CORS配置源 | |||||
| */ | |||||
| @Bean | |||||
| public CorsConfigurationSource corsConfigurationSource() { | |||||
| CorsConfiguration configuration = new CorsConfiguration(); | |||||
| configuration.setAllowedOriginPatterns(Arrays.asList("*")); | |||||
| configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); | |||||
| configuration.setAllowedHeaders(Arrays.asList("*")); | |||||
| configuration.setAllowCredentials(true); | |||||
| configuration.setMaxAge(3600L); | |||||
| UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); | |||||
| source.registerCorsConfiguration("/**", configuration); | |||||
| return source; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,58 @@ | |||||
| package com.example.webapi.controller; | |||||
| import com.example.webapi.dto.ImageInfoQueryDTO; | |||||
| import com.example.webapi.entity.ImageInfo; | |||||
| import com.example.webapi.service.ImageInfoService; | |||||
| import com.example.webapi.dto.ApiResponse; | |||||
| import io.swagger.annotations.Api; | |||||
| import io.swagger.annotations.ApiOperation; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.data.domain.Page; | |||||
| import org.springframework.data.domain.PageRequest; | |||||
| import org.springframework.web.bind.annotation.*; | |||||
| import java.util.Optional; | |||||
| @Api(tags = "图片信息管理") | |||||
| @RestController | |||||
| @RequestMapping("/image-info") | |||||
| public class ImageInfoController { | |||||
| @Autowired | |||||
| private ImageInfoService service; | |||||
| @ApiOperation("条件查询图片信息(分页)") | |||||
| @PostMapping("/page/conditions") | |||||
| public ApiResponse<Page<ImageInfo>> pageByConditions(@RequestBody ImageInfoQueryDTO queryDTO) { | |||||
| return ApiResponse.success(service.findByConditions(queryDTO)); | |||||
| } | |||||
| @ApiOperation("根据ID查询图片信息") | |||||
| @GetMapping("/{id}") | |||||
| public ApiResponse<ImageInfo> getById(@PathVariable Integer id) { | |||||
| Optional<ImageInfo> result = service.findById(id); | |||||
| return result.map(ApiResponse::success).orElseGet(() -> ApiResponse.error("未找到该图片信息")); | |||||
| } | |||||
| @ApiOperation("新增图片信息") | |||||
| @PostMapping | |||||
| public ApiResponse<ImageInfo> create(@RequestBody ImageInfo entity) { | |||||
| return ApiResponse.success(service.save(entity)); | |||||
| } | |||||
| @ApiOperation("更新图片信息") | |||||
| @PutMapping("/{id}") | |||||
| public ApiResponse<ImageInfo> update(@PathVariable Integer id, @RequestBody ImageInfo entity) { | |||||
| entity.setId(id); | |||||
| return ApiResponse.success(service.save(entity)); | |||||
| } | |||||
| @ApiOperation("删除图片信息") | |||||
| @DeleteMapping("/{id}") | |||||
| public ApiResponse<Void> delete(@PathVariable Integer id) { | |||||
| service.deleteById(id); | |||||
| return ApiResponse.success(); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,57 @@ | |||||
| package com.example.webapi.controller; | |||||
| import com.example.webapi.dto.MaterialInfoQueryDTO; | |||||
| import com.example.webapi.entity.MaterialInfo; | |||||
| import com.example.webapi.service.MaterialInfoService; | |||||
| import com.example.webapi.dto.ApiResponse; | |||||
| import io.swagger.annotations.Api; | |||||
| import io.swagger.annotations.ApiOperation; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.data.domain.Page; | |||||
| import org.springframework.data.domain.PageRequest; | |||||
| import org.springframework.web.bind.annotation.*; | |||||
| import java.util.Optional; | |||||
| @Api(tags = "品种信息管理") | |||||
| @RestController | |||||
| @RequestMapping("/material-info") | |||||
| public class MaterialInfoController { | |||||
| @Autowired | |||||
| private MaterialInfoService service; | |||||
| @ApiOperation("条件查询品种信息(分页)") | |||||
| @PostMapping("/page/conditions") | |||||
| public ApiResponse<Page<MaterialInfo>> pageByConditions(@RequestBody MaterialInfoQueryDTO queryDTO) { | |||||
| return ApiResponse.success(service.findByConditions(queryDTO)); | |||||
| } | |||||
| @ApiOperation("根据ID查询品种信息") | |||||
| @GetMapping("/{id}") | |||||
| public ApiResponse<MaterialInfo> getById(@PathVariable Integer id) { | |||||
| Optional<MaterialInfo> result = service.findById(id); | |||||
| return result.map(ApiResponse::success).orElseGet(() -> ApiResponse.error("未找到该品种信息")); | |||||
| } | |||||
| @ApiOperation("新增品种信息") | |||||
| @PostMapping | |||||
| public ApiResponse<MaterialInfo> create(@RequestBody MaterialInfo entity) { | |||||
| return ApiResponse.success(service.save(entity)); | |||||
| } | |||||
| @ApiOperation("更新品种信息") | |||||
| @PutMapping("/{id}") | |||||
| public ApiResponse<MaterialInfo> update(@PathVariable Integer id, @RequestBody MaterialInfo entity) { | |||||
| entity.setId(id); | |||||
| return ApiResponse.success(service.save(entity)); | |||||
| } | |||||
| @ApiOperation("删除品种信息") | |||||
| @DeleteMapping("/{id}") | |||||
| public ApiResponse<Void> delete(@PathVariable Integer id) { | |||||
| service.deleteById(id); | |||||
| return ApiResponse.success(); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,57 @@ | |||||
| package com.example.webapi.controller; | |||||
| import com.example.webapi.dto.SupplierQueryDTO; | |||||
| import com.example.webapi.entity.Supplier; | |||||
| import com.example.webapi.service.SupplierService; | |||||
| import com.example.webapi.dto.ApiResponse; | |||||
| import io.swagger.annotations.Api; | |||||
| import io.swagger.annotations.ApiOperation; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.data.domain.Page; | |||||
| import org.springframework.data.domain.PageRequest; | |||||
| import org.springframework.web.bind.annotation.*; | |||||
| import java.util.Optional; | |||||
| @Api(tags = "供应商信息管理") | |||||
| @RestController | |||||
| @RequestMapping("/supplier") | |||||
| public class SupplierController { | |||||
| @Autowired | |||||
| private SupplierService service; | |||||
| @ApiOperation("条件查询供应商信息(分页)") | |||||
| @PostMapping("/page/conditions") | |||||
| public ApiResponse<Page<Supplier>> pageByConditions(@RequestBody SupplierQueryDTO queryDTO) { | |||||
| return ApiResponse.success(service.findByConditions(queryDTO)); | |||||
| } | |||||
| @ApiOperation("根据ID查询供应商信息") | |||||
| @GetMapping("/{id}") | |||||
| public ApiResponse<Supplier> getById(@PathVariable Integer id) { | |||||
| Optional<Supplier> result = service.findById(id); | |||||
| return result.map(ApiResponse::success).orElseGet(() -> ApiResponse.error("未找到该供应商信息")); | |||||
| } | |||||
| @ApiOperation("新增供应商信息") | |||||
| @PostMapping | |||||
| public ApiResponse<Supplier> create(@RequestBody Supplier entity) { | |||||
| return ApiResponse.success(service.save(entity)); | |||||
| } | |||||
| @ApiOperation("更新供应商信息") | |||||
| @PutMapping("/{id}") | |||||
| public ApiResponse<Supplier> update(@PathVariable Integer id, @RequestBody Supplier entity) { | |||||
| entity.setId(id); | |||||
| return ApiResponse.success(service.save(entity)); | |||||
| } | |||||
| @ApiOperation("删除供应商信息") | |||||
| @DeleteMapping("/{id}") | |||||
| public ApiResponse<Void> delete(@PathVariable Integer id) { | |||||
| service.deleteById(id); | |||||
| return ApiResponse.success(); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,108 @@ | |||||
| package com.example.webapi.controller; | |||||
| import com.example.webapi.dto.SupplyVarietyQueryDTO; | |||||
| import com.example.webapi.entity.SupplyVariety; | |||||
| import com.example.webapi.service.SupplyVarietyService; | |||||
| import com.example.webapi.dto.ApiResponse; | |||||
| import io.swagger.annotations.Api; | |||||
| import io.swagger.annotations.ApiOperation; | |||||
| import io.swagger.annotations.ApiParam; | |||||
| import io.swagger.v3.oas.annotations.media.Content; | |||||
| import io.swagger.v3.oas.annotations.media.Schema; | |||||
| import io.swagger.v3.oas.annotations.responses.ApiResponses; | |||||
| import io.swagger.v3.oas.annotations.tags.Tag; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.data.domain.Page; | |||||
| import org.springframework.web.bind.annotation.*; | |||||
| import java.util.Optional; | |||||
| @Api(tags = "供应标识品种信息管理") | |||||
| @Tag(name = "供应标识品种信息管理", description = "提供供应标识品种信息的增删改查接口") | |||||
| @RestController | |||||
| @RequestMapping("/supply-variety") | |||||
| public class SupplyVarietyController { | |||||
| @Autowired | |||||
| private SupplyVarietyService service; | |||||
| @ApiOperation(value = "条件查询供应标识品种信息(分页)", notes = "根据提供的查询条件分页查询供应标识品种信息") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @PostMapping("/page/conditions") | |||||
| public ApiResponse<Page<SupplyVariety>> pageByConditions( | |||||
| @ApiParam(value = "查询条件DTO,包含分页信息和过滤条件", required = true) | |||||
| @RequestBody SupplyVarietyQueryDTO queryDTO) { | |||||
| return ApiResponse.success(service.findByConditions(queryDTO)); | |||||
| } | |||||
| @ApiOperation(value = "根据ID查询供应标识品种信息", notes = "根据ID获取单条供应标识品种信息详情") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @GetMapping("/{id}") | |||||
| public ApiResponse<SupplyVariety> getById( | |||||
| @ApiParam(value = "供应标识品种ID", required = true, example = "1") | |||||
| @PathVariable Integer id) { | |||||
| Optional<SupplyVariety> result = service.findById(id); | |||||
| return result.map(ApiResponse::success).orElseGet(() -> ApiResponse.error("未找到该供应标识品种信息")); | |||||
| } | |||||
| @ApiOperation(value = "新增供应标识品种信息", notes = "创建新的供应标识品种信息") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "创建成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "请求参数错误"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @PostMapping | |||||
| public ApiResponse<SupplyVariety> create( | |||||
| @ApiParam(value = "供应标识品种实体", required = true) | |||||
| @RequestBody SupplyVariety entity) { | |||||
| return ApiResponse.success(service.save(entity)); | |||||
| } | |||||
| @ApiOperation(value = "更新供应标识品种信息", notes = "根据ID更新供应标识品种信息") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "更新成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "请求参数错误"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @PutMapping("/{id}") | |||||
| public ApiResponse<SupplyVariety> update( | |||||
| @ApiParam(value = "供应标识品种ID", required = true, example = "1") | |||||
| @PathVariable Integer id, | |||||
| @ApiParam(value = "更新后的供应标识品种实体", required = true) | |||||
| @RequestBody SupplyVariety entity) { | |||||
| entity.setId(id); | |||||
| return ApiResponse.success(service.save(entity)); | |||||
| } | |||||
| @ApiOperation(value = "删除供应标识品种信息", notes = "根据ID删除供应标识品种信息") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "删除成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @DeleteMapping("/{id}") | |||||
| public ApiResponse<Void> delete( | |||||
| @ApiParam(value = "供应标识品种ID", required = true, example = "1") | |||||
| @PathVariable Integer id) { | |||||
| service.deleteById(id); | |||||
| return ApiResponse.success(); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,109 @@ | |||||
| package com.example.webapi.controller; | |||||
| import com.example.webapi.dto.TransferRecordQueryDTO; | |||||
| import com.example.webapi.entity.TransferRecord; | |||||
| import com.example.webapi.service.TransferRecordService; | |||||
| import com.example.webapi.dto.ApiResponse; | |||||
| import io.swagger.annotations.Api; | |||||
| import io.swagger.annotations.ApiOperation; | |||||
| import io.swagger.annotations.ApiParam; | |||||
| import io.swagger.v3.oas.annotations.media.Content; | |||||
| import io.swagger.v3.oas.annotations.media.Schema; | |||||
| import io.swagger.v3.oas.annotations.responses.ApiResponses; | |||||
| import io.swagger.v3.oas.annotations.tags.Tag; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.data.domain.Page; | |||||
| import org.springframework.web.bind.annotation.*; | |||||
| import java.util.Optional; | |||||
| @Api(tags = "转运记录管理") | |||||
| @Tag(name = "转运记录管理", description = "提供转运记录的增删改查接口") | |||||
| @RestController | |||||
| @RequestMapping("/transfer-record") | |||||
| public class TransferRecordController { | |||||
| @Autowired | |||||
| private TransferRecordService service; | |||||
| @ApiOperation(value = "条件查询转运记录(分页)", notes = "根据提供的查询条件分页查询转运记录") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @PostMapping("/page/conditions") | |||||
| public ApiResponse<Page<TransferRecord>> pageByConditions( | |||||
| @ApiParam(value = "查询条件DTO,包含分页信息和过滤条件", required = true) | |||||
| @RequestBody TransferRecordQueryDTO queryDTO) { | |||||
| queryDTO.setSortBy("issuedTime"); | |||||
| return ApiResponse.success(service.findByConditions(queryDTO)); | |||||
| } | |||||
| @ApiOperation(value = "根据ID查询转运记录", notes = "根据ID获取单条转运记录详情") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @GetMapping("/{id}") | |||||
| public ApiResponse<TransferRecord> getById( | |||||
| @ApiParam(value = "转运记录ID", required = true, example = "1") | |||||
| @PathVariable Integer id) { | |||||
| Optional<TransferRecord> result = service.findById(id); | |||||
| return result.map(ApiResponse::success).orElseGet(() -> ApiResponse.error("未找到该转运记录")); | |||||
| } | |||||
| @ApiOperation(value = "新增转运记录", notes = "创建新的转运记录") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "创建成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "请求参数错误"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @PostMapping | |||||
| public ApiResponse<TransferRecord> create( | |||||
| @ApiParam(value = "转运记录实体", required = true) | |||||
| @RequestBody TransferRecord entity) { | |||||
| return ApiResponse.success(service.save(entity)); | |||||
| } | |||||
| @ApiOperation(value = "更新转运记录", notes = "根据ID更新转运记录信息") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "更新成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "请求参数错误"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @PutMapping("/{id}") | |||||
| public ApiResponse<TransferRecord> update( | |||||
| @ApiParam(value = "转运记录ID", required = true, example = "1") | |||||
| @PathVariable Integer id, | |||||
| @ApiParam(value = "更新后的转运记录实体", required = true) | |||||
| @RequestBody TransferRecord entity) { | |||||
| entity.setId(id); | |||||
| return ApiResponse.success(service.save(entity)); | |||||
| } | |||||
| @ApiOperation(value = "删除转运记录", notes = "根据ID删除转运记录") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "删除成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @DeleteMapping("/{id}") | |||||
| public ApiResponse<Void> delete( | |||||
| @ApiParam(value = "转运记录ID", required = true, example = "1") | |||||
| @PathVariable Integer id) { | |||||
| service.deleteById(id); | |||||
| return ApiResponse.success(); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,108 @@ | |||||
| package com.example.webapi.controller; | |||||
| import com.example.webapi.dto.TransportCompanyQueryDTO; | |||||
| import com.example.webapi.entity.TransportCompany; | |||||
| import com.example.webapi.service.TransportCompanyService; | |||||
| import com.example.webapi.dto.ApiResponse; | |||||
| import io.swagger.annotations.Api; | |||||
| import io.swagger.annotations.ApiOperation; | |||||
| import io.swagger.annotations.ApiParam; | |||||
| import io.swagger.v3.oas.annotations.media.Content; | |||||
| import io.swagger.v3.oas.annotations.media.Schema; | |||||
| import io.swagger.v3.oas.annotations.responses.ApiResponses; | |||||
| import io.swagger.v3.oas.annotations.tags.Tag; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.data.domain.Page; | |||||
| import org.springframework.web.bind.annotation.*; | |||||
| import java.util.Optional; | |||||
| @Api(tags = "运输公司管理") | |||||
| @Tag(name = "运输公司管理", description = "提供运输公司的增删改查接口") | |||||
| @RestController | |||||
| @RequestMapping("/transport-company") | |||||
| public class TransportCompanyController { | |||||
| @Autowired | |||||
| private TransportCompanyService service; | |||||
| @ApiOperation(value = "条件查询运输公司(分页)", notes = "根据提供的查询条件分页查询运输公司") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @PostMapping("/page/conditions") | |||||
| public ApiResponse<Page<TransportCompany>> pageByConditions( | |||||
| @ApiParam(value = "查询条件DTO,包含分页信息和过滤条件", required = true) | |||||
| @RequestBody TransportCompanyQueryDTO queryDTO) { | |||||
| return ApiResponse.success(service.findByConditions(queryDTO)); | |||||
| } | |||||
| @ApiOperation(value = "根据ID查询运输公司", notes = "根据ID获取单条运输公司详情") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @GetMapping("/{id}") | |||||
| public ApiResponse<TransportCompany> getById( | |||||
| @ApiParam(value = "运输公司ID", required = true, example = "1") | |||||
| @PathVariable Integer id) { | |||||
| Optional<TransportCompany> result = service.findById(id); | |||||
| return result.map(ApiResponse::success).orElseGet(() -> ApiResponse.error("未找到该运输公司")); | |||||
| } | |||||
| @ApiOperation(value = "新增运输公司", notes = "创建新的运输公司") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "创建成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "请求参数错误"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @PostMapping | |||||
| public ApiResponse<TransportCompany> create( | |||||
| @ApiParam(value = "运输公司实体", required = true) | |||||
| @RequestBody TransportCompany entity) { | |||||
| return ApiResponse.success(service.save(entity)); | |||||
| } | |||||
| @ApiOperation(value = "更新运输公司", notes = "根据ID更新运输公司信息") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "更新成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "请求参数错误"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @PutMapping("/{id}") | |||||
| public ApiResponse<TransportCompany> update( | |||||
| @ApiParam(value = "运输公司ID", required = true, example = "1") | |||||
| @PathVariable Integer id, | |||||
| @ApiParam(value = "更新后的运输公司实体", required = true) | |||||
| @RequestBody TransportCompany entity) { | |||||
| entity.setId(id); | |||||
| return ApiResponse.success(service.save(entity)); | |||||
| } | |||||
| @ApiOperation(value = "删除运输公司", notes = "根据ID删除运输公司") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "删除成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @DeleteMapping("/{id}") | |||||
| public ApiResponse<Void> delete( | |||||
| @ApiParam(value = "运输公司ID", required = true, example = "1") | |||||
| @PathVariable Integer id) { | |||||
| service.deleteById(id); | |||||
| return ApiResponse.success(); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,108 @@ | |||||
| package com.example.webapi.controller; | |||||
| import com.example.webapi.dto.VehicleInfoQueryDTO; | |||||
| import com.example.webapi.entity.VehicleInfo; | |||||
| import com.example.webapi.service.VehicleInfoService; | |||||
| import com.example.webapi.dto.ApiResponse; | |||||
| import io.swagger.annotations.Api; | |||||
| import io.swagger.annotations.ApiOperation; | |||||
| import io.swagger.annotations.ApiParam; | |||||
| import io.swagger.v3.oas.annotations.media.Content; | |||||
| import io.swagger.v3.oas.annotations.media.Schema; | |||||
| import io.swagger.v3.oas.annotations.responses.ApiResponses; | |||||
| import io.swagger.v3.oas.annotations.tags.Tag; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.data.domain.Page; | |||||
| import org.springframework.web.bind.annotation.*; | |||||
| import java.util.Optional; | |||||
| @Api(tags = "车辆信息管理") | |||||
| @Tag(name = "车辆信息管理", description = "提供车辆信息的增删改查接口") | |||||
| @RestController | |||||
| @RequestMapping("/vehicle-info") | |||||
| public class VehicleInfoController { | |||||
| @Autowired | |||||
| private VehicleInfoService service; | |||||
| @ApiOperation(value = "条件查询车辆信息(分页)", notes = "根据提供的查询条件分页查询车辆信息") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @PostMapping("/page/conditions") | |||||
| public ApiResponse<Page<VehicleInfo>> pageByConditions( | |||||
| @ApiParam(value = "查询条件DTO,包含分页信息和过滤条件", required = true) | |||||
| @RequestBody VehicleInfoQueryDTO queryDTO) { | |||||
| return ApiResponse.success(service.findByConditions(queryDTO)); | |||||
| } | |||||
| @ApiOperation(value = "根据ID查询车辆信息", notes = "根据ID获取单条车辆信息详情") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @GetMapping("/{id}") | |||||
| public ApiResponse<VehicleInfo> getById( | |||||
| @ApiParam(value = "车辆ID", required = true, example = "1") | |||||
| @PathVariable Integer id) { | |||||
| Optional<VehicleInfo> result = service.findById(id); | |||||
| return result.map(ApiResponse::success).orElseGet(() -> ApiResponse.error("未找到该车辆信息")); | |||||
| } | |||||
| @ApiOperation(value = "新增车辆信息", notes = "创建新的车辆信息") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "创建成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "请求参数错误"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @PostMapping | |||||
| public ApiResponse<VehicleInfo> create( | |||||
| @ApiParam(value = "车辆信息实体", required = true) | |||||
| @RequestBody VehicleInfo entity) { | |||||
| return ApiResponse.success(service.save(entity)); | |||||
| } | |||||
| @ApiOperation(value = "更新车辆信息", notes = "根据ID更新车辆信息") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "更新成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "请求参数错误"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @PutMapping("/{id}") | |||||
| public ApiResponse<VehicleInfo> update( | |||||
| @ApiParam(value = "车辆ID", required = true, example = "1") | |||||
| @PathVariable Integer id, | |||||
| @ApiParam(value = "更新后的车辆信息实体", required = true) | |||||
| @RequestBody VehicleInfo entity) { | |||||
| entity.setId(id); | |||||
| return ApiResponse.success(service.save(entity)); | |||||
| } | |||||
| @ApiOperation(value = "删除车辆信息", notes = "根据ID删除车辆信息") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "删除成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @DeleteMapping("/{id}") | |||||
| public ApiResponse<Void> delete( | |||||
| @ApiParam(value = "车辆ID", required = true, example = "1") | |||||
| @PathVariable Integer id) { | |||||
| service.deleteById(id); | |||||
| return ApiResponse.success(); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,125 @@ | |||||
| package com.example.webapi.controller; | |||||
| import com.example.webapi.dto.WeighingRecordQueryDTO; | |||||
| import com.example.webapi.entity.TransferRecord; | |||||
| import com.example.webapi.entity.WeighingRecord; | |||||
| import com.example.webapi.service.TransferRecordService; | |||||
| import com.example.webapi.service.WeighingRecordService; | |||||
| import com.example.webapi.dto.ApiResponse; | |||||
| import io.swagger.annotations.Api; | |||||
| import io.swagger.annotations.ApiOperation; | |||||
| import io.swagger.annotations.ApiParam; | |||||
| import io.swagger.v3.oas.annotations.media.Content; | |||||
| import io.swagger.v3.oas.annotations.media.Schema; | |||||
| import io.swagger.v3.oas.annotations.responses.ApiResponses; | |||||
| import io.swagger.v3.oas.annotations.tags.Tag; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.data.domain.Page; | |||||
| import org.springframework.web.bind.annotation.*; | |||||
| import java.util.Optional; | |||||
| @Api(tags = "称重记录管理") | |||||
| @Tag(name = "称重记录管理", description = "提供称重记录的增删改查接口") | |||||
| @RestController | |||||
| @RequestMapping("/weighing-record") | |||||
| public class WeighingRecordController { | |||||
| @Autowired | |||||
| private WeighingRecordService service; | |||||
| @Autowired | |||||
| private TransferRecordService transferRecordService; | |||||
| @ApiOperation(value = "条件查询称重记录(分页)", notes = "根据提供的查询条件分页查询称重记录") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @PostMapping("/page/conditions") | |||||
| public ApiResponse<Page<WeighingRecord>> pageByConditions( | |||||
| @ApiParam(value = "查询条件DTO,包含分页信息和过滤条件", required = true) | |||||
| @RequestBody WeighingRecordQueryDTO queryDTO) { | |||||
| return ApiResponse.success(service.findByConditions(queryDTO)); | |||||
| } | |||||
| @ApiOperation(value = "根据ID查询称重记录", notes = "根据ID获取单条称重记录详情") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @GetMapping("/{id}") | |||||
| public ApiResponse<WeighingRecord> getById( | |||||
| @ApiParam(value = "称重记录ID", required = true, example = "1") | |||||
| @PathVariable Integer id) { | |||||
| Optional<WeighingRecord> result = service.findById(id); | |||||
| return result.map(ApiResponse::success) | |||||
| .orElseGet(() -> ApiResponse.error("未找到该称重记录")); | |||||
| } | |||||
| @ApiOperation(value = "新增称重记录", notes = "创建新的称重记录") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "创建成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "请求参数错误"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @PostMapping | |||||
| public ApiResponse<WeighingRecord> create( | |||||
| @ApiParam(value = "称重记录实体", required = true) | |||||
| @RequestBody WeighingRecord entity) { | |||||
| WeighingRecord weighingRecord= service.save(entity); | |||||
| if(weighingRecord.getMaterielId()!=null){ | |||||
| Optional<TransferRecord> result = transferRecordService.findById(weighingRecord.getMaterielId()); | |||||
| if( result.isPresent()){ | |||||
| TransferRecord record= result.get(); | |||||
| record .setStatus(1); | |||||
| transferRecordService.save(record); | |||||
| } | |||||
| } | |||||
| return ApiResponse.success(); | |||||
| } | |||||
| @ApiOperation(value = "更新称重记录", notes = "根据ID更新称重记录信息") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "更新成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "请求参数错误"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @PutMapping("/{id}") | |||||
| public ApiResponse<WeighingRecord> update( | |||||
| @ApiParam(value = "称重记录ID", required = true, example = "1") | |||||
| @PathVariable Integer id, | |||||
| @ApiParam(value = "更新后的称重记录实体", required = true) | |||||
| @RequestBody WeighingRecord entity) { | |||||
| entity.setId(id); | |||||
| return ApiResponse.success(service.save(entity)); | |||||
| } | |||||
| @ApiOperation(value = "删除称重记录", notes = "根据ID删除称重记录") | |||||
| @ApiResponses(value = { | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "删除成功", | |||||
| content = @Content(mediaType = "application/json", | |||||
| schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"), | |||||
| @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误") | |||||
| }) | |||||
| @DeleteMapping("/{id}") | |||||
| public ApiResponse<Void> delete( | |||||
| @ApiParam(value = "称重记录ID", required = true, example = "1") | |||||
| @PathVariable Integer id) { | |||||
| service.deleteById(id); | |||||
| return ApiResponse.success(); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,86 @@ | |||||
| package com.example.webapi.dto; | |||||
| import io.swagger.annotations.ApiModel; | |||||
| import io.swagger.annotations.ApiModelProperty; | |||||
| import lombok.Data; | |||||
| import java.time.LocalDateTime; | |||||
| /** | |||||
| * 通用API响应类 | |||||
| * | |||||
| * @author Your Name | |||||
| * @version 1.0.0 | |||||
| */ | |||||
| @Data | |||||
| @ApiModel(description = "API通用响应结构") | |||||
| public class ApiResponse<T> { | |||||
| @ApiModelProperty(value = "响应状态码", example = "200", notes = "200表示成功,其他值表示失败") | |||||
| private Integer code; | |||||
| @ApiModelProperty(value = "响应消息", example = "操作成功") | |||||
| private String message; | |||||
| @ApiModelProperty(value = "响应数据") | |||||
| private T data; | |||||
| @ApiModelProperty(value = "响应时间戳", example = "2023-05-01T10:30:00") | |||||
| private LocalDateTime timestamp; | |||||
| public ApiResponse() { | |||||
| this.timestamp = LocalDateTime.now(); | |||||
| } | |||||
| public ApiResponse(Integer code, String message) { | |||||
| this(); | |||||
| this.code = code; | |||||
| this.message = message; | |||||
| } | |||||
| public ApiResponse(Integer code, String message, T data) { | |||||
| this(code, message); | |||||
| this.data = data; | |||||
| } | |||||
| /** | |||||
| * 成功响应 | |||||
| * | |||||
| * @param data 响应数据 | |||||
| * @param <T> 数据类型 | |||||
| * @return 响应对象 | |||||
| */ | |||||
| public static <T> ApiResponse<T> success(T data) { | |||||
| return new ApiResponse<>(200, "操作成功", data); | |||||
| } | |||||
| /** | |||||
| * 成功响应(无数据) | |||||
| * | |||||
| * @return 响应对象 | |||||
| */ | |||||
| public static <T> ApiResponse<T> success() { | |||||
| return new ApiResponse<>(200, "操作成功"); | |||||
| } | |||||
| /** | |||||
| * 失败响应 | |||||
| * | |||||
| * @param message 错误消息 | |||||
| * @return 响应对象 | |||||
| */ | |||||
| public static <T> ApiResponse<T> error(String message) { | |||||
| return new ApiResponse<>(500, message); | |||||
| } | |||||
| /** | |||||
| * 失败响应 | |||||
| * | |||||
| * @param code 错误码 | |||||
| * @param message 错误消息 | |||||
| * @return 响应对象 | |||||
| */ | |||||
| public static <T> ApiResponse<T> error(Integer code, String message) { | |||||
| return new ApiResponse<>(code, message); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,40 @@ | |||||
| package com.example.webapi.dto; | |||||
| import io.swagger.annotations.ApiModel; | |||||
| import io.swagger.annotations.ApiModelProperty; | |||||
| import lombok.Data; | |||||
| /** | |||||
| * 基础分页DTO | |||||
| * | |||||
| * @author Your Name | |||||
| * @version 1.0.0 | |||||
| */ | |||||
| @Data | |||||
| @ApiModel(description = "基础分页参数") | |||||
| public class BasePageDTO { | |||||
| /** | |||||
| * 页码(从0开始) | |||||
| */ | |||||
| @ApiModelProperty(value = "页码(从0开始)", example = "0", notes = "默认为0") | |||||
| private Integer page = 0; | |||||
| /** | |||||
| * 每页大小 | |||||
| */ | |||||
| @ApiModelProperty(value = "每页大小", example = "10", notes = "默认为10") | |||||
| private Integer size = 10; | |||||
| /** | |||||
| * 排序字段 | |||||
| */ | |||||
| @ApiModelProperty(value = "排序字段", example = "id", notes = "可选") | |||||
| private String sortBy; | |||||
| /** | |||||
| * 排序方向(asc/desc) | |||||
| */ | |||||
| @ApiModelProperty(value = "排序方向", example = "asc", notes = "可选值:asc(升序)、desc(降序),默认为asc") | |||||
| private String sortDirection = "asc"; | |||||
| } | |||||
| @@ -0,0 +1,33 @@ | |||||
| package com.example.webapi.dto; | |||||
| import io.swagger.annotations.ApiModel; | |||||
| import io.swagger.annotations.ApiModelProperty; | |||||
| import lombok.Data; | |||||
| import lombok.EqualsAndHashCode; | |||||
| /** | |||||
| * 图片信息查询条件DTO | |||||
| * | |||||
| * @author Your Name | |||||
| * @version 1.0.0 | |||||
| */ | |||||
| @Data | |||||
| @EqualsAndHashCode(callSuper = true) | |||||
| @ApiModel(description = "图片信息查询条件数据传输对象") | |||||
| public class ImageInfoQueryDTO extends BasePageDTO { | |||||
| @ApiModelProperty(value = "文件名", example = "image001", notes = "支持模糊查询") | |||||
| private String fileName; | |||||
| @ApiModelProperty(value = "文件扩展名", example = "jpg", notes = "精确匹配") | |||||
| private String fileExtension; | |||||
| @ApiModelProperty(value = "MIME类型", example = "image/jpeg", notes = "精确匹配") | |||||
| private String mimeType; | |||||
| @ApiModelProperty(value = "文件大小最小值(字节)", example = "1024", notes = "单位:字节") | |||||
| private Long fileSizeMin; | |||||
| @ApiModelProperty(value = "文件大小最大值(字节)", example = "1048576", notes = "单位:字节") | |||||
| private Long fileSizeMax; | |||||
| } | |||||
| @@ -0,0 +1,27 @@ | |||||
| package com.example.webapi.dto; | |||||
| import io.swagger.annotations.ApiModel; | |||||
| import io.swagger.annotations.ApiModelProperty; | |||||
| import lombok.Data; | |||||
| import lombok.EqualsAndHashCode; | |||||
| /** | |||||
| * 品种信息查询条件DTO | |||||
| * | |||||
| * @author Your Name | |||||
| * @version 1.0.0 | |||||
| */ | |||||
| @Data | |||||
| @EqualsAndHashCode(callSuper = true) | |||||
| @ApiModel(description = "品种信息查询条件数据传输对象") | |||||
| public class MaterialInfoQueryDTO extends BasePageDTO { | |||||
| @ApiModelProperty(value = "品种编码", example = "M001", notes = "支持模糊查询") | |||||
| private String code; // 品种编码(模糊查询) | |||||
| @ApiModelProperty(value = "品种名称", example = "钢材", notes = "支持模糊查询") | |||||
| private String name; // 品种名称(模糊查询) | |||||
| @ApiModelProperty(value = "激活状态", example = "true", notes = "true=激活,false=未激活") | |||||
| private Boolean activate; // 激活状态 | |||||
| } | |||||
| @@ -0,0 +1,30 @@ | |||||
| package com.example.webapi.dto; | |||||
| import io.swagger.annotations.ApiModel; | |||||
| import io.swagger.annotations.ApiModelProperty; | |||||
| import lombok.Data; | |||||
| import lombok.EqualsAndHashCode; | |||||
| /** | |||||
| * 供应商信息查询条件DTO | |||||
| * | |||||
| * @author Your Name | |||||
| * @version 1.0.0 | |||||
| */ | |||||
| @Data | |||||
| @EqualsAndHashCode(callSuper = true) | |||||
| @ApiModel(description = "供应商信息查询条件数据传输对象") | |||||
| public class SupplierQueryDTO extends BasePageDTO { | |||||
| @ApiModelProperty(value = "供应商编码", example = "SUP001", notes = "支持模糊查询") | |||||
| private String code; // 供应商编码(模糊查询) | |||||
| @ApiModelProperty(value = "供应商名称", example = "福泉供应商", notes = "支持模糊查询") | |||||
| private String name; // 供应商名称(模糊查询) | |||||
| @ApiModelProperty(value = "激活状态", example = "true", notes = "true=激活,false=未激活") | |||||
| private Boolean active; // 激活状态 | |||||
| @ApiModelProperty(value = "备注", example = "长期合作伙伴", notes = "支持模糊查询") | |||||
| private String remark; // 备注(模糊查询) | |||||
| } | |||||
| @@ -0,0 +1,27 @@ | |||||
| package com.example.webapi.dto; | |||||
| import io.swagger.annotations.ApiModel; | |||||
| import io.swagger.annotations.ApiModelProperty; | |||||
| import lombok.Data; | |||||
| import lombok.EqualsAndHashCode; | |||||
| /** | |||||
| * 供应标识品种信息查询条件DTO | |||||
| * | |||||
| * @author Your Name | |||||
| * @version 1.0.0 | |||||
| */ | |||||
| @Data | |||||
| @EqualsAndHashCode(callSuper = true) | |||||
| @ApiModel(description = "供应标识品种信息查询条件数据传输对象") | |||||
| public class SupplyVarietyQueryDTO extends BasePageDTO { | |||||
| @ApiModelProperty(value = "供应商ID", example = "1", notes = "精确匹配") | |||||
| private Integer supplyId; // 供应商ID | |||||
| @ApiModelProperty(value = "品种ID", example = "1", notes = "精确匹配") | |||||
| private Integer good; // 品种ID | |||||
| @ApiModelProperty(value = "激活状态", example = "true", notes = "true=激活,false=未激活") | |||||
| private Boolean active; // 激活状态 | |||||
| } | |||||
| @@ -0,0 +1,41 @@ | |||||
| package com.example.webapi.dto; | |||||
| import io.swagger.annotations.ApiModel; | |||||
| import io.swagger.annotations.ApiModelProperty; | |||||
| import lombok.Data; | |||||
| import lombok.EqualsAndHashCode; | |||||
| /** | |||||
| * 转运记录查询条件DTO | |||||
| * | |||||
| * @author Your Name | |||||
| * @version 1.0.0 | |||||
| */ | |||||
| @Data | |||||
| @EqualsAndHashCode(callSuper = true) | |||||
| @ApiModel(description = "转运记录查询条件数据传输对象") | |||||
| public class TransferRecordQueryDTO extends BasePageDTO { | |||||
| // 基础查询条件(支持模糊查询) | |||||
| @ApiModelProperty(value = "单据号", example = "TR20230501001", notes = "支持模糊查询") | |||||
| private String billNo; | |||||
| @ApiModelProperty(value = "车牌号", example = "京A12345", notes = "支持模糊查询") | |||||
| private String vehicleNo; | |||||
| @ApiModelProperty(value = "卡号", example = "C0001", notes = "支持模糊查询") | |||||
| private String cardNo; | |||||
| // 精确匹配查询 | |||||
| @ApiModelProperty(value = "物料ID", example = "1", notes = "精确匹配") | |||||
| private Integer materielId; | |||||
| @ApiModelProperty(value = "收货公司ID", example = "1", notes = "精确匹配") | |||||
| private Integer receiveCompanyId; | |||||
| @ApiModelProperty(value = "转运公司ID", example = "1", notes = "精确匹配") | |||||
| private Integer transitCompanyId; | |||||
| @ApiModelProperty(value = "供应商ID", example = "1", notes = "精确匹配") | |||||
| private Integer supplyId; | |||||
| } | |||||
| @@ -0,0 +1,24 @@ | |||||
| package com.example.webapi.dto; | |||||
| import io.swagger.annotations.ApiModel; | |||||
| import io.swagger.annotations.ApiModelProperty; | |||||
| import lombok.Data; | |||||
| import lombok.EqualsAndHashCode; | |||||
| /** | |||||
| * 运输公司查询条件DTO | |||||
| * | |||||
| * @author Your Name | |||||
| * @version 1.0.0 | |||||
| */ | |||||
| @Data | |||||
| @EqualsAndHashCode(callSuper = true) | |||||
| @ApiModel(description = "运输公司查询条件数据传输对象") | |||||
| public class TransportCompanyQueryDTO extends BasePageDTO { | |||||
| @ApiModelProperty(value = "公司名称", example = "福泉物流", notes = "支持模糊查询") | |||||
| private String name; // 公司名称(模糊查询) | |||||
| @ApiModelProperty(value = "备注", example = "长期合作伙伴", notes = "支持模糊查询") | |||||
| private String remark; // 备注(模糊查询) | |||||
| } | |||||
| @@ -0,0 +1,39 @@ | |||||
| package com.example.webapi.dto; | |||||
| import io.swagger.annotations.ApiModel; | |||||
| import io.swagger.annotations.ApiModelProperty; | |||||
| import lombok.Data; | |||||
| import lombok.EqualsAndHashCode; | |||||
| /** | |||||
| * 车辆信息查询条件DTO | |||||
| * | |||||
| * @author Your Name | |||||
| * @version 1.0.0 | |||||
| */ | |||||
| @Data | |||||
| @EqualsAndHashCode(callSuper = true) | |||||
| @ApiModel(description = "车辆信息查询条件数据传输对象") | |||||
| public class VehicleInfoQueryDTO extends BasePageDTO { | |||||
| @ApiModelProperty(value = "车牌号", example = "京A12345", notes = "支持模糊查询") | |||||
| private String licensePlate; // 车牌号(模糊查询) | |||||
| @ApiModelProperty(value = "车辆类型", example = "货车", notes = "精确匹配") | |||||
| private String type; // 车辆类型 | |||||
| @ApiModelProperty(value = "停用状态", example = "false", notes = "true=已停用,false=未停用") | |||||
| private Boolean outage; // 停用状态 | |||||
| @ApiModelProperty(value = "锁定状态", example = "false", notes = "true=已锁定,false=未锁定") | |||||
| private Boolean lock; // 锁定状态 | |||||
| @ApiModelProperty(value = "运输公司ID", example = "1", notes = "精确匹配") | |||||
| private Integer transCompany; // 运输公司ID | |||||
| @ApiModelProperty(value = "审核状态", example = "true", notes = "true=已审核,false=未审核") | |||||
| private Boolean reviewed; // 审核状态 | |||||
| @ApiModelProperty(value = "备注", example = "新购车辆", notes = "支持模糊查询") | |||||
| private String remarks; // 备注(模糊查询) | |||||
| } | |||||
| @@ -0,0 +1,59 @@ | |||||
| package com.example.webapi.dto; | |||||
| import io.swagger.annotations.ApiModel; | |||||
| import io.swagger.annotations.ApiModelProperty; | |||||
| import lombok.Data; | |||||
| import lombok.EqualsAndHashCode; | |||||
| /** | |||||
| * 称重记录查询条件DTO | |||||
| * | |||||
| * @author Your Name | |||||
| * @version 1.0.0 | |||||
| */ | |||||
| @Data | |||||
| @EqualsAndHashCode(callSuper = true) | |||||
| @ApiModel(description = "称重记录查询条件数据传输对象") | |||||
| public class WeighingRecordQueryDTO extends BasePageDTO { | |||||
| // 基础查询条件(支持模糊查询) | |||||
| @ApiModelProperty(value = "单据号", example = "BL20230501001", notes = "支持模糊查询") | |||||
| private String billNo; | |||||
| @ApiModelProperty(value = "车牌号", example = "京A12345", notes = "支持模糊查询") | |||||
| private String vehicleNo; | |||||
| @ApiModelProperty(value = "卡号", example = "C0001", notes = "支持模糊查询") | |||||
| private String cardNo; | |||||
| @ApiModelProperty(value = "RFID号", example = "RF0001", notes = "支持模糊查询") | |||||
| private String rfidNo; | |||||
| @ApiModelProperty(value = "开单人", example = "张三", notes = "支持模糊查询") | |||||
| private String issuedBy; | |||||
| @ApiModelProperty(value = "毛重操作人", example = "李四", notes = "支持模糊查询") | |||||
| private String gwBy; | |||||
| @ApiModelProperty(value = "皮重操作人", example = "王五", notes = "支持模糊查询") | |||||
| private String tBy; | |||||
| // 精确匹配查询 | |||||
| @ApiModelProperty(value = "物料ID", example = "1", notes = "精确匹配") | |||||
| private Integer materielId; | |||||
| @ApiModelProperty(value = "仓库ID", example = "1", notes = "精确匹配") | |||||
| private Integer warehouseId; | |||||
| @ApiModelProperty(value = "收货公司ID", example = "1", notes = "精确匹配") | |||||
| private Integer receiveCompanyId; | |||||
| @ApiModelProperty(value = "转运公司ID", example = "1", notes = "精确匹配") | |||||
| private Integer transitCompanyId; | |||||
| @ApiModelProperty(value = "车辆ID", example = "1", notes = "精确匹配") | |||||
| private Integer vehicleId; | |||||
| @ApiModelProperty(value = "供应商ID", example = "1", notes = "精确匹配") | |||||
| private Integer supplyId; | |||||
| } | |||||
| @@ -0,0 +1,44 @@ | |||||
| package com.example.webapi.entity; | |||||
| import io.swagger.annotations.ApiModel; | |||||
| import io.swagger.annotations.ApiModelProperty; | |||||
| import lombok.Data; | |||||
| import javax.persistence.*; | |||||
| import java.util.Date; | |||||
| @Data | |||||
| @Entity | |||||
| @Table(name = "图片信息表") | |||||
| @ApiModel(description = "图片信息实体") | |||||
| public class ImageInfo { | |||||
| @Id | |||||
| @GeneratedValue(strategy = GenerationType.IDENTITY) | |||||
| @Column(name = "id") | |||||
| @ApiModelProperty(value = "图片ID", example = "1", notes = "主键,自动生成") | |||||
| private Integer id; | |||||
| @Column(name = "FileName", length = 255, nullable = false) | |||||
| @ApiModelProperty(value = "文件名", example = "vehicle_photo_001", required = true) | |||||
| private String fileName; | |||||
| @Column(name = "FileExtension", length = 10, nullable = false) | |||||
| @ApiModelProperty(value = "文件扩展名", example = "jpg", required = true) | |||||
| private String fileExtension; | |||||
| @Column(name = "MimeType ", length = 50, nullable = false) | |||||
| @ApiModelProperty(value = "MIME类型", example = "image/jpeg", required = true) | |||||
| private String mimeType; | |||||
| @Lob | |||||
| @Column(name = "ImageData", nullable = false) | |||||
| @ApiModelProperty(value = "图片二进制数据", required = true, hidden = true) | |||||
| private byte[] imageData; | |||||
| @Column(name = "FileSize", nullable = false) | |||||
| @ApiModelProperty(value = "文件大小(字节)", example = "102400", required = true, notes = "单位:字节") | |||||
| private Long fileSize; | |||||
| @Column(name = "UploadTime", nullable = false) | |||||
| @ApiModelProperty(value = "上传时间", example = "2023-05-01 10:30:00", required = true) | |||||
| private Date uploadTime; | |||||
| } | |||||
| @@ -0,0 +1,29 @@ | |||||
| package com.example.webapi.entity; | |||||
| import io.swagger.annotations.ApiModel; | |||||
| import io.swagger.annotations.ApiModelProperty; | |||||
| import lombok.Data; | |||||
| import javax.persistence.*; | |||||
| @Data | |||||
| @Entity | |||||
| @Table(name = "品种信息表") | |||||
| @ApiModel(description = "品种信息实体") | |||||
| public class MaterialInfo { | |||||
| @Id | |||||
| @Column(name = "ID") | |||||
| @ApiModelProperty(value = "品种ID", example = "1", notes = "主键,自动生成") | |||||
| private Integer id; | |||||
| @Column(name = "Code", length = 30, nullable = false) | |||||
| @ApiModelProperty(value = "品种编码", example = "M001", required = true) | |||||
| private String code; | |||||
| @Column(name = "Name", length = 50, nullable = false) | |||||
| @ApiModelProperty(value = "品种名称", example = "钢材", required = true) | |||||
| private String name; | |||||
| @Column(name = "Activate", nullable = false) | |||||
| @ApiModelProperty(value = "激活状态", example = "true", notes = "true=激活,false=未激活") | |||||
| private Boolean activate; | |||||
| } | |||||
| @@ -0,0 +1,33 @@ | |||||
| package com.example.webapi.entity; | |||||
| import io.swagger.annotations.ApiModel; | |||||
| import io.swagger.annotations.ApiModelProperty; | |||||
| import lombok.Data; | |||||
| import javax.persistence.*; | |||||
| @Data | |||||
| @Entity | |||||
| @Table(name = "供应商信息表") | |||||
| @ApiModel(description = "供应商信息实体") | |||||
| public class Supplier { | |||||
| @Id | |||||
| @Column(name = "ID") | |||||
| @ApiModelProperty(value = "供应商ID", example = "1", notes = "主键,自动生成") | |||||
| private Integer id; | |||||
| @Column(name = "Code", length = 50, nullable = false) | |||||
| @ApiModelProperty(value = "供应商编码", example = "SUP001", required = true) | |||||
| private String code; | |||||
| @Column(name = "Name", length = 100, nullable = false) | |||||
| @ApiModelProperty(value = "供应商名称", example = "福泉供应商", required = true) | |||||
| private String name; | |||||
| @Column(name = "Active") | |||||
| @ApiModelProperty(value = "激活状态", example = "true", notes = "true=激活,false=未激活") | |||||
| private Boolean active; | |||||
| @Column(name = "Remark", length = 300) | |||||
| @ApiModelProperty(value = "备注", example = "长期合作伙伴") | |||||
| private String remark; | |||||
| } | |||||
| @@ -0,0 +1,29 @@ | |||||
| package com.example.webapi.entity; | |||||
| import io.swagger.annotations.ApiModel; | |||||
| import io.swagger.annotations.ApiModelProperty; | |||||
| import lombok.Data; | |||||
| import javax.persistence.*; | |||||
| @Data | |||||
| @Entity | |||||
| @Table(name = "供应标识品种信息") | |||||
| @ApiModel(description = "供应标识品种信息实体") | |||||
| public class SupplyVariety { | |||||
| @Id | |||||
| @Column(name = "ID") | |||||
| @ApiModelProperty(value = "记录ID", example = "1", notes = "主键,自动生成") | |||||
| private Integer id; | |||||
| @Column(name = "SupplyID", nullable = false) | |||||
| @ApiModelProperty(value = "供应商ID", example = "1", required = true, notes = "关联供应商信息") | |||||
| private Integer supplyId; | |||||
| @Column(name = "Good", nullable = false) | |||||
| @ApiModelProperty(value = "品种ID", example = "1", required = true, notes = "关联品种信息") | |||||
| private Integer good; | |||||
| @Column(name = "Active") | |||||
| @ApiModelProperty(value = "激活状态", example = "true", notes = "true=激活,false=未激活") | |||||
| private Boolean active; | |||||
| } | |||||
| @@ -0,0 +1,76 @@ | |||||
| package com.example.webapi.entity; | |||||
| import io.swagger.annotations.ApiModel; | |||||
| import io.swagger.annotations.ApiModelProperty; | |||||
| import lombok.Data; | |||||
| import javax.persistence.*; | |||||
| import java.math.BigDecimal; | |||||
| import java.util.Date; | |||||
| @Data | |||||
| @Entity | |||||
| @Table(name = "转运记录表") | |||||
| @ApiModel(description = "转运记录实体") | |||||
| public class TransferRecord { | |||||
| @Id | |||||
| @Column(name = "ID") | |||||
| @ApiModelProperty(value = "记录ID", example = "1", notes = "主键,自动生成") | |||||
| private Integer id; | |||||
| @Column(name = "Materiel_ID") | |||||
| @ApiModelProperty(value = "物料ID", example = "1", notes = "关联物料信息") | |||||
| private Integer materielId; | |||||
| @Column(name = "Receive_Company_ID") | |||||
| @ApiModelProperty(value = "收货公司ID", example = "1", notes = "关联收货公司信息") | |||||
| private Integer receiveCompanyId; | |||||
| @Column(name = "Transit_Company_ID") | |||||
| @ApiModelProperty(value = "转运公司ID", example = "1", notes = "关联转运公司信息") | |||||
| private Integer transitCompanyId; | |||||
| @Column(name = "Bill_NO", length = 50, nullable = false) | |||||
| @ApiModelProperty(value = "单据号", example = "TR20230501001", required = true) | |||||
| private String billNo; | |||||
| @Column(name = "Supply_ID") | |||||
| @ApiModelProperty(value = "供应商ID", example = "1", notes = "关联供应商信息") | |||||
| private Integer supplyId; | |||||
| @Column(name = "Card_NO", length = 8) | |||||
| @ApiModelProperty(value = "卡号", example = "C0001") | |||||
| private String cardNo; | |||||
| @Column(name = "Vehicle_NO", length = 15, nullable = false) | |||||
| @ApiModelProperty(value = "车牌号", example = "京A12345", required = true) | |||||
| private String vehicleNo; | |||||
| @Column(name = "Issued_Time") | |||||
| @ApiModelProperty(value = "开单时间", example = "2023-05-01 10:00:00") | |||||
| private Date issuedTime; | |||||
| @Column(name = "GW", precision = 18, scale = 4) | |||||
| @ApiModelProperty(value = "毛重(kg)", example = "5000.5", notes = "单位:千克") | |||||
| private BigDecimal gw; | |||||
| @Column(name = "T", precision = 18, scale = 4) | |||||
| @ApiModelProperty(value = "皮重(kg)", example = "1000.5", notes = "单位:千克") | |||||
| private BigDecimal t; | |||||
| @Column(name = "T_Time") | |||||
| @ApiModelProperty(value = "皮重时间", example = "2023-05-01 11:00:00") | |||||
| private Date tTime; | |||||
| @Column(name = "NW", precision = 18, scale = 4) | |||||
| @ApiModelProperty(value = "净重(kg)", example = "4000.0", notes = "单位:千克,毛重-皮重") | |||||
| private BigDecimal nw; | |||||
| @Column(name = "Comments", length = 500) | |||||
| @ApiModelProperty(value = "备注", example = "货物完好") | |||||
| private String comments; | |||||
| @Column(name = "status") | |||||
| @ApiModelProperty(value = "是否已转运", example = "1", notes = "是否已转运0.否 1是") | |||||
| private Integer status; | |||||
| } | |||||
| @@ -0,0 +1,25 @@ | |||||
| package com.example.webapi.entity; | |||||
| import io.swagger.annotations.ApiModel; | |||||
| import io.swagger.annotations.ApiModelProperty; | |||||
| import lombok.Data; | |||||
| import javax.persistence.*; | |||||
| @Data | |||||
| @Entity | |||||
| @Table(name = "运输公司") | |||||
| @ApiModel(description = "运输公司实体") | |||||
| public class TransportCompany { | |||||
| @Id | |||||
| @Column(name = "编号") | |||||
| @ApiModelProperty(value = "公司ID", example = "1", notes = "主键,自动生成") | |||||
| private Integer id; | |||||
| @Column(name = "公司名称", length = 100) | |||||
| @ApiModelProperty(value = "公司名称", example = "福泉物流") | |||||
| private String name; | |||||
| @Column(name = "备注", length = 300) | |||||
| @ApiModelProperty(value = "备注", example = "长期合作伙伴") | |||||
| private String remark; | |||||
| } | |||||
| @@ -0,0 +1,45 @@ | |||||
| package com.example.webapi.entity; | |||||
| import io.swagger.annotations.ApiModel; | |||||
| import io.swagger.annotations.ApiModelProperty; | |||||
| import lombok.Data; | |||||
| import javax.persistence.*; | |||||
| @Data | |||||
| @Entity | |||||
| @Table(name = "车辆信息") | |||||
| @ApiModel(description = "车辆信息实体") | |||||
| public class VehicleInfo { | |||||
| @Id | |||||
| @Column(name = "ID") | |||||
| @ApiModelProperty(value = "车辆ID", example = "1", notes = "主键,自动生成") | |||||
| private Integer id; | |||||
| @Column(name = "LicensePlate", nullable = false, length = 20) | |||||
| @ApiModelProperty(value = "车牌号", example = "京A12345", required = true) | |||||
| private String licensePlate; | |||||
| @Column(name = "Type", length = 20) | |||||
| @ApiModelProperty(value = "车辆类型", example = "货车") | |||||
| private String type; | |||||
| @Column(name = "Outage") | |||||
| @ApiModelProperty(value = "停用状态", example = "false", notes = "true=已停用,false=未停用") | |||||
| private Boolean outage; | |||||
| @Column(name = "Lock") | |||||
| @ApiModelProperty(value = "锁定状态", example = "false", notes = "true=已锁定,false=未锁定") | |||||
| private Boolean lock; | |||||
| @Column(name = "TransCompany") | |||||
| @ApiModelProperty(value = "运输公司ID", example = "1", notes = "关联运输公司信息") | |||||
| private Integer transCompany; | |||||
| @Column(name = "Reviewed") | |||||
| @ApiModelProperty(value = "审核状态", example = "true", notes = "true=已审核,false=未审核") | |||||
| private Boolean reviewed; | |||||
| @Column(name = "Remarks", length = 1000) | |||||
| @ApiModelProperty(value = "备注", example = "新购车辆") | |||||
| private String remarks; | |||||
| } | |||||
| @@ -0,0 +1,135 @@ | |||||
| package com.example.webapi.entity; | |||||
| import io.swagger.annotations.ApiModel; | |||||
| import io.swagger.annotations.ApiModelProperty; | |||||
| import lombok.Data; | |||||
| import javax.persistence.*; | |||||
| import java.math.BigDecimal; | |||||
| import java.util.Date; | |||||
| @Data | |||||
| @Entity | |||||
| @Table(name = "称重记录表") | |||||
| @ApiModel(description = "称重记录实体") | |||||
| public class WeighingRecord { | |||||
| @Id | |||||
| @Column(name = "ID") | |||||
| @ApiModelProperty(value = "记录ID", example = "1", notes = "主键,自动生成") | |||||
| private Integer id; | |||||
| @Column(name = "Materiel_ID") | |||||
| @ApiModelProperty(value = "物料ID", example = "1", notes = "关联物料信息") | |||||
| private Integer materielId; | |||||
| @Column(name = "Warehouse_ID") | |||||
| @ApiModelProperty(value = "仓库ID", example = "1", notes = "关联仓库信息") | |||||
| private Integer warehouseId; | |||||
| @Column(name = "Receive_Company_ID") | |||||
| @ApiModelProperty(value = "收货公司ID", example = "1", notes = "关联收货公司信息") | |||||
| private Integer receiveCompanyId; | |||||
| @Column(name = "Transit_Company_ID") | |||||
| @ApiModelProperty(value = "转运公司ID", example = "1", notes = "关联转运公司信息") | |||||
| private Integer transitCompanyId; | |||||
| @Column(name = "Vehicle_ID") | |||||
| @ApiModelProperty(value = "车辆ID", example = "1", notes = "关联车辆信息") | |||||
| private Integer vehicleId; | |||||
| @Column(name = "Bill_NO", length = 50, nullable = false) | |||||
| @ApiModelProperty(value = "单据号", example = "BL20230501001", required = true) | |||||
| private String billNo; | |||||
| @Column(name = "Supply_ID") | |||||
| @ApiModelProperty(value = "供应商ID", example = "1", notes = "关联供应商信息") | |||||
| private Integer supplyId; | |||||
| @Column(name = "Card_NO", length = 8) | |||||
| @ApiModelProperty(value = "卡号", example = "C0001") | |||||
| private String cardNo; | |||||
| @Column(name = "RFID_NO", length = 30) | |||||
| @ApiModelProperty(value = "RFID号", example = "RF0001") | |||||
| private String rfidNo; | |||||
| @Column(name = "Vehicle_NO", length = 15, nullable = false) | |||||
| @ApiModelProperty(value = "车牌号", example = "京A12345", required = true) | |||||
| private String vehicleNo; | |||||
| @Column(name = "Issued_Machine_NO", length = 50) | |||||
| @ApiModelProperty(value = "开单机器编号", example = "M001") | |||||
| private String issuedMachineNo; | |||||
| @Column(name = "Issued_By", length = 20) | |||||
| @ApiModelProperty(value = "开单人", example = "张三") | |||||
| private String issuedBy; | |||||
| @Column(name = "Issued_Time") | |||||
| @ApiModelProperty(value = "开单时间", example = "2023-05-01 10:00:00") | |||||
| private Date issuedTime; | |||||
| @Column(name = "GW", precision = 18, scale = 4) | |||||
| @ApiModelProperty(value = "毛重(kg)", example = "5000.5", notes = "单位:千克") | |||||
| private BigDecimal gw; | |||||
| @Column(name = "GW_Scale_NO", length = 50) | |||||
| @ApiModelProperty(value = "毛重秤编号", example = "S001") | |||||
| private String gwScaleNo; | |||||
| @Column(name = "GW_Time") | |||||
| @ApiModelProperty(value = "毛重时间", example = "2023-05-01 10:30:00") | |||||
| private Date gwTime; | |||||
| @Column(name = "GW_By", length = 20) | |||||
| @ApiModelProperty(value = "毛重操作人", example = "李四") | |||||
| private String gwBy; | |||||
| @Column(name = "T", precision = 18, scale = 4) | |||||
| @ApiModelProperty(value = "皮重(kg)", example = "1000.5", notes = "单位:千克") | |||||
| private BigDecimal t; | |||||
| @Column(name = "T_Scale_NO", length = 50) | |||||
| @ApiModelProperty(value = "皮重秤编号", example = "S002") | |||||
| private String tScaleNo; | |||||
| @Column(name = "T_Time") | |||||
| @ApiModelProperty(value = "皮重时间", example = "2023-05-01 11:00:00") | |||||
| private Date tTime; | |||||
| @Column(name = "T_By", length = 20) | |||||
| @ApiModelProperty(value = "皮重操作人", example = "王五") | |||||
| private String tBy; | |||||
| @Column(name = "NW", precision = 18, scale = 4) | |||||
| @ApiModelProperty(value = "净重(kg)", example = "4000.0", notes = "单位:千克,毛重-皮重") | |||||
| private BigDecimal nw; | |||||
| @Column(name = "Comments", length = 500) | |||||
| @ApiModelProperty(value = "备注", example = "货物完好") | |||||
| private String comments; | |||||
| @Column(name = "Operate_Time") | |||||
| @ApiModelProperty(value = "操作时间", example = "2023-05-01 11:30:00") | |||||
| private Date operateTime; | |||||
| @Column(name = "Arrival_Time") | |||||
| @ApiModelProperty(value = "到达时间", example = "2023-05-01 09:30:00") | |||||
| private Date arrivalTime; | |||||
| @Column(name = "Leave_Time") | |||||
| @ApiModelProperty(value = "离开时间", example = "2023-05-01 12:00:00") | |||||
| private Date leaveTime; | |||||
| @Column(name = "Pic01") | |||||
| @ApiModelProperty(value = "图片1ID", example = "101") | |||||
| private Integer pic01; | |||||
| @Column(name = "Pic02") | |||||
| @ApiModelProperty(value = "图片2ID", example = "102") | |||||
| private Integer pic02; | |||||
| @Column(name = "WTId") | |||||
| @ApiModelProperty(value = "称重类型ID", example = "1") | |||||
| private Integer wtId; | |||||
| } | |||||
| @@ -0,0 +1,140 @@ | |||||
| package com.example.webapi.interceptor; | |||||
| import com.example.webapi.util.SignatureUtil; | |||||
| import lombok.extern.slf4j.Slf4j; | |||||
| import org.springframework.beans.factory.annotation.Value; | |||||
| import org.springframework.stereotype.Component; | |||||
| import org.springframework.web.method.HandlerMethod; | |||||
| import org.springframework.web.servlet.HandlerInterceptor; | |||||
| import org.springframework.web.servlet.ModelAndView; | |||||
| import org.springframework.web.util.ContentCachingRequestWrapper; | |||||
| import javax.servlet.http.HttpServletRequest; | |||||
| import javax.servlet.http.HttpServletResponse; | |||||
| import java.time.Instant; | |||||
| import java.time.LocalDateTime; | |||||
| import java.time.ZoneId; | |||||
| import java.util.Objects; | |||||
| /** | |||||
| * 签名验证拦截器 | |||||
| * | |||||
| * @author Your Name | |||||
| * @version 1.0.0 | |||||
| */ | |||||
| @Slf4j | |||||
| @Component | |||||
| public class SignatureInterceptor implements HandlerInterceptor { | |||||
| @Value("${api.client.ak}") | |||||
| private String configAk; | |||||
| @Value("${api.client.sk}") | |||||
| private String configSk; | |||||
| // 时间戳有效期(分钟) | |||||
| private static final long TIMESTAMP_VALIDITY_MINUTES = 10; | |||||
| @Override | |||||
| public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { | |||||
| // // 只处理方法请求 | |||||
| // if (!(handler instanceof HandlerMethod)) { | |||||
| // return true; | |||||
| // } | |||||
| // | |||||
| // // 包装请求,使其可以重复读取 | |||||
| // ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request); | |||||
| // | |||||
| // // 获取请求头 | |||||
| // String ak = requestWrapper.getHeader("ak"); | |||||
| // String timestamp = requestWrapper.getHeader("timestamp"); | |||||
| // String signature = requestWrapper.getHeader("signature"); | |||||
| // | |||||
| // // 验证请求头是否存在 | |||||
| // if (ak == null || timestamp == null || signature == null) { | |||||
| // log.error("缺少必要的请求头: ak={}, timestamp={}, signature={}", ak, timestamp, signature); | |||||
| // response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); | |||||
| // response.getWriter().write("Missing required headers"); | |||||
| // return false; | |||||
| // } | |||||
| // | |||||
| // // 验证ak是否匹配 | |||||
| // if (!Objects.equals(ak, configAk)) { | |||||
| // log.error("无效的ak: 请求ak={}, 配置ak={}", ak, configAk); | |||||
| // response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); | |||||
| // response.getWriter().write("Invalid ak"); | |||||
| // return false; | |||||
| // } | |||||
| // | |||||
| // // 验证时间戳是否在有效期内 | |||||
| // if (!isTimestampValid(timestamp)) { | |||||
| // log.error("时间戳已过期或无效: timestamp={}", timestamp); | |||||
| // response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); | |||||
| // response.getWriter().write("Timestamp expired or invalid"); | |||||
| // return false; | |||||
| // } | |||||
| // | |||||
| // // 验证客户端生成的签名 | |||||
| // String calculatedSignature = SignatureUtil.generateSignature(ak, configSk, timestamp); | |||||
| // if (!signature.equals(calculatedSignature)) { | |||||
| // log.error("签名验证失败,请求签名:{},计算签名:{},时间戳:{}", signature, calculatedSignature, timestamp); | |||||
| // response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); | |||||
| // response.getWriter().write("Invalid signature"); | |||||
| // return false; | |||||
| // } | |||||
| // | |||||
| // log.debug("签名验证成功,用户: {}", ak); | |||||
| return true; | |||||
| } | |||||
| /** | |||||
| * 验证时间戳是否在有效期内 | |||||
| * | |||||
| * @param timestamp 时间戳字符串 | |||||
| * @return 是否有效 | |||||
| */ | |||||
| private boolean isTimestampValid(String timestamp) { | |||||
| try { | |||||
| // 解析时间戳 | |||||
| long timestampMillis = Long.parseLong(timestamp); | |||||
| LocalDateTime requestTime = LocalDateTime.ofInstant( | |||||
| Instant.ofEpochMilli(timestampMillis), | |||||
| ZoneId.systemDefault() | |||||
| ); | |||||
| // 获取当前时间 | |||||
| LocalDateTime currentTime = LocalDateTime.now(); | |||||
| // 计算时间差(分钟) | |||||
| long timeDiffMinutes = Math.abs( | |||||
| java.time.Duration.between(requestTime, currentTime).toMinutes() | |||||
| ); | |||||
| // 检查是否在有效期内(10分钟) | |||||
| boolean isValid = timeDiffMinutes <= TIMESTAMP_VALIDITY_MINUTES; | |||||
| if (!isValid) { | |||||
| log.warn("时间戳超出有效期: 请求时间={}, 当前时间={}, 时间差={}分钟, 有效期={}分钟", | |||||
| requestTime, currentTime, timeDiffMinutes, TIMESTAMP_VALIDITY_MINUTES); | |||||
| } | |||||
| return isValid; | |||||
| } catch (NumberFormatException e) { | |||||
| log.error("时间戳格式错误: {}", timestamp, e); | |||||
| return false; | |||||
| } catch (Exception e) { | |||||
| log.error("验证时间戳时发生错误: {}", timestamp, e); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| @Override | |||||
| public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { | |||||
| // 不需要实现 | |||||
| } | |||||
| @Override | |||||
| public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { | |||||
| // 不需要实现 | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,9 @@ | |||||
| package com.example.webapi.repository; | |||||
| import com.example.webapi.entity.ImageInfo; | |||||
| import org.springframework.data.jpa.repository.JpaRepository; | |||||
| import org.springframework.stereotype.Repository; | |||||
| @Repository | |||||
| public interface ImageInfoRepository extends JpaRepository<ImageInfo, Integer> { | |||||
| } | |||||
| @@ -0,0 +1,9 @@ | |||||
| package com.example.webapi.repository; | |||||
| import com.example.webapi.entity.MaterialInfo; | |||||
| import org.springframework.data.jpa.repository.JpaRepository; | |||||
| import org.springframework.stereotype.Repository; | |||||
| @Repository | |||||
| public interface MaterialInfoRepository extends JpaRepository<MaterialInfo, Integer> { | |||||
| } | |||||
| @@ -0,0 +1,9 @@ | |||||
| package com.example.webapi.repository; | |||||
| import com.example.webapi.entity.Supplier; | |||||
| import org.springframework.data.jpa.repository.JpaRepository; | |||||
| import org.springframework.stereotype.Repository; | |||||
| @Repository | |||||
| public interface SupplierRepository extends JpaRepository<Supplier, Integer> { | |||||
| } | |||||
| @@ -0,0 +1,9 @@ | |||||
| package com.example.webapi.repository; | |||||
| import com.example.webapi.entity.SupplyVariety; | |||||
| import org.springframework.data.jpa.repository.JpaRepository; | |||||
| import org.springframework.stereotype.Repository; | |||||
| @Repository | |||||
| public interface SupplyVarietyRepository extends JpaRepository<SupplyVariety, Integer> { | |||||
| } | |||||
| @@ -0,0 +1,9 @@ | |||||
| package com.example.webapi.repository; | |||||
| import com.example.webapi.entity.TransferRecord; | |||||
| import org.springframework.data.jpa.repository.JpaRepository; | |||||
| import org.springframework.stereotype.Repository; | |||||
| @Repository | |||||
| public interface TransferRecordRepository extends JpaRepository<TransferRecord, Integer> { | |||||
| } | |||||
| @@ -0,0 +1,9 @@ | |||||
| package com.example.webapi.repository; | |||||
| import com.example.webapi.entity.TransportCompany; | |||||
| import org.springframework.data.jpa.repository.JpaRepository; | |||||
| import org.springframework.stereotype.Repository; | |||||
| @Repository | |||||
| public interface TransportCompanyRepository extends JpaRepository<TransportCompany, Integer> { | |||||
| } | |||||
| @@ -0,0 +1,9 @@ | |||||
| package com.example.webapi.repository; | |||||
| import com.example.webapi.entity.VehicleInfo; | |||||
| import org.springframework.data.jpa.repository.JpaRepository; | |||||
| import org.springframework.stereotype.Repository; | |||||
| @Repository | |||||
| public interface VehicleInfoRepository extends JpaRepository<VehicleInfo, Integer> { | |||||
| } | |||||
| @@ -0,0 +1,9 @@ | |||||
| package com.example.webapi.repository; | |||||
| import com.example.webapi.entity.WeighingRecord; | |||||
| import org.springframework.data.jpa.repository.JpaRepository; | |||||
| import org.springframework.stereotype.Repository; | |||||
| @Repository | |||||
| public interface WeighingRecordRepository extends JpaRepository<WeighingRecord, Integer> { | |||||
| } | |||||
| @@ -0,0 +1,78 @@ | |||||
| package com.example.webapi.service; | |||||
| import com.example.webapi.dto.ImageInfoQueryDTO; | |||||
| import com.example.webapi.entity.ImageInfo; | |||||
| import com.example.webapi.repository.ImageInfoRepository; | |||||
| import com.example.webapi.util.PageUtil; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.data.domain.Example; | |||||
| import org.springframework.data.domain.ExampleMatcher; | |||||
| import org.springframework.data.domain.Page; | |||||
| import org.springframework.data.domain.Pageable; | |||||
| import org.springframework.stereotype.Service; | |||||
| import org.springframework.util.StringUtils; | |||||
| import java.util.Optional; | |||||
| @Service | |||||
| public class ImageInfoService { | |||||
| @Autowired | |||||
| private ImageInfoRepository repository; | |||||
| public Page<ImageInfo> findAll(Pageable pageable) { | |||||
| return repository.findAll(pageable); | |||||
| } | |||||
| /** | |||||
| * 根据条件查询图片信息(分页) | |||||
| * | |||||
| * @param queryDTO 查询条件(包含分页参数) | |||||
| * @return 分页结果 | |||||
| */ | |||||
| public Page<ImageInfo> findByConditions(ImageInfoQueryDTO queryDTO) { | |||||
| // 从QueryDTO中提取分页参数 | |||||
| Pageable pageable = PageUtil.createPageable(queryDTO); | |||||
| // 创建实体对象作为查询条件 | |||||
| ImageInfo probe = new ImageInfo(); | |||||
| // 设置查询条件(只设置非空值) | |||||
| if (StringUtils.hasText(queryDTO.getFileName())) { | |||||
| probe.setFileName(queryDTO.getFileName()); | |||||
| } | |||||
| if (StringUtils.hasText(queryDTO.getFileExtension())) { | |||||
| probe.setFileExtension(queryDTO.getFileExtension()); | |||||
| } | |||||
| if (StringUtils.hasText(queryDTO.getMimeType())) { | |||||
| probe.setMimeType(queryDTO.getMimeType()); | |||||
| } | |||||
| if (queryDTO.getFileSizeMin() != null) { | |||||
| probe.setFileSize(queryDTO.getFileSizeMin()); | |||||
| } | |||||
| // 创建ExampleMatcher,配置模糊查询 | |||||
| ExampleMatcher matcher = ExampleMatcher.matching() | |||||
| .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) // 字符串使用包含匹配 | |||||
| .withIgnoreCase() // 忽略大小写 | |||||
| .withIgnoreNullValues(); // 忽略空值 | |||||
| // 创建Example对象 | |||||
| Example<ImageInfo> example = Example.of(probe, matcher); | |||||
| // 执行查询 | |||||
| return repository.findAll(example, pageable); | |||||
| } | |||||
| public Optional<ImageInfo> findById(Integer id) { | |||||
| return repository.findById(id); | |||||
| } | |||||
| public ImageInfo save(ImageInfo entity) { | |||||
| return repository.save(entity); | |||||
| } | |||||
| public void deleteById(Integer id) { | |||||
| repository.deleteById(id); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,75 @@ | |||||
| package com.example.webapi.service; | |||||
| import com.example.webapi.dto.MaterialInfoQueryDTO; | |||||
| import com.example.webapi.entity.MaterialInfo; | |||||
| import com.example.webapi.repository.MaterialInfoRepository; | |||||
| import com.example.webapi.util.PageUtil; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.data.domain.Example; | |||||
| import org.springframework.data.domain.ExampleMatcher; | |||||
| import org.springframework.data.domain.Page; | |||||
| import org.springframework.data.domain.Pageable; | |||||
| import org.springframework.stereotype.Service; | |||||
| import org.springframework.util.StringUtils; | |||||
| import java.util.Optional; | |||||
| @Service | |||||
| public class MaterialInfoService { | |||||
| @Autowired | |||||
| private MaterialInfoRepository repository; | |||||
| public Page<MaterialInfo> findAll(Pageable pageable) { | |||||
| return repository.findAll(pageable); | |||||
| } | |||||
| /** | |||||
| * 根据条件查询品种信息(分页) | |||||
| * | |||||
| * @param queryDTO 查询条件(包含分页参数) | |||||
| * @return 分页结果 | |||||
| */ | |||||
| public Page<MaterialInfo> findByConditions(MaterialInfoQueryDTO queryDTO) { | |||||
| // 从QueryDTO中提取分页参数 | |||||
| Pageable pageable = PageUtil.createPageable(queryDTO); | |||||
| // 创建实体对象作为查询条件 | |||||
| MaterialInfo probe = new MaterialInfo(); | |||||
| // 设置查询条件(只设置非空值) | |||||
| if (StringUtils.hasText(queryDTO.getCode())) { | |||||
| probe.setCode(queryDTO.getCode()); | |||||
| } | |||||
| if (StringUtils.hasText(queryDTO.getName())) { | |||||
| probe.setName(queryDTO.getName()); | |||||
| } | |||||
| if (queryDTO.getActivate() != null) { | |||||
| probe.setActivate(queryDTO.getActivate()); | |||||
| } | |||||
| // 创建ExampleMatcher,配置模糊查询 | |||||
| ExampleMatcher matcher = ExampleMatcher.matching() | |||||
| .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) // 字符串使用包含匹配 | |||||
| .withIgnoreCase() // 忽略大小写 | |||||
| .withIgnoreNullValues(); // 忽略空值 | |||||
| // 创建Example对象 | |||||
| Example<MaterialInfo> example = Example.of(probe, matcher); | |||||
| // 执行查询 | |||||
| return repository.findAll(example, pageable); | |||||
| } | |||||
| public Optional<MaterialInfo> findById(Integer id) { | |||||
| return repository.findById(id); | |||||
| } | |||||
| public MaterialInfo save(MaterialInfo entity) { | |||||
| return repository.save(entity); | |||||
| } | |||||
| public void deleteById(Integer id) { | |||||
| repository.deleteById(id); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,78 @@ | |||||
| package com.example.webapi.service; | |||||
| import com.example.webapi.dto.SupplierQueryDTO; | |||||
| import com.example.webapi.entity.Supplier; | |||||
| import com.example.webapi.repository.SupplierRepository; | |||||
| import com.example.webapi.util.PageUtil; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.data.domain.Example; | |||||
| import org.springframework.data.domain.ExampleMatcher; | |||||
| import org.springframework.data.domain.Page; | |||||
| import org.springframework.data.domain.Pageable; | |||||
| import org.springframework.stereotype.Service; | |||||
| import org.springframework.util.StringUtils; | |||||
| import java.util.Optional; | |||||
| @Service | |||||
| public class SupplierService { | |||||
| @Autowired | |||||
| private SupplierRepository repository; | |||||
| public Page<Supplier> findAll(Pageable pageable) { | |||||
| return repository.findAll(pageable); | |||||
| } | |||||
| /** | |||||
| * 根据条件查询供应商信息(分页) | |||||
| * | |||||
| * @param queryDTO 查询条件(包含分页参数) | |||||
| * @return 分页结果 | |||||
| */ | |||||
| public Page<Supplier> findByConditions(SupplierQueryDTO queryDTO) { | |||||
| // 从QueryDTO中提取分页参数 | |||||
| Pageable pageable = PageUtil.createPageable(queryDTO); | |||||
| // 创建实体对象作为查询条件 | |||||
| Supplier probe = new Supplier(); | |||||
| // 设置查询条件(只设置非空值) | |||||
| if (StringUtils.hasText(queryDTO.getCode())) { | |||||
| probe.setCode(queryDTO.getCode()); | |||||
| } | |||||
| if (StringUtils.hasText(queryDTO.getName())) { | |||||
| probe.setName(queryDTO.getName()); | |||||
| } | |||||
| if (queryDTO.getActive() != null) { | |||||
| probe.setActive(queryDTO.getActive()); | |||||
| } | |||||
| if (StringUtils.hasText(queryDTO.getRemark())) { | |||||
| probe.setRemark(queryDTO.getRemark()); | |||||
| } | |||||
| // 创建ExampleMatcher,配置模糊查询 | |||||
| ExampleMatcher matcher = ExampleMatcher.matching() | |||||
| .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) // 字符串使用包含匹配 | |||||
| .withIgnoreCase() // 忽略大小写 | |||||
| .withIgnoreNullValues(); // 忽略空值 | |||||
| // 创建Example对象 | |||||
| Example<Supplier> example = Example.of(probe, matcher); | |||||
| // 执行查询 | |||||
| return repository.findAll(example, pageable); | |||||
| } | |||||
| public Optional<Supplier> findById(Integer id) { | |||||
| return repository.findById(id); | |||||
| } | |||||
| public Supplier save(Supplier entity) { | |||||
| return repository.save(entity); | |||||
| } | |||||
| public void deleteById(Integer id) { | |||||
| repository.deleteById(id); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,72 @@ | |||||
| package com.example.webapi.service; | |||||
| import com.example.webapi.dto.SupplyVarietyQueryDTO; | |||||
| import com.example.webapi.entity.SupplyVariety; | |||||
| import com.example.webapi.repository.SupplyVarietyRepository; | |||||
| import com.example.webapi.util.PageUtil; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.data.domain.Example; | |||||
| import org.springframework.data.domain.ExampleMatcher; | |||||
| import org.springframework.data.domain.Page; | |||||
| import org.springframework.data.domain.Pageable; | |||||
| import org.springframework.stereotype.Service; | |||||
| import java.util.Optional; | |||||
| @Service | |||||
| public class SupplyVarietyService { | |||||
| @Autowired | |||||
| private SupplyVarietyRepository repository; | |||||
| public Page<SupplyVariety> findAll(Pageable pageable) { | |||||
| return repository.findAll(pageable); | |||||
| } | |||||
| /** | |||||
| * 根据条件查询供应标识品种信息(分页) | |||||
| * | |||||
| * @param queryDTO 查询条件(包含分页参数) | |||||
| * @return 分页结果 | |||||
| */ | |||||
| public Page<SupplyVariety> findByConditions(SupplyVarietyQueryDTO queryDTO) { | |||||
| // 从QueryDTO中提取分页参数 | |||||
| Pageable pageable = PageUtil.createPageable(queryDTO); | |||||
| // 创建实体对象作为查询条件 | |||||
| SupplyVariety probe = new SupplyVariety(); | |||||
| // 设置查询条件(只设置非空值) | |||||
| if (queryDTO.getSupplyId() != null) { | |||||
| probe.setSupplyId(queryDTO.getSupplyId()); | |||||
| } | |||||
| if (queryDTO.getGood() != null) { | |||||
| probe.setGood(queryDTO.getGood()); | |||||
| } | |||||
| if (queryDTO.getActive() != null) { | |||||
| probe.setActive(queryDTO.getActive()); | |||||
| } | |||||
| // 创建ExampleMatcher,配置精确匹配 | |||||
| ExampleMatcher matcher = ExampleMatcher.matching() | |||||
| .withIgnoreNullValues(); // 忽略空值 | |||||
| // 创建Example对象 | |||||
| Example<SupplyVariety> example = Example.of(probe, matcher); | |||||
| // 执行查询 | |||||
| return repository.findAll(example, pageable); | |||||
| } | |||||
| public Optional<SupplyVariety> findById(Integer id) { | |||||
| return repository.findById(id); | |||||
| } | |||||
| public SupplyVariety save(SupplyVariety entity) { | |||||
| return repository.save(entity); | |||||
| } | |||||
| public void deleteById(Integer id) { | |||||
| repository.deleteById(id); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,87 @@ | |||||
| package com.example.webapi.service; | |||||
| import com.example.webapi.dto.TransferRecordQueryDTO; | |||||
| import com.example.webapi.entity.TransferRecord; | |||||
| import com.example.webapi.repository.TransferRecordRepository; | |||||
| import com.example.webapi.util.PageUtil; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.data.domain.Example; | |||||
| import org.springframework.data.domain.ExampleMatcher; | |||||
| import org.springframework.data.domain.Page; | |||||
| import org.springframework.data.domain.Pageable; | |||||
| import org.springframework.stereotype.Service; | |||||
| import org.springframework.util.StringUtils; | |||||
| import java.util.Optional; | |||||
| @Service | |||||
| public class TransferRecordService { | |||||
| @Autowired | |||||
| private TransferRecordRepository repository; | |||||
| public Page<TransferRecord> findAll(Pageable pageable) { | |||||
| return repository.findAll(pageable); | |||||
| } | |||||
| /** | |||||
| * 根据条件查询转运记录(分页) | |||||
| * | |||||
| * @param queryDTO 查询条件(包含分页参数) | |||||
| * @return 分页结果 | |||||
| */ | |||||
| public Page<TransferRecord> findByConditions(TransferRecordQueryDTO queryDTO) { | |||||
| // 从QueryDTO中提取分页参数 | |||||
| Pageable pageable = PageUtil.createPageable(queryDTO); | |||||
| // 创建实体对象作为查询条件 | |||||
| TransferRecord probe = new TransferRecord(); | |||||
| // 设置查询条件(只设置非空值) | |||||
| if (StringUtils.hasText(queryDTO.getBillNo())) { | |||||
| probe.setBillNo(queryDTO.getBillNo()); | |||||
| } | |||||
| if (StringUtils.hasText(queryDTO.getVehicleNo())) { | |||||
| probe.setVehicleNo(queryDTO.getVehicleNo()); | |||||
| } | |||||
| if (StringUtils.hasText(queryDTO.getCardNo())) { | |||||
| probe.setCardNo(queryDTO.getCardNo()); | |||||
| } | |||||
| if (queryDTO.getMaterielId() != null) { | |||||
| probe.setMaterielId(queryDTO.getMaterielId()); | |||||
| } | |||||
| if (queryDTO.getReceiveCompanyId() != null) { | |||||
| probe.setReceiveCompanyId(queryDTO.getReceiveCompanyId()); | |||||
| } | |||||
| if (queryDTO.getTransitCompanyId() != null) { | |||||
| probe.setTransitCompanyId(queryDTO.getTransitCompanyId()); | |||||
| } | |||||
| if (queryDTO.getSupplyId() != null) { | |||||
| probe.setSupplyId(queryDTO.getSupplyId()); | |||||
| } | |||||
| probe.setStatus(0); | |||||
| // 创建ExampleMatcher,配置模糊查询 | |||||
| ExampleMatcher matcher = ExampleMatcher.matching() | |||||
| .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) // 字符串使用包含匹配 | |||||
| .withIgnoreCase() // 忽略大小写 | |||||
| .withIgnoreNullValues(); // 忽略空值 | |||||
| // 创建Example对象 | |||||
| Example<TransferRecord> example = Example.of(probe, matcher); | |||||
| // 执行查询 | |||||
| return repository.findAll(example, pageable); | |||||
| } | |||||
| public Optional<TransferRecord> findById(Integer id) { | |||||
| return repository.findById(id); | |||||
| } | |||||
| public TransferRecord save(TransferRecord entity) { | |||||
| return repository.save(entity); | |||||
| } | |||||
| public void deleteById(Integer id) { | |||||
| repository.deleteById(id); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,72 @@ | |||||
| package com.example.webapi.service; | |||||
| import com.example.webapi.dto.TransportCompanyQueryDTO; | |||||
| import com.example.webapi.entity.TransportCompany; | |||||
| import com.example.webapi.repository.TransportCompanyRepository; | |||||
| import com.example.webapi.util.PageUtil; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.data.domain.Example; | |||||
| import org.springframework.data.domain.ExampleMatcher; | |||||
| import org.springframework.data.domain.Page; | |||||
| import org.springframework.data.domain.Pageable; | |||||
| import org.springframework.stereotype.Service; | |||||
| import org.springframework.util.StringUtils; | |||||
| import java.util.Optional; | |||||
| @Service | |||||
| public class TransportCompanyService { | |||||
| @Autowired | |||||
| private TransportCompanyRepository repository; | |||||
| public Page<TransportCompany> findAll(Pageable pageable) { | |||||
| return repository.findAll(pageable); | |||||
| } | |||||
| /** | |||||
| * 根据条件查询运输公司(分页) | |||||
| * | |||||
| * @param queryDTO 查询条件(包含分页参数) | |||||
| * @return 分页结果 | |||||
| */ | |||||
| public Page<TransportCompany> findByConditions(TransportCompanyQueryDTO queryDTO) { | |||||
| // 从QueryDTO中提取分页参数 | |||||
| Pageable pageable = PageUtil.createPageable(queryDTO); | |||||
| // 创建实体对象作为查询条件 | |||||
| TransportCompany probe = new TransportCompany(); | |||||
| // 设置查询条件(只设置非空值) | |||||
| if (StringUtils.hasText(queryDTO.getName())) { | |||||
| probe.setName(queryDTO.getName()); | |||||
| } | |||||
| if (StringUtils.hasText(queryDTO.getRemark())) { | |||||
| probe.setRemark(queryDTO.getRemark()); | |||||
| } | |||||
| // 创建ExampleMatcher,配置模糊查询 | |||||
| ExampleMatcher matcher = ExampleMatcher.matching() | |||||
| .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) // 字符串使用包含匹配 | |||||
| .withIgnoreCase() // 忽略大小写 | |||||
| .withIgnoreNullValues(); // 忽略空值 | |||||
| // 创建Example对象 | |||||
| Example<TransportCompany> example = Example.of(probe, matcher); | |||||
| // 执行查询 | |||||
| return repository.findAll(example, pageable); | |||||
| } | |||||
| public Optional<TransportCompany> findById(Integer id) { | |||||
| return repository.findById(id); | |||||
| } | |||||
| public TransportCompany save(TransportCompany entity) { | |||||
| return repository.save(entity); | |||||
| } | |||||
| public void deleteById(Integer id) { | |||||
| repository.deleteById(id); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,87 @@ | |||||
| package com.example.webapi.service; | |||||
| import com.example.webapi.dto.VehicleInfoQueryDTO; | |||||
| import com.example.webapi.entity.VehicleInfo; | |||||
| import com.example.webapi.repository.VehicleInfoRepository; | |||||
| import com.example.webapi.util.PageUtil; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.data.domain.Example; | |||||
| import org.springframework.data.domain.ExampleMatcher; | |||||
| import org.springframework.data.domain.Page; | |||||
| import org.springframework.data.domain.Pageable; | |||||
| import org.springframework.stereotype.Service; | |||||
| import org.springframework.util.StringUtils; | |||||
| import java.util.Optional; | |||||
| @Service | |||||
| public class VehicleInfoService { | |||||
| @Autowired | |||||
| private VehicleInfoRepository repository; | |||||
| public Page<VehicleInfo> findAll(Pageable pageable) { | |||||
| return repository.findAll(pageable); | |||||
| } | |||||
| /** | |||||
| * 根据条件查询车辆信息(分页) | |||||
| * | |||||
| * @param queryDTO 查询条件(包含分页参数) | |||||
| * @return 分页结果 | |||||
| */ | |||||
| public Page<VehicleInfo> findByConditions(VehicleInfoQueryDTO queryDTO) { | |||||
| // 从QueryDTO中提取分页参数 | |||||
| Pageable pageable = PageUtil.createPageable(queryDTO); | |||||
| // 创建实体对象作为查询条件 | |||||
| VehicleInfo probe = new VehicleInfo(); | |||||
| // 设置查询条件(只设置非空值) | |||||
| if (StringUtils.hasText(queryDTO.getLicensePlate())) { | |||||
| probe.setLicensePlate(queryDTO.getLicensePlate()); | |||||
| } | |||||
| if (StringUtils.hasText(queryDTO.getType())) { | |||||
| probe.setType(queryDTO.getType()); | |||||
| } | |||||
| if (queryDTO.getOutage() != null) { | |||||
| probe.setOutage(queryDTO.getOutage()); | |||||
| } | |||||
| if (queryDTO.getLock() != null) { | |||||
| probe.setLock(queryDTO.getLock()); | |||||
| } | |||||
| if (queryDTO.getTransCompany() != null) { | |||||
| probe.setTransCompany(queryDTO.getTransCompany()); | |||||
| } | |||||
| if (queryDTO.getReviewed() != null) { | |||||
| probe.setReviewed(queryDTO.getReviewed()); | |||||
| } | |||||
| if (StringUtils.hasText(queryDTO.getRemarks())) { | |||||
| probe.setRemarks(queryDTO.getRemarks()); | |||||
| } | |||||
| // 创建ExampleMatcher,配置模糊查询 | |||||
| ExampleMatcher matcher = ExampleMatcher.matching() | |||||
| .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) // 字符串使用包含匹配 | |||||
| .withIgnoreCase() // 忽略大小写 | |||||
| .withIgnoreNullValues(); // 忽略空值 | |||||
| // 创建Example对象 | |||||
| Example<VehicleInfo> example = Example.of(probe, matcher); | |||||
| // 执行查询 | |||||
| return repository.findAll(example, pageable); | |||||
| } | |||||
| public Optional<VehicleInfo> findById(Integer id) { | |||||
| return repository.findById(id); | |||||
| } | |||||
| public VehicleInfo save(VehicleInfo entity) { | |||||
| return repository.save(entity); | |||||
| } | |||||
| public void deleteById(Integer id) { | |||||
| repository.deleteById(id); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,105 @@ | |||||
| package com.example.webapi.service; | |||||
| import com.example.webapi.dto.WeighingRecordQueryDTO; | |||||
| import com.example.webapi.entity.WeighingRecord; | |||||
| import com.example.webapi.repository.WeighingRecordRepository; | |||||
| import com.example.webapi.util.PageUtil; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.data.domain.Example; | |||||
| import org.springframework.data.domain.ExampleMatcher; | |||||
| import org.springframework.data.domain.Page; | |||||
| import org.springframework.data.domain.Pageable; | |||||
| import org.springframework.stereotype.Service; | |||||
| import org.springframework.util.StringUtils; | |||||
| import java.util.Optional; | |||||
| @Service | |||||
| public class WeighingRecordService { | |||||
| @Autowired | |||||
| private WeighingRecordRepository repository; | |||||
| public Page<WeighingRecord> findAll(Pageable pageable) { | |||||
| return repository.findAll(pageable); | |||||
| } | |||||
| /** | |||||
| * 根据条件查询称重记录(分页) | |||||
| * | |||||
| * @param queryDTO 查询条件(包含分页参数) | |||||
| * @return 分页结果 | |||||
| */ | |||||
| public Page<WeighingRecord> findByConditions(WeighingRecordQueryDTO queryDTO) { | |||||
| // 从QueryDTO中提取分页参数 | |||||
| Pageable pageable = PageUtil.createPageable(queryDTO); | |||||
| // 创建实体对象作为查询条件 | |||||
| WeighingRecord probe = new WeighingRecord(); | |||||
| // 设置查询条件(只设置非空值) | |||||
| if (StringUtils.hasText(queryDTO.getBillNo())) { | |||||
| probe.setBillNo(queryDTO.getBillNo()); | |||||
| } | |||||
| if (StringUtils.hasText(queryDTO.getVehicleNo())) { | |||||
| probe.setVehicleNo(queryDTO.getVehicleNo()); | |||||
| } | |||||
| if (StringUtils.hasText(queryDTO.getCardNo())) { | |||||
| probe.setCardNo(queryDTO.getCardNo()); | |||||
| } | |||||
| if (StringUtils.hasText(queryDTO.getRfidNo())) { | |||||
| probe.setRfidNo(queryDTO.getRfidNo()); | |||||
| } | |||||
| if (StringUtils.hasText(queryDTO.getIssuedBy())) { | |||||
| probe.setIssuedBy(queryDTO.getIssuedBy()); | |||||
| } | |||||
| if (StringUtils.hasText(queryDTO.getGwBy())) { | |||||
| probe.setGwBy(queryDTO.getGwBy()); | |||||
| } | |||||
| if (StringUtils.hasText(queryDTO.getTBy())) { | |||||
| probe.setTBy(queryDTO.getTBy()); | |||||
| } | |||||
| if (queryDTO.getMaterielId() != null) { | |||||
| probe.setMaterielId(queryDTO.getMaterielId()); | |||||
| } | |||||
| if (queryDTO.getWarehouseId() != null) { | |||||
| probe.setWarehouseId(queryDTO.getWarehouseId()); | |||||
| } | |||||
| if (queryDTO.getReceiveCompanyId() != null) { | |||||
| probe.setReceiveCompanyId(queryDTO.getReceiveCompanyId()); | |||||
| } | |||||
| if (queryDTO.getTransitCompanyId() != null) { | |||||
| probe.setTransitCompanyId(queryDTO.getTransitCompanyId()); | |||||
| } | |||||
| if (queryDTO.getVehicleId() != null) { | |||||
| probe.setVehicleId(queryDTO.getVehicleId()); | |||||
| } | |||||
| if (queryDTO.getSupplyId() != null) { | |||||
| probe.setSupplyId(queryDTO.getSupplyId()); | |||||
| } | |||||
| // 创建ExampleMatcher,配置模糊查询 | |||||
| ExampleMatcher matcher = ExampleMatcher.matching() | |||||
| .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) // 字符串使用包含匹配 | |||||
| .withIgnoreCase() // 忽略大小写 | |||||
| .withIgnoreNullValues(); // 忽略空值 | |||||
| // 创建Example对象 | |||||
| Example<WeighingRecord> example = Example.of(probe, matcher); | |||||
| // 执行查询 | |||||
| return repository.findAll(example, pageable); | |||||
| } | |||||
| public Optional<WeighingRecord> findById(Integer id) { | |||||
| return repository.findById(id); | |||||
| } | |||||
| public WeighingRecord save(WeighingRecord entity) { | |||||
| return repository.save(entity); | |||||
| } | |||||
| public void deleteById(Integer id) { | |||||
| repository.deleteById(id); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,43 @@ | |||||
| package com.example.webapi.util; | |||||
| import com.example.webapi.dto.BasePageDTO; | |||||
| import org.springframework.data.domain.PageRequest; | |||||
| import org.springframework.data.domain.Pageable; | |||||
| import org.springframework.data.domain.Sort; | |||||
| /** | |||||
| * 分页工具类 | |||||
| * | |||||
| * @author Your Name | |||||
| * @version 1.0.0 | |||||
| */ | |||||
| public class PageUtil { | |||||
| /** | |||||
| * 从BasePageDTO创建Pageable对象 | |||||
| * | |||||
| * @param basePageDTO 基础分页DTO | |||||
| * @return Pageable对象 | |||||
| */ | |||||
| public static Pageable createPageable(BasePageDTO basePageDTO) { | |||||
| if (basePageDTO == null) { | |||||
| return PageRequest.of(0, 10); | |||||
| } | |||||
| // 处理页码和大小 | |||||
| int page = basePageDTO.getPage() != null ? basePageDTO.getPage() : 0; | |||||
| int size = basePageDTO.getSize() != null ? basePageDTO.getSize() : 10; | |||||
| // 处理排序 | |||||
| if (basePageDTO.getSortBy() != null && !basePageDTO.getSortBy().trim().isEmpty()) { | |||||
| Sort.Direction direction = Sort.Direction.ASC; | |||||
| if ("desc".equalsIgnoreCase(basePageDTO.getSortDirection())) { | |||||
| direction = Sort.Direction.DESC; | |||||
| } | |||||
| Sort sort = Sort.by(direction, basePageDTO.getSortBy()); | |||||
| return PageRequest.of(page, size, sort); | |||||
| } | |||||
| return PageRequest.of(page, size); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,109 @@ | |||||
| package com.example.webapi.util; | |||||
| import java.security.MessageDigest; | |||||
| import java.security.NoSuchAlgorithmException; | |||||
| /** | |||||
| * 签名生成工具类 | |||||
| * 用于在Swagger中测试时生成签名 | |||||
| * | |||||
| * @author Your Name | |||||
| * @version 1.0.0 | |||||
| */ | |||||
| public class SignatureGenerator { | |||||
| // 配置的Access Key和Secret Key(与application.yml中的配置一致) | |||||
| private static final String AK = "2760cd7c-cc0e-4034-86f3-d58e89f03d80"; | |||||
| private static final String SK = "e2c0e9c1aaa72a0b1444f879c86a9034bf2f03be31a58b1e5b3b077948da75cf"; | |||||
| /** | |||||
| * 生成签名 | |||||
| * | |||||
| * @param ak Access Key | |||||
| * @param sk Secret Key | |||||
| * @param timestamp 时间戳 | |||||
| * @return MD5签名 | |||||
| */ | |||||
| public static String generateSignature(String ak, String sk, String timestamp) { | |||||
| String content = ak + sk + timestamp; | |||||
| return md5(content); | |||||
| } | |||||
| /** | |||||
| * 使用默认配置生成签名 | |||||
| * | |||||
| * @param timestamp 时间戳 | |||||
| * @return MD5签名 | |||||
| */ | |||||
| public static String generateSignature(String timestamp) { | |||||
| return generateSignature(AK, SK, timestamp); | |||||
| } | |||||
| /** | |||||
| * 生成当前时间戳的签名 | |||||
| * | |||||
| * @return MD5签名 | |||||
| */ | |||||
| public static String generateCurrentSignature() { | |||||
| String timestamp = String.valueOf(System.currentTimeMillis()); | |||||
| return generateSignature(timestamp); | |||||
| } | |||||
| /** | |||||
| * 获取当前时间戳 | |||||
| * | |||||
| * @return 当前时间戳(毫秒) | |||||
| */ | |||||
| public static String getCurrentTimestamp() { | |||||
| return String.valueOf(System.currentTimeMillis()); | |||||
| } | |||||
| /** | |||||
| * 获取配置的Access Key | |||||
| * | |||||
| * @return Access Key | |||||
| */ | |||||
| public static String getAk() { | |||||
| return AK; | |||||
| } | |||||
| /** | |||||
| * MD5加密 | |||||
| * | |||||
| * @param content 待加密内容 | |||||
| * @return MD5值 | |||||
| */ | |||||
| private static String md5(String content) { | |||||
| try { | |||||
| MessageDigest md = MessageDigest.getInstance("MD5"); | |||||
| byte[] bytes = md.digest(content.getBytes()); | |||||
| StringBuilder sb = new StringBuilder(); | |||||
| for (byte b : bytes) { | |||||
| sb.append(String.format("%02x", b)); | |||||
| } | |||||
| return sb.toString(); | |||||
| } catch (NoSuchAlgorithmException e) { | |||||
| throw new RuntimeException("MD5算法不可用", e); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * 生成完整的测试信息 | |||||
| * 用于在Swagger中复制粘贴 | |||||
| * | |||||
| * @return 格式化的测试信息 | |||||
| */ | |||||
| public static String generateTestInfo() { | |||||
| String timestamp = getCurrentTimestamp(); | |||||
| String signature = generateSignature(timestamp); | |||||
| return String.format( | |||||
| "测试信息:\n" + | |||||
| "ak: %s\n" + | |||||
| "timestamp: %s\n" + | |||||
| "signature: %s\n" + | |||||
| "签名算法: MD5(ak + sk + timestamp)", | |||||
| AK, timestamp, signature | |||||
| ); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,41 @@ | |||||
| package com.example.webapi.util; | |||||
| import java.nio.charset.StandardCharsets; | |||||
| import java.security.MessageDigest; | |||||
| import java.security.NoSuchAlgorithmException; | |||||
| public class SignatureUtil { | |||||
| public static String generateSignature(String ak, String sk, String timestamp) { | |||||
| String stringToSign = ak + sk + timestamp; | |||||
| return md5(stringToSign); | |||||
| } | |||||
| private static String md5(String input) { | |||||
| try { | |||||
| MessageDigest md = MessageDigest.getInstance("MD5"); | |||||
| byte[] hashInBytes = md.digest(input.getBytes(StandardCharsets.UTF_8)); | |||||
| StringBuilder sb = new StringBuilder(); | |||||
| for (byte b : hashInBytes) { | |||||
| sb.append(String.format("%02x", b)); | |||||
| } | |||||
| return sb.toString(); | |||||
| } catch (NoSuchAlgorithmException e) { | |||||
| throw new RuntimeException("MD5 algorithm not found", e); | |||||
| } | |||||
| } | |||||
| // For testing the example given in the document | |||||
| public static void main(String[] args) { | |||||
| String ak_test = "2760cd7c-cc0e-4034-86f3-d58e89f03d80"; | |||||
| String sk_test = "e2c0e9c1aaa72a0b1444f879c86a9034bf2f03be31a58b1e5b3b077948da75cf"; | |||||
| String timestamp_test = "1753428477102"; | |||||
| String expectedSignature = "efce140aa6914c617d1c823996f48bc3"; | |||||
| String generatedSignature = generateSignature(ak_test, sk_test, timestamp_test); | |||||
| System.out.println("Generated Signature: " + generatedSignature); | |||||
| System.out.println("Expected Signature: " + expectedSignature); | |||||
| System.out.println("Signatures match: " + expectedSignature.equals(generatedSignature)); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,42 @@ | |||||
| server: | |||||
| port: 8806 | |||||
| servlet: | |||||
| context-path: /fuquanapi | |||||
| spring: | |||||
| application: | |||||
| name: fuquanapi | |||||
| datasource: | |||||
| url: jdbc:sqlserver://112.33.47.173:6789;SelectMethod=cursor;rewriteBatchedStatements=true;DatabaseName=ERPPlatForm2025_FQ_JK;encrypt=false;trustServerCertificate=true | |||||
| username: PlatForm_FuQ | |||||
| password: p|Rc9fZza[@XR-4 | |||||
| driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver | |||||
| jpa: | |||||
| hibernate: | |||||
| ddl-auto: none | |||||
| show-sql: true | |||||
| properties: | |||||
| hibernate: | |||||
| dialect: org.hibernate.dialect.SQLServer2012Dialect | |||||
| format_sql: true | |||||
| physical_naming_strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl | |||||
| use_sql_comments: true | |||||
| jackson: | |||||
| date-format: yyyy-MM-dd HH:mm:ss | |||||
| time-zone: GMT+8 | |||||
| mvc: | |||||
| pathmatch: | |||||
| matching-strategy: ant_path_matcher | |||||
| # API客户端配置 | |||||
| api: | |||||
| client: | |||||
| ak: 2760cd7c-cc0e-4034-86f3-d58e89f03d80 | |||||
| sk: e2c0e9c1aaa72a0b1444f879c86a9034bf2f03be31a58b1e5b3b077948da75cf | |||||
| # 日志配置 | |||||
| logging: | |||||
| level: | |||||
| com.example.webapi: DEBUG | |||||
| pattern: | |||||
| console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" | |||||
| @@ -0,0 +1,239 @@ | |||||
| #!/bin/bash | |||||
| # 福泉WebAPI 启动脚本 | |||||
| # 作者: Your Name | |||||
| # 版本: 1.0.0 | |||||
| # 应用配置 | |||||
| APP_NAME="福泉WebAPI" | |||||
| APP_JAR="webapi-1.0.0.jar" | |||||
| APP_PORT=8806 | |||||
| APP_CONTEXT_PATH="/fuquanapi" | |||||
| # JVM配置 | |||||
| JVM_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC -XX:+UseStringDeduplication" | |||||
| JVM_OPTS="$JVM_OPTS -Dserver.port=$APP_PORT" | |||||
| JVM_OPTS="$JVM_OPTS -Dserver.servlet.context-path=$APP_CONTEXT_PATH" | |||||
| # 日志配置 | |||||
| LOG_DIR="./logs" | |||||
| LOG_FILE="$LOG_DIR/app.log" | |||||
| PID_FILE="./app.pid" | |||||
| # 颜色定义 | |||||
| RED='\033[0;31m' | |||||
| GREEN='\033[0;32m' | |||||
| YELLOW='\033[1;33m' | |||||
| BLUE='\033[0;34m' | |||||
| NC='\033[0m' # No Color | |||||
| # 打印带颜色的消息 | |||||
| print_message() { | |||||
| local color=$1 | |||||
| local message=$2 | |||||
| echo -e "${color}[$(date '+%Y-%m-%d %H:%M:%S')] $message${NC}" | |||||
| } | |||||
| # 检查Java环境 | |||||
| check_java() { | |||||
| if ! command -v java &> /dev/null; then | |||||
| print_message $RED "错误: 未找到Java环境,请先安装JDK 1.8+" | |||||
| exit 1 | |||||
| fi | |||||
| JAVA_VERSION=$(java -version 2>&1 | head -n 1 | cut -d'"' -f2) | |||||
| print_message $BLUE "检测到Java版本: $JAVA_VERSION" | |||||
| } | |||||
| # 检查应用JAR文件 | |||||
| check_jar() { | |||||
| if [ ! -f "$APP_JAR" ]; then | |||||
| print_message $RED "错误: 未找到应用JAR文件: $APP_JAR" | |||||
| print_message $YELLOW "请确保在正确的目录下运行此脚本" | |||||
| exit 1 | |||||
| fi | |||||
| print_message $GREEN "找到应用JAR文件: $APP_JAR" | |||||
| } | |||||
| # 创建日志目录 | |||||
| create_log_dir() { | |||||
| if [ ! -d "$LOG_DIR" ]; then | |||||
| mkdir -p "$LOG_DIR" | |||||
| print_message $BLUE "创建日志目录: $LOG_DIR" | |||||
| fi | |||||
| } | |||||
| # 检查应用是否已运行 | |||||
| check_running() { | |||||
| if [ -f "$PID_FILE" ]; then | |||||
| PID=$(cat "$PID_FILE") | |||||
| if ps -p $PID > /dev/null 2>&1; then | |||||
| print_message $YELLOW "应用已在运行中,PID: $PID" | |||||
| return 0 | |||||
| else | |||||
| print_message $YELLOW "发现无效的PID文件,正在清理..." | |||||
| rm -f "$PID_FILE" | |||||
| fi | |||||
| fi | |||||
| return 1 | |||||
| } | |||||
| # 启动应用 | |||||
| start_app() { | |||||
| print_message $BLUE "正在启动 $APP_NAME..." | |||||
| # 启动应用 | |||||
| nohup java $JVM_OPTS -jar "$APP_JAR" > "$LOG_FILE" 2>&1 & | |||||
| # 获取进程ID | |||||
| PID=$! | |||||
| echo $PID > "$PID_FILE" | |||||
| # 等待应用启动 | |||||
| print_message $BLUE "应用启动中,PID: $PID" | |||||
| sleep 3 | |||||
| # 检查应用是否成功启动 | |||||
| if ps -p $PID > /dev/null 2>&1; then | |||||
| print_message $GREEN "$APP_NAME 启动成功!" | |||||
| print_message $GREEN "访问地址: http://localhost:$APP_PORT$APP_CONTEXT_PATH" | |||||
| print_message $GREEN "API文档: http://localhost:$APP_PORT$APP_CONTEXT_PATH/swagger-ui.html" | |||||
| print_message $GREEN "日志文件: $LOG_FILE" | |||||
| print_message $GREEN "PID文件: $PID_FILE" | |||||
| else | |||||
| print_message $RED "应用启动失败,请检查日志文件: $LOG_FILE" | |||||
| rm -f "$PID_FILE" | |||||
| exit 1 | |||||
| fi | |||||
| } | |||||
| # 停止应用 | |||||
| stop_app() { | |||||
| if [ -f "$PID_FILE" ]; then | |||||
| PID=$(cat "$PID_FILE") | |||||
| if ps -p $PID > /dev/null 2>&1; then | |||||
| print_message $BLUE "正在停止 $APP_NAME (PID: $PID)..." | |||||
| kill $PID | |||||
| # 等待进程结束 | |||||
| for i in {1..30}; do | |||||
| if ! ps -p $PID > /dev/null 2>&1; then | |||||
| print_message $GREEN "$APP_NAME 已停止" | |||||
| rm -f "$PID_FILE" | |||||
| return 0 | |||||
| fi | |||||
| sleep 1 | |||||
| done | |||||
| # 强制杀死进程 | |||||
| print_message $YELLOW "应用未正常停止,正在强制终止..." | |||||
| kill -9 $PID | |||||
| rm -f "$PID_FILE" | |||||
| print_message $GREEN "$APP_NAME 已强制停止" | |||||
| else | |||||
| print_message $YELLOW "应用未在运行" | |||||
| rm -f "$PID_FILE" | |||||
| fi | |||||
| else | |||||
| print_message $YELLOW "未找到PID文件,应用可能未在运行" | |||||
| fi | |||||
| } | |||||
| # 重启应用 | |||||
| restart_app() { | |||||
| print_message $BLUE "正在重启 $APP_NAME..." | |||||
| stop_app | |||||
| sleep 2 | |||||
| start_app | |||||
| } | |||||
| # 查看应用状态 | |||||
| status_app() { | |||||
| if [ -f "$PID_FILE" ]; then | |||||
| PID=$(cat "$PID_FILE") | |||||
| if ps -p $PID > /dev/null 2>&1; then | |||||
| print_message $GREEN "$APP_NAME 正在运行,PID: $PID" | |||||
| print_message $GREEN "访问地址: http://localhost:$APP_PORT$APP_CONTEXT_PATH" | |||||
| else | |||||
| print_message $RED "$APP_NAME 未在运行(PID文件存在但进程不存在)" | |||||
| rm -f "$PID_FILE" | |||||
| fi | |||||
| else | |||||
| print_message $YELLOW "$APP_NAME 未在运行" | |||||
| fi | |||||
| } | |||||
| # 查看日志 | |||||
| view_logs() { | |||||
| if [ -f "$LOG_FILE" ]; then | |||||
| print_message $BLUE "显示最新日志 (最后50行):" | |||||
| echo "----------------------------------------" | |||||
| tail -n 50 "$LOG_FILE" | |||||
| echo "----------------------------------------" | |||||
| else | |||||
| print_message $YELLOW "日志文件不存在: $LOG_FILE" | |||||
| fi | |||||
| } | |||||
| # 显示帮助信息 | |||||
| show_help() { | |||||
| echo "福泉WebAPI 管理脚本" | |||||
| echo "" | |||||
| echo "用法: $0 {start|stop|restart|status|logs|help}" | |||||
| echo "" | |||||
| echo "命令:" | |||||
| echo " start - 启动应用" | |||||
| echo " stop - 停止应用" | |||||
| echo " restart - 重启应用" | |||||
| echo " status - 查看应用状态" | |||||
| echo " logs - 查看应用日志" | |||||
| echo " help - 显示此帮助信息" | |||||
| echo "" | |||||
| echo "配置:" | |||||
| echo " 应用JAR: $APP_JAR" | |||||
| echo " 端口: $APP_PORT" | |||||
| echo " 上下文路径: $APP_CONTEXT_PATH" | |||||
| echo " 日志文件: $LOG_FILE" | |||||
| } | |||||
| # 主函数 | |||||
| main() { | |||||
| case "$1" in | |||||
| start) | |||||
| check_java | |||||
| check_jar | |||||
| create_log_dir | |||||
| if check_running; then | |||||
| exit 0 | |||||
| fi | |||||
| start_app | |||||
| ;; | |||||
| stop) | |||||
| stop_app | |||||
| ;; | |||||
| restart) | |||||
| check_java | |||||
| check_jar | |||||
| create_log_dir | |||||
| restart_app | |||||
| ;; | |||||
| status) | |||||
| status_app | |||||
| ;; | |||||
| logs) | |||||
| view_logs | |||||
| ;; | |||||
| help|--help|-h) | |||||
| show_help | |||||
| ;; | |||||
| *) | |||||
| print_message $RED "错误: 未知命令 '$1'" | |||||
| echo "" | |||||
| show_help | |||||
| exit 1 | |||||
| ;; | |||||
| esac | |||||
| } | |||||
| # 执行主函数 | |||||
| main "$@" | |||||