From fd29fa50acfa5de5b248b3b1af269f7f3255c6d5 Mon Sep 17 00:00:00 2001 From: Searises Hao Wang Date: Fri, 25 Jul 2025 15:53:36 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 199 +++++++++++++- install.sh | 248 ++++++++++++++++++ pom.xml | 92 +++++++ run.sh | 48 ++++ .../com/example/webapi/WebApiApplication.java | 22 ++ .../example/webapi/config/SwaggerConfig.java | 93 +++++++ .../com/example/webapi/config/WebConfig.java | 75 ++++++ .../controller/ImageInfoController.java | 58 ++++ .../controller/MaterialInfoController.java | 57 ++++ .../webapi/controller/SupplierController.java | 57 ++++ .../controller/SupplyVarietyController.java | 108 ++++++++ .../controller/TransferRecordController.java | 109 ++++++++ .../TransportCompanyController.java | 108 ++++++++ .../controller/VehicleInfoController.java | 108 ++++++++ .../controller/WeighingRecordController.java | 125 +++++++++ .../com/example/webapi/dto/ApiResponse.java | 86 ++++++ .../com/example/webapi/dto/BasePageDTO.java | 40 +++ .../example/webapi/dto/ImageInfoQueryDTO.java | 33 +++ .../webapi/dto/MaterialInfoQueryDTO.java | 27 ++ .../example/webapi/dto/SupplierQueryDTO.java | 30 +++ .../webapi/dto/SupplyVarietyQueryDTO.java | 27 ++ .../webapi/dto/TransferRecordQueryDTO.java | 41 +++ .../webapi/dto/TransportCompanyQueryDTO.java | 24 ++ .../webapi/dto/VehicleInfoQueryDTO.java | 39 +++ .../webapi/dto/WeighingRecordQueryDTO.java | 59 +++++ .../com/example/webapi/entity/ImageInfo.java | 44 ++++ .../example/webapi/entity/MaterialInfo.java | 29 ++ .../com/example/webapi/entity/Supplier.java | 33 +++ .../example/webapi/entity/SupplyVariety.java | 29 ++ .../example/webapi/entity/TransferRecord.java | 76 ++++++ .../webapi/entity/TransportCompany.java | 25 ++ .../example/webapi/entity/VehicleInfo.java | 45 ++++ .../example/webapi/entity/WeighingRecord.java | 135 ++++++++++ .../interceptor/SignatureInterceptor.java | 140 ++++++++++ .../repository/ImageInfoRepository.java | 9 + .../repository/MaterialInfoRepository.java | 9 + .../webapi/repository/SupplierRepository.java | 9 + .../repository/SupplyVarietyRepository.java | 9 + .../repository/TransferRecordRepository.java | 9 + .../TransportCompanyRepository.java | 9 + .../repository/VehicleInfoRepository.java | 9 + .../repository/WeighingRecordRepository.java | 9 + .../webapi/service/ImageInfoService.java | 78 ++++++ .../webapi/service/MaterialInfoService.java | 75 ++++++ .../webapi/service/SupplierService.java | 78 ++++++ .../webapi/service/SupplyVarietyService.java | 72 +++++ .../webapi/service/TransferRecordService.java | 87 ++++++ .../service/TransportCompanyService.java | 72 +++++ .../webapi/service/VehicleInfoService.java | 87 ++++++ .../webapi/service/WeighingRecordService.java | 105 ++++++++ .../com/example/webapi/util/PageUtil.java | 43 +++ .../webapi/util/SignatureGenerator.java | 109 ++++++++ .../example/webapi/util/SignatureUtil.java | 41 +++ src/main/resources/application.yml | 42 +++ start.sh | 239 +++++++++++++++++ 55 files changed, 3668 insertions(+), 1 deletion(-) create mode 100644 install.sh create mode 100644 pom.xml create mode 100644 run.sh create mode 100644 src/main/java/com/example/webapi/WebApiApplication.java create mode 100644 src/main/java/com/example/webapi/config/SwaggerConfig.java create mode 100644 src/main/java/com/example/webapi/config/WebConfig.java create mode 100644 src/main/java/com/example/webapi/controller/ImageInfoController.java create mode 100644 src/main/java/com/example/webapi/controller/MaterialInfoController.java create mode 100644 src/main/java/com/example/webapi/controller/SupplierController.java create mode 100644 src/main/java/com/example/webapi/controller/SupplyVarietyController.java create mode 100644 src/main/java/com/example/webapi/controller/TransferRecordController.java create mode 100644 src/main/java/com/example/webapi/controller/TransportCompanyController.java create mode 100644 src/main/java/com/example/webapi/controller/VehicleInfoController.java create mode 100644 src/main/java/com/example/webapi/controller/WeighingRecordController.java create mode 100644 src/main/java/com/example/webapi/dto/ApiResponse.java create mode 100644 src/main/java/com/example/webapi/dto/BasePageDTO.java create mode 100644 src/main/java/com/example/webapi/dto/ImageInfoQueryDTO.java create mode 100644 src/main/java/com/example/webapi/dto/MaterialInfoQueryDTO.java create mode 100644 src/main/java/com/example/webapi/dto/SupplierQueryDTO.java create mode 100644 src/main/java/com/example/webapi/dto/SupplyVarietyQueryDTO.java create mode 100644 src/main/java/com/example/webapi/dto/TransferRecordQueryDTO.java create mode 100644 src/main/java/com/example/webapi/dto/TransportCompanyQueryDTO.java create mode 100644 src/main/java/com/example/webapi/dto/VehicleInfoQueryDTO.java create mode 100644 src/main/java/com/example/webapi/dto/WeighingRecordQueryDTO.java create mode 100644 src/main/java/com/example/webapi/entity/ImageInfo.java create mode 100644 src/main/java/com/example/webapi/entity/MaterialInfo.java create mode 100644 src/main/java/com/example/webapi/entity/Supplier.java create mode 100644 src/main/java/com/example/webapi/entity/SupplyVariety.java create mode 100644 src/main/java/com/example/webapi/entity/TransferRecord.java create mode 100644 src/main/java/com/example/webapi/entity/TransportCompany.java create mode 100644 src/main/java/com/example/webapi/entity/VehicleInfo.java create mode 100644 src/main/java/com/example/webapi/entity/WeighingRecord.java create mode 100644 src/main/java/com/example/webapi/interceptor/SignatureInterceptor.java create mode 100644 src/main/java/com/example/webapi/repository/ImageInfoRepository.java create mode 100644 src/main/java/com/example/webapi/repository/MaterialInfoRepository.java create mode 100644 src/main/java/com/example/webapi/repository/SupplierRepository.java create mode 100644 src/main/java/com/example/webapi/repository/SupplyVarietyRepository.java create mode 100644 src/main/java/com/example/webapi/repository/TransferRecordRepository.java create mode 100644 src/main/java/com/example/webapi/repository/TransportCompanyRepository.java create mode 100644 src/main/java/com/example/webapi/repository/VehicleInfoRepository.java create mode 100644 src/main/java/com/example/webapi/repository/WeighingRecordRepository.java create mode 100644 src/main/java/com/example/webapi/service/ImageInfoService.java create mode 100644 src/main/java/com/example/webapi/service/MaterialInfoService.java create mode 100644 src/main/java/com/example/webapi/service/SupplierService.java create mode 100644 src/main/java/com/example/webapi/service/SupplyVarietyService.java create mode 100644 src/main/java/com/example/webapi/service/TransferRecordService.java create mode 100644 src/main/java/com/example/webapi/service/TransportCompanyService.java create mode 100644 src/main/java/com/example/webapi/service/VehicleInfoService.java create mode 100644 src/main/java/com/example/webapi/service/WeighingRecordService.java create mode 100644 src/main/java/com/example/webapi/util/PageUtil.java create mode 100644 src/main/java/com/example/webapi/util/SignatureGenerator.java create mode 100644 src/main/java/com/example/webapi/util/SignatureUtil.java create mode 100644 src/main/resources/application.yml create mode 100644 start.sh diff --git a/README.md b/README.md index 74f5002..835df02 100644 --- a/README.md +++ b/README.md @@ -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** - 让物流管理更智能! 🚀 diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..353592e --- /dev/null +++ b/install.sh @@ -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 "$@" \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..055c1c2 --- /dev/null +++ b/pom.xml @@ -0,0 +1,92 @@ + + + 4.0.0 + + com.example + webapi + 1.0.0 + jar + + webapi + SpringBoot WebAPI with Access Key/Secret Key Authentication + + + org.springframework.boot + spring-boot-starter-parent + 2.7.18 + + + + + 1.8 + UTF-8 + UTF-8 + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + + com.microsoft.sqlserver + mssql-jdbc + runtime + + + + + org.springframework.boot + spring-boot-starter-validation + + + + + org.projectlombok + lombok + true + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + io.springfox + springfox-boot-starter + 3.0.0 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + \ No newline at end of file diff --git a/run.sh b/run.sh new file mode 100644 index 0000000..9004fb9 --- /dev/null +++ b/run.sh @@ -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}" \ No newline at end of file diff --git a/src/main/java/com/example/webapi/WebApiApplication.java b/src/main/java/com/example/webapi/WebApiApplication.java new file mode 100644 index 0000000..e9ba4b9 --- /dev/null +++ b/src/main/java/com/example/webapi/WebApiApplication.java @@ -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("================================="); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/config/SwaggerConfig.java b/src/main/java/com/example/webapi/config/SwaggerConfig.java new file mode 100644 index 0000000..56fdd62 --- /dev/null +++ b/src/main/java/com/example/webapi/config/SwaggerConfig.java @@ -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 getGlobalRequestParameters() { + List 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; + } +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/config/WebConfig.java b/src/main/java/com/example/webapi/config/WebConfig.java new file mode 100644 index 0000000..9fbcb9c --- /dev/null +++ b/src/main/java/com/example/webapi/config/WebConfig.java @@ -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; + } +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/controller/ImageInfoController.java b/src/main/java/com/example/webapi/controller/ImageInfoController.java new file mode 100644 index 0000000..5155def --- /dev/null +++ b/src/main/java/com/example/webapi/controller/ImageInfoController.java @@ -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> pageByConditions(@RequestBody ImageInfoQueryDTO queryDTO) { + return ApiResponse.success(service.findByConditions(queryDTO)); + } + + @ApiOperation("根据ID查询图片信息") + @GetMapping("/{id}") + public ApiResponse getById(@PathVariable Integer id) { + Optional result = service.findById(id); + return result.map(ApiResponse::success).orElseGet(() -> ApiResponse.error("未找到该图片信息")); + } + + @ApiOperation("新增图片信息") + @PostMapping + public ApiResponse create(@RequestBody ImageInfo entity) { + return ApiResponse.success(service.save(entity)); + } + + @ApiOperation("更新图片信息") + @PutMapping("/{id}") + public ApiResponse update(@PathVariable Integer id, @RequestBody ImageInfo entity) { + entity.setId(id); + return ApiResponse.success(service.save(entity)); + } + + @ApiOperation("删除图片信息") + @DeleteMapping("/{id}") + public ApiResponse delete(@PathVariable Integer id) { + service.deleteById(id); + return ApiResponse.success(); + } +} diff --git a/src/main/java/com/example/webapi/controller/MaterialInfoController.java b/src/main/java/com/example/webapi/controller/MaterialInfoController.java new file mode 100644 index 0000000..fbdd982 --- /dev/null +++ b/src/main/java/com/example/webapi/controller/MaterialInfoController.java @@ -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> pageByConditions(@RequestBody MaterialInfoQueryDTO queryDTO) { + return ApiResponse.success(service.findByConditions(queryDTO)); + } + + @ApiOperation("根据ID查询品种信息") + @GetMapping("/{id}") + public ApiResponse getById(@PathVariable Integer id) { + Optional result = service.findById(id); + return result.map(ApiResponse::success).orElseGet(() -> ApiResponse.error("未找到该品种信息")); + } + + @ApiOperation("新增品种信息") + @PostMapping + public ApiResponse create(@RequestBody MaterialInfo entity) { + return ApiResponse.success(service.save(entity)); + } + + @ApiOperation("更新品种信息") + @PutMapping("/{id}") + public ApiResponse update(@PathVariable Integer id, @RequestBody MaterialInfo entity) { + entity.setId(id); + return ApiResponse.success(service.save(entity)); + } + + @ApiOperation("删除品种信息") + @DeleteMapping("/{id}") + public ApiResponse delete(@PathVariable Integer id) { + service.deleteById(id); + return ApiResponse.success(); + } +} diff --git a/src/main/java/com/example/webapi/controller/SupplierController.java b/src/main/java/com/example/webapi/controller/SupplierController.java new file mode 100644 index 0000000..a9ab27c --- /dev/null +++ b/src/main/java/com/example/webapi/controller/SupplierController.java @@ -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> pageByConditions(@RequestBody SupplierQueryDTO queryDTO) { + return ApiResponse.success(service.findByConditions(queryDTO)); + } + + @ApiOperation("根据ID查询供应商信息") + @GetMapping("/{id}") + public ApiResponse getById(@PathVariable Integer id) { + Optional result = service.findById(id); + return result.map(ApiResponse::success).orElseGet(() -> ApiResponse.error("未找到该供应商信息")); + } + + @ApiOperation("新增供应商信息") + @PostMapping + public ApiResponse create(@RequestBody Supplier entity) { + return ApiResponse.success(service.save(entity)); + } + + @ApiOperation("更新供应商信息") + @PutMapping("/{id}") + public ApiResponse update(@PathVariable Integer id, @RequestBody Supplier entity) { + entity.setId(id); + return ApiResponse.success(service.save(entity)); + } + + @ApiOperation("删除供应商信息") + @DeleteMapping("/{id}") + public ApiResponse delete(@PathVariable Integer id) { + service.deleteById(id); + return ApiResponse.success(); + } +} diff --git a/src/main/java/com/example/webapi/controller/SupplyVarietyController.java b/src/main/java/com/example/webapi/controller/SupplyVarietyController.java new file mode 100644 index 0000000..12286a0 --- /dev/null +++ b/src/main/java/com/example/webapi/controller/SupplyVarietyController.java @@ -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> 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 getById( + @ApiParam(value = "供应标识品种ID", required = true, example = "1") + @PathVariable Integer id) { + Optional 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 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 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 delete( + @ApiParam(value = "供应标识品种ID", required = true, example = "1") + @PathVariable Integer id) { + service.deleteById(id); + return ApiResponse.success(); + } +} diff --git a/src/main/java/com/example/webapi/controller/TransferRecordController.java b/src/main/java/com/example/webapi/controller/TransferRecordController.java new file mode 100644 index 0000000..2f99206 --- /dev/null +++ b/src/main/java/com/example/webapi/controller/TransferRecordController.java @@ -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> 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 getById( + @ApiParam(value = "转运记录ID", required = true, example = "1") + @PathVariable Integer id) { + Optional 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 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 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 delete( + @ApiParam(value = "转运记录ID", required = true, example = "1") + @PathVariable Integer id) { + service.deleteById(id); + return ApiResponse.success(); + } +} diff --git a/src/main/java/com/example/webapi/controller/TransportCompanyController.java b/src/main/java/com/example/webapi/controller/TransportCompanyController.java new file mode 100644 index 0000000..0f676cb --- /dev/null +++ b/src/main/java/com/example/webapi/controller/TransportCompanyController.java @@ -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> 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 getById( + @ApiParam(value = "运输公司ID", required = true, example = "1") + @PathVariable Integer id) { + Optional 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 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 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 delete( + @ApiParam(value = "运输公司ID", required = true, example = "1") + @PathVariable Integer id) { + service.deleteById(id); + return ApiResponse.success(); + } +} diff --git a/src/main/java/com/example/webapi/controller/VehicleInfoController.java b/src/main/java/com/example/webapi/controller/VehicleInfoController.java new file mode 100644 index 0000000..9c40e80 --- /dev/null +++ b/src/main/java/com/example/webapi/controller/VehicleInfoController.java @@ -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> 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 getById( + @ApiParam(value = "车辆ID", required = true, example = "1") + @PathVariable Integer id) { + Optional 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 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 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 delete( + @ApiParam(value = "车辆ID", required = true, example = "1") + @PathVariable Integer id) { + service.deleteById(id); + return ApiResponse.success(); + } +} diff --git a/src/main/java/com/example/webapi/controller/WeighingRecordController.java b/src/main/java/com/example/webapi/controller/WeighingRecordController.java new file mode 100644 index 0000000..d525195 --- /dev/null +++ b/src/main/java/com/example/webapi/controller/WeighingRecordController.java @@ -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> 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 getById( + @ApiParam(value = "称重记录ID", required = true, example = "1") + @PathVariable Integer id) { + Optional 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 create( + @ApiParam(value = "称重记录实体", required = true) + @RequestBody WeighingRecord entity) { + WeighingRecord weighingRecord= service.save(entity); + if(weighingRecord.getMaterielId()!=null){ + Optional 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 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 delete( + @ApiParam(value = "称重记录ID", required = true, example = "1") + @PathVariable Integer id) { + service.deleteById(id); + return ApiResponse.success(); + } +} diff --git a/src/main/java/com/example/webapi/dto/ApiResponse.java b/src/main/java/com/example/webapi/dto/ApiResponse.java new file mode 100644 index 0000000..eb692c6 --- /dev/null +++ b/src/main/java/com/example/webapi/dto/ApiResponse.java @@ -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 { + + @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 数据类型 + * @return 响应对象 + */ + public static ApiResponse success(T data) { + return new ApiResponse<>(200, "操作成功", data); + } + + /** + * 成功响应(无数据) + * + * @return 响应对象 + */ + public static ApiResponse success() { + return new ApiResponse<>(200, "操作成功"); + } + + /** + * 失败响应 + * + * @param message 错误消息 + * @return 响应对象 + */ + public static ApiResponse error(String message) { + return new ApiResponse<>(500, message); + } + + /** + * 失败响应 + * + * @param code 错误码 + * @param message 错误消息 + * @return 响应对象 + */ + public static ApiResponse error(Integer code, String message) { + return new ApiResponse<>(code, message); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/dto/BasePageDTO.java b/src/main/java/com/example/webapi/dto/BasePageDTO.java new file mode 100644 index 0000000..a2178c8 --- /dev/null +++ b/src/main/java/com/example/webapi/dto/BasePageDTO.java @@ -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"; +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/dto/ImageInfoQueryDTO.java b/src/main/java/com/example/webapi/dto/ImageInfoQueryDTO.java new file mode 100644 index 0000000..c48877c --- /dev/null +++ b/src/main/java/com/example/webapi/dto/ImageInfoQueryDTO.java @@ -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; +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/dto/MaterialInfoQueryDTO.java b/src/main/java/com/example/webapi/dto/MaterialInfoQueryDTO.java new file mode 100644 index 0000000..b428266 --- /dev/null +++ b/src/main/java/com/example/webapi/dto/MaterialInfoQueryDTO.java @@ -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; // 激活状态 +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/dto/SupplierQueryDTO.java b/src/main/java/com/example/webapi/dto/SupplierQueryDTO.java new file mode 100644 index 0000000..e26eef1 --- /dev/null +++ b/src/main/java/com/example/webapi/dto/SupplierQueryDTO.java @@ -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; // 备注(模糊查询) +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/dto/SupplyVarietyQueryDTO.java b/src/main/java/com/example/webapi/dto/SupplyVarietyQueryDTO.java new file mode 100644 index 0000000..bafff20 --- /dev/null +++ b/src/main/java/com/example/webapi/dto/SupplyVarietyQueryDTO.java @@ -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; // 激活状态 +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/dto/TransferRecordQueryDTO.java b/src/main/java/com/example/webapi/dto/TransferRecordQueryDTO.java new file mode 100644 index 0000000..4d3e573 --- /dev/null +++ b/src/main/java/com/example/webapi/dto/TransferRecordQueryDTO.java @@ -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; +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/dto/TransportCompanyQueryDTO.java b/src/main/java/com/example/webapi/dto/TransportCompanyQueryDTO.java new file mode 100644 index 0000000..038e9e2 --- /dev/null +++ b/src/main/java/com/example/webapi/dto/TransportCompanyQueryDTO.java @@ -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; // 备注(模糊查询) +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/dto/VehicleInfoQueryDTO.java b/src/main/java/com/example/webapi/dto/VehicleInfoQueryDTO.java new file mode 100644 index 0000000..48669d2 --- /dev/null +++ b/src/main/java/com/example/webapi/dto/VehicleInfoQueryDTO.java @@ -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; // 备注(模糊查询) +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/dto/WeighingRecordQueryDTO.java b/src/main/java/com/example/webapi/dto/WeighingRecordQueryDTO.java new file mode 100644 index 0000000..f37784f --- /dev/null +++ b/src/main/java/com/example/webapi/dto/WeighingRecordQueryDTO.java @@ -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; +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/entity/ImageInfo.java b/src/main/java/com/example/webapi/entity/ImageInfo.java new file mode 100644 index 0000000..88f25c2 --- /dev/null +++ b/src/main/java/com/example/webapi/entity/ImageInfo.java @@ -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; +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/entity/MaterialInfo.java b/src/main/java/com/example/webapi/entity/MaterialInfo.java new file mode 100644 index 0000000..cd3b3b3 --- /dev/null +++ b/src/main/java/com/example/webapi/entity/MaterialInfo.java @@ -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; +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/entity/Supplier.java b/src/main/java/com/example/webapi/entity/Supplier.java new file mode 100644 index 0000000..29b8b35 --- /dev/null +++ b/src/main/java/com/example/webapi/entity/Supplier.java @@ -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; +} diff --git a/src/main/java/com/example/webapi/entity/SupplyVariety.java b/src/main/java/com/example/webapi/entity/SupplyVariety.java new file mode 100644 index 0000000..f2ea143 --- /dev/null +++ b/src/main/java/com/example/webapi/entity/SupplyVariety.java @@ -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; +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/entity/TransferRecord.java b/src/main/java/com/example/webapi/entity/TransferRecord.java new file mode 100644 index 0000000..8ac2c07 --- /dev/null +++ b/src/main/java/com/example/webapi/entity/TransferRecord.java @@ -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; +} diff --git a/src/main/java/com/example/webapi/entity/TransportCompany.java b/src/main/java/com/example/webapi/entity/TransportCompany.java new file mode 100644 index 0000000..7f377fd --- /dev/null +++ b/src/main/java/com/example/webapi/entity/TransportCompany.java @@ -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; +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/entity/VehicleInfo.java b/src/main/java/com/example/webapi/entity/VehicleInfo.java new file mode 100644 index 0000000..8877aee --- /dev/null +++ b/src/main/java/com/example/webapi/entity/VehicleInfo.java @@ -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; +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/entity/WeighingRecord.java b/src/main/java/com/example/webapi/entity/WeighingRecord.java new file mode 100644 index 0000000..c21fe28 --- /dev/null +++ b/src/main/java/com/example/webapi/entity/WeighingRecord.java @@ -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; +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/interceptor/SignatureInterceptor.java b/src/main/java/com/example/webapi/interceptor/SignatureInterceptor.java new file mode 100644 index 0000000..075907d --- /dev/null +++ b/src/main/java/com/example/webapi/interceptor/SignatureInterceptor.java @@ -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 { + // 不需要实现 + } +} diff --git a/src/main/java/com/example/webapi/repository/ImageInfoRepository.java b/src/main/java/com/example/webapi/repository/ImageInfoRepository.java new file mode 100644 index 0000000..643a04e --- /dev/null +++ b/src/main/java/com/example/webapi/repository/ImageInfoRepository.java @@ -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 { +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/repository/MaterialInfoRepository.java b/src/main/java/com/example/webapi/repository/MaterialInfoRepository.java new file mode 100644 index 0000000..a9b1339 --- /dev/null +++ b/src/main/java/com/example/webapi/repository/MaterialInfoRepository.java @@ -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 { +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/repository/SupplierRepository.java b/src/main/java/com/example/webapi/repository/SupplierRepository.java new file mode 100644 index 0000000..6c9d21f --- /dev/null +++ b/src/main/java/com/example/webapi/repository/SupplierRepository.java @@ -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 { +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/repository/SupplyVarietyRepository.java b/src/main/java/com/example/webapi/repository/SupplyVarietyRepository.java new file mode 100644 index 0000000..c9a4033 --- /dev/null +++ b/src/main/java/com/example/webapi/repository/SupplyVarietyRepository.java @@ -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 { +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/repository/TransferRecordRepository.java b/src/main/java/com/example/webapi/repository/TransferRecordRepository.java new file mode 100644 index 0000000..f3543be --- /dev/null +++ b/src/main/java/com/example/webapi/repository/TransferRecordRepository.java @@ -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 { +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/repository/TransportCompanyRepository.java b/src/main/java/com/example/webapi/repository/TransportCompanyRepository.java new file mode 100644 index 0000000..f75d909 --- /dev/null +++ b/src/main/java/com/example/webapi/repository/TransportCompanyRepository.java @@ -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 { +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/repository/VehicleInfoRepository.java b/src/main/java/com/example/webapi/repository/VehicleInfoRepository.java new file mode 100644 index 0000000..7ad12bd --- /dev/null +++ b/src/main/java/com/example/webapi/repository/VehicleInfoRepository.java @@ -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 { +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/repository/WeighingRecordRepository.java b/src/main/java/com/example/webapi/repository/WeighingRecordRepository.java new file mode 100644 index 0000000..71e2c09 --- /dev/null +++ b/src/main/java/com/example/webapi/repository/WeighingRecordRepository.java @@ -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 { +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/service/ImageInfoService.java b/src/main/java/com/example/webapi/service/ImageInfoService.java new file mode 100644 index 0000000..f2ff88b --- /dev/null +++ b/src/main/java/com/example/webapi/service/ImageInfoService.java @@ -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 findAll(Pageable pageable) { + return repository.findAll(pageable); + } + + /** + * 根据条件查询图片信息(分页) + * + * @param queryDTO 查询条件(包含分页参数) + * @return 分页结果 + */ + public Page 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 example = Example.of(probe, matcher); + + // 执行查询 + return repository.findAll(example, pageable); + } + + public Optional findById(Integer id) { + return repository.findById(id); + } + + public ImageInfo save(ImageInfo entity) { + return repository.save(entity); + } + + public void deleteById(Integer id) { + repository.deleteById(id); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/service/MaterialInfoService.java b/src/main/java/com/example/webapi/service/MaterialInfoService.java new file mode 100644 index 0000000..1affcda --- /dev/null +++ b/src/main/java/com/example/webapi/service/MaterialInfoService.java @@ -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 findAll(Pageable pageable) { + return repository.findAll(pageable); + } + + /** + * 根据条件查询品种信息(分页) + * + * @param queryDTO 查询条件(包含分页参数) + * @return 分页结果 + */ + public Page 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 example = Example.of(probe, matcher); + + // 执行查询 + return repository.findAll(example, pageable); + } + + public Optional findById(Integer id) { + return repository.findById(id); + } + + public MaterialInfo save(MaterialInfo entity) { + return repository.save(entity); + } + + public void deleteById(Integer id) { + repository.deleteById(id); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/service/SupplierService.java b/src/main/java/com/example/webapi/service/SupplierService.java new file mode 100644 index 0000000..454bbd4 --- /dev/null +++ b/src/main/java/com/example/webapi/service/SupplierService.java @@ -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 findAll(Pageable pageable) { + return repository.findAll(pageable); + } + + /** + * 根据条件查询供应商信息(分页) + * + * @param queryDTO 查询条件(包含分页参数) + * @return 分页结果 + */ + public Page 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 example = Example.of(probe, matcher); + + // 执行查询 + return repository.findAll(example, pageable); + } + + public Optional findById(Integer id) { + return repository.findById(id); + } + + public Supplier save(Supplier entity) { + return repository.save(entity); + } + + public void deleteById(Integer id) { + repository.deleteById(id); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/service/SupplyVarietyService.java b/src/main/java/com/example/webapi/service/SupplyVarietyService.java new file mode 100644 index 0000000..cfda1de --- /dev/null +++ b/src/main/java/com/example/webapi/service/SupplyVarietyService.java @@ -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 findAll(Pageable pageable) { + return repository.findAll(pageable); + } + + /** + * 根据条件查询供应标识品种信息(分页) + * + * @param queryDTO 查询条件(包含分页参数) + * @return 分页结果 + */ + public Page 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 example = Example.of(probe, matcher); + + // 执行查询 + return repository.findAll(example, pageable); + } + + public Optional findById(Integer id) { + return repository.findById(id); + } + + public SupplyVariety save(SupplyVariety entity) { + return repository.save(entity); + } + + public void deleteById(Integer id) { + repository.deleteById(id); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/service/TransferRecordService.java b/src/main/java/com/example/webapi/service/TransferRecordService.java new file mode 100644 index 0000000..64c6b82 --- /dev/null +++ b/src/main/java/com/example/webapi/service/TransferRecordService.java @@ -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 findAll(Pageable pageable) { + return repository.findAll(pageable); + } + + /** + * 根据条件查询转运记录(分页) + * + * @param queryDTO 查询条件(包含分页参数) + * @return 分页结果 + */ + public Page 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 example = Example.of(probe, matcher); + + // 执行查询 + return repository.findAll(example, pageable); + } + + public Optional findById(Integer id) { + return repository.findById(id); + } + + public TransferRecord save(TransferRecord entity) { + return repository.save(entity); + } + + public void deleteById(Integer id) { + repository.deleteById(id); + } +} diff --git a/src/main/java/com/example/webapi/service/TransportCompanyService.java b/src/main/java/com/example/webapi/service/TransportCompanyService.java new file mode 100644 index 0000000..a145466 --- /dev/null +++ b/src/main/java/com/example/webapi/service/TransportCompanyService.java @@ -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 findAll(Pageable pageable) { + return repository.findAll(pageable); + } + + /** + * 根据条件查询运输公司(分页) + * + * @param queryDTO 查询条件(包含分页参数) + * @return 分页结果 + */ + public Page 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 example = Example.of(probe, matcher); + + // 执行查询 + return repository.findAll(example, pageable); + } + + public Optional findById(Integer id) { + return repository.findById(id); + } + + public TransportCompany save(TransportCompany entity) { + return repository.save(entity); + } + + public void deleteById(Integer id) { + repository.deleteById(id); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/service/VehicleInfoService.java b/src/main/java/com/example/webapi/service/VehicleInfoService.java new file mode 100644 index 0000000..1bfffbc --- /dev/null +++ b/src/main/java/com/example/webapi/service/VehicleInfoService.java @@ -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 findAll(Pageable pageable) { + return repository.findAll(pageable); + } + + /** + * 根据条件查询车辆信息(分页) + * + * @param queryDTO 查询条件(包含分页参数) + * @return 分页结果 + */ + public Page 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 example = Example.of(probe, matcher); + + // 执行查询 + return repository.findAll(example, pageable); + } + + public Optional findById(Integer id) { + return repository.findById(id); + } + + public VehicleInfo save(VehicleInfo entity) { + return repository.save(entity); + } + + public void deleteById(Integer id) { + repository.deleteById(id); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/service/WeighingRecordService.java b/src/main/java/com/example/webapi/service/WeighingRecordService.java new file mode 100644 index 0000000..4195e93 --- /dev/null +++ b/src/main/java/com/example/webapi/service/WeighingRecordService.java @@ -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 findAll(Pageable pageable) { + return repository.findAll(pageable); + } + + /** + * 根据条件查询称重记录(分页) + * + * @param queryDTO 查询条件(包含分页参数) + * @return 分页结果 + */ + public Page 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 example = Example.of(probe, matcher); + + // 执行查询 + return repository.findAll(example, pageable); + } + + public Optional findById(Integer id) { + return repository.findById(id); + } + + public WeighingRecord save(WeighingRecord entity) { + return repository.save(entity); + } + + public void deleteById(Integer id) { + repository.deleteById(id); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/util/PageUtil.java b/src/main/java/com/example/webapi/util/PageUtil.java new file mode 100644 index 0000000..f1f7cad --- /dev/null +++ b/src/main/java/com/example/webapi/util/PageUtil.java @@ -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); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/util/SignatureGenerator.java b/src/main/java/com/example/webapi/util/SignatureGenerator.java new file mode 100644 index 0000000..d386579 --- /dev/null +++ b/src/main/java/com/example/webapi/util/SignatureGenerator.java @@ -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 + ); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/webapi/util/SignatureUtil.java b/src/main/java/com/example/webapi/util/SignatureUtil.java new file mode 100644 index 0000000..28ca17a --- /dev/null +++ b/src/main/java/com/example/webapi/util/SignatureUtil.java @@ -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)); + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..87656f1 --- /dev/null +++ b/src/main/resources/application.yml @@ -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" diff --git a/start.sh b/start.sh new file mode 100644 index 0000000..69f5dd6 --- /dev/null +++ b/start.sh @@ -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 "$@"