浏览代码

初始化项目

master
Searises Hao Wang 1 个月前
父节点
当前提交
fd29fa50ac
共有 55 个文件被更改,包括 3668 次插入1 次删除
  1. +198
    -1
      README.md
  2. +248
    -0
      install.sh
  3. +92
    -0
      pom.xml
  4. +48
    -0
      run.sh
  5. +22
    -0
      src/main/java/com/example/webapi/WebApiApplication.java
  6. +93
    -0
      src/main/java/com/example/webapi/config/SwaggerConfig.java
  7. +75
    -0
      src/main/java/com/example/webapi/config/WebConfig.java
  8. +58
    -0
      src/main/java/com/example/webapi/controller/ImageInfoController.java
  9. +57
    -0
      src/main/java/com/example/webapi/controller/MaterialInfoController.java
  10. +57
    -0
      src/main/java/com/example/webapi/controller/SupplierController.java
  11. +108
    -0
      src/main/java/com/example/webapi/controller/SupplyVarietyController.java
  12. +109
    -0
      src/main/java/com/example/webapi/controller/TransferRecordController.java
  13. +108
    -0
      src/main/java/com/example/webapi/controller/TransportCompanyController.java
  14. +108
    -0
      src/main/java/com/example/webapi/controller/VehicleInfoController.java
  15. +125
    -0
      src/main/java/com/example/webapi/controller/WeighingRecordController.java
  16. +86
    -0
      src/main/java/com/example/webapi/dto/ApiResponse.java
  17. +40
    -0
      src/main/java/com/example/webapi/dto/BasePageDTO.java
  18. +33
    -0
      src/main/java/com/example/webapi/dto/ImageInfoQueryDTO.java
  19. +27
    -0
      src/main/java/com/example/webapi/dto/MaterialInfoQueryDTO.java
  20. +30
    -0
      src/main/java/com/example/webapi/dto/SupplierQueryDTO.java
  21. +27
    -0
      src/main/java/com/example/webapi/dto/SupplyVarietyQueryDTO.java
  22. +41
    -0
      src/main/java/com/example/webapi/dto/TransferRecordQueryDTO.java
  23. +24
    -0
      src/main/java/com/example/webapi/dto/TransportCompanyQueryDTO.java
  24. +39
    -0
      src/main/java/com/example/webapi/dto/VehicleInfoQueryDTO.java
  25. +59
    -0
      src/main/java/com/example/webapi/dto/WeighingRecordQueryDTO.java
  26. +44
    -0
      src/main/java/com/example/webapi/entity/ImageInfo.java
  27. +29
    -0
      src/main/java/com/example/webapi/entity/MaterialInfo.java
  28. +33
    -0
      src/main/java/com/example/webapi/entity/Supplier.java
  29. +29
    -0
      src/main/java/com/example/webapi/entity/SupplyVariety.java
  30. +76
    -0
      src/main/java/com/example/webapi/entity/TransferRecord.java
  31. +25
    -0
      src/main/java/com/example/webapi/entity/TransportCompany.java
  32. +45
    -0
      src/main/java/com/example/webapi/entity/VehicleInfo.java
  33. +135
    -0
      src/main/java/com/example/webapi/entity/WeighingRecord.java
  34. +140
    -0
      src/main/java/com/example/webapi/interceptor/SignatureInterceptor.java
  35. +9
    -0
      src/main/java/com/example/webapi/repository/ImageInfoRepository.java
  36. +9
    -0
      src/main/java/com/example/webapi/repository/MaterialInfoRepository.java
  37. +9
    -0
      src/main/java/com/example/webapi/repository/SupplierRepository.java
  38. +9
    -0
      src/main/java/com/example/webapi/repository/SupplyVarietyRepository.java
  39. +9
    -0
      src/main/java/com/example/webapi/repository/TransferRecordRepository.java
  40. +9
    -0
      src/main/java/com/example/webapi/repository/TransportCompanyRepository.java
  41. +9
    -0
      src/main/java/com/example/webapi/repository/VehicleInfoRepository.java
  42. +9
    -0
      src/main/java/com/example/webapi/repository/WeighingRecordRepository.java
  43. +78
    -0
      src/main/java/com/example/webapi/service/ImageInfoService.java
  44. +75
    -0
      src/main/java/com/example/webapi/service/MaterialInfoService.java
  45. +78
    -0
      src/main/java/com/example/webapi/service/SupplierService.java
  46. +72
    -0
      src/main/java/com/example/webapi/service/SupplyVarietyService.java
  47. +87
    -0
      src/main/java/com/example/webapi/service/TransferRecordService.java
  48. +72
    -0
      src/main/java/com/example/webapi/service/TransportCompanyService.java
  49. +87
    -0
      src/main/java/com/example/webapi/service/VehicleInfoService.java
  50. +105
    -0
      src/main/java/com/example/webapi/service/WeighingRecordService.java
  51. +43
    -0
      src/main/java/com/example/webapi/util/PageUtil.java
  52. +109
    -0
      src/main/java/com/example/webapi/util/SignatureGenerator.java
  53. +41
    -0
      src/main/java/com/example/webapi/util/SignatureUtil.java
  54. +42
    -0
      src/main/resources/application.yml
  55. +239
    -0
      start.sh

+ 198
- 1
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** - 让物流管理更智能! 🚀

+ 248
- 0
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 "$@"

+ 92
- 0
pom.xml 查看文件

@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.example</groupId>
<artifactId>webapi</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>

<name>webapi</name>
<description>SpringBoot WebAPI with Access Key/Secret Key Authentication</description>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
<relativePath/>
</parent>

<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>

<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Spring Boot Starter Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<!-- SQL Server JDBC Driver -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<scope>runtime</scope>
</dependency>

<!-- Spring Boot Starter Validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

<!-- Spring Boot Starter Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Swagger3/Springfox 3.x 依赖 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

+ 48
- 0
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}"

+ 22
- 0
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("=================================");
}
}

+ 93
- 0
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<RequestParameter> getGlobalRequestParameters() {
List<RequestParameter> parameters = new ArrayList<>();
// AK (Access Key) - 在Swagger中设为非必需,便于测试
RequestParameter akParam = new RequestParameterBuilder()
.name("ak")
.description("访问密钥 (Access Key) - 必填")
.in(ParameterType.HEADER.toString())
.required(false) // 改为false,让Swagger UI可以正常访问
.query(param -> param.model(model -> model.scalarModel(ScalarType.STRING)))
.build();
parameters.add(akParam);
// Timestamp - 在Swagger中设为非必需,便于测试
RequestParameter timestampParam = new RequestParameterBuilder()
.name("timestamp")
.description("时间戳 (毫秒) - 必填")
.in(ParameterType.HEADER.toString())
.required(false) // 改为false,让Swagger UI可以正常访问
.query(param -> param.model(model -> model.scalarModel(ScalarType.STRING)))
.build();
parameters.add(timestampParam);
// Signature - 在Swagger中设为非必需,便于测试
RequestParameter signatureParam = new RequestParameterBuilder()
.name("signature")
.description("签名 (MD5(ak + sk + timestamp)) - 必填")
.in(ParameterType.HEADER.toString())
.required(false) // 改为false,让Swagger UI可以正常访问
.query(param -> param.model(model -> model.scalarModel(ScalarType.STRING)))
.build();
parameters.add(signatureParam);
return parameters;
}
}

+ 75
- 0
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;
}
}

+ 58
- 0
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<Page<ImageInfo>> pageByConditions(@RequestBody ImageInfoQueryDTO queryDTO) {
return ApiResponse.success(service.findByConditions(queryDTO));
}

@ApiOperation("根据ID查询图片信息")
@GetMapping("/{id}")
public ApiResponse<ImageInfo> getById(@PathVariable Integer id) {
Optional<ImageInfo> result = service.findById(id);
return result.map(ApiResponse::success).orElseGet(() -> ApiResponse.error("未找到该图片信息"));
}

@ApiOperation("新增图片信息")
@PostMapping
public ApiResponse<ImageInfo> create(@RequestBody ImageInfo entity) {
return ApiResponse.success(service.save(entity));
}

@ApiOperation("更新图片信息")
@PutMapping("/{id}")
public ApiResponse<ImageInfo> update(@PathVariable Integer id, @RequestBody ImageInfo entity) {
entity.setId(id);
return ApiResponse.success(service.save(entity));
}

@ApiOperation("删除图片信息")
@DeleteMapping("/{id}")
public ApiResponse<Void> delete(@PathVariable Integer id) {
service.deleteById(id);
return ApiResponse.success();
}
}

+ 57
- 0
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<Page<MaterialInfo>> pageByConditions(@RequestBody MaterialInfoQueryDTO queryDTO) {
return ApiResponse.success(service.findByConditions(queryDTO));
}

@ApiOperation("根据ID查询品种信息")
@GetMapping("/{id}")
public ApiResponse<MaterialInfo> getById(@PathVariable Integer id) {
Optional<MaterialInfo> result = service.findById(id);
return result.map(ApiResponse::success).orElseGet(() -> ApiResponse.error("未找到该品种信息"));
}

@ApiOperation("新增品种信息")
@PostMapping
public ApiResponse<MaterialInfo> create(@RequestBody MaterialInfo entity) {
return ApiResponse.success(service.save(entity));
}

@ApiOperation("更新品种信息")
@PutMapping("/{id}")
public ApiResponse<MaterialInfo> update(@PathVariable Integer id, @RequestBody MaterialInfo entity) {
entity.setId(id);
return ApiResponse.success(service.save(entity));
}

@ApiOperation("删除品种信息")
@DeleteMapping("/{id}")
public ApiResponse<Void> delete(@PathVariable Integer id) {
service.deleteById(id);
return ApiResponse.success();
}
}

+ 57
- 0
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<Page<Supplier>> pageByConditions(@RequestBody SupplierQueryDTO queryDTO) {
return ApiResponse.success(service.findByConditions(queryDTO));
}

@ApiOperation("根据ID查询供应商信息")
@GetMapping("/{id}")
public ApiResponse<Supplier> getById(@PathVariable Integer id) {
Optional<Supplier> result = service.findById(id);
return result.map(ApiResponse::success).orElseGet(() -> ApiResponse.error("未找到该供应商信息"));
}

@ApiOperation("新增供应商信息")
@PostMapping
public ApiResponse<Supplier> create(@RequestBody Supplier entity) {
return ApiResponse.success(service.save(entity));
}

@ApiOperation("更新供应商信息")
@PutMapping("/{id}")
public ApiResponse<Supplier> update(@PathVariable Integer id, @RequestBody Supplier entity) {
entity.setId(id);
return ApiResponse.success(service.save(entity));
}

@ApiOperation("删除供应商信息")
@DeleteMapping("/{id}")
public ApiResponse<Void> delete(@PathVariable Integer id) {
service.deleteById(id);
return ApiResponse.success();
}
}

+ 108
- 0
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<Page<SupplyVariety>> pageByConditions(
@ApiParam(value = "查询条件DTO,包含分页信息和过滤条件", required = true)
@RequestBody SupplyVarietyQueryDTO queryDTO) {
return ApiResponse.success(service.findByConditions(queryDTO));
}

@ApiOperation(value = "根据ID查询供应标识品种信息", notes = "根据ID获取单条供应标识品种信息详情")
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@GetMapping("/{id}")
public ApiResponse<SupplyVariety> getById(
@ApiParam(value = "供应标识品种ID", required = true, example = "1")
@PathVariable Integer id) {
Optional<SupplyVariety> result = service.findById(id);
return result.map(ApiResponse::success).orElseGet(() -> ApiResponse.error("未找到该供应标识品种信息"));
}

@ApiOperation(value = "新增供应标识品种信息", notes = "创建新的供应标识品种信息")
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "创建成功",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "请求参数错误"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@PostMapping
public ApiResponse<SupplyVariety> create(
@ApiParam(value = "供应标识品种实体", required = true)
@RequestBody SupplyVariety entity) {
return ApiResponse.success(service.save(entity));
}

@ApiOperation(value = "更新供应标识品种信息", notes = "根据ID更新供应标识品种信息")
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "更新成功",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "请求参数错误"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@PutMapping("/{id}")
public ApiResponse<SupplyVariety> update(
@ApiParam(value = "供应标识品种ID", required = true, example = "1")
@PathVariable Integer id,
@ApiParam(value = "更新后的供应标识品种实体", required = true)
@RequestBody SupplyVariety entity) {
entity.setId(id);
return ApiResponse.success(service.save(entity));
}

@ApiOperation(value = "删除供应标识品种信息", notes = "根据ID删除供应标识品种信息")
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "删除成功",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@DeleteMapping("/{id}")
public ApiResponse<Void> delete(
@ApiParam(value = "供应标识品种ID", required = true, example = "1")
@PathVariable Integer id) {
service.deleteById(id);
return ApiResponse.success();
}
}

+ 109
- 0
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<Page<TransferRecord>> pageByConditions(
@ApiParam(value = "查询条件DTO,包含分页信息和过滤条件", required = true)
@RequestBody TransferRecordQueryDTO queryDTO) {
queryDTO.setSortBy("issuedTime");
return ApiResponse.success(service.findByConditions(queryDTO));
}

@ApiOperation(value = "根据ID查询转运记录", notes = "根据ID获取单条转运记录详情")
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@GetMapping("/{id}")
public ApiResponse<TransferRecord> getById(
@ApiParam(value = "转运记录ID", required = true, example = "1")
@PathVariable Integer id) {
Optional<TransferRecord> result = service.findById(id);
return result.map(ApiResponse::success).orElseGet(() -> ApiResponse.error("未找到该转运记录"));
}

@ApiOperation(value = "新增转运记录", notes = "创建新的转运记录")
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "创建成功",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "请求参数错误"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@PostMapping
public ApiResponse<TransferRecord> create(
@ApiParam(value = "转运记录实体", required = true)
@RequestBody TransferRecord entity) {
return ApiResponse.success(service.save(entity));
}

@ApiOperation(value = "更新转运记录", notes = "根据ID更新转运记录信息")
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "更新成功",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "请求参数错误"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@PutMapping("/{id}")
public ApiResponse<TransferRecord> update(
@ApiParam(value = "转运记录ID", required = true, example = "1")
@PathVariable Integer id,
@ApiParam(value = "更新后的转运记录实体", required = true)
@RequestBody TransferRecord entity) {
entity.setId(id);
return ApiResponse.success(service.save(entity));
}

@ApiOperation(value = "删除转运记录", notes = "根据ID删除转运记录")
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "删除成功",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@DeleteMapping("/{id}")
public ApiResponse<Void> delete(
@ApiParam(value = "转运记录ID", required = true, example = "1")
@PathVariable Integer id) {
service.deleteById(id);
return ApiResponse.success();
}
}

+ 108
- 0
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<Page<TransportCompany>> pageByConditions(
@ApiParam(value = "查询条件DTO,包含分页信息和过滤条件", required = true)
@RequestBody TransportCompanyQueryDTO queryDTO) {
return ApiResponse.success(service.findByConditions(queryDTO));
}

@ApiOperation(value = "根据ID查询运输公司", notes = "根据ID获取单条运输公司详情")
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@GetMapping("/{id}")
public ApiResponse<TransportCompany> getById(
@ApiParam(value = "运输公司ID", required = true, example = "1")
@PathVariable Integer id) {
Optional<TransportCompany> result = service.findById(id);
return result.map(ApiResponse::success).orElseGet(() -> ApiResponse.error("未找到该运输公司"));
}

@ApiOperation(value = "新增运输公司", notes = "创建新的运输公司")
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "创建成功",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "请求参数错误"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@PostMapping
public ApiResponse<TransportCompany> create(
@ApiParam(value = "运输公司实体", required = true)
@RequestBody TransportCompany entity) {
return ApiResponse.success(service.save(entity));
}

@ApiOperation(value = "更新运输公司", notes = "根据ID更新运输公司信息")
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "更新成功",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "请求参数错误"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@PutMapping("/{id}")
public ApiResponse<TransportCompany> update(
@ApiParam(value = "运输公司ID", required = true, example = "1")
@PathVariable Integer id,
@ApiParam(value = "更新后的运输公司实体", required = true)
@RequestBody TransportCompany entity) {
entity.setId(id);
return ApiResponse.success(service.save(entity));
}

@ApiOperation(value = "删除运输公司", notes = "根据ID删除运输公司")
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "删除成功",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@DeleteMapping("/{id}")
public ApiResponse<Void> delete(
@ApiParam(value = "运输公司ID", required = true, example = "1")
@PathVariable Integer id) {
service.deleteById(id);
return ApiResponse.success();
}
}

+ 108
- 0
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<Page<VehicleInfo>> pageByConditions(
@ApiParam(value = "查询条件DTO,包含分页信息和过滤条件", required = true)
@RequestBody VehicleInfoQueryDTO queryDTO) {
return ApiResponse.success(service.findByConditions(queryDTO));
}

@ApiOperation(value = "根据ID查询车辆信息", notes = "根据ID获取单条车辆信息详情")
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@GetMapping("/{id}")
public ApiResponse<VehicleInfo> getById(
@ApiParam(value = "车辆ID", required = true, example = "1")
@PathVariable Integer id) {
Optional<VehicleInfo> result = service.findById(id);
return result.map(ApiResponse::success).orElseGet(() -> ApiResponse.error("未找到该车辆信息"));
}

@ApiOperation(value = "新增车辆信息", notes = "创建新的车辆信息")
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "创建成功",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "请求参数错误"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@PostMapping
public ApiResponse<VehicleInfo> create(
@ApiParam(value = "车辆信息实体", required = true)
@RequestBody VehicleInfo entity) {
return ApiResponse.success(service.save(entity));
}

@ApiOperation(value = "更新车辆信息", notes = "根据ID更新车辆信息")
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "更新成功",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "请求参数错误"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@PutMapping("/{id}")
public ApiResponse<VehicleInfo> update(
@ApiParam(value = "车辆ID", required = true, example = "1")
@PathVariable Integer id,
@ApiParam(value = "更新后的车辆信息实体", required = true)
@RequestBody VehicleInfo entity) {
entity.setId(id);
return ApiResponse.success(service.save(entity));
}

@ApiOperation(value = "删除车辆信息", notes = "根据ID删除车辆信息")
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "删除成功",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@DeleteMapping("/{id}")
public ApiResponse<Void> delete(
@ApiParam(value = "车辆ID", required = true, example = "1")
@PathVariable Integer id) {
service.deleteById(id);
return ApiResponse.success();
}
}

+ 125
- 0
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<Page<WeighingRecord>> pageByConditions(
@ApiParam(value = "查询条件DTO,包含分页信息和过滤条件", required = true)
@RequestBody WeighingRecordQueryDTO queryDTO) {
return ApiResponse.success(service.findByConditions(queryDTO));
}

@ApiOperation(value = "根据ID查询称重记录", notes = "根据ID获取单条称重记录详情")
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "查询成功",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@GetMapping("/{id}")
public ApiResponse<WeighingRecord> getById(
@ApiParam(value = "称重记录ID", required = true, example = "1")
@PathVariable Integer id) {
Optional<WeighingRecord> result = service.findById(id);
return result.map(ApiResponse::success)
.orElseGet(() -> ApiResponse.error("未找到该称重记录"));
}

@ApiOperation(value = "新增称重记录", notes = "创建新的称重记录")
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "创建成功",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "请求参数错误"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@PostMapping
public ApiResponse<WeighingRecord> create(
@ApiParam(value = "称重记录实体", required = true)
@RequestBody WeighingRecord entity) {
WeighingRecord weighingRecord= service.save(entity);
if(weighingRecord.getMaterielId()!=null){
Optional<TransferRecord> result = transferRecordService.findById(weighingRecord.getMaterielId());
if( result.isPresent()){
TransferRecord record= result.get();
record .setStatus(1);
transferRecordService.save(record);
}
}
return ApiResponse.success();


}

@ApiOperation(value = "更新称重记录", notes = "根据ID更新称重记录信息")
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "更新成功",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "请求参数错误"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@PutMapping("/{id}")
public ApiResponse<WeighingRecord> update(
@ApiParam(value = "称重记录ID", required = true, example = "1")
@PathVariable Integer id,
@ApiParam(value = "更新后的称重记录实体", required = true)
@RequestBody WeighingRecord entity) {
entity.setId(id);
return ApiResponse.success(service.save(entity));
}

@ApiOperation(value = "删除称重记录", notes = "根据ID删除称重记录")
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "删除成功",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = com.example.webapi.dto.ApiResponse.class))),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "记录不存在"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "500", description = "服务器内部错误")
})
@DeleteMapping("/{id}")
public ApiResponse<Void> delete(
@ApiParam(value = "称重记录ID", required = true, example = "1")
@PathVariable Integer id) {
service.deleteById(id);
return ApiResponse.success();
}
}

+ 86
- 0
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<T> {

@ApiModelProperty(value = "响应状态码", example = "200", notes = "200表示成功,其他值表示失败")
private Integer code;
@ApiModelProperty(value = "响应消息", example = "操作成功")
private String message;
@ApiModelProperty(value = "响应数据")
private T data;
@ApiModelProperty(value = "响应时间戳", example = "2023-05-01T10:30:00")
private LocalDateTime timestamp;

public ApiResponse() {
this.timestamp = LocalDateTime.now();
}

public ApiResponse(Integer code, String message) {
this();
this.code = code;
this.message = message;
}

public ApiResponse(Integer code, String message, T data) {
this(code, message);
this.data = data;
}

/**
* 成功响应
*
* @param data 响应数据
* @param <T> 数据类型
* @return 响应对象
*/
public static <T> ApiResponse<T> success(T data) {
return new ApiResponse<>(200, "操作成功", data);
}

/**
* 成功响应(无数据)
*
* @return 响应对象
*/
public static <T> ApiResponse<T> success() {
return new ApiResponse<>(200, "操作成功");
}

/**
* 失败响应
*
* @param message 错误消息
* @return 响应对象
*/
public static <T> ApiResponse<T> error(String message) {
return new ApiResponse<>(500, message);
}

/**
* 失败响应
*
* @param code 错误码
* @param message 错误消息
* @return 响应对象
*/
public static <T> ApiResponse<T> error(Integer code, String message) {
return new ApiResponse<>(code, message);
}
}

+ 40
- 0
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";
}

+ 33
- 0
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;
}

+ 27
- 0
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; // 激活状态
}

+ 30
- 0
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; // 备注(模糊查询)
}

+ 27
- 0
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; // 激活状态
}

+ 41
- 0
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;
}

+ 24
- 0
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; // 备注(模糊查询)
}

+ 39
- 0
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; // 备注(模糊查询)
}

+ 59
- 0
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;
}

+ 44
- 0
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;
}

+ 29
- 0
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;
}

+ 33
- 0
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;
}

+ 29
- 0
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;
}

+ 76
- 0
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;
}

+ 25
- 0
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;
}

+ 45
- 0
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;
}

+ 135
- 0
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;
}

+ 140
- 0
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 {
// 不需要实现
}
}

+ 9
- 0
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<ImageInfo, Integer> {
}

+ 9
- 0
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<MaterialInfo, Integer> {
}

+ 9
- 0
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<Supplier, Integer> {
}

+ 9
- 0
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<SupplyVariety, Integer> {
}

+ 9
- 0
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<TransferRecord, Integer> {
}

+ 9
- 0
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<TransportCompany, Integer> {
}

+ 9
- 0
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<VehicleInfo, Integer> {
}

+ 9
- 0
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<WeighingRecord, Integer> {
}

+ 78
- 0
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<ImageInfo> findAll(Pageable pageable) {
return repository.findAll(pageable);
}

/**
* 根据条件查询图片信息(分页)
*
* @param queryDTO 查询条件(包含分页参数)
* @return 分页结果
*/
public Page<ImageInfo> findByConditions(ImageInfoQueryDTO queryDTO) {
// 从QueryDTO中提取分页参数
Pageable pageable = PageUtil.createPageable(queryDTO);
// 创建实体对象作为查询条件
ImageInfo probe = new ImageInfo();
// 设置查询条件(只设置非空值)
if (StringUtils.hasText(queryDTO.getFileName())) {
probe.setFileName(queryDTO.getFileName());
}
if (StringUtils.hasText(queryDTO.getFileExtension())) {
probe.setFileExtension(queryDTO.getFileExtension());
}
if (StringUtils.hasText(queryDTO.getMimeType())) {
probe.setMimeType(queryDTO.getMimeType());
}
if (queryDTO.getFileSizeMin() != null) {
probe.setFileSize(queryDTO.getFileSizeMin());
}
// 创建ExampleMatcher,配置模糊查询
ExampleMatcher matcher = ExampleMatcher.matching()
.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) // 字符串使用包含匹配
.withIgnoreCase() // 忽略大小写
.withIgnoreNullValues(); // 忽略空值
// 创建Example对象
Example<ImageInfo> example = Example.of(probe, matcher);
// 执行查询
return repository.findAll(example, pageable);
}

public Optional<ImageInfo> findById(Integer id) {
return repository.findById(id);
}

public ImageInfo save(ImageInfo entity) {
return repository.save(entity);
}

public void deleteById(Integer id) {
repository.deleteById(id);
}
}

+ 75
- 0
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<MaterialInfo> findAll(Pageable pageable) {
return repository.findAll(pageable);
}

/**
* 根据条件查询品种信息(分页)
*
* @param queryDTO 查询条件(包含分页参数)
* @return 分页结果
*/
public Page<MaterialInfo> findByConditions(MaterialInfoQueryDTO queryDTO) {
// 从QueryDTO中提取分页参数
Pageable pageable = PageUtil.createPageable(queryDTO);
// 创建实体对象作为查询条件
MaterialInfo probe = new MaterialInfo();
// 设置查询条件(只设置非空值)
if (StringUtils.hasText(queryDTO.getCode())) {
probe.setCode(queryDTO.getCode());
}
if (StringUtils.hasText(queryDTO.getName())) {
probe.setName(queryDTO.getName());
}
if (queryDTO.getActivate() != null) {
probe.setActivate(queryDTO.getActivate());
}
// 创建ExampleMatcher,配置模糊查询
ExampleMatcher matcher = ExampleMatcher.matching()
.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) // 字符串使用包含匹配
.withIgnoreCase() // 忽略大小写
.withIgnoreNullValues(); // 忽略空值
// 创建Example对象
Example<MaterialInfo> example = Example.of(probe, matcher);
// 执行查询
return repository.findAll(example, pageable);
}

public Optional<MaterialInfo> findById(Integer id) {
return repository.findById(id);
}

public MaterialInfo save(MaterialInfo entity) {
return repository.save(entity);
}

public void deleteById(Integer id) {
repository.deleteById(id);
}
}

+ 78
- 0
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<Supplier> findAll(Pageable pageable) {
return repository.findAll(pageable);
}

/**
* 根据条件查询供应商信息(分页)
*
* @param queryDTO 查询条件(包含分页参数)
* @return 分页结果
*/
public Page<Supplier> findByConditions(SupplierQueryDTO queryDTO) {
// 从QueryDTO中提取分页参数
Pageable pageable = PageUtil.createPageable(queryDTO);
// 创建实体对象作为查询条件
Supplier probe = new Supplier();
// 设置查询条件(只设置非空值)
if (StringUtils.hasText(queryDTO.getCode())) {
probe.setCode(queryDTO.getCode());
}
if (StringUtils.hasText(queryDTO.getName())) {
probe.setName(queryDTO.getName());
}
if (queryDTO.getActive() != null) {
probe.setActive(queryDTO.getActive());
}
if (StringUtils.hasText(queryDTO.getRemark())) {
probe.setRemark(queryDTO.getRemark());
}
// 创建ExampleMatcher,配置模糊查询
ExampleMatcher matcher = ExampleMatcher.matching()
.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) // 字符串使用包含匹配
.withIgnoreCase() // 忽略大小写
.withIgnoreNullValues(); // 忽略空值
// 创建Example对象
Example<Supplier> example = Example.of(probe, matcher);
// 执行查询
return repository.findAll(example, pageable);
}

public Optional<Supplier> findById(Integer id) {
return repository.findById(id);
}

public Supplier save(Supplier entity) {
return repository.save(entity);
}

public void deleteById(Integer id) {
repository.deleteById(id);
}
}

+ 72
- 0
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<SupplyVariety> findAll(Pageable pageable) {
return repository.findAll(pageable);
}

/**
* 根据条件查询供应标识品种信息(分页)
*
* @param queryDTO 查询条件(包含分页参数)
* @return 分页结果
*/
public Page<SupplyVariety> findByConditions(SupplyVarietyQueryDTO queryDTO) {
// 从QueryDTO中提取分页参数
Pageable pageable = PageUtil.createPageable(queryDTO);
// 创建实体对象作为查询条件
SupplyVariety probe = new SupplyVariety();
// 设置查询条件(只设置非空值)
if (queryDTO.getSupplyId() != null) {
probe.setSupplyId(queryDTO.getSupplyId());
}
if (queryDTO.getGood() != null) {
probe.setGood(queryDTO.getGood());
}
if (queryDTO.getActive() != null) {
probe.setActive(queryDTO.getActive());
}
// 创建ExampleMatcher,配置精确匹配
ExampleMatcher matcher = ExampleMatcher.matching()
.withIgnoreNullValues(); // 忽略空值
// 创建Example对象
Example<SupplyVariety> example = Example.of(probe, matcher);
// 执行查询
return repository.findAll(example, pageable);
}

public Optional<SupplyVariety> findById(Integer id) {
return repository.findById(id);
}

public SupplyVariety save(SupplyVariety entity) {
return repository.save(entity);
}

public void deleteById(Integer id) {
repository.deleteById(id);
}
}

+ 87
- 0
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<TransferRecord> findAll(Pageable pageable) {
return repository.findAll(pageable);
}

/**
* 根据条件查询转运记录(分页)
*
* @param queryDTO 查询条件(包含分页参数)
* @return 分页结果
*/
public Page<TransferRecord> findByConditions(TransferRecordQueryDTO queryDTO) {
// 从QueryDTO中提取分页参数
Pageable pageable = PageUtil.createPageable(queryDTO);

// 创建实体对象作为查询条件
TransferRecord probe = new TransferRecord();

// 设置查询条件(只设置非空值)
if (StringUtils.hasText(queryDTO.getBillNo())) {
probe.setBillNo(queryDTO.getBillNo());
}
if (StringUtils.hasText(queryDTO.getVehicleNo())) {
probe.setVehicleNo(queryDTO.getVehicleNo());
}
if (StringUtils.hasText(queryDTO.getCardNo())) {
probe.setCardNo(queryDTO.getCardNo());
}
if (queryDTO.getMaterielId() != null) {
probe.setMaterielId(queryDTO.getMaterielId());
}
if (queryDTO.getReceiveCompanyId() != null) {
probe.setReceiveCompanyId(queryDTO.getReceiveCompanyId());
}
if (queryDTO.getTransitCompanyId() != null) {
probe.setTransitCompanyId(queryDTO.getTransitCompanyId());
}
if (queryDTO.getSupplyId() != null) {
probe.setSupplyId(queryDTO.getSupplyId());
}
probe.setStatus(0);
// 创建ExampleMatcher,配置模糊查询
ExampleMatcher matcher = ExampleMatcher.matching()
.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) // 字符串使用包含匹配
.withIgnoreCase() // 忽略大小写
.withIgnoreNullValues(); // 忽略空值

// 创建Example对象
Example<TransferRecord> example = Example.of(probe, matcher);

// 执行查询
return repository.findAll(example, pageable);
}

public Optional<TransferRecord> findById(Integer id) {
return repository.findById(id);
}

public TransferRecord save(TransferRecord entity) {
return repository.save(entity);
}

public void deleteById(Integer id) {
repository.deleteById(id);
}
}

+ 72
- 0
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<TransportCompany> findAll(Pageable pageable) {
return repository.findAll(pageable);
}

/**
* 根据条件查询运输公司(分页)
*
* @param queryDTO 查询条件(包含分页参数)
* @return 分页结果
*/
public Page<TransportCompany> findByConditions(TransportCompanyQueryDTO queryDTO) {
// 从QueryDTO中提取分页参数
Pageable pageable = PageUtil.createPageable(queryDTO);
// 创建实体对象作为查询条件
TransportCompany probe = new TransportCompany();
// 设置查询条件(只设置非空值)
if (StringUtils.hasText(queryDTO.getName())) {
probe.setName(queryDTO.getName());
}
if (StringUtils.hasText(queryDTO.getRemark())) {
probe.setRemark(queryDTO.getRemark());
}
// 创建ExampleMatcher,配置模糊查询
ExampleMatcher matcher = ExampleMatcher.matching()
.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) // 字符串使用包含匹配
.withIgnoreCase() // 忽略大小写
.withIgnoreNullValues(); // 忽略空值
// 创建Example对象
Example<TransportCompany> example = Example.of(probe, matcher);
// 执行查询
return repository.findAll(example, pageable);
}

public Optional<TransportCompany> findById(Integer id) {
return repository.findById(id);
}

public TransportCompany save(TransportCompany entity) {
return repository.save(entity);
}

public void deleteById(Integer id) {
repository.deleteById(id);
}
}

+ 87
- 0
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<VehicleInfo> findAll(Pageable pageable) {
return repository.findAll(pageable);
}

/**
* 根据条件查询车辆信息(分页)
*
* @param queryDTO 查询条件(包含分页参数)
* @return 分页结果
*/
public Page<VehicleInfo> findByConditions(VehicleInfoQueryDTO queryDTO) {
// 从QueryDTO中提取分页参数
Pageable pageable = PageUtil.createPageable(queryDTO);
// 创建实体对象作为查询条件
VehicleInfo probe = new VehicleInfo();
// 设置查询条件(只设置非空值)
if (StringUtils.hasText(queryDTO.getLicensePlate())) {
probe.setLicensePlate(queryDTO.getLicensePlate());
}
if (StringUtils.hasText(queryDTO.getType())) {
probe.setType(queryDTO.getType());
}
if (queryDTO.getOutage() != null) {
probe.setOutage(queryDTO.getOutage());
}
if (queryDTO.getLock() != null) {
probe.setLock(queryDTO.getLock());
}
if (queryDTO.getTransCompany() != null) {
probe.setTransCompany(queryDTO.getTransCompany());
}
if (queryDTO.getReviewed() != null) {
probe.setReviewed(queryDTO.getReviewed());
}
if (StringUtils.hasText(queryDTO.getRemarks())) {
probe.setRemarks(queryDTO.getRemarks());
}
// 创建ExampleMatcher,配置模糊查询
ExampleMatcher matcher = ExampleMatcher.matching()
.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) // 字符串使用包含匹配
.withIgnoreCase() // 忽略大小写
.withIgnoreNullValues(); // 忽略空值
// 创建Example对象
Example<VehicleInfo> example = Example.of(probe, matcher);
// 执行查询
return repository.findAll(example, pageable);
}

public Optional<VehicleInfo> findById(Integer id) {
return repository.findById(id);
}

public VehicleInfo save(VehicleInfo entity) {
return repository.save(entity);
}

public void deleteById(Integer id) {
repository.deleteById(id);
}
}

+ 105
- 0
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<WeighingRecord> findAll(Pageable pageable) {
return repository.findAll(pageable);
}

/**
* 根据条件查询称重记录(分页)
*
* @param queryDTO 查询条件(包含分页参数)
* @return 分页结果
*/
public Page<WeighingRecord> findByConditions(WeighingRecordQueryDTO queryDTO) {
// 从QueryDTO中提取分页参数
Pageable pageable = PageUtil.createPageable(queryDTO);
// 创建实体对象作为查询条件
WeighingRecord probe = new WeighingRecord();
// 设置查询条件(只设置非空值)
if (StringUtils.hasText(queryDTO.getBillNo())) {
probe.setBillNo(queryDTO.getBillNo());
}
if (StringUtils.hasText(queryDTO.getVehicleNo())) {
probe.setVehicleNo(queryDTO.getVehicleNo());
}
if (StringUtils.hasText(queryDTO.getCardNo())) {
probe.setCardNo(queryDTO.getCardNo());
}
if (StringUtils.hasText(queryDTO.getRfidNo())) {
probe.setRfidNo(queryDTO.getRfidNo());
}
if (StringUtils.hasText(queryDTO.getIssuedBy())) {
probe.setIssuedBy(queryDTO.getIssuedBy());
}
if (StringUtils.hasText(queryDTO.getGwBy())) {
probe.setGwBy(queryDTO.getGwBy());
}
if (StringUtils.hasText(queryDTO.getTBy())) {
probe.setTBy(queryDTO.getTBy());
}
if (queryDTO.getMaterielId() != null) {
probe.setMaterielId(queryDTO.getMaterielId());
}
if (queryDTO.getWarehouseId() != null) {
probe.setWarehouseId(queryDTO.getWarehouseId());
}
if (queryDTO.getReceiveCompanyId() != null) {
probe.setReceiveCompanyId(queryDTO.getReceiveCompanyId());
}
if (queryDTO.getTransitCompanyId() != null) {
probe.setTransitCompanyId(queryDTO.getTransitCompanyId());
}
if (queryDTO.getVehicleId() != null) {
probe.setVehicleId(queryDTO.getVehicleId());
}
if (queryDTO.getSupplyId() != null) {
probe.setSupplyId(queryDTO.getSupplyId());
}
// 创建ExampleMatcher,配置模糊查询
ExampleMatcher matcher = ExampleMatcher.matching()
.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) // 字符串使用包含匹配
.withIgnoreCase() // 忽略大小写
.withIgnoreNullValues(); // 忽略空值
// 创建Example对象
Example<WeighingRecord> example = Example.of(probe, matcher);
// 执行查询
return repository.findAll(example, pageable);
}

public Optional<WeighingRecord> findById(Integer id) {
return repository.findById(id);
}

public WeighingRecord save(WeighingRecord entity) {
return repository.save(entity);
}

public void deleteById(Integer id) {
repository.deleteById(id);
}
}

+ 43
- 0
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);
}
}

+ 109
- 0
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
);
}
}

+ 41
- 0
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));
}
}

+ 42
- 0
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"

+ 239
- 0
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 "$@"

正在加载...
取消
保存