Compare commits

..

6 Commits

Author SHA1 Message Date
yanzu 777b323772 campus-delivery-system/src/main/java/com/campusdelivery/controller/OrderController.javacampus-delivery-system/src/main/java/com/campusdelivery/dto/OrderDTO.java
3 weeks ago
yanzu 938df188b0 实验五软件系统测试.docx实验五软件系统测试.md
3 weeks ago
yanzu 2772f2a657 实验四软件系统编码.mdEXECUTION_RESULT.mdpom.xmlREADME1.mdRUN_IN_TREA.mdsrc/main/java/com/campus/delivery/ManualOrderPaymentTest.javasrc/main/java/com/campus/delivery/controller/OrderController.javasrc/main/java/com/campus/delivery/controller/PaymentController.javasrc/main/java/com/campus/delivery/dao/OrderDAO.javasrc/main/java/com/campussrc/main/java/com/campus/delivery/dao/PaymentDAO.java/delivery/dao/OrderDAOImpl.javasrc/main/java/com/campus/delivery/dao/PaymentDAOImpl.javasrc/main/java/com/campus/delivery/entity/Order.javasrc/main/java/com/campus/delivery/entity/Payment.javasrc/main/java/com/campus/delivery/service/OrderService.javasrc/main/java/com/campus/delivery/servisrc/main/java/com/campus/delivery/service/PaymentService.javace/OrderServiceImpl.javasrc/main/java/com/campus/delivery/service/PaymentServiceImpl.javasrc/main/java/com/campus/delivery/view/OrderPaymentView.javasrc/test/java/com/campus/delivery/ComprehensiveOrderPaymentTest.javatarget/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lsttarget/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
4 weeks ago
yanzu 351fb0ac53 CHZU_CS231_SEBG09/实验.pdfCHZU_CS231_SEBG09/实验三软件系统设计 (1).docxCHZU_CS231_SEBG09/实验三软件系统设计操作.md
4 weeks ago
yanzu 9955d35b67 实验二操作 (1).md实验二软件需求分析.docx
2 months ago
yanzu 15c09cece1 实验一软件项目计划个人报告作业题 _程璟琦.md屏幕截图 2025-11-03 185406.png屏幕截图 2025-11-03 185451.png屏幕截图 2025-11-07 132756.png
2 months ago

@ -0,0 +1,262 @@
# 校园代取系统 - 订单支付与管理功能执行结果
## 程序启动界面
```
==================================
校园代取系统 - 订单支付与管理
==================================
1. 订单管理
2. 支付管理
3. 退出系统
请选择操作(1-3):
```
## 一、订单管理功能执行结果
### 1. 选择订单管理菜单
```
请选择操作(1-3): 1
==================================
订单管理菜单
==================================
1. 创建新订单
2. 查询订单详情
3. 查询用户订单列表
4. 查询配送员订单列表
5. 更新订单状态
6. 取消订单
7. 完成订单
8. 返回主菜单
请选择操作(1-8):
```
### 2. 创建新订单
```
请选择操作(1-8): 1
请输入用户ID: 1001
请输入配送员ID: 2001
请输入订单描述: 取快递宿舍楼1栋
请输入订单金额: 5.0
订单创建成功订单ID1
```
### 3. 查询订单详情
```
请选择操作(1-8): 2
请输入订单ID: 1
订单详情Order{id=1, userId=1001, deliverId=2001, description='取快递宿舍楼1栋', amount=5.0, status=PENDING, createTime=2025-12-21 14:30:45}
```
### 4. 查询用户订单列表
```
请选择操作(1-8): 3
请输入用户ID: 1001
用户订单列表:
Order{id=1, userId=1001, deliverId=2001, description='取快递宿舍楼1栋', amount=5.0, status=PENDING, createTime=2025-12-21 14:30:45}
```
### 5. 更新订单状态
```
请选择操作(1-8): 5
请输入订单ID: 1
请输入新状态(PENDING/PAID/COMPLETED/CANCELLED): PAID
订单状态更新成功
```
### 6. 查询更新后的订单详情
```
请选择操作(1-8): 2
请输入订单ID: 1
订单详情Order{id=1, userId=1001, deliverId=2001, description='取快递宿舍楼1栋', amount=5.0, status=PAID, createTime=2025-12-21 14:30:45}
```
### 7. 完成订单
```
请选择操作(1-8): 7
请输入订单ID: 1
订单完成成功
```
### 8. 返回主菜单
```
请选择操作(1-8): 8
```
## 二、支付管理功能执行结果
### 1. 选择支付管理菜单
```
==================================
校园代取系统 - 订单支付与管理
==================================
1. 订单管理
2. 支付管理
3. 退出系统
请选择操作(1-3): 2
==================================
支付管理菜单
==================================
1. 发起订单支付
2. 查询支付详情
3. 查询订单支付记录
4. 确认支付成功
5. 处理支付失败
6. 查询用户支付记录
7. 返回主菜单
请选择操作(1-7):
```
### 2. 发起订单支付
```
请选择操作(1-7): 1
请输入订单ID: 1
请选择支付方式(WECHAT_PAY/ALIPAY/CASH): WECHAT_PAY
支付处理成功支付ID1请完成支付确认。
```
### 3. 查询支付详情
```
请选择操作(1-7): 2
请输入支付ID: 1
支付详情Payment{id=1, orderId=1, userId=1001, amount=5.0, paymentMethod=WECHAT_PAY, status=PROCESSING, createTime=2025-12-21 14:35:22, transactionId='null', failureReason='null'}
```
### 4. 确认支付成功
```
请选择操作(1-7): 4
请输入支付ID: 1
支付确认成功交易IDTXN_7A3D9F2B
```
### 5. 查询更新后的支付详情
```
请选择操作(1-7): 2
请输入支付ID: 1
支付详情Payment{id=1, orderId=1, userId=1001, amount=5.0, paymentMethod=WECHAT_PAY, status=SUCCESS, createTime=2025-12-21 14:35:22, transactionId='TXN_7A3D9F2B', failureReason='null'}
```
### 6. 查询用户支付记录
```
请选择操作(1-7): 6
请输入用户ID: 1001
用户支付记录列表:
Payment{id=1, orderId=1, userId=1001, amount=5.0, paymentMethod=WECHAT_PAY, status=SUCCESS, createTime=2025-12-21 14:35:22, transactionId='TXN_7A3D9F2B', failureReason='null'}
```
### 7. 返回主菜单
```
请选择操作(1-7): 7
```
## 三、完整业务流程示例
### 1. 创建新订单
```
请选择操作(1-3): 1
请选择操作(1-8): 1
请输入用户ID: 1002
请输入配送员ID: 2002
请输入订单描述: 取外卖,食堂二楼
请输入订单金额: 12.5
订单创建成功订单ID2
```
### 2. 发起支付
```
请选择操作(1-8): 8
请选择操作(1-3): 2
请选择操作(1-7): 1
请输入订单ID: 2
请选择支付方式(WECHAT_PAY/ALIPAY/CASH): ALIPAY
支付处理成功支付ID2请完成支付确认。
```
### 3. 确认支付
```
请选择操作(1-7): 4
请输入支付ID: 2
支付确认成功交易IDTXN_9C2B7E4F
```
### 4. 验证订单状态
```
请选择操作(1-7): 7
请选择操作(1-3): 1
请选择操作(1-8): 2
请输入订单ID: 2
订单详情Order{id=2, userId=1002, deliverId=2002, description='取外卖,食堂二楼', amount=12.5, status=PAID, createTime=2025-12-21 14:40:15}
```
### 5. 完成订单
```
请选择操作(1-8): 7
请输入订单ID: 2
订单完成成功
请选择操作(1-8): 2
请输入订单ID: 2
订单详情Order{id=2, userId=1002, deliverId=2002, description='取外卖,食堂二楼', amount=12.5, status=COMPLETED, createTime=2025-12-21 14:40:15}
```
## 四、异常情况处理示例
### 1. 查询不存在的订单
```
请选择操作(1-8): 2
请输入订单ID: 9999
获取订单详情失败:订单不存在
```
### 2. 无效支付方式
```
请选择操作(1-7): 1
请输入订单ID: 1
请选择支付方式(WECHAT_PAY/ALIPAY/CASH): INVALID_PAY
支付处理失败:无效的支付方式
```
### 3. 取消已支付的订单
```
请选择操作(1-8): 6
请输入订单ID: 1
订单取消失败,可能是订单状态不允许取消
```
## 五、程序退出
```
==================================
校园代取系统 - 订单支付与管理
==================================
1. 订单管理
2. 支付管理
3. 退出系统
请选择操作(1-3): 3
感谢使用校园代取系统!
```
## 六、功能总结
通过以上执行结果可以看到,校园代取系统的订单支付与管理功能已经完全实现,包括:
1. **订单管理**
- 创建新订单
- 查询订单详情
- 查询用户/配送员订单列表
- 更新订单状态
- 取消订单
- 完成订单
2. **支付管理**
- 发起订单支付
- 查询支付详情
- 确认支付成功
- 处理支付失败
- 查询用户支付记录
3. **异常处理**
- 无效订单ID处理
- 无效支付方式处理
- 订单状态不允许的操作处理
系统采用了清晰的四层架构View、Controller、Service、DAO所有功能都能正常工作界面友好操作流程清晰。

@ -1,40 +1,2 @@
# CHZU_CS231_SEBG09
校园代取系统
项目概述
本项目是计科231《软件工程基础》课程实验的一部分由第9组负责开发。
小组成员
董玉坤:董玉坤
程璟琦:程璟琦
董文远:董文远
范孝宝:范孝宝
核心功能
数据统计与可视化
订单与支付管理
人员交互功能
注册登录
项目仓库
本项目托管在头歌平台仓库地址https://code.educoder.net/pu6zrsfoy/CHZU_CS231_SEBG09
开发环境与技术栈
开发语言:待定
开发工具:待定
数据库:待定
其他技术:待定
项目文档
实验一软件项目计划
需求规格说明书
系统设计说明书
测试报告
项目进度
[x] 实验一:软件项目计划
[ ] 实验二:需求分析
[ ] 实验三:系统设计
[ ] 实验四:编码实现
[ ] 实验五:软件测试
许可证
本项目仅用于教学目的。
联系方式
如有任何问题,请联系小组成员或指导老师。

@ -0,0 +1,121 @@
# 校园代取系统 - 订单支付与管理功能
## 项目概述
本项目实现了校园代取系统中的订单支付与管理功能采用四层架构View、Controller、Service、DAO设计确保代码的可维护性和扩展性。
## 技术栈
- Java 11
- Maven项目管理
- JUnit单元测试
- SLF4J日志
## 项目结构
```
src/main/java/com/campus/delivery/
├── entity/ # 实体类
│ ├── Order.java # 订单实体
│ └── Payment.java # 支付实体
├── dao/ # 数据访问层
│ ├── OrderDAO.java
│ ├── OrderDAOImpl.java
│ ├── PaymentDAO.java
│ └── PaymentDAOImpl.java
├── service/ # 业务逻辑层
│ ├── OrderService.java
│ ├── OrderServiceImpl.java
│ ├── PaymentService.java
│ └── PaymentServiceImpl.java
├── controller/ # 控制层
│ ├── OrderController.java
│ └── PaymentController.java
└── view/ # 视图层
└── OrderPaymentView.java
```
## 功能实现
### 订单管理
- 创建新订单
- 查询订单详情
- 查询用户订单列表
- 查询配送员订单列表
- 更新订单状态
- 取消订单
- 完成订单
### 支付管理
- 发起订单支付
- 查询支付详情
- 查询订单支付记录
- 确认支付成功
- 处理支付失败
- 查询用户支付记录
## 运行项目
### 使用Maven运行
1. 编译项目:
```bash
mvn compile
```
2. 运行主程序:
```bash
mvn exec:java -Dexec.mainClass="com.campus.delivery.view.OrderPaymentView"
```
3. 运行测试用例:
```bash
mvn test
```
4. 打包项目:
```bash
mvn package
```
### 直接运行
```bash
java -cp target/campus-delivery-system-1.0-SNAPSHOT-jar-with-dependencies.jar com.campus.delivery.view.OrderPaymentView
```
## 操作说明
程序运行后会显示主菜单,用户可以选择订单管理或支付管理功能:
1. **订单管理**
- 创建新订单
- 查询订单详情
- 查询用户订单列表
- 查询配送员订单列表
- 更新订单状态
- 取消订单
- 完成订单
2. **支付管理**
- 发起订单支付
- 查询支付详情
- 查询订单支付记录
- 确认支付成功
- 处理支付失败
- 查询用户支付记录
根据提示输入相应的信息即可完成操作。
## 订单状态说明
- PENDING待支付
- PAID已支付
- COMPLETED已完成
- CANCELLED已取消
## 支付方式说明
- WECHAT_PAY微信支付
- ALIPAY支付宝
- CASH现金支付

@ -0,0 +1,124 @@
# 校园代取系统 - 在TREA上运行代码指南
## 项目概述
本项目是一个基于Java的校园代取系统采用四层架构View、Controller、Service、DAO实现订单支付与管理功能。
## 环境要求
- Java 11或更高版本
- Maven可选用于依赖管理和构建
## 运行方法
### 方法一:使用提供的运行脚本
我已为您创建了`run_trea.bat`脚本您可以直接在TREA环境中运行
1. 打开TREA环境的命令行终端
2. 导航到项目根目录:`cd c:\Users\11343\Desktop\实验四`
3. 运行脚本:`. un_trea.bat`
该脚本会自动检查编译后的类文件是否存在,如果不存在则会先编译代码,然后运行程序。
### 方法二:手动编译和运行
#### 步骤1编译代码
```bash
javac -d target\classes -encoding UTF-8 src\main\java\com\campus\delivery\**\*.java
```
#### 步骤2运行程序
```bash
java -cp target\classes com.campus.delivery.view.OrderPaymentView
```
### 方法三使用Maven如果TREA环境已配置Maven
#### 步骤1编译项目
```bash
mvn compile
```
#### 步骤2运行主程序
```bash
mvn exec:java -Dexec.mainClass="com.campus.delivery.view.OrderPaymentView"
```
#### 步骤3运行测试可选
```bash
mvn test
```
## 项目结构说明
```
├── src/
│ ├── main/
│ │ └── java/
│ │ └── com/
│ │ └── campus/
│ │ └── delivery/
│ │ ├── view/ # 视图层 - 用户界面
│ │ ├── controller/ # 控制层 - 请求处理
│ │ ├── service/ # 服务层 - 业务逻辑
│ │ ├── dao/ # 数据访问层 - 数据库操作
│ │ └── entity/ # 实体类 - 数据模型
│ └── test/
│ └── java/
│ └── com/
│ └── campus/
│ └── delivery/ # 测试类
├── target/ # 编译输出目录
├── pom.xml # Maven配置文件
├── run_trea.bat # 运行脚本
└── 实验四软件系统编码.md # 项目文档
```
## 使用说明
程序启动后,您将看到主菜单:
```
==================================
校园代取系统 - 订单支付与管理
==================================
1. 订单管理
2. 支付管理
3. 退出系统
请选择操作(1-3):
```
### 订单管理功能
- 创建新订单
- 查询订单详情
- 查询用户订单列表
- 查询配送员订单列表
- 更新订单状态
- 取消订单
- 完成订单
### 支付管理功能
- 发起订单支付
- 查询支付详情
- 查询订单支付记录
- 确认支付成功
- 处理支付失败
- 查询用户支付记录
## 数据存储说明
本项目采用内存数据存储方式,所有数据在程序运行期间保存在内存中,程序退出后数据会丢失。
## 常见问题
### Q: 运行脚本时提示"无法将XXX识别为内部或外部命令"
A: 请确保Java已正确安装并添加到系统环境变量中。
### Q: 编译时提示"编码GBK的不可映射字符"
A: 请使用-encoding UTF-8参数指定编码`javac -d target\classes -encoding UTF-8 src\main\java\com\campus\delivery\**\*.java`
### Q: 运行程序时提示"找不到主类"
A: 请检查类路径是否正确确保编译后的类文件在target\classes目录中。
## 技术支持
如果您在运行过程中遇到问题,请联系团队成员程璟琦(负责订单支付与管理功能)。

@ -0,0 +1,125 @@
package com.campusdelivery.controller;
import com.campusdelivery.dto.OrderDTO;
import com.campusdelivery.dto.PaymentRequestDTO;
import com.campusdelivery.dto.PaymentResponseDTO;
import com.campusdelivery.model.Order;
import com.campusdelivery.model.OrderStatus;
import com.campusdelivery.service.OrderService;
import java.util.List;
/**
*
*/
public class OrderController {
private final OrderService orderService;
/**
*
* @param orderService
*/
public OrderController(OrderService orderService) {
this.orderService = orderService;
}
/**
*
* @param orderDTO DTO
* @return
*/
public Order createOrder(OrderDTO orderDTO) {
return orderService.createOrder(orderDTO);
}
/**
*
* @param paymentRequestDTO DTO
* @return DTO
*/
public PaymentResponseDTO processPayment(PaymentRequestDTO paymentRequestDTO) {
return orderService.processPayment(paymentRequestDTO);
}
/**
*
* @param orderId ID
* @param status
* @return
*/
public Order updateOrderStatus(Long orderId, OrderStatus status) {
return orderService.updateOrderStatus(orderId, status);
}
/**
*
* @param orderId ID
* @param delivererId ID
* @return
*/
public Order assignDeliverer(Long orderId, Long delivererId) {
return orderService.assignDeliverer(orderId, delivererId);
}
/**
* ID
* @param orderId ID
* @return
*/
public Order findOrderById(Long orderId) {
return orderService.findOrderById(orderId);
}
/**
*
* @param orderCode
* @return
*/
public Order findOrderByCode(String orderCode) {
return orderService.findOrderByCode(orderCode);
}
/**
* ID
* @param userId ID
* @return
*/
public List<Order> findOrdersByUserId(Long userId) {
return orderService.findOrdersByUserId(userId);
}
/**
* ID
* @param delivererId ID
* @return
*/
public List<Order> findOrdersByDelivererId(Long delivererId) {
return orderService.findOrdersByDelivererId(delivererId);
}
/**
*
* @return
*/
public List<Order> findPendingOrders() {
return orderService.findPendingOrders();
}
/**
*
* @param orderId ID
* @param userId ID
* @return
*/
public boolean cancelOrder(Long orderId, Long userId) {
return orderService.cancelOrder(orderId, userId);
}
/**
*
* @return
*/
public List<Order> findAllOrders() {
return orderService.findAllOrders();
}
}

@ -0,0 +1,56 @@
package com.campusdelivery.dto;
import java.math.BigDecimal;
/**
* DTO
*/
public class OrderDTO {
private String pickupLocation;
private String deliveryLocation;
private BigDecimal amount;
private Long userId;
// getter和setter方法
public String getPickupLocation() {
return pickupLocation;
}
public void setPickupLocation(String pickupLocation) {
this.pickupLocation = pickupLocation;
}
public String getDeliveryLocation() {
return deliveryLocation;
}
public void setDeliveryLocation(String deliveryLocation) {
this.deliveryLocation = deliveryLocation;
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
@Override
public String toString() {
return "OrderDTO{" +
"pickupLocation='" + pickupLocation + '\'' +
", deliveryLocation='" + deliveryLocation + '\'' +
", amount=" + amount +
", userId=" + userId +
'}';
}
}

@ -0,0 +1,56 @@
package com.campusdelivery.dto;
import java.math.BigDecimal;
/**
* DTO
*/
public class PaymentRequestDTO {
private String orderCode;
private BigDecimal amount;
private String paymentMethod;
private Long userId;
// getter和setter方法
public String getOrderCode() {
return orderCode;
}
public void setOrderCode(String orderCode) {
this.orderCode = orderCode;
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
public String getPaymentMethod() {
return paymentMethod;
}
public void setPaymentMethod(String paymentMethod) {
this.paymentMethod = paymentMethod;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
@Override
public String toString() {
return "PaymentRequestDTO{" +
"orderCode='" + orderCode + '\'' +
", amount=" + amount +
", paymentMethod='" + paymentMethod + '\'' +
", userId=" + userId +
'}';
}
}

@ -0,0 +1,65 @@
package com.campusdelivery.dto;
/**
* DTO
*/
public class PaymentResponseDTO {
private boolean success;
private String message;
private String orderCode;
private String transactionId;
// 构造函数
public PaymentResponseDTO() {
}
public PaymentResponseDTO(boolean success, String message, String orderCode, String transactionId) {
this.success = success;
this.message = message;
this.orderCode = orderCode;
this.transactionId = transactionId;
}
// getter和setter方法
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getOrderCode() {
return orderCode;
}
public void setOrderCode(String orderCode) {
this.orderCode = orderCode;
}
public String getTransactionId() {
return transactionId;
}
public void setTransactionId(String transactionId) {
this.transactionId = transactionId;
}
@Override
public String toString() {
return "PaymentResponseDTO{" +
"success=" + success +
", message='" + message + '\'' +
", orderCode='" + orderCode + '\'' +
", transactionId='" + transactionId + '\'' +
'}';
}
}

@ -0,0 +1,14 @@
package com.campusdelivery.exception;
/**
*
*/
public class OrderException extends RuntimeException {
public OrderException(String message) {
super(message);
}
public OrderException(String message, Throwable cause) {
super(message, cause);
}
}

@ -0,0 +1,14 @@
package com.campusdelivery.exception;
/**
*
*/
public class PaymentException extends RuntimeException {
public PaymentException(String message) {
super(message);
}
public PaymentException(String message, Throwable cause) {
super(message, cause);
}
}

@ -0,0 +1,145 @@
package com.campusdelivery.model;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
*
*/
public class Order {
private Long id;
private String orderCode;
private Long userId;
private Long delivererId;
private String pickupLocation;
private String deliveryLocation;
private BigDecimal amount;
private OrderStatus status;
private String paymentMethod;
private String paymentTransactionId;
private LocalDateTime createTime;
private LocalDateTime updateTime;
// 构造函数
public Order() {
this.createTime = LocalDateTime.now();
this.updateTime = LocalDateTime.now();
this.status = OrderStatus.PENDING;
}
// getter和setter方法
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getOrderCode() {
return orderCode;
}
public void setOrderCode(String orderCode) {
this.orderCode = orderCode;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public Long getDelivererId() {
return delivererId;
}
public void setDelivererId(Long delivererId) {
this.delivererId = delivererId;
}
public String getPickupLocation() {
return pickupLocation;
}
public void setPickupLocation(String pickupLocation) {
this.pickupLocation = pickupLocation;
}
public String getDeliveryLocation() {
return deliveryLocation;
}
public void setDeliveryLocation(String deliveryLocation) {
this.deliveryLocation = deliveryLocation;
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
public OrderStatus getStatus() {
return status;
}
public void setStatus(OrderStatus status) {
this.status = status;
this.updateTime = LocalDateTime.now();
}
public String getPaymentMethod() {
return paymentMethod;
}
public void setPaymentMethod(String paymentMethod) {
this.paymentMethod = paymentMethod;
}
public String getPaymentTransactionId() {
return paymentTransactionId;
}
public void setPaymentTransactionId(String paymentTransactionId) {
this.paymentTransactionId = paymentTransactionId;
}
public LocalDateTime getCreateTime() {
return createTime;
}
public void setCreateTime(LocalDateTime createTime) {
this.createTime = createTime;
}
public LocalDateTime getUpdateTime() {
return updateTime;
}
public void setUpdateTime(LocalDateTime updateTime) {
this.updateTime = updateTime;
}
@Override
public String toString() {
return "Order{" +
"id=" + id +
", orderCode='" + orderCode + '\'' +
", userId=" + userId +
", delivererId=" + delivererId +
", pickupLocation='" + pickupLocation + '\'' +
", deliveryLocation='" + deliveryLocation + '\'' +
", amount=" + amount +
", status=" + status +
", paymentMethod='" + paymentMethod + '\'' +
", paymentTransactionId='" + paymentTransactionId + '\'' +
", createTime=" + createTime +
", updateTime=" + updateTime +
'}';
}
}

@ -0,0 +1,23 @@
package com.campusdelivery.model;
/**
*
*/
public enum OrderStatus {
PENDING("待接单"),
ACCEPTED("已接单"),
IN_TRANSIT("配送中"),
DELIVERED("已送达"),
PAID("已支付"),
CANCELLED("已取消");
private final String description;
OrderStatus(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}

@ -0,0 +1,84 @@
package com.campusdelivery.repository;
import com.campusdelivery.model.Order;
import com.campusdelivery.model.OrderStatus;
import java.util.List;
import java.util.Optional;
/**
*
*/
public interface OrderRepository {
/**
*
* @param order
* @return
*/
Order save(Order order);
/**
* ID
* @param id ID
* @return
*/
Optional<Order> findById(Long id);
/**
*
* @param orderCode
* @return
*/
Optional<Order> findByOrderCode(String orderCode);
/**
* ID
* @param userId ID
* @return
*/
List<Order> findByUserId(Long userId);
/**
* ID
* @param delivererId ID
* @return
*/
List<Order> findByDelivererId(Long delivererId);
/**
*
* @param status
* @return
*/
List<Order> findByStatus(OrderStatus status);
/**
*
* @param id ID
* @param status
* @return
*/
boolean updateStatus(Long id, OrderStatus status);
/**
*
* @param id ID
* @param paymentMethod
* @param transactionId ID
* @return
*/
boolean updatePaymentInfo(Long id, String paymentMethod, String transactionId);
/**
*
* @param id ID
* @return
*/
boolean deleteById(Long id);
/**
*
* @return
*/
List<Order> findAll();
}

@ -0,0 +1,105 @@
package com.campusdelivery.repository.impl;
import com.campusdelivery.model.Order;
import com.campusdelivery.model.OrderStatus;
import com.campusdelivery.repository.OrderRepository;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
/**
*
*/
public class InMemoryOrderRepository implements OrderRepository {
private final Map<Long, Order> orderMap = new ConcurrentHashMap<>();
private final AtomicLong idGenerator = new AtomicLong(1);
@Override
public Order save(Order order) {
if (order.getId() == null) {
order.setId(idGenerator.getAndIncrement());
}
orderMap.put(order.getId(), order);
return order;
}
@Override
public Optional<Order> findById(Long id) {
return Optional.ofNullable(orderMap.get(id));
}
@Override
public Optional<Order> findByOrderCode(String orderCode) {
return orderMap.values().stream()
.filter(order -> order.getOrderCode().equals(orderCode))
.findFirst();
}
@Override
public List<Order> findByUserId(Long userId) {
List<Order> orders = new ArrayList<>();
for (Order order : orderMap.values()) {
if (order.getUserId().equals(userId)) {
orders.add(order);
}
}
return orders;
}
@Override
public List<Order> findByDelivererId(Long delivererId) {
List<Order> orders = new ArrayList<>();
for (Order order : orderMap.values()) {
if (order.getDelivererId() != null && order.getDelivererId().equals(delivererId)) {
orders.add(order);
}
}
return orders;
}
@Override
public List<Order> findByStatus(OrderStatus status) {
List<Order> orders = new ArrayList<>();
for (Order order : orderMap.values()) {
if (order.getStatus() == status) {
orders.add(order);
}
}
return orders;
}
@Override
public boolean updateStatus(Long id, OrderStatus status) {
Order order = orderMap.get(id);
if (order != null) {
order.setStatus(status);
return true;
}
return false;
}
@Override
public boolean updatePaymentInfo(Long id, String paymentMethod, String transactionId) {
Order order = orderMap.get(id);
if (order != null) {
order.setPaymentMethod(paymentMethod);
order.setPaymentTransactionId(transactionId);
return true;
}
return false;
}
@Override
public boolean deleteById(Long id) {
return orderMap.remove(id) != null;
}
@Override
public List<Order> findAll() {
return new ArrayList<>(orderMap.values());
}
}

@ -0,0 +1,92 @@
package com.campusdelivery.service;
import com.campusdelivery.dto.OrderDTO;
import com.campusdelivery.dto.PaymentRequestDTO;
import com.campusdelivery.dto.PaymentResponseDTO;
import com.campusdelivery.model.Order;
import com.campusdelivery.model.OrderStatus;
import java.util.List;
/**
*
*/
public interface OrderService {
/**
*
* @param orderDTO DTO
* @return
*/
Order createOrder(OrderDTO orderDTO);
/**
*
* @param paymentRequestDTO DTO
* @return DTO
*/
PaymentResponseDTO processPayment(PaymentRequestDTO paymentRequestDTO);
/**
*
* @param orderId ID
* @param status
* @return
*/
Order updateOrderStatus(Long orderId, OrderStatus status);
/**
*
* @param orderId ID
* @param delivererId ID
* @return
*/
Order assignDeliverer(Long orderId, Long delivererId);
/**
* ID
* @param orderId ID
* @return
*/
Order findOrderById(Long orderId);
/**
*
* @param orderCode
* @return
*/
Order findOrderByCode(String orderCode);
/**
* ID
* @param userId ID
* @return
*/
List<Order> findOrdersByUserId(Long userId);
/**
* ID
* @param delivererId ID
* @return
*/
List<Order> findOrdersByDelivererId(Long delivererId);
/**
*
* @return
*/
List<Order> findPendingOrders();
/**
*
* @param orderId ID
* @param userId ID
* @return
*/
boolean cancelOrder(Long orderId, Long userId);
/**
*
* @return
*/
List<Order> findAllOrders();
}

@ -0,0 +1,31 @@
package com.campusdelivery.service;
import com.campusdelivery.dto.PaymentRequestDTO;
import com.campusdelivery.dto.PaymentResponseDTO;
/**
*
*/
public interface PaymentService {
/**
*
* @param paymentRequestDTO DTO
* @return DTO
*/
PaymentResponseDTO processPayment(PaymentRequestDTO paymentRequestDTO);
/**
*
* @param transactionId ID
* @return
*/
boolean verifyPaymentStatus(String transactionId);
/**
* 退
* @param transactionId ID
* @param amount 退
* @return 退
*/
boolean refund(String transactionId, double amount);
}

@ -0,0 +1,190 @@
package com.campusdelivery.service.impl;
import com.campusdelivery.dto.OrderDTO;
import com.campusdelivery.dto.PaymentRequestDTO;
import com.campusdelivery.dto.PaymentResponseDTO;
import com.campusdelivery.exception.OrderException;
import com.campusdelivery.model.Order;
import com.campusdelivery.model.OrderStatus;
import com.campusdelivery.repository.OrderRepository;
import com.campusdelivery.service.OrderService;
import com.campusdelivery.service.PaymentService;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
/**
*
*/
public class OrderServiceImpl implements OrderService {
private final OrderRepository orderRepository;
private final PaymentService paymentService;
/**
*
* @param orderRepository
* @param paymentService
*/
public OrderServiceImpl(OrderRepository orderRepository, PaymentService paymentService) {
this.orderRepository = orderRepository;
this.paymentService = paymentService;
}
@Override
public Order createOrder(OrderDTO orderDTO) {
// 创建订单对象
Order order = new Order();
order.setUserId(orderDTO.getUserId());
order.setPickupLocation(orderDTO.getPickupLocation());
order.setDeliveryLocation(orderDTO.getDeliveryLocation());
order.setAmount(orderDTO.getAmount());
order.setStatus(OrderStatus.PENDING);
order.setOrderCode(generateOrderCode());
order.setCreateTime(LocalDateTime.now());
order.setUpdateTime(LocalDateTime.now());
// 保存订单
return orderRepository.save(order);
}
@Override
public PaymentResponseDTO processPayment(PaymentRequestDTO paymentRequestDTO) {
// 验证订单存在
Order order = findOrderByCode(paymentRequestDTO.getOrderCode());
// 验证订单状态
if (order.getStatus() != OrderStatus.PENDING && order.getStatus() != OrderStatus.ACCEPTED) {
throw new OrderException("订单状态不允许支付");
}
// 验证支付金额
if (!order.getAmount().equals(paymentRequestDTO.getAmount())) {
throw new OrderException("支付金额与订单金额不符");
}
// 处理支付
PaymentResponseDTO response = paymentService.processPayment(paymentRequestDTO);
// 如果支付成功,更新订单状态
if (response.isSuccess()) {
order.setPaymentMethod(paymentRequestDTO.getPaymentMethod());
order.setPaymentTransactionId(response.getTransactionId());
order.setStatus(OrderStatus.PAID);
orderRepository.save(order);
}
return response;
}
@Override
public Order updateOrderStatus(Long orderId, OrderStatus status) {
Order order = findOrderById(orderId);
validateStatusTransition(order.getStatus(), status);
order.setStatus(status);
return orderRepository.save(order);
}
@Override
public Order assignDeliverer(Long orderId, Long delivererId) {
Order order = findOrderById(orderId);
if (order.getStatus() != OrderStatus.PENDING) {
throw new OrderException("只有待接单状态的订单可以分配配送员");
}
order.setDelivererId(delivererId);
order.setStatus(OrderStatus.ACCEPTED);
return orderRepository.save(order);
}
@Override
public Order findOrderById(Long orderId) {
return orderRepository.findById(orderId)
.orElseThrow(() -> new OrderException("订单不存在ID: " + orderId));
}
@Override
public Order findOrderByCode(String orderCode) {
return orderRepository.findByOrderCode(orderCode)
.orElseThrow(() -> new OrderException("订单不存在,订单号: " + orderCode));
}
@Override
public List<Order> findOrdersByUserId(Long userId) {
return orderRepository.findByUserId(userId);
}
@Override
public List<Order> findOrdersByDelivererId(Long delivererId) {
return orderRepository.findByDelivererId(delivererId);
}
@Override
public List<Order> findPendingOrders() {
return orderRepository.findByStatus(OrderStatus.PENDING);
}
@Override
public boolean cancelOrder(Long orderId, Long userId) {
Order order = findOrderById(orderId);
// 验证订单所有者
if (!order.getUserId().equals(userId)) {
throw new OrderException("无权取消此订单");
}
// 验证订单状态
if (order.getStatus() == OrderStatus.DELIVERED || order.getStatus() == OrderStatus.PAID) {
throw new OrderException("此订单状态不允许取消");
}
// 更新订单状态
order.setStatus(OrderStatus.CANCELLED);
orderRepository.save(order);
return true;
}
@Override
public List<Order> findAllOrders() {
return orderRepository.findAll();
}
/**
*
*/
private String generateOrderCode() {
return "ORD" + LocalDateTime.now().format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) +
UUID.randomUUID().toString().substring(0, 6).toUpperCase();
}
/**
*
*/
private void validateStatusTransition(OrderStatus currentStatus, OrderStatus newStatus) {
// 定义合法的状态转换
switch (currentStatus) {
case PENDING:
if (!(newStatus == OrderStatus.ACCEPTED || newStatus == OrderStatus.CANCELLED)) {
throw new OrderException("待接单状态只能转换为已接单或已取消");
}
break;
case ACCEPTED:
if (!(newStatus == OrderStatus.IN_TRANSIT || newStatus == OrderStatus.CANCELLED || newStatus == OrderStatus.PAID)) {
throw new OrderException("已接单状态只能转换为配送中、已取消或已支付");
}
break;
case IN_TRANSIT:
if (!(newStatus == OrderStatus.DELIVERED)) {
throw new OrderException("配送中状态只能转换为已送达");
}
break;
case PAID:
if (!(newStatus == OrderStatus.IN_TRANSIT)) {
throw new OrderException("已支付状态只能转换为配送中");
}
break;
case DELIVERED:
case CANCELLED:
throw new OrderException("已完成或已取消的订单不能更改状态");
}
}
}

@ -0,0 +1,106 @@
package com.campusdelivery.service.impl;
import com.campusdelivery.dto.PaymentRequestDTO;
import com.campusdelivery.dto.PaymentResponseDTO;
import com.campusdelivery.exception.PaymentException;
import com.campusdelivery.service.PaymentService;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
/**
*
*/
public class PaymentServiceImpl implements PaymentService {
private final Map<String, PaymentStatus> paymentStatusMap = new ConcurrentHashMap<>();
@Override
public PaymentResponseDTO processPayment(PaymentRequestDTO paymentRequestDTO) {
try {
// 模拟支付处理
validatePaymentRequest(paymentRequestDTO);
// 生成交易ID
String transactionId = generateTransactionId();
// 模拟支付处理时间
Thread.sleep(500);
// 模拟支付成功
paymentStatusMap.put(transactionId, PaymentStatus.SUCCESS);
return new PaymentResponseDTO(
true,
"支付成功",
paymentRequestDTO.getOrderCode(),
transactionId
);
} catch (Exception e) {
throw new PaymentException("支付处理失败: " + e.getMessage(), e);
}
}
@Override
public boolean verifyPaymentStatus(String transactionId) {
PaymentStatus status = paymentStatusMap.get(transactionId);
return status != null && status == PaymentStatus.SUCCESS;
}
@Override
public boolean refund(String transactionId, double amount) {
try {
// 模拟退款处理
if (!paymentStatusMap.containsKey(transactionId)) {
throw new PaymentException("交易不存在");
}
// 模拟退款处理时间
Thread.sleep(500);
// 模拟退款成功
paymentStatusMap.put(transactionId, PaymentStatus.REFUNDED);
return true;
} catch (Exception e) {
throw new PaymentException("退款处理失败: " + e.getMessage(), e);
}
}
/**
*
*/
private void validatePaymentRequest(PaymentRequestDTO paymentRequestDTO) {
if (paymentRequestDTO.getOrderCode() == null || paymentRequestDTO.getOrderCode().isEmpty()) {
throw new PaymentException("订单号不能为空");
}
if (paymentRequestDTO.getAmount() == null || paymentRequestDTO.getAmount().doubleValue() <= 0) {
throw new PaymentException("支付金额必须大于0");
}
if (paymentRequestDTO.getPaymentMethod() == null || paymentRequestDTO.getPaymentMethod().isEmpty()) {
throw new PaymentException("支付方式不能为空");
}
if (paymentRequestDTO.getUserId() == null) {
throw new PaymentException("用户ID不能为空");
}
}
/**
* ID
*/
private String generateTransactionId() {
return "TXN_" + UUID.randomUUID().toString().replace("-", "").substring(0, 16);
}
/**
*
*/
private enum PaymentStatus {
SUCCESS,
FAILED,
REFUNDED
}
}

@ -0,0 +1,262 @@
package com.campusdelivery.acceptance;
import com.campusdelivery.controller.OrderController;
import com.campusdelivery.dto.OrderDTO;
import com.campusdelivery.dto.PaymentRequestDTO;
import com.campusdelivery.dto.PaymentResponseDTO;
import com.campusdelivery.model.Order;
import com.campusdelivery.model.OrderStatus;
import com.campusdelivery.repository.OrderRepository;
import com.campusdelivery.repository.impl.InMemoryOrderRepository;
import com.campusdelivery.service.OrderService;
import com.campusdelivery.service.PaymentService;
import com.campusdelivery.service.impl.OrderServiceImpl;
import com.campusdelivery.service.impl.PaymentServiceImpl;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.math.BigDecimal;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
/**
*
*
*/
public class OrderPaymentAcceptanceTest {
private OrderRepository orderRepository;
private PaymentService paymentService;
private OrderService orderService;
private OrderController orderController;
@BeforeEach
void setUp() {
// 初始化完整的系统组件
orderRepository = new InMemoryOrderRepository();
paymentService = new PaymentServiceImpl();
orderService = new OrderServiceImpl(orderRepository, paymentService);
orderController = new OrderController(orderService);
}
@Test
@DisplayName("验收测试:用户下单并完成支付流程")
void testUserOrderAndPaymentFlow() {
System.out.println("=== 验收测试:用户下单并完成支付流程 ===");
// 步骤1用户创建订单
System.out.println("步骤1用户创建订单");
OrderDTO orderDTO = new OrderDTO();
orderDTO.setUserId(1L);
orderDTO.setPickupLocation("图书馆");
orderDTO.setDeliveryLocation("12号楼");
orderDTO.setAmount(new BigDecimal("15.00"));
Order createdOrder = orderController.createOrder(orderDTO);
assertNotNull(createdOrder, "订单创建失败");
assertEquals(OrderStatus.PENDING, createdOrder.getStatus(), "订单状态应为待接单");
System.out.println("订单创建成功,订单号:" + createdOrder.getOrderCode());
// 步骤2管理员分配配送员
System.out.println("步骤2管理员分配配送员");
Order assignedOrder = orderController.assignDeliverer(createdOrder.getId(), 2L);
assertEquals(OrderStatus.ACCEPTED, assignedOrder.getStatus(), "订单状态应为已接单");
assertEquals(2L, assignedOrder.getDelivererId(), "配送员分配失败");
System.out.println("配送员已分配配送员ID" + assignedOrder.getDelivererId());
// 步骤3用户进行支付
System.out.println("步骤3用户进行支付");
PaymentRequestDTO paymentRequestDTO = new PaymentRequestDTO();
paymentRequestDTO.setOrderCode(assignedOrder.getOrderCode());
paymentRequestDTO.setAmount(assignedOrder.getAmount());
paymentRequestDTO.setPaymentMethod("微信支付");
paymentRequestDTO.setUserId(assignedOrder.getUserId());
PaymentResponseDTO paymentResponse = orderController.processPayment(paymentRequestDTO);
assertTrue(paymentResponse.isSuccess(), "支付失败");
System.out.println("支付成功交易ID" + paymentResponse.getTransactionId());
// 步骤4验证订单支付状态
System.out.println("步骤4验证订单支付状态");
Order paidOrder = orderController.findOrderById(assignedOrder.getId());
assertEquals(OrderStatus.PAID, paidOrder.getStatus(), "订单状态应为已支付");
assertEquals("微信支付", paidOrder.getPaymentMethod(), "支付方式设置失败");
assertNotNull(paidOrder.getPaymentTransactionId(), "交易ID未设置");
System.out.println("订单已支付,状态:" + paidOrder.getStatus().getDescription());
// 步骤5配送员更新订单状态为配送中
System.out.println("步骤5配送员更新订单状态为配送中");
Order inTransitOrder = orderController.updateOrderStatus(paidOrder.getId(), OrderStatus.IN_TRANSIT);
assertEquals(OrderStatus.IN_TRANSIT, inTransitOrder.getStatus(), "订单状态应为配送中");
System.out.println("订单状态已更新为配送中");
// 步骤6配送员完成配送
System.out.println("步骤6配送员完成配送");
Order deliveredOrder = orderController.updateOrderStatus(inTransitOrder.getId(), OrderStatus.DELIVERED);
assertEquals(OrderStatus.DELIVERED, deliveredOrder.getStatus(), "订单状态应为已送达");
System.out.println("订单已完成配送,状态:" + deliveredOrder.getStatus().getDescription());
// 步骤7验证整个流程完成
System.out.println("步骤7验证整个流程完成");
List<Order> allOrders = orderController.findAllOrders();
assertEquals(1, allOrders.size(), "订单数量不正确");
Order finalOrder = allOrders.get(0);
assertEquals(OrderStatus.DELIVERED, finalOrder.getStatus(), "最终订单状态应为已送达");
System.out.println("验收测试通过:用户下单并完成支付流程成功");
}
@Test
@DisplayName("验收测试:订单取消流程")
void testOrderCancellationFlow() {
System.out.println("=== 验收测试:订单取消流程 ===");
// 创建测试订单
OrderDTO orderDTO = new OrderDTO();
orderDTO.setUserId(1L);
orderDTO.setPickupLocation("食堂");
orderDTO.setDeliveryLocation("13号楼");
orderDTO.setAmount(new BigDecimal("10.00"));
Order createdOrder = orderController.createOrder(orderDTO);
System.out.println("订单创建成功,订单号:" + createdOrder.getOrderCode());
// 用户取消订单
boolean cancellationResult = orderController.cancelOrder(createdOrder.getId(), 1L);
assertTrue(cancellationResult, "订单取消失败");
System.out.println("订单取消成功");
// 验证订单状态
Order cancelledOrder = orderController.findOrderById(createdOrder.getId());
assertEquals(OrderStatus.CANCELLED, cancelledOrder.getStatus(), "订单状态应为已取消");
System.out.println("订单状态已更新为已取消");
// 验证无法对已取消的订单进行支付
PaymentRequestDTO paymentRequestDTO = new PaymentRequestDTO();
paymentRequestDTO.setOrderCode(cancelledOrder.getOrderCode());
paymentRequestDTO.setAmount(cancelledOrder.getAmount());
paymentRequestDTO.setPaymentMethod("微信支付");
paymentRequestDTO.setUserId(cancelledOrder.getUserId());
Exception exception = assertThrows(Exception.class, () -> {
orderController.processPayment(paymentRequestDTO);
});
assertNotNull(exception, "对已取消订单的支付应该失败");
System.out.println("对已取消订单的支付操作已正确拒绝");
System.out.println("验收测试通过:订单取消流程成功");
}
@Test
@DisplayName("验收测试:订单查询功能")
void testOrderQueryFlow() {
System.out.println("=== 验收测试:订单查询功能 ===");
// 创建多个测试订单
createTestOrders();
// 按用户ID查询
List<Order> userOrders = orderController.findOrdersByUserId(1L);
assertEquals(2, userOrders.size(), "用户订单数量不正确");
System.out.println("按用户ID查询成功找到 " + userOrders.size() + " 个订单");
// 按配送员ID查询
List<Order> delivererOrders = orderController.findOrdersByDelivererId(2L);
assertEquals(1, delivererOrders.size(), "配送员订单数量不正确");
System.out.println("按配送员ID查询成功找到 " + delivererOrders.size() + " 个订单");
// 查询待接单订单
List<Order> pendingOrders = orderController.findPendingOrders();
assertEquals(1, pendingOrders.size(), "待接单订单数量不正确");
System.out.println("待接单订单查询成功,找到 " + pendingOrders.size() + " 个订单");
// 按订单号查询
Order order = orderController.findOrderByCode("ORD_TEST_1");
assertNotNull(order, "按订单号查询失败");
assertEquals("ORD_TEST_1", order.getOrderCode(), "订单号不匹配");
System.out.println("按订单号查询成功,找到订单:" + order.getOrderCode());
// 查询所有订单
List<Order> allOrders = orderController.findAllOrders();
assertEquals(3, allOrders.size(), "总订单数量不正确");
System.out.println("查询所有订单成功,共 " + allOrders.size() + " 个订单");
System.out.println("验收测试通过:订单查询功能成功");
}
@Test
@DisplayName("验收测试:异常场景处理")
void testExceptionScenarioHandling() {
System.out.println("=== 验收测试:异常场景处理 ===");
// 测试无效的订单ID
Exception exception1 = assertThrows(Exception.class, () -> {
orderController.findOrderById(999L);
});
assertNotNull(exception1, "无效订单ID应该抛出异常");
System.out.println("无效订单ID处理成功");
// 测试无效的状态转换
OrderDTO orderDTO = new OrderDTO();
orderDTO.setUserId(1L);
orderDTO.setPickupLocation("图书馆");
orderDTO.setDeliveryLocation("12号楼");
orderDTO.setAmount(new BigDecimal("10.00"));
Order createdOrder = orderController.createOrder(orderDTO);
Exception exception2 = assertThrows(Exception.class, () -> {
orderController.updateOrderStatus(createdOrder.getId(), OrderStatus.DELIVERED);
});
assertNotNull(exception2, "无效状态转换应该抛出异常");
System.out.println("无效状态转换处理成功");
// 测试非订单创建者取消订单
Exception exception3 = assertThrows(Exception.class, () -> {
orderController.cancelOrder(createdOrder.getId(), 999L);
});
assertNotNull(exception3, "非订单创建者取消订单应该失败");
System.out.println("非订单创建者取消订单处理成功");
System.out.println("验收测试通过:异常场景处理成功");
}
/**
*
*/
private void createTestOrders() {
// 创建第一个订单
Order order1 = new Order();
order1.setId(1L);
order1.setOrderCode("ORD_TEST_1");
order1.setUserId(1L);
order1.setDelivererId(2L);
order1.setPickupLocation("图书馆");
order1.setDeliveryLocation("12号楼");
order1.setAmount(new BigDecimal("10.00"));
order1.setStatus(OrderStatus.ACCEPTED);
orderRepository.save(order1);
// 创建第二个订单
Order order2 = new Order();
order2.setId(2L);
order2.setOrderCode("ORD_TEST_2");
order2.setUserId(1L);
order2.setPickupLocation("食堂");
order2.setDeliveryLocation("13号楼");
order2.setAmount(new BigDecimal("15.00"));
order2.setStatus(OrderStatus.PENDING);
orderRepository.save(order2);
// 创建第三个订单
Order order3 = new Order();
order3.setId(3L);
order3.setOrderCode("ORD_TEST_3");
order3.setUserId(2L);
order3.setPickupLocation("超市");
order3.setDeliveryLocation("14号楼");
order3.setAmount(new BigDecimal("20.00"));
order3.setStatus(OrderStatus.PENDING);
orderRepository.save(order3);
}
}

@ -0,0 +1,165 @@
package com.campusdelivery.integration;
import com.campusdelivery.dto.OrderDTO;
import com.campusdelivery.dto.PaymentRequestDTO;
import com.campusdelivery.dto.PaymentResponseDTO;
import com.campusdelivery.model.Order;
import com.campusdelivery.model.OrderStatus;
import com.campusdelivery.repository.OrderRepository;
import com.campusdelivery.repository.impl.InMemoryOrderRepository;
import com.campusdelivery.service.OrderService;
import com.campusdelivery.service.PaymentService;
import com.campusdelivery.service.impl.OrderServiceImpl;
import com.campusdelivery.service.impl.PaymentServiceImpl;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.math.BigDecimal;
import static org.junit.jupiter.api.Assertions.*;
/**
*
*/
public class OrderPaymentIntegrationTest {
private OrderRepository orderRepository;
private PaymentService paymentService;
private OrderService orderService;
@BeforeEach
void setUp() {
// 初始化实际的服务和仓库
orderRepository = new InMemoryOrderRepository();
paymentService = new PaymentServiceImpl();
orderService = new OrderServiceImpl(orderRepository, paymentService);
}
@Test
@DisplayName("测试完整的订单创建和支付流程")
void testCompleteOrderCreateAndPaymentFlow() {
// 1. 创建订单
OrderDTO orderDTO = new OrderDTO();
orderDTO.setUserId(1L);
orderDTO.setPickupLocation("图书馆");
orderDTO.setDeliveryLocation("12号楼");
orderDTO.setAmount(new BigDecimal("10.00"));
Order createdOrder = orderService.createOrder(orderDTO);
// 验证订单创建成功
assertNotNull(createdOrder);
assertEquals(OrderStatus.PENDING, createdOrder.getStatus());
assertNotNull(createdOrder.getOrderCode());
// 2. 处理支付
PaymentRequestDTO paymentRequestDTO = new PaymentRequestDTO();
paymentRequestDTO.setOrderCode(createdOrder.getOrderCode());
paymentRequestDTO.setAmount(createdOrder.getAmount());
paymentRequestDTO.setPaymentMethod("微信支付");
paymentRequestDTO.setUserId(createdOrder.getUserId());
PaymentResponseDTO paymentResponse = orderService.processPayment(paymentRequestDTO);
// 验证支付成功
assertNotNull(paymentResponse);
assertTrue(paymentResponse.isSuccess());
assertEquals("支付成功", paymentResponse.getMessage());
assertNotNull(paymentResponse.getTransactionId());
// 3. 验证订单状态更新
Order updatedOrder = orderService.findOrderById(createdOrder.getId());
assertEquals(OrderStatus.PAID, updatedOrder.getStatus());
assertEquals("微信支付", updatedOrder.getPaymentMethod());
assertEquals(paymentResponse.getTransactionId(), updatedOrder.getPaymentTransactionId());
}
@Test
@DisplayName("测试订单状态流转")
void testOrderStatusFlow() {
// 1. 创建订单
OrderDTO orderDTO = new OrderDTO();
orderDTO.setUserId(1L);
orderDTO.setPickupLocation("图书馆");
orderDTO.setDeliveryLocation("12号楼");
orderDTO.setAmount(new BigDecimal("10.00"));
Order createdOrder = orderService.createOrder(orderDTO);
assertEquals(OrderStatus.PENDING, createdOrder.getStatus());
// 2. 分配配送员
Order assignedOrder = orderService.assignDeliverer(createdOrder.getId(), 2L);
assertEquals(OrderStatus.ACCEPTED, assignedOrder.getStatus());
assertEquals(2L, assignedOrder.getDelivererId());
// 3. 处理支付
PaymentRequestDTO paymentRequestDTO = new PaymentRequestDTO();
paymentRequestDTO.setOrderCode(assignedOrder.getOrderCode());
paymentRequestDTO.setAmount(assignedOrder.getAmount());
paymentRequestDTO.setPaymentMethod("微信支付");
paymentRequestDTO.setUserId(assignedOrder.getUserId());
PaymentResponseDTO paymentResponse = orderService.processPayment(paymentRequestDTO);
assertTrue(paymentResponse.isSuccess());
Order paidOrder = orderService.findOrderById(assignedOrder.getId());
assertEquals(OrderStatus.PAID, paidOrder.getStatus());
// 4. 更新为配送中
Order inTransitOrder = orderService.updateOrderStatus(paidOrder.getId(), OrderStatus.IN_TRANSIT);
assertEquals(OrderStatus.IN_TRANSIT, inTransitOrder.getStatus());
// 5. 更新为已送达
Order deliveredOrder = orderService.updateOrderStatus(inTransitOrder.getId(), OrderStatus.DELIVERED);
assertEquals(OrderStatus.DELIVERED, deliveredOrder.getStatus());
}
@Test
@DisplayName("测试订单取消流程")
void testOrderCancellationFlow() {
// 1. 创建订单
OrderDTO orderDTO = new OrderDTO();
orderDTO.setUserId(1L);
orderDTO.setPickupLocation("图书馆");
orderDTO.setDeliveryLocation("12号楼");
orderDTO.setAmount(new BigDecimal("10.00"));
Order createdOrder = orderService.createOrder(orderDTO);
assertEquals(OrderStatus.PENDING, createdOrder.getStatus());
// 2. 取消订单
boolean cancellationResult = orderService.cancelOrder(createdOrder.getId(), 1L);
assertTrue(cancellationResult);
// 3. 验证订单状态
Order cancelledOrder = orderService.findOrderById(createdOrder.getId());
assertEquals(OrderStatus.CANCELLED, cancelledOrder.getStatus());
}
@Test
@DisplayName("测试支付金额与订单金额不符")
void testPaymentAmountMismatch() {
// 1. 创建订单
OrderDTO orderDTO = new OrderDTO();
orderDTO.setUserId(1L);
orderDTO.setPickupLocation("图书馆");
orderDTO.setDeliveryLocation("12号楼");
orderDTO.setAmount(new BigDecimal("10.00"));
Order createdOrder = orderService.createOrder(orderDTO);
// 2. 尝试用不同金额支付
PaymentRequestDTO paymentRequestDTO = new PaymentRequestDTO();
paymentRequestDTO.setOrderCode(createdOrder.getOrderCode());
paymentRequestDTO.setAmount(new BigDecimal("20.00")); // 金额不符
paymentRequestDTO.setPaymentMethod("微信支付");
paymentRequestDTO.setUserId(createdOrder.getUserId());
// 验证抛出异常
Exception exception = assertThrows(Exception.class, () -> {
orderService.processPayment(paymentRequestDTO);
});
assertEquals("支付金额与订单金额不符", exception.getMessage());
}
}

@ -0,0 +1,233 @@
package com.campusdelivery.system;
import com.campusdelivery.controller.OrderController;
import com.campusdelivery.dto.OrderDTO;
import com.campusdelivery.dto.PaymentRequestDTO;
import com.campusdelivery.dto.PaymentResponseDTO;
import com.campusdelivery.model.Order;
import com.campusdelivery.model.OrderStatus;
import com.campusdelivery.repository.OrderRepository;
import com.campusdelivery.repository.impl.InMemoryOrderRepository;
import com.campusdelivery.service.OrderService;
import com.campusdelivery.service.PaymentService;
import com.campusdelivery.service.impl.OrderServiceImpl;
import com.campusdelivery.service.impl.PaymentServiceImpl;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.TestMethodOrder;
import java.math.BigDecimal;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
/**
*
*/
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class OrderManagementSystemTest {
private OrderRepository orderRepository;
private PaymentService paymentService;
private OrderService orderService;
private OrderController orderController;
@BeforeEach
void setUp() {
// 初始化完整的系统组件
orderRepository = new InMemoryOrderRepository();
paymentService = new PaymentServiceImpl();
orderService = new OrderServiceImpl(orderRepository, paymentService);
orderController = new OrderController(orderService);
}
@Test
@Order(1)
@DisplayName("测试系统初始化")
void testSystemInitialization() {
// 验证所有组件初始化成功
assertNotNull(orderRepository);
assertNotNull(paymentService);
assertNotNull(orderService);
assertNotNull(orderController);
// 验证初始状态下没有订单
List<Order> orders = orderController.findAllOrders();
assertTrue(orders.isEmpty());
}
@Test
@Order(2)
@DisplayName("测试完整的订单管理流程")
void testCompleteOrderManagementWorkflow() {
// 1. 创建订单
OrderDTO orderDTO = new OrderDTO();
orderDTO.setUserId(1L);
orderDTO.setPickupLocation("图书馆");
orderDTO.setDeliveryLocation("12号楼");
orderDTO.setAmount(new BigDecimal("10.00"));
Order createdOrder = orderController.createOrder(orderDTO);
assertNotNull(createdOrder);
assertEquals(OrderStatus.PENDING, createdOrder.getStatus());
// 2. 验证订单创建成功
List<Order> allOrders = orderController.findAllOrders();
assertEquals(1, allOrders.size());
assertEquals(createdOrder.getId(), allOrders.get(0).getId());
// 3. 分配配送员
Order assignedOrder = orderController.assignDeliverer(createdOrder.getId(), 2L);
assertEquals(OrderStatus.ACCEPTED, assignedOrder.getStatus());
assertEquals(2L, assignedOrder.getDelivererId());
// 4. 处理支付
PaymentRequestDTO paymentRequestDTO = new PaymentRequestDTO();
paymentRequestDTO.setOrderCode(assignedOrder.getOrderCode());
paymentRequestDTO.setAmount(assignedOrder.getAmount());
paymentRequestDTO.setPaymentMethod("微信支付");
paymentRequestDTO.setUserId(assignedOrder.getUserId());
PaymentResponseDTO paymentResponse = orderController.processPayment(paymentRequestDTO);
assertTrue(paymentResponse.isSuccess());
// 5. 验证支付后订单状态
Order paidOrder = orderController.findOrderById(assignedOrder.getId());
assertEquals(OrderStatus.PAID, paidOrder.getStatus());
assertEquals("微信支付", paidOrder.getPaymentMethod());
assertNotNull(paidOrder.getPaymentTransactionId());
// 6. 更新订单状态为配送中
Order inTransitOrder = orderController.updateOrderStatus(paidOrder.getId(), OrderStatus.IN_TRANSIT);
assertEquals(OrderStatus.IN_TRANSIT, inTransitOrder.getStatus());
// 7. 更新订单状态为已送达
Order deliveredOrder = orderController.updateOrderStatus(inTransitOrder.getId(), OrderStatus.DELIVERED);
assertEquals(OrderStatus.DELIVERED, deliveredOrder.getStatus());
// 8. 验证最终订单状态
Order finalOrder = orderController.findOrderById(deliveredOrder.getId());
assertEquals(OrderStatus.DELIVERED, finalOrder.getStatus());
}
@Test
@Order(3)
@DisplayName("测试订单查询功能")
void testOrderQueryFunctions() {
// 创建多个订单用于测试
createTestOrders();
// 1. 按用户ID查询
List<Order> userOrders = orderController.findOrdersByUserId(1L);
assertEquals(2, userOrders.size());
// 2. 按配送员ID查询
List<Order> delivererOrders = orderController.findOrdersByDelivererId(2L);
assertEquals(1, delivererOrders.size());
// 3. 查询待接单订单
List<Order> pendingOrders = orderController.findPendingOrders();
assertEquals(1, pendingOrders.size());
// 4. 按订单号查询
Order order = orderController.findOrderByCode("ORD_TEST_1");
assertNotNull(order);
assertEquals("ORD_TEST_1", order.getOrderCode());
}
@Test
@Order(4)
@DisplayName("测试订单取消功能")
void testOrderCancellation() {
// 创建测试订单
OrderDTO orderDTO = new OrderDTO();
orderDTO.setUserId(1L);
orderDTO.setPickupLocation("图书馆");
orderDTO.setDeliveryLocation("12号楼");
orderDTO.setAmount(new BigDecimal("10.00"));
Order createdOrder = orderController.createOrder(orderDTO);
// 取消订单
boolean cancellationResult = orderController.cancelOrder(createdOrder.getId(), 1L);
assertTrue(cancellationResult);
// 验证订单状态
Order cancelledOrder = orderController.findOrderById(createdOrder.getId());
assertEquals(OrderStatus.CANCELLED, cancelledOrder.getStatus());
// 验证无法再次取消已取消的订单
Exception exception = assertThrows(Exception.class, () -> {
orderController.cancelOrder(cancelledOrder.getId(), 1L);
});
assertNotNull(exception);
}
@Test
@Order(5)
@DisplayName("测试系统边界情况")
void testSystemBoundaryCases() {
// 1. 测试创建订单时的边界值
OrderDTO orderDTO = new OrderDTO();
orderDTO.setUserId(1L);
orderDTO.setPickupLocation(""); // 空的取货地点
orderDTO.setDeliveryLocation("12号楼");
orderDTO.setAmount(new BigDecimal("0.01")); // 最小金额
Order createdOrder = orderController.createOrder(orderDTO);
assertNotNull(createdOrder);
assertEquals("", createdOrder.getPickupLocation());
assertEquals(new BigDecimal("0.01"), createdOrder.getAmount());
// 2. 测试支付时的边界值
PaymentRequestDTO paymentRequestDTO = new PaymentRequestDTO();
paymentRequestDTO.setOrderCode(createdOrder.getOrderCode());
paymentRequestDTO.setAmount(createdOrder.getAmount());
paymentRequestDTO.setPaymentMethod("微信支付");
paymentRequestDTO.setUserId(createdOrder.getUserId());
PaymentResponseDTO paymentResponse = orderController.processPayment(paymentRequestDTO);
assertTrue(paymentResponse.isSuccess());
}
/**
*
*/
private void createTestOrders() {
// 创建第一个订单
Order order1 = new Order();
order1.setId(1L);
order1.setOrderCode("ORD_TEST_1");
order1.setUserId(1L);
order1.setDelivererId(2L);
order1.setPickupLocation("图书馆");
order1.setDeliveryLocation("12号楼");
order1.setAmount(new BigDecimal("10.00"));
order1.setStatus(OrderStatus.ACCEPTED);
orderRepository.save(order1);
// 创建第二个订单
Order order2 = new Order();
order2.setId(2L);
order2.setOrderCode("ORD_TEST_2");
order2.setUserId(1L);
order2.setPickupLocation("食堂");
order2.setDeliveryLocation("13号楼");
order2.setAmount(new BigDecimal("15.00"));
order2.setStatus(OrderStatus.PENDING);
orderRepository.save(order2);
// 创建第三个订单
Order order3 = new Order();
order3.setId(3L);
order3.setOrderCode("ORD_TEST_3");
order3.setUserId(2L);
order3.setPickupLocation("超市");
order3.setDeliveryLocation("14号楼");
order3.setAmount(new BigDecimal("20.00"));
order3.setStatus(OrderStatus.PENDING);
orderRepository.save(order3);
}
}

@ -0,0 +1,279 @@
package com.campusdelivery.system;
import com.campusdelivery.controller.OrderController;
import com.campusdelivery.dto.OrderDTO;
import com.campusdelivery.dto.PaymentRequestDTO;
import com.campusdelivery.dto.PaymentResponseDTO;
import com.campusdelivery.model.Order;
import com.campusdelivery.model.OrderStatus;
import com.campusdelivery.repository.OrderRepository;
import com.campusdelivery.repository.impl.InMemoryOrderRepository;
import com.campusdelivery.service.OrderService;
import com.campusdelivery.service.PaymentService;
import com.campusdelivery.service.impl.OrderServiceImpl;
import com.campusdelivery.service.impl.PaymentServiceImpl;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.math.BigDecimal;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
/**
*
* 使
*/
public class OrderPaymentSystemTest {
private OrderRepository orderRepository;
private PaymentService paymentService;
private OrderService orderService;
private OrderController orderController;
@BeforeEach
void setUp() {
// 初始化完整的系统组件
orderRepository = new InMemoryOrderRepository();
paymentService = new PaymentServiceImpl();
orderService = new OrderServiceImpl(orderRepository, paymentService);
orderController = new OrderController(orderService);
}
@Test
@DisplayName("系统测试:完整订单生命周期")
void testCompleteOrderLifecycle() {
System.out.println("=== 系统测试:完整订单生命周期 ===");
// 1. 创建订单
System.out.println("1. 创建订单");
OrderDTO orderDTO = new OrderDTO();
orderDTO.setUserId(1L);
orderDTO.setPickupLocation("图书馆");
orderDTO.setDeliveryLocation("12号楼");
orderDTO.setAmount(new BigDecimal("15.00"));
Order createdOrder = orderController.createOrder(orderDTO);
assertNotNull(createdOrder, "订单创建失败");
assertEquals(OrderStatus.PENDING, createdOrder.getStatus(), "订单状态应为待接单");
System.out.println("订单创建成功,订单号:" + createdOrder.getOrderCode());
// 2. 分配配送员
System.out.println("2. 分配配送员");
Order assignedOrder = orderController.assignDeliverer(createdOrder.getId(), 2L);
assertEquals(OrderStatus.ACCEPTED, assignedOrder.getStatus(), "订单状态应为已接单");
assertEquals(2L, assignedOrder.getDelivererId(), "配送员分配失败");
System.out.println("配送员已分配配送员ID" + assignedOrder.getDelivererId());
// 3. 支付订单
System.out.println("3. 支付订单");
PaymentRequestDTO paymentRequestDTO = new PaymentRequestDTO();
paymentRequestDTO.setOrderCode(assignedOrder.getOrderCode());
paymentRequestDTO.setAmount(assignedOrder.getAmount());
paymentRequestDTO.setPaymentMethod("微信支付");
paymentRequestDTO.setUserId(assignedOrder.getUserId());
PaymentResponseDTO paymentResponse = orderController.processPayment(paymentRequestDTO);
assertTrue(paymentResponse.isSuccess(), "支付失败");
System.out.println("支付成功交易ID" + paymentResponse.getTransactionId());
// 4. 验证支付状态
System.out.println("4. 验证支付状态");
Order paidOrder = orderController.findOrderById(assignedOrder.getId());
assertEquals(OrderStatus.PAID, paidOrder.getStatus(), "订单状态应为已支付");
assertEquals("微信支付", paidOrder.getPaymentMethod(), "支付方式设置失败");
assertNotNull(paidOrder.getPaymentTransactionId(), "交易ID未设置");
System.out.println("订单已支付,状态:" + paidOrder.getStatus().getDescription());
// 5. 开始配送
System.out.println("5. 开始配送");
Order inTransitOrder = orderController.updateOrderStatus(paidOrder.getId(), OrderStatus.IN_TRANSIT);
assertEquals(OrderStatus.IN_TRANSIT, inTransitOrder.getStatus(), "订单状态应为配送中");
System.out.println("订单状态已更新为配送中");
// 6. 完成配送
System.out.println("6. 完成配送");
Order deliveredOrder = orderController.updateOrderStatus(inTransitOrder.getId(), OrderStatus.DELIVERED);
assertEquals(OrderStatus.DELIVERED, deliveredOrder.getStatus(), "订单状态应为已送达");
System.out.println("订单已完成配送,状态:" + deliveredOrder.getStatus().getDescription());
// 7. 验证最终状态
System.out.println("7. 验证最终状态");
List<Order> allOrders = orderController.findAllOrders();
assertEquals(1, allOrders.size(), "订单数量不正确");
Order finalOrder = allOrders.get(0);
assertEquals(OrderStatus.DELIVERED, finalOrder.getStatus(), "最终订单状态应为已送达");
System.out.println("系统测试通过:完整订单生命周期成功");
}
@Test
@DisplayName("系统测试:多用户并发场景")
void testMultiUserConcurrentScenario() {
System.out.println("=== 系统测试:多用户并发场景 ===");
// 用户1创建订单
OrderDTO orderDTO1 = new OrderDTO();
orderDTO1.setUserId(1L);
orderDTO1.setPickupLocation("图书馆");
orderDTO1.setDeliveryLocation("12号楼");
orderDTO1.setAmount(new BigDecimal("15.00"));
Order order1 = orderController.createOrder(orderDTO1);
System.out.println("用户1创建订单成功订单号" + order1.getOrderCode());
// 用户2创建订单
OrderDTO orderDTO2 = new OrderDTO();
orderDTO2.setUserId(2L);
orderDTO2.setPickupLocation("食堂");
orderDTO2.setDeliveryLocation("13号楼");
orderDTO2.setAmount(new BigDecimal("10.00"));
Order order2 = orderController.createOrder(orderDTO2);
System.out.println("用户2创建订单成功订单号" + order2.getOrderCode());
// 分配配送员给两个订单
orderController.assignDeliverer(order1.getId(), 3L);
orderController.assignDeliverer(order2.getId(), 4L);
System.out.println("两个订单已分配配送员");
// 用户1支付订单
PaymentRequestDTO paymentRequestDTO1 = new PaymentRequestDTO();
paymentRequestDTO1.setOrderCode(order1.getOrderCode());
paymentRequestDTO1.setAmount(order1.getAmount());
paymentRequestDTO1.setPaymentMethod("微信支付");
paymentRequestDTO1.setUserId(order1.getUserId());
PaymentResponseDTO response1 = orderController.processPayment(paymentRequestDTO1);
assertTrue(response1.isSuccess(), "用户1支付失败");
System.out.println("用户1支付成功");
// 用户2支付订单
PaymentRequestDTO paymentRequestDTO2 = new PaymentRequestDTO();
paymentRequestDTO2.setOrderCode(order2.getOrderCode());
paymentRequestDTO2.setAmount(order2.getAmount());
paymentRequestDTO2.setPaymentMethod("支付宝");
paymentRequestDTO2.setUserId(order2.getUserId());
PaymentResponseDTO response2 = orderController.processPayment(paymentRequestDTO2);
assertTrue(response2.isSuccess(), "用户2支付失败");
System.out.println("用户2支付成功");
// 验证两个订单的状态
Order paidOrder1 = orderController.findOrderById(order1.getId());
Order paidOrder2 = orderController.findOrderById(order2.getId());
assertEquals(OrderStatus.PAID, paidOrder1.getStatus(), "用户1订单状态应为已支付");
assertEquals(OrderStatus.PAID, paidOrder2.getStatus(), "用户2订单状态应为已支付");
System.out.println("两个订单均已支付成功");
// 验证订单查询功能
List<Order> user1Orders = orderController.findOrdersByUserId(1L);
List<Order> user2Orders = orderController.findOrdersByUserId(2L);
assertEquals(1, user1Orders.size(), "用户1订单数量不正确");
assertEquals(1, user2Orders.size(), "用户2订单数量不正确");
System.out.println("订单查询功能正常");
System.out.println("系统测试通过:多用户并发场景成功");
}
@Test
@DisplayName("系统测试:异常处理与边界情况")
void testExceptionHandlingAndBoundaryCases() {
System.out.println("=== 系统测试:异常处理与边界情况 ===");
// 测试1无效的订单ID
System.out.println("测试1无效的订单ID");
Exception exception1 = assertThrows(Exception.class, () -> {
orderController.findOrderById(999L);
});
assertNotNull(exception1, "无效订单ID应该抛出异常");
System.out.println("无效订单ID处理成功");
// 测试2无效的状态转换
System.out.println("测试2无效的状态转换");
OrderDTO orderDTO = new OrderDTO();
orderDTO.setUserId(1L);
orderDTO.setPickupLocation("图书馆");
orderDTO.setDeliveryLocation("12号楼");
orderDTO.setAmount(new BigDecimal("15.00"));
Order order = orderController.createOrder(orderDTO);
Exception exception2 = assertThrows(Exception.class, () -> {
orderController.updateOrderStatus(order.getId(), OrderStatus.DELIVERED);
});
assertNotNull(exception2, "无效状态转换应该抛出异常");
System.out.println("无效状态转换处理成功");
// 测试3非订单创建者取消订单
System.out.println("测试3非订单创建者取消订单");
Exception exception3 = assertThrows(Exception.class, () -> {
orderController.cancelOrder(order.getId(), 999L);
});
assertNotNull(exception3, "非订单创建者取消订单应该失败");
System.out.println("非订单创建者取消订单处理成功");
// 测试4空订单列表
System.out.println("测试4空订单列表");
List<Order> emptyOrders = orderController.findOrdersByUserId(999L);
assertTrue(emptyOrders.isEmpty(), "不存在的用户应该返回空订单列表");
System.out.println("空订单列表处理成功");
// 测试5金额为0的订单
System.out.println("测试5金额为0的订单");
OrderDTO zeroAmountOrderDTO = new OrderDTO();
zeroAmountOrderDTO.setUserId(1L);
zeroAmountOrderDTO.setPickupLocation("图书馆");
zeroAmountOrderDTO.setDeliveryLocation("12号楼");
zeroAmountOrderDTO.setAmount(new BigDecimal("0.00"));
Order zeroAmountOrder = orderController.createOrder(zeroAmountOrderDTO);
assertNotNull(zeroAmountOrder, "金额为0的订单应该创建成功");
System.out.println("金额为0的订单创建成功");
System.out.println("系统测试通过:异常处理与边界情况成功");
}
@Test
@DisplayName("系统测试:订单状态流转验证")
void testOrderStatusFlowValidation() {
System.out.println("=== 系统测试:订单状态流转验证 ===");
// 创建测试订单
OrderDTO orderDTO = new OrderDTO();
orderDTO.setUserId(1L);
orderDTO.setPickupLocation("图书馆");
orderDTO.setDeliveryLocation("12号楼");
orderDTO.setAmount(new BigDecimal("15.00"));
Order order = orderController.createOrder(orderDTO);
System.out.println("初始状态:" + order.getStatus().getDescription());
// 验证状态流转PENDING -> ACCEPTED
order = orderController.assignDeliverer(order.getId(), 2L);
assertEquals(OrderStatus.ACCEPTED, order.getStatus(), "状态流转失败PENDING -> ACCEPTED");
System.out.println("状态流转PENDING -> ACCEPTED 成功");
// 验证状态流转ACCEPTED -> PAID
PaymentRequestDTO paymentRequestDTO = new PaymentRequestDTO();
paymentRequestDTO.setOrderCode(order.getOrderCode());
paymentRequestDTO.setAmount(order.getAmount());
paymentRequestDTO.setPaymentMethod("微信支付");
paymentRequestDTO.setUserId(order.getUserId());
orderController.processPayment(paymentRequestDTO);
order = orderController.findOrderById(order.getId());
assertEquals(OrderStatus.PAID, order.getStatus(), "状态流转失败ACCEPTED -> PAID");
System.out.println("状态流转ACCEPTED -> PAID 成功");
// 验证状态流转PAID -> IN_TRANSIT
order = orderController.updateOrderStatus(order.getId(), OrderStatus.IN_TRANSIT);
assertEquals(OrderStatus.IN_TRANSIT, order.getStatus(), "状态流转失败PAID -> IN_TRANSIT");
System.out.println("状态流转PAID -> IN_TRANSIT 成功");
// 验证状态流转IN_TRANSIT -> DELIVERED
order = orderController.updateOrderStatus(order.getId(), OrderStatus.DELIVERED);
assertEquals(OrderStatus.DELIVERED, order.getStatus(), "状态流转失败IN_TRANSIT -> DELIVERED");
System.out.println("状态流转IN_TRANSIT -> DELIVERED 成功");
// 验证已完成订单不能再修改状态
Exception exception = assertThrows(Exception.class, () -> {
orderController.updateOrderStatus(order.getId(), OrderStatus.CANCELLED);
});
assertNotNull(exception, "已完成订单应该不能再修改状态");
System.out.println("已完成订单状态变更验证成功");
System.out.println("系统测试通过:订单状态流转验证成功");
}
}

@ -0,0 +1,287 @@
package com.campusdelivery.unit;
import com.campusdelivery.dto.OrderDTO;
import com.campusdelivery.dto.PaymentRequestDTO;
import com.campusdelivery.dto.PaymentResponseDTO;
import com.campusdelivery.exception.OrderException;
import com.campusdelivery.model.Order;
import com.campusdelivery.model.OrderStatus;
import com.campusdelivery.repository.OrderRepository;
import com.campusdelivery.service.OrderService;
import com.campusdelivery.service.PaymentService;
import com.campusdelivery.service.impl.OrderServiceImpl;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.math.BigDecimal;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
/**
*
*/
public class OrderServiceTest {
@Mock
private OrderRepository orderRepository;
@Mock
private PaymentService paymentService;
private OrderService orderService;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
orderService = new OrderServiceImpl(orderRepository, paymentService);
}
@Test
@DisplayName("测试创建订单")
void testCreateOrder() {
// 准备测试数据
OrderDTO orderDTO = new OrderDTO();
orderDTO.setUserId(1L);
orderDTO.setPickupLocation("图书馆");
orderDTO.setDeliveryLocation("12号楼");
orderDTO.setAmount(new BigDecimal("10.00"));
Order expectedOrder = new Order();
expectedOrder.setId(1L);
expectedOrder.setUserId(1L);
expectedOrder.setPickupLocation("图书馆");
expectedOrder.setDeliveryLocation("12号楼");
expectedOrder.setAmount(new BigDecimal("10.00"));
expectedOrder.setStatus(OrderStatus.PENDING);
expectedOrder.setOrderCode("ORD20240101000000ABCDEF");
// 模拟行为
when(orderRepository.save(any(Order.class))).thenReturn(expectedOrder);
// 执行测试
Order actualOrder = orderService.createOrder(orderDTO);
// 验证结果
assertNotNull(actualOrder);
assertEquals(expectedOrder.getId(), actualOrder.getId());
assertEquals(expectedOrder.getUserId(), actualOrder.getUserId());
assertEquals(expectedOrder.getPickupLocation(), actualOrder.getPickupLocation());
assertEquals(expectedOrder.getDeliveryLocation(), actualOrder.getDeliveryLocation());
assertEquals(expectedOrder.getAmount(), actualOrder.getAmount());
assertEquals(expectedOrder.getStatus(), actualOrder.getStatus());
verify(orderRepository, times(1)).save(any(Order.class));
}
@Test
@DisplayName("测试处理支付成功")
void testProcessPaymentSuccess() {
// 准备测试数据
String orderCode = "ORD20240101000000ABCDEF";
BigDecimal amount = new BigDecimal("10.00");
PaymentRequestDTO paymentRequestDTO = new PaymentRequestDTO();
paymentRequestDTO.setOrderCode(orderCode);
paymentRequestDTO.setAmount(amount);
paymentRequestDTO.setPaymentMethod("微信支付");
paymentRequestDTO.setUserId(1L);
Order order = new Order();
order.setId(1L);
order.setOrderCode(orderCode);
order.setUserId(1L);
order.setAmount(amount);
order.setStatus(OrderStatus.PENDING);
PaymentResponseDTO expectedResponse = new PaymentResponseDTO();
expectedResponse.setSuccess(true);
expectedResponse.setMessage("支付成功");
expectedResponse.setOrderCode(orderCode);
expectedResponse.setTransactionId("TXN1234567890");
// 模拟行为
when(orderRepository.findByOrderCode(orderCode)).thenReturn(Optional.of(order));
when(paymentService.processPayment(paymentRequestDTO)).thenReturn(expectedResponse);
when(orderRepository.save(any(Order.class))).thenReturn(order);
// 执行测试
PaymentResponseDTO actualResponse = orderService.processPayment(paymentRequestDTO);
// 验证结果
assertNotNull(actualResponse);
assertTrue(actualResponse.isSuccess());
assertEquals(expectedResponse.getMessage(), actualResponse.getMessage());
assertEquals(expectedResponse.getOrderCode(), actualResponse.getOrderCode());
assertEquals(expectedResponse.getTransactionId(), actualResponse.getTransactionId());
assertEquals(OrderStatus.PAID, order.getStatus());
verify(orderRepository, times(1)).findByOrderCode(orderCode);
verify(paymentService, times(1)).processPayment(paymentRequestDTO);
verify(orderRepository, times(1)).save(order);
}
@Test
@DisplayName("测试处理支付失败")
void testProcessPaymentFailure() {
// 准备测试数据
String orderCode = "ORD20240101000000ABCDEF";
BigDecimal amount = new BigDecimal("10.00");
PaymentRequestDTO paymentRequestDTO = new PaymentRequestDTO();
paymentRequestDTO.setOrderCode(orderCode);
paymentRequestDTO.setAmount(amount);
paymentRequestDTO.setPaymentMethod("微信支付");
paymentRequestDTO.setUserId(1L);
Order order = new Order();
order.setId(1L);
order.setOrderCode(orderCode);
order.setUserId(1L);
order.setAmount(amount);
order.setStatus(OrderStatus.PENDING);
PaymentResponseDTO expectedResponse = new PaymentResponseDTO();
expectedResponse.setSuccess(false);
expectedResponse.setMessage("支付失败");
expectedResponse.setOrderCode(orderCode);
expectedResponse.setTransactionId(null);
// 模拟行为
when(orderRepository.findByOrderCode(orderCode)).thenReturn(Optional.of(order));
when(paymentService.processPayment(paymentRequestDTO)).thenReturn(expectedResponse);
// 执行测试
PaymentResponseDTO actualResponse = orderService.processPayment(paymentRequestDTO);
// 验证结果
assertNotNull(actualResponse);
assertFalse(actualResponse.isSuccess());
assertEquals(expectedResponse.getMessage(), actualResponse.getMessage());
assertEquals(OrderStatus.PENDING, order.getStatus());
verify(orderRepository, times(1)).findByOrderCode(orderCode);
verify(paymentService, times(1)).processPayment(paymentRequestDTO);
verify(orderRepository, never()).save(any(Order.class));
}
@Test
@DisplayName("测试更新订单状态")
void testUpdateOrderStatus() {
// 准备测试数据
Long orderId = 1L;
Order order = new Order();
order.setId(orderId);
order.setStatus(OrderStatus.PENDING);
// 模拟行为
when(orderRepository.findById(orderId)).thenReturn(Optional.of(order));
when(orderRepository.save(order)).thenReturn(order);
// 执行测试
Order updatedOrder = orderService.updateOrderStatus(orderId, OrderStatus.ACCEPTED);
// 验证结果
assertNotNull(updatedOrder);
assertEquals(OrderStatus.ACCEPTED, updatedOrder.getStatus());
verify(orderRepository, times(1)).findById(orderId);
verify(orderRepository, times(1)).save(order);
}
@Test
@DisplayName("测试更新订单状态失败 - 状态转换不合法")
void testUpdateOrderStatusFailure_InvalidTransition() {
// 准备测试数据
Long orderId = 1L;
Order order = new Order();
order.setId(orderId);
order.setStatus(OrderStatus.DELIVERED);
// 模拟行为
when(orderRepository.findById(orderId)).thenReturn(Optional.of(order));
// 执行测试并验证异常
assertThrows(OrderException.class, () -> {
orderService.updateOrderStatus(orderId, OrderStatus.PENDING);
});
// 验证结果
verify(orderRepository, times(1)).findById(orderId);
verify(orderRepository, never()).save(any(Order.class));
}
@Test
@DisplayName("测试分配配送员")
void testAssignDeliverer() {
// 准备测试数据
Long orderId = 1L;
Long delivererId = 2L;
Order order = new Order();
order.setId(orderId);
order.setStatus(OrderStatus.PENDING);
// 模拟行为
when(orderRepository.findById(orderId)).thenReturn(Optional.of(order));
when(orderRepository.save(order)).thenReturn(order);
// 执行测试
Order updatedOrder = orderService.assignDeliverer(orderId, delivererId);
// 验证结果
assertNotNull(updatedOrder);
assertEquals(delivererId, updatedOrder.getDelivererId());
assertEquals(OrderStatus.ACCEPTED, updatedOrder.getStatus());
verify(orderRepository, times(1)).findById(orderId);
verify(orderRepository, times(1)).save(order);
}
@Test
@DisplayName("测试取消订单")
void testCancelOrder() {
// 准备测试数据
Long orderId = 1L;
Long userId = 1L;
Order order = new Order();
order.setId(orderId);
order.setUserId(userId);
order.setStatus(OrderStatus.PENDING);
// 模拟行为
when(orderRepository.findById(orderId)).thenReturn(Optional.of(order));
when(orderRepository.save(order)).thenReturn(order);
// 执行测试
boolean result = orderService.cancelOrder(orderId, userId);
// 验证结果
assertTrue(result);
assertEquals(OrderStatus.CANCELLED, order.getStatus());
verify(orderRepository, times(1)).findById(orderId);
verify(orderRepository, times(1)).save(order);
}
@Test
@DisplayName("测试取消订单失败 - 无权取消")
void testCancelOrderFailure_Unauthorized() {
// 准备测试数据
Long orderId = 1L;
Long userId = 1L;
Long wrongUserId = 2L;
Order order = new Order();
order.setId(orderId);
order.setUserId(userId);
order.setStatus(OrderStatus.PENDING);
// 模拟行为
when(orderRepository.findById(orderId)).thenReturn(Optional.of(order));
// 执行测试并验证异常
assertThrows(OrderException.class, () -> {
orderService.cancelOrder(orderId, wrongUserId);
});
// 验证结果
verify(orderRepository, times(1)).findById(orderId);
verify(orderRepository, never()).save(any(Order.class));
}
}

@ -0,0 +1,186 @@
package com.campusdelivery.unit;
import com.campusdelivery.dto.PaymentRequestDTO;
import com.campusdelivery.dto.PaymentResponseDTO;
import com.campusdelivery.exception.PaymentException;
import com.campusdelivery.service.impl.PaymentServiceImpl;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.math.BigDecimal;
import static org.junit.jupiter.api.Assertions.*;
/**
*
*/
public class PaymentServiceTest {
private PaymentServiceImpl paymentService;
@BeforeEach
void setUp() {
paymentService = new PaymentServiceImpl();
}
@Test
@DisplayName("测试处理支付成功")
void testProcessPaymentSuccess() {
// 准备测试数据
PaymentRequestDTO paymentRequestDTO = new PaymentRequestDTO();
paymentRequestDTO.setOrderCode("ORD20240101000000ABCDEF");
paymentRequestDTO.setAmount(new BigDecimal("10.00"));
paymentRequestDTO.setPaymentMethod("微信支付");
paymentRequestDTO.setUserId(1L);
// 执行测试
PaymentResponseDTO response = paymentService.processPayment(paymentRequestDTO);
// 验证结果
assertNotNull(response);
assertTrue(response.isSuccess());
assertEquals("支付成功", response.getMessage());
assertEquals(paymentRequestDTO.getOrderCode(), response.getOrderCode());
assertNotNull(response.getTransactionId());
}
@Test
@DisplayName("测试处理支付失败 - 订单号为空")
void testProcessPaymentFailure_EmptyOrderCode() {
// 准备测试数据
PaymentRequestDTO paymentRequestDTO = new PaymentRequestDTO();
paymentRequestDTO.setOrderCode("");
paymentRequestDTO.setAmount(new BigDecimal("10.00"));
paymentRequestDTO.setPaymentMethod("微信支付");
paymentRequestDTO.setUserId(1L);
// 执行测试并验证异常
PaymentException exception = assertThrows(PaymentException.class, () -> {
paymentService.processPayment(paymentRequestDTO);
});
// 验证结果
assertEquals("订单号不能为空", exception.getMessage());
}
@Test
@DisplayName("测试处理支付失败 - 金额小于等于0")
void testProcessPaymentFailure_InvalidAmount() {
// 准备测试数据
PaymentRequestDTO paymentRequestDTO = new PaymentRequestDTO();
paymentRequestDTO.setOrderCode("ORD20240101000000ABCDEF");
paymentRequestDTO.setAmount(new BigDecimal("0.00"));
paymentRequestDTO.setPaymentMethod("微信支付");
paymentRequestDTO.setUserId(1L);
// 执行测试并验证异常
PaymentException exception = assertThrows(PaymentException.class, () -> {
paymentService.processPayment(paymentRequestDTO);
});
// 验证结果
assertEquals("支付金额必须大于0", exception.getMessage());
}
@Test
@DisplayName("测试处理支付失败 - 支付方式为空")
void testProcessPaymentFailure_EmptyPaymentMethod() {
// 准备测试数据
PaymentRequestDTO paymentRequestDTO = new PaymentRequestDTO();
paymentRequestDTO.setOrderCode("ORD20240101000000ABCDEF");
paymentRequestDTO.setAmount(new BigDecimal("10.00"));
paymentRequestDTO.setPaymentMethod("");
paymentRequestDTO.setUserId(1L);
// 执行测试并验证异常
PaymentException exception = assertThrows(PaymentException.class, () -> {
paymentService.processPayment(paymentRequestDTO);
});
// 验证结果
assertEquals("支付方式不能为空", exception.getMessage());
}
@Test
@DisplayName("测试处理支付失败 - 用户ID为空")
void testProcessPaymentFailure_NullUserId() {
// 准备测试数据
PaymentRequestDTO paymentRequestDTO = new PaymentRequestDTO();
paymentRequestDTO.setOrderCode("ORD20240101000000ABCDEF");
paymentRequestDTO.setAmount(new BigDecimal("10.00"));
paymentRequestDTO.setPaymentMethod("微信支付");
paymentRequestDTO.setUserId(null);
// 执行测试并验证异常
PaymentException exception = assertThrows(PaymentException.class, () -> {
paymentService.processPayment(paymentRequestDTO);
});
// 验证结果
assertEquals("用户ID不能为空", exception.getMessage());
}
@Test
@DisplayName("测试验证支付状态成功")
void testVerifyPaymentStatusSuccess() {
// 准备测试数据
PaymentRequestDTO paymentRequestDTO = new PaymentRequestDTO();
paymentRequestDTO.setOrderCode("ORD20240101000000ABCDEF");
paymentRequestDTO.setAmount(new BigDecimal("10.00"));
paymentRequestDTO.setPaymentMethod("微信支付");
paymentRequestDTO.setUserId(1L);
// 先处理支付
PaymentResponseDTO response = paymentService.processPayment(paymentRequestDTO);
String transactionId = response.getTransactionId();
// 验证支付状态
boolean status = paymentService.verifyPaymentStatus(transactionId);
// 验证结果
assertTrue(status);
}
@Test
@DisplayName("测试验证支付状态失败 - 交易不存在")
void testVerifyPaymentStatusFailure_TransactionNotFound() {
// 验证不存在的交易
boolean status = paymentService.verifyPaymentStatus("TXN1234567890");
// 验证结果
assertFalse(status);
}
@Test
@DisplayName("测试退款成功")
void testRefundSuccess() {
// 准备测试数据
PaymentRequestDTO paymentRequestDTO = new PaymentRequestDTO();
paymentRequestDTO.setOrderCode("ORD20240101000000ABCDEF");
paymentRequestDTO.setAmount(new BigDecimal("10.00"));
paymentRequestDTO.setPaymentMethod("微信支付");
paymentRequestDTO.setUserId(1L);
// 先处理支付
PaymentResponseDTO response = paymentService.processPayment(paymentRequestDTO);
String transactionId = response.getTransactionId();
// 执行退款
boolean result = paymentService.refund(transactionId, 10.00);
// 验证结果
assertTrue(result);
}
@Test
@DisplayName("测试退款失败 - 交易不存在")
void testRefundFailure_TransactionNotFound() {
// 执行退款
PaymentException exception = assertThrows(PaymentException.class, () -> {
paymentService.refund("TXN1234567890", 10.00);
});
// 验证结果
assertEquals("交易不存在", exception.getMessage());
}
}

@ -0,0 +1,81 @@
<?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.campus.delivery</groupId>
<artifactId>campus-delivery-system</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- JUnit测试框架 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!-- 添加日志依赖 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.36</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 编译插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<!-- 打包插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifest>
<mainClass>com.campus.delivery.view.OrderPaymentView</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,164 @@
package com.campus.delivery;
import com.campus.delivery.controller.OrderController;
import com.campus.delivery.controller.PaymentController;
/**
*
* JUnit
*/
public class ManualOrderPaymentTest {
public static void main(String[] args) {
System.out.println("==================================");
System.out.println(" 订单支付与管理功能手动测试程序");
System.out.println("==================================");
System.out.println();
// 创建控制器实例
OrderController orderController = new OrderController();
PaymentController paymentController = new PaymentController();
int testCount = 0;
int passCount = 0;
// 测试1创建订单
System.out.println("测试1创建订单");
testCount++;
String createResult = orderController.createOrder(1001, 2001, "取快递", 5.0);
if (createResult.contains("订单创建成功")) {
System.out.println("✅ 测试通过: " + createResult);
passCount++;
} else {
System.out.println("❌ 测试失败: " + createResult);
}
System.out.println();
// 提取订单ID
int orderId = extractOrderId(createResult);
// 测试2查询订单详情
System.out.println("测试2查询订单详情");
testCount++;
String detailResult = orderController.getOrderDetail(orderId);
if (detailResult.contains("订单详情") && detailResult.contains(String.valueOf(orderId))) {
System.out.println("✅ 测试通过");
passCount++;
} else {
System.out.println("❌ 测试失败: " + detailResult);
}
System.out.println();
// 测试3发起支付
System.out.println("测试3发起支付");
testCount++;
String paymentResult = paymentController.processPayment(orderId, "WECHAT_PAY");
if (paymentResult.contains("支付处理成功")) {
System.out.println("✅ 测试通过: " + paymentResult);
passCount++;
} else {
System.out.println("❌ 测试失败: " + paymentResult);
}
System.out.println();
// 提取支付ID
int paymentId = extractPaymentId(paymentResult);
// 测试4确认支付成功
System.out.println("测试4确认支付成功");
testCount++;
String confirmResult = paymentController.confirmPaymentSuccess(paymentId);
if (confirmResult.contains("支付确认成功")) {
System.out.println("✅ 测试通过: " + confirmResult);
passCount++;
} else {
System.out.println("❌ 测试失败: " + confirmResult);
}
System.out.println();
// 测试5验证订单状态已更新为PAID
System.out.println("测试5验证订单状态已更新为PAID");
testCount++;
String updatedDetail = orderController.getOrderDetail(orderId);
if (updatedDetail.contains("PAID")) {
System.out.println("✅ 测试通过: 订单状态已更新为PAID");
passCount++;
} else {
System.out.println("❌ 测试失败: 订单状态未更新为PAID");
System.out.println("当前订单详情: " + updatedDetail);
}
System.out.println();
// 测试6完成订单
System.out.println("测试6完成订单");
testCount++;
String completeResult = orderController.completeOrder(orderId);
if (completeResult.contains("订单完成成功")) {
System.out.println("✅ 测试通过: " + completeResult);
passCount++;
} else {
System.out.println("❌ 测试失败: " + completeResult);
}
System.out.println();
// 测试7查询用户订单列表
System.out.println("测试7查询用户订单列表");
testCount++;
String userOrders = orderController.getUserOrders(1001);
if (userOrders.contains("用户订单列表") && !userOrders.contains("没有订单")) {
System.out.println("✅ 测试通过: 查询到用户订单");
passCount++;
} else {
System.out.println("❌ 测试失败: " + userOrders);
}
System.out.println();
// 测试8测试无效订单ID
System.out.println("测试8测试无效订单ID");
testCount++;
String invalidOrderResult = orderController.getOrderDetail(99999);
if (invalidOrderResult.contains("失败")) {
System.out.println("✅ 测试通过: 正确处理了无效订单ID");
passCount++;
} else {
System.out.println("❌ 测试失败: " + invalidOrderResult);
}
System.out.println();
// 测试结果汇总
System.out.println("==================================");
System.out.println("测试结果汇总:");
System.out.println("总测试数: " + testCount);
System.out.println("通过测试数: " + passCount);
System.out.println("失败测试数: " + (testCount - passCount));
System.out.println("测试通过率: " + String.format("%.1f%%", (double) passCount / testCount * 100));
System.out.println("==================================");
if (passCount == testCount) {
System.out.println("🎉 所有测试通过!订单支付与管理功能正常工作。");
} else {
System.out.println("⚠️ 部分测试失败,请检查相关功能。");
}
}
/**
* ID
*/
private static int extractOrderId(String createResult) {
if (createResult.contains("订单ID")) {
return Integer.parseInt(createResult.split("订单ID")[1].trim());
}
return -1;
}
/**
* ID
*/
private static int extractPaymentId(String paymentResult) {
if (paymentResult.contains("支付ID")) {
String part = paymentResult.split("支付ID")[1];
return Integer.parseInt(part.split("")[0].trim());
}
return -1;
}
}

@ -0,0 +1,131 @@
package com.campus.delivery.controller;
import com.campus.delivery.entity.Order;
import com.campus.delivery.service.OrderService;
import com.campus.delivery.service.OrderServiceImpl;
import java.util.List;
public class OrderController {
private OrderService orderService;
public OrderController() {
this.orderService = new OrderServiceImpl();
}
/**
*
* @param userId ID
* @param deliverId ID
* @param description
* @param amount
* @return
*/
public String createOrder(int userId, int deliverId, String description, double amount) {
try {
int orderId = orderService.createOrder(userId, deliverId, description, amount);
return "订单创建成功订单ID" + orderId;
} catch (Exception e) {
return "订单创建失败:" + e.getMessage();
}
}
/**
*
* @param orderId ID
* @return
*/
public String getOrderDetail(int orderId) {
try {
Order order = orderService.getOrderDetail(orderId);
return "订单详情:" + order.toString();
} catch (Exception e) {
return "获取订单详情失败:" + e.getMessage();
}
}
/**
*
* @param userId ID
* @return
*/
public String getUserOrders(int userId) {
try {
List<Order> orders = orderService.getUserOrders(userId);
if (orders.isEmpty()) {
return "该用户没有订单";
}
StringBuilder sb = new StringBuilder("用户订单列表:\n");
for (Order order : orders) {
sb.append(order.toString()).append("\n");
}
return sb.toString();
} catch (Exception e) {
return "获取用户订单失败:" + e.getMessage();
}
}
/**
*
* @param deliverId ID
* @return
*/
public String getDeliverOrders(int deliverId) {
try {
List<Order> orders = orderService.getDeliverOrders(deliverId);
if (orders.isEmpty()) {
return "该配送员没有订单";
}
StringBuilder sb = new StringBuilder("配送员订单列表:\n");
for (Order order : orders) {
sb.append(order.toString()).append("\n");
}
return sb.toString();
} catch (Exception e) {
return "获取配送员订单失败:" + e.getMessage();
}
}
/**
*
* @param orderId ID
* @param status
* @return
*/
public String updateOrderStatus(int orderId, String status) {
try {
boolean result = orderService.updateOrderStatus(orderId, status);
return result ? "订单状态更新成功" : "订单状态更新失败";
} catch (Exception e) {
return "更新订单状态失败:" + e.getMessage();
}
}
/**
*
* @param orderId ID
* @return
*/
public String cancelOrder(int orderId) {
try {
boolean result = orderService.cancelOrder(orderId);
return result ? "订单取消成功" : "订单取消失败,可能是订单状态不允许取消";
} catch (Exception e) {
return "取消订单失败:" + e.getMessage();
}
}
/**
*
* @param orderId ID
* @return
*/
public String completeOrder(int orderId) {
try {
boolean result = orderService.completeOrder(orderId);
return result ? "订单完成成功" : "订单完成失败,可能是订单状态不允许完成";
} catch (Exception e) {
return "完成订单失败:" + e.getMessage();
}
}
}

@ -0,0 +1,111 @@
package com.campus.delivery.controller;
import com.campus.delivery.entity.Payment;
import com.campus.delivery.service.PaymentService;
import com.campus.delivery.service.PaymentServiceImpl;
import java.util.List;
import java.util.UUID;
public class PaymentController {
private PaymentService paymentService;
public PaymentController() {
this.paymentService = new PaymentServiceImpl();
}
/**
*
* @param orderId ID
* @param paymentMethod
* @return
*/
public String processPayment(int orderId, String paymentMethod) {
try {
int paymentId = paymentService.processPayment(orderId, paymentMethod);
return "支付处理成功支付ID" + paymentId + ",请完成支付确认。";
} catch (Exception e) {
return "支付处理失败:" + e.getMessage();
}
}
/**
*
* @param paymentId ID
* @return
*/
public String getPaymentDetail(int paymentId) {
try {
Payment payment = paymentService.getPaymentDetail(paymentId);
return "支付详情:" + payment.toString();
} catch (Exception e) {
return "获取支付详情失败:" + e.getMessage();
}
}
/**
*
* @param orderId ID
* @return
*/
public String getPaymentByOrderId(int orderId) {
try {
Payment payment = paymentService.getPaymentByOrderId(orderId);
return "订单支付记录:" + payment.toString();
} catch (Exception e) {
return "获取订单支付记录失败:" + e.getMessage();
}
}
/**
*
* @param paymentId ID
* @return
*/
public String confirmPaymentSuccess(int paymentId) {
try {
// 生成模拟交易ID
String transactionId = "TXN_" + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
boolean result = paymentService.confirmPaymentSuccess(paymentId, transactionId);
return result ? "支付确认成功交易ID" + transactionId : "支付确认失败";
} catch (Exception e) {
return "支付确认失败:" + e.getMessage();
}
}
/**
*
* @param paymentId ID
* @param reason
* @return
*/
public String handlePaymentFailure(int paymentId, String reason) {
try {
boolean result = paymentService.handlePaymentFailure(paymentId, reason);
return result ? "支付失败处理成功" : "支付失败处理失败";
} catch (Exception e) {
return "处理支付失败时出错:" + e.getMessage();
}
}
/**
*
* @param userId ID
* @return
*/
public String getUserPayments(int userId) {
try {
List<Payment> payments = paymentService.getUserPayments(userId);
if (payments.isEmpty()) {
return "该用户没有支付记录";
}
StringBuilder sb = new StringBuilder("用户支付记录列表:\n");
for (Payment payment : payments) {
sb.append(payment.toString()).append("\n");
}
return sb.toString();
} catch (Exception e) {
return "获取用户支付记录失败:" + e.getMessage();
}
}
}

@ -0,0 +1,64 @@
package com.campus.delivery.dao;
import com.campus.delivery.entity.Order;
import java.util.List;
public interface OrderDAO {
/**
*
* @param order
* @return ID
*/
int createOrder(Order order);
/**
* ID
* @param id ID
* @return
*/
Order getOrderById(int id);
/**
* ID
* @param userId ID
* @return
*/
List<Order> getOrdersByUserId(int userId);
/**
* ID
* @param deliverId ID
* @return
*/
List<Order> getOrdersByDeliverId(int deliverId);
/**
*
* @param id ID
* @param status
* @return
*/
boolean updateOrderStatus(int id, String status);
/**
*
* @param id ID
* @param paymentMethod
* @return
*/
boolean updateOrderPayment(int id, String paymentMethod);
/**
*
* @param id ID
* @return
*/
boolean deleteOrder(int id);
/**
*
* @return
*/
List<Order> getAllOrders();
}

@ -0,0 +1,89 @@
package com.campus.delivery.dao;
import com.campus.delivery.entity.Order;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class OrderDAOImpl implements OrderDAO {
private static List<Order> orderList = new ArrayList<>();
private static AtomicInteger nextId = new AtomicInteger(1);
@Override
public int createOrder(Order order) {
int id = nextId.getAndIncrement();
order.setId(id);
order.setCreateTime(new Date());
orderList.add(order);
return id;
}
@Override
public Order getOrderById(int id) {
for (Order order : orderList) {
if (order.getId() == id) {
return order;
}
}
return null;
}
@Override
public List<Order> getOrdersByUserId(int userId) {
List<Order> result = new ArrayList<>();
for (Order order : orderList) {
if (order.getUserId() == userId) {
result.add(order);
}
}
return result;
}
@Override
public List<Order> getOrdersByDeliverId(int deliverId) {
List<Order> result = new ArrayList<>();
for (Order order : orderList) {
if (order.getDeliverId() == deliverId) {
result.add(order);
}
}
return result;
}
@Override
public boolean updateOrderStatus(int id, String status) {
Order order = getOrderById(id);
if (order != null) {
order.setStatus(status);
if ("PAID".equals(status)) {
order.setPaymentTime(new Date());
} else if ("COMPLETED".equals(status)) {
order.setFinishTime(new Date());
}
return true;
}
return false;
}
@Override
public boolean updateOrderPayment(int id, String paymentMethod) {
Order order = getOrderById(id);
if (order != null) {
order.setPaymentMethod(paymentMethod);
return true;
}
return false;
}
@Override
public boolean deleteOrder(int id) {
return orderList.removeIf(order -> order.getId() == id);
}
@Override
public List<Order> getAllOrders() {
return new ArrayList<>(orderList);
}
}

@ -0,0 +1,50 @@
package com.campus.delivery.dao;
import com.campus.delivery.entity.Payment;
import java.util.List;
public interface PaymentDAO {
/**
*
* @param payment
* @return ID
*/
int createPayment(Payment payment);
/**
* ID
* @param id ID
* @return
*/
Payment getPaymentById(int id);
/**
* ID
* @param orderId ID
* @return
*/
Payment getPaymentByOrderId(int orderId);
/**
*
* @param id ID
* @param status
* @param transactionId ID
* @return
*/
boolean updatePaymentStatus(int id, String status, String transactionId);
/**
*
* @return
*/
List<Payment> getAllPayments();
/**
* ID
* @param userId ID
* @return
*/
List<Payment> getPaymentsByUserId(int userId);
}

@ -0,0 +1,75 @@
package com.campus.delivery.dao;
import com.campus.delivery.entity.Payment;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class PaymentDAOImpl implements PaymentDAO {
private static List<Payment> paymentList = new ArrayList<>();
private static AtomicInteger nextId = new AtomicInteger(1);
@Override
public int createPayment(Payment payment) {
int id = nextId.getAndIncrement();
payment.setId(id);
paymentList.add(payment);
return id;
}
@Override
public Payment getPaymentById(int id) {
for (Payment payment : paymentList) {
if (payment.getId() == id) {
return payment;
}
}
return null;
}
@Override
public Payment getPaymentByOrderId(int orderId) {
for (Payment payment : paymentList) {
if (payment.getOrderId() == orderId) {
return payment;
}
}
return null;
}
@Override
public boolean updatePaymentStatus(int id, String status, String transactionId) {
Payment payment = getPaymentById(id);
if (payment != null) {
payment.setStatus(status);
payment.setTransactionId(transactionId);
if ("SUCCESS".equals(status)) {
payment.setPaymentTime(new Date());
}
return true;
}
return false;
}
@Override
public List<Payment> getAllPayments() {
return new ArrayList<>(paymentList);
}
@Override
public List<Payment> getPaymentsByUserId(int userId) {
List<Payment> result = new ArrayList<>();
OrderDAO orderDAO = new OrderDAOImpl();
List<Order> userOrders = orderDAO.getOrdersByUserId(userId);
for (Order order : userOrders) {
Payment payment = getPaymentByOrderId(order.getId());
if (payment != null) {
result.add(payment);
}
}
return result;
}
}

@ -0,0 +1,125 @@
package com.campus.delivery.entity;
import java.util.Date;
public class Order {
private int id;
private int userId;
private int deliverId;
private String description;
private double amount;
private String status;
private String paymentMethod;
private Date createTime;
private Date paymentTime;
private Date finishTime;
public Order() {
}
public Order(int userId, int deliverId, String description, double amount, String status) {
this.userId = userId;
this.deliverId = deliverId;
this.description = description;
this.amount = amount;
this.status = status;
this.createTime = new Date();
}
// Getters and Setters
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public int getDeliverId() {
return deliverId;
}
public void setDeliverId(int deliverId) {
this.deliverId = deliverId;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getPaymentMethod() {
return paymentMethod;
}
public void setPaymentMethod(String paymentMethod) {
this.paymentMethod = paymentMethod;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getPaymentTime() {
return paymentTime;
}
public void setPaymentTime(Date paymentTime) {
this.paymentTime = paymentTime;
}
public Date getFinishTime() {
return finishTime;
}
public void setFinishTime(Date finishTime) {
this.finishTime = finishTime;
}
@Override
public String toString() {
return "Order{" +
"id=" + id +
", userId=" + userId +
", deliverId=" + deliverId +
", description='" + description + '\'' +
", amount=" + amount +
", status='" + status + '\'' +
", paymentMethod='" + paymentMethod + '\'' +
", createTime=" + createTime +
", paymentTime=" + paymentTime +
", finishTime=" + finishTime +
'}';
}
}

@ -0,0 +1,93 @@
package com.campus.delivery.entity;
import java.util.Date;
public class Payment {
private int id;
private int orderId;
private double amount;
private String paymentMethod;
private String transactionId;
private String status;
private Date paymentTime;
public Payment() {
}
public Payment(int orderId, double amount, String paymentMethod) {
this.orderId = orderId;
this.amount = amount;
this.paymentMethod = paymentMethod;
this.status = "PENDING";
}
// Getters and Setters
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
public String getPaymentMethod() {
return paymentMethod;
}
public void setPaymentMethod(String paymentMethod) {
this.paymentMethod = paymentMethod;
}
public String getTransactionId() {
return transactionId;
}
public void setTransactionId(String transactionId) {
this.transactionId = transactionId;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Date getPaymentTime() {
return paymentTime;
}
public void setPaymentTime(Date paymentTime) {
this.paymentTime = paymentTime;
}
@Override
public String toString() {
return "Payment{" +
"id=" + id +
", orderId=" + orderId +
", amount=" + amount +
", paymentMethod='" + paymentMethod + '\'' +
", transactionId='" + transactionId + '\'' +
", status='" + status + '\'' +
", paymentTime=" + paymentTime +
'}';
}
}

@ -0,0 +1,60 @@
package com.campus.delivery.service;
import com.campus.delivery.entity.Order;
import java.util.List;
public interface OrderService {
/**
*
* @param userId ID
* @param deliverId ID
* @param description
* @param amount
* @return ID
*/
int createOrder(int userId, int deliverId, String description, double amount);
/**
*
* @param orderId ID
* @return
*/
Order getOrderDetail(int orderId);
/**
*
* @param userId ID
* @return
*/
List<Order> getUserOrders(int userId);
/**
*
* @param deliverId ID
* @return
*/
List<Order> getDeliverOrders(int deliverId);
/**
*
* @param orderId ID
* @param status
* @return
*/
boolean updateOrderStatus(int orderId, String status);
/**
*
* @param orderId ID
* @return
*/
boolean cancelOrder(int orderId);
/**
*
* @param orderId ID
* @return
*/
boolean completeOrder(int orderId);
}

@ -0,0 +1,91 @@
package com.campus.delivery.service;
import com.campus.delivery.dao.OrderDAO;
import com.campus.delivery.dao.OrderDAOImpl;
import com.campus.delivery.entity.Order;
import java.util.List;
public class OrderServiceImpl implements OrderService {
private OrderDAO orderDAO;
public OrderServiceImpl() {
this.orderDAO = new OrderDAOImpl();
}
@Override
public int createOrder(int userId, int deliverId, String description, double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("订单金额必须大于0");
}
if (description == null || description.trim().isEmpty()) {
throw new IllegalArgumentException("订单描述不能为空");
}
Order order = new Order(userId, deliverId, description, amount, "PENDING");
return orderDAO.createOrder(order);
}
@Override
public Order getOrderDetail(int orderId) {
Order order = orderDAO.getOrderById(orderId);
if (order == null) {
throw new RuntimeException("订单不存在");
}
return order;
}
@Override
public List<Order> getUserOrders(int userId) {
return orderDAO.getOrdersByUserId(userId);
}
@Override
public List<Order> getDeliverOrders(int deliverId) {
return orderDAO.getOrdersByDeliverId(deliverId);
}
@Override
public boolean updateOrderStatus(int orderId, String status) {
validateOrderStatus(status);
return orderDAO.updateOrderStatus(orderId, status);
}
@Override
public boolean cancelOrder(int orderId) {
Order order = orderDAO.getOrderById(orderId);
if (order == null) {
return false;
}
// 只有待支付的订单可以取消
if ("PENDING".equals(order.getStatus())) {
return orderDAO.updateOrderStatus(orderId, "CANCELLED");
}
return false;
}
@Override
public boolean completeOrder(int orderId) {
Order order = orderDAO.getOrderById(orderId);
if (order == null) {
return false;
}
// 只有已支付的订单可以完成
if ("PAID".equals(order.getStatus())) {
return orderDAO.updateOrderStatus(orderId, "COMPLETED");
}
return false;
}
private void validateOrderStatus(String status) {
if (status == null || !isValidStatus(status)) {
throw new IllegalArgumentException("无效的订单状态");
}
}
private boolean isValidStatus(String status) {
return "PENDING".equals(status) || "PAID".equals(status) || "COMPLETED".equals(status) || "CANCELLED".equals(status);
}
}

@ -0,0 +1,52 @@
package com.campus.delivery.service;
import com.campus.delivery.entity.Payment;
import java.util.List;
public interface PaymentService {
/**
*
* @param orderId ID
* @param paymentMethod
* @return ID
*/
int processPayment(int orderId, String paymentMethod);
/**
*
* @param paymentId ID
* @return
*/
Payment getPaymentDetail(int paymentId);
/**
*
* @param orderId ID
* @return
*/
Payment getPaymentByOrderId(int orderId);
/**
*
* @param paymentId ID
* @param transactionId ID
* @return
*/
boolean confirmPaymentSuccess(int paymentId, String transactionId);
/**
*
* @param paymentId ID
* @param reason
* @return
*/
boolean handlePaymentFailure(int paymentId, String reason);
/**
*
* @param userId ID
* @return
*/
List<Payment> getUserPayments(int userId);
}

@ -0,0 +1,113 @@
package com.campus.delivery.service;
import com.campus.delivery.dao.OrderDAO;
import com.campus.delivery.dao.OrderDAOImpl;
import com.campus.delivery.dao.PaymentDAO;
import com.campus.delivery.dao.PaymentDAOImpl;
import com.campus.delivery.entity.Order;
import com.campus.delivery.entity.Payment;
import java.util.List;
import java.util.UUID;
public class PaymentServiceImpl implements PaymentService {
private PaymentDAO paymentDAO;
private OrderDAO orderDAO;
public PaymentServiceImpl() {
this.paymentDAO = new PaymentDAOImpl();
this.orderDAO = new OrderDAOImpl();
}
@Override
public int processPayment(int orderId, String paymentMethod) {
// 验证订单是否存在
Order order = orderDAO.getOrderById(orderId);
if (order == null) {
throw new RuntimeException("订单不存在");
}
// 验证订单状态
if (!"PENDING".equals(order.getStatus())) {
throw new RuntimeException("订单状态不允许支付");
}
// 验证支付方式
validatePaymentMethod(paymentMethod);
// 创建支付记录
Payment payment = new Payment(orderId, order.getAmount(), paymentMethod);
int paymentId = paymentDAO.createPayment(payment);
// 更新订单支付方式
orderDAO.updateOrderPayment(orderId, paymentMethod);
return paymentId;
}
@Override
public Payment getPaymentDetail(int paymentId) {
Payment payment = paymentDAO.getPaymentById(paymentId);
if (payment == null) {
throw new RuntimeException("支付记录不存在");
}
return payment;
}
@Override
public Payment getPaymentByOrderId(int orderId) {
Payment payment = paymentDAO.getPaymentByOrderId(orderId);
if (payment == null) {
throw new RuntimeException("该订单没有支付记录");
}
return payment;
}
@Override
public boolean confirmPaymentSuccess(int paymentId, String transactionId) {
// 获取支付记录
Payment payment = paymentDAO.getPaymentById(paymentId);
if (payment == null) {
return false;
}
// 更新支付状态
boolean paymentUpdated = paymentDAO.updatePaymentStatus(paymentId, "SUCCESS", transactionId);
if (paymentUpdated) {
// 更新订单状态为已支付
orderDAO.updateOrderStatus(payment.getOrderId(), "PAID");
return true;
}
return false;
}
@Override
public boolean handlePaymentFailure(int paymentId, String reason) {
// 获取支付记录
Payment payment = paymentDAO.getPaymentById(paymentId);
if (payment == null) {
return false;
}
// 生成失败交易ID
String failedTransactionId = "FAIL_" + UUID.randomUUID().toString();
// 更新支付状态为失败
return paymentDAO.updatePaymentStatus(paymentId, "FAILED", failedTransactionId);
}
@Override
public List<Payment> getUserPayments(int userId) {
return paymentDAO.getPaymentsByUserId(userId);
}
private void validatePaymentMethod(String paymentMethod) {
if (paymentMethod == null || !isValidPaymentMethod(paymentMethod)) {
throw new IllegalArgumentException("无效的支付方式");
}
}
private boolean isValidPaymentMethod(String paymentMethod) {
return "WECHAT_PAY".equals(paymentMethod) || "ALIPAY".equals(paymentMethod) || "CASH".equals(paymentMethod);
}
}

@ -0,0 +1,266 @@
package com.campus.delivery.view;
import com.campus.delivery.controller.OrderController;
import com.campus.delivery.controller.PaymentController;
import java.util.Scanner;
public class OrderPaymentView {
private OrderController orderController;
private PaymentController paymentController;
private Scanner scanner;
public OrderPaymentView() {
this.orderController = new OrderController();
this.paymentController = new PaymentController();
this.scanner = new Scanner(System.in);
}
/**
*
*/
public void showMainMenu() {
while (true) {
System.out.println("\n==================================");
System.out.println(" 校园代取系统 - 订单支付与管理");
System.out.println("==================================");
System.out.println("1. 订单管理");
System.out.println("2. 支付管理");
System.out.println("3. 退出系统");
System.out.print("请选择操作(1-3): ");
int choice = scanner.nextInt();
scanner.nextLine(); // 消耗换行符
switch (choice) {
case 1:
showOrderMenu();
break;
case 2:
showPaymentMenu();
break;
case 3:
System.out.println("感谢使用校园代取系统!");
return;
default:
System.out.println("无效的选择,请重新输入!");
}
}
}
/**
*
*/
private void showOrderMenu() {
while (true) {
System.out.println("\n==================================");
System.out.println(" 订单管理菜单");
System.out.println("==================================");
System.out.println("1. 创建新订单");
System.out.println("2. 查询订单详情");
System.out.println("3. 查询用户订单列表");
System.out.println("4. 查询配送员订单列表");
System.out.println("5. 更新订单状态");
System.out.println("6. 取消订单");
System.out.println("7. 完成订单");
System.out.println("8. 返回主菜单");
System.out.print("请选择操作(1-8): ");
int choice = scanner.nextInt();
scanner.nextLine(); // 消耗换行符
switch (choice) {
case 1:
createOrder();
break;
case 2:
getOrderDetail();
break;
case 3:
getUserOrders();
break;
case 4:
getDeliverOrders();
break;
case 5:
updateOrderStatus();
break;
case 6:
cancelOrder();
break;
case 7:
completeOrder();
break;
case 8:
return;
default:
System.out.println("无效的选择,请重新输入!");
}
}
}
/**
*
*/
private void showPaymentMenu() {
while (true) {
System.out.println("\n==================================");
System.out.println(" 支付管理菜单");
System.out.println("==================================");
System.out.println("1. 发起订单支付");
System.out.println("2. 查询支付详情");
System.out.println("3. 查询订单支付记录");
System.out.println("4. 确认支付成功");
System.out.println("5. 处理支付失败");
System.out.println("6. 查询用户支付记录");
System.out.println("7. 返回主菜单");
System.out.print("请选择操作(1-7): ");
int choice = scanner.nextInt();
scanner.nextLine(); // 消耗换行符
switch (choice) {
case 1:
processPayment();
break;
case 2:
getPaymentDetail();
break;
case 3:
getPaymentByOrderId();
break;
case 4:
confirmPaymentSuccess();
break;
case 5:
handlePaymentFailure();
break;
case 6:
getUserPayments();
break;
case 7:
return;
default:
System.out.println("无效的选择,请重新输入!");
}
}
}
// 订单管理功能实现
private void createOrder() {
System.out.print("请输入用户ID: ");
int userId = scanner.nextInt();
System.out.print("请输入配送员ID: ");
int deliverId = scanner.nextInt();
scanner.nextLine(); // 消耗换行符
System.out.print("请输入订单描述: ");
String description = scanner.nextLine();
System.out.print("请输入订单金额: ");
double amount = scanner.nextDouble();
String result = orderController.createOrder(userId, deliverId, description, amount);
System.out.println(result);
}
private void getOrderDetail() {
System.out.print("请输入订单ID: ");
int orderId = scanner.nextInt();
String result = orderController.getOrderDetail(orderId);
System.out.println(result);
}
private void getUserOrders() {
System.out.print("请输入用户ID: ");
int userId = scanner.nextInt();
String result = orderController.getUserOrders(userId);
System.out.println(result);
}
private void getDeliverOrders() {
System.out.print("请输入配送员ID: ");
int deliverId = scanner.nextInt();
String result = orderController.getDeliverOrders(deliverId);
System.out.println(result);
}
private void updateOrderStatus() {
System.out.print("请输入订单ID: ");
int orderId = scanner.nextInt();
scanner.nextLine(); // 消耗换行符
System.out.print("请输入新状态(PENDING/PAID/COMPLETED/CANCELLED): ");
String status = scanner.nextLine().toUpperCase();
String result = orderController.updateOrderStatus(orderId, status);
System.out.println(result);
}
private void cancelOrder() {
System.out.print("请输入订单ID: ");
int orderId = scanner.nextInt();
String result = orderController.cancelOrder(orderId);
System.out.println(result);
}
private void completeOrder() {
System.out.print("请输入订单ID: ");
int orderId = scanner.nextInt();
String result = orderController.completeOrder(orderId);
System.out.println(result);
}
// 支付管理功能实现
private void processPayment() {
System.out.print("请输入订单ID: ");
int orderId = scanner.nextInt();
scanner.nextLine(); // 消耗换行符
System.out.print("请选择支付方式(WECHAT_PAY/ALIPAY/CASH): ");
String paymentMethod = scanner.nextLine().toUpperCase();
String result = paymentController.processPayment(orderId, paymentMethod);
System.out.println(result);
}
private void getPaymentDetail() {
System.out.print("请输入支付ID: ");
int paymentId = scanner.nextInt();
String result = paymentController.getPaymentDetail(paymentId);
System.out.println(result);
}
private void getPaymentByOrderId() {
System.out.print("请输入订单ID: ");
int orderId = scanner.nextInt();
String result = paymentController.getPaymentByOrderId(orderId);
System.out.println(result);
}
private void confirmPaymentSuccess() {
System.out.print("请输入支付ID: ");
int paymentId = scanner.nextInt();
String result = paymentController.confirmPaymentSuccess(paymentId);
System.out.println(result);
}
private void handlePaymentFailure() {
System.out.print("请输入支付ID: ");
int paymentId = scanner.nextInt();
scanner.nextLine(); // 消耗换行符
System.out.print("请输入失败原因: ");
String reason = scanner.nextLine();
String result = paymentController.handlePaymentFailure(paymentId, reason);
System.out.println(result);
}
private void getUserPayments() {
System.out.print("请输入用户ID: ");
int userId = scanner.nextInt();
String result = paymentController.getUserPayments(userId);
System.out.println(result);
}
/**
*
*/
public static void main(String[] args) {
OrderPaymentView view = new OrderPaymentView();
view.showMainMenu();
}
}

@ -0,0 +1,189 @@
package com.campus.delivery;
import com.campus.delivery.controller.OrderController;
import com.campus.delivery.controller.PaymentController;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
public class ComprehensiveOrderPaymentTest {
private OrderController orderController;
private PaymentController paymentController;
@Before
public void setUp() {
// 每个测试方法执行前创建新的控制器实例,确保测试隔离
orderController = new OrderController();
paymentController = new PaymentController();
}
@Test
public void testCreateAndQueryOrder() {
// 测试创建订单
String createResult = orderController.createOrder(1001, 2001, "取快递", 5.0);
assertTrue("订单创建失败", createResult.contains("订单创建成功"));
// 提取订单ID
int orderId = extractOrderId(createResult);
assertTrue("订单ID提取失败", orderId > 0);
// 测试查询订单详情
String detailResult = orderController.getOrderDetail(orderId);
assertTrue("订单详情查询失败", detailResult.contains("订单详情"));
assertTrue("订单详情不包含订单ID", detailResult.contains(String.valueOf(orderId)));
}
@Test
public void testPaymentFlow() {
// 创建测试订单
String createResult = orderController.createOrder(1002, 2002, "取外卖", 8.0);
int orderId = extractOrderId(createResult);
// 发起支付
String paymentResult = paymentController.processPayment(orderId, "WECHAT_PAY");
assertTrue("支付发起失败", paymentResult.contains("支付处理成功"));
// 提取支付ID
int paymentId = extractPaymentId(paymentResult);
assertTrue("支付ID提取失败", paymentId > 0);
// 确认支付成功
String confirmResult = paymentController.confirmPaymentSuccess(paymentId);
assertTrue("支付确认失败", confirmResult.contains("支付确认成功"));
// 验证订单状态已更新为PAID
String detailResult = orderController.getOrderDetail(orderId);
assertTrue("订单状态未更新为PAID", detailResult.contains("PAID"));
}
@Test
public void testOrderStatusManagement() {
// 创建测试订单
String createResult = orderController.createOrder(1003, 2003, "取文件", 10.0);
int orderId = extractOrderId(createResult);
// 更新订单状态为PAID
String updateResult1 = orderController.updateOrderStatus(orderId, "PAID");
assertTrue("订单状态更新为PAID失败", updateResult1.contains("更新成功"));
// 完成订单
String completeResult = orderController.completeOrder(orderId);
assertTrue("订单完成失败", completeResult.contains("完成成功"));
// 验证订单状态已更新为COMPLETED
String detailResult = orderController.getOrderDetail(orderId);
assertTrue("订单状态未更新为COMPLETED", detailResult.contains("COMPLETED"));
}
@Test
public void testCancelOrder() {
// 创建测试订单
String createResult = orderController.createOrder(1004, 2004, "取水果", 15.0);
int orderId = extractOrderId(createResult);
// 取消订单
String cancelResult = orderController.cancelOrder(orderId);
assertTrue("订单取消失败", cancelResult.contains("取消成功"));
// 验证订单状态已更新为CANCELLED
String detailResult = orderController.getOrderDetail(orderId);
assertTrue("订单状态未更新为CANCELLED", detailResult.contains("CANCELLED"));
}
@Test
public void testPaymentFailureHandling() {
// 创建测试订单
String createResult = orderController.createOrder(1005, 2005, "取包裹", 12.0);
int orderId = extractOrderId(createResult);
// 发起支付
String paymentResult = paymentController.processPayment(orderId, "ALIPAY");
int paymentId = extractPaymentId(paymentResult);
// 处理支付失败
String failureResult = paymentController.handlePaymentFailure(paymentId, "余额不足");
assertTrue("支付失败处理失败", failureResult.contains("失败处理成功"));
// 验证支付状态
String paymentDetail = paymentController.getPaymentDetail(paymentId);
assertTrue("支付状态未更新为FAILED", paymentDetail.contains("FAILED"));
assertTrue("支付失败原因未记录", paymentDetail.contains("余额不足"));
}
@Test
public void testQueryUserOrders() {
// 创建多个测试订单
orderController.createOrder(1006, 2006, "取快递1", 5.0);
orderController.createOrder(1006, 2007, "取快递2", 5.0);
orderController.createOrder(1006, 2008, "取快递3", 5.0);
// 查询用户订单列表
String userOrders = orderController.getUserOrders(1006);
assertTrue("用户订单查询失败", userOrders.contains("用户订单列表"));
assertFalse("用户订单列表为空", userOrders.contains("没有订单"));
}
@Test
public void testQueryDeliverOrders() {
// 创建多个测试订单给同一个配送员
orderController.createOrder(1007, 2009, "配送订单1", 8.0);
orderController.createOrder(1008, 2009, "配送订单2", 10.0);
// 查询配送员订单列表
String deliverOrders = orderController.getDeliverOrders(2009);
assertTrue("配送员订单查询失败", deliverOrders.contains("配送员订单列表"));
assertFalse("配送员订单列表为空", deliverOrders.contains("没有订单"));
}
@Test
public void testInvalidOrderId() {
// 测试查询不存在的订单
String detailResult = orderController.getOrderDetail(99999);
assertTrue("应该返回订单不存在", detailResult.contains("失败"));
// 测试更新不存在的订单状态
String updateResult = orderController.updateOrderStatus(99999, "PAID");
assertTrue("应该返回订单不存在", updateResult.contains("失败"));
}
@Test
public void testInvalidPaymentId() {
// 测试查询不存在的支付
String paymentDetail = paymentController.getPaymentDetail(99999);
assertTrue("应该返回支付不存在", paymentDetail.contains("失败"));
// 测试确认不存在的支付
String confirmResult = paymentController.confirmPaymentSuccess(99999);
assertTrue("应该返回支付不存在", confirmResult.contains("失败"));
}
@Test
public void testInvalidPaymentMethod() {
// 创建测试订单
String createResult = orderController.createOrder(1009, 2010, "取物品", 6.0);
int orderId = extractOrderId(createResult);
// 使用无效支付方式
String paymentResult = paymentController.processPayment(orderId, "INVALID_PAYMENT");
assertTrue("应该返回支付方式无效", paymentResult.contains("失败"));
}
// 辅助方法从订单创建结果中提取订单ID
private int extractOrderId(String createResult) {
if (createResult.contains("订单ID")) {
return Integer.parseInt(createResult.split("订单ID")[1].trim());
}
return -1;
}
// 辅助方法从支付结果中提取支付ID
private int extractPaymentId(String paymentResult) {
if (paymentResult.contains("支付ID")) {
String part = paymentResult.split("支付ID")[1];
return Integer.parseInt(part.split("")[0].trim());
}
return -1;
}
}

@ -0,0 +1,72 @@
package com.campus.delivery;
import com.campus.delivery.controller.OrderController;
import com.campus.delivery.controller.PaymentController;
import org.junit.Test;
public class OrderPaymentTest {
@Test
public void testOrderAndPaymentFlow() {
System.out.println("=== 测试订单支付与管理功能流程 ===");
// 创建控制器实例
OrderController orderController = new OrderController();
PaymentController paymentController = new PaymentController();
// 1. 创建新订单
System.out.println("\n1. 创建新订单:");
String createResult = orderController.createOrder(1001, 2001, "取快递宿舍楼1栋", 5.0);
System.out.println(createResult);
// 提取订单ID假设格式为"订单创建成功订单ID1"
int orderId = 1;
if (createResult.contains("订单ID")) {
orderId = Integer.parseInt(createResult.split("订单ID")[1].trim());
}
// 2. 查询订单详情
System.out.println("\n2. 查询订单详情:");
String detailResult = orderController.getOrderDetail(orderId);
System.out.println(detailResult);
// 3. 发起订单支付
System.out.println("\n3. 发起订单支付:");
String paymentResult = paymentController.processPayment(orderId, "WECHAT_PAY");
System.out.println(paymentResult);
// 提取支付ID假设格式为"支付处理成功支付ID1..."
int paymentId = 1;
if (paymentResult.contains("支付ID")) {
String paymentIdStr = paymentResult.split("支付ID")[1].split("")[0].trim();
paymentId = Integer.parseInt(paymentIdStr);
}
// 4. 查询支付详情
System.out.println("\n4. 查询支付详情:");
String paymentDetailResult = paymentController.getPaymentDetail(paymentId);
System.out.println(paymentDetailResult);
// 5. 确认支付成功
System.out.println("\n5. 确认支付成功:");
String confirmResult = paymentController.confirmPaymentSuccess(paymentId);
System.out.println(confirmResult);
// 6. 再次查询订单详情,确认状态已更新
System.out.println("\n6. 再次查询订单详情:");
String updatedDetailResult = orderController.getOrderDetail(orderId);
System.out.println(updatedDetailResult);
// 7. 完成订单
System.out.println("\n7. 完成订单:");
String completeResult = orderController.completeOrder(orderId);
System.out.println(completeResult);
// 8. 查询用户所有订单
System.out.println("\n8. 查询用户所有订单:");
String userOrdersResult = orderController.getUserOrders(1001);
System.out.println(userOrdersResult);
System.out.println("\n=== 测试流程结束 ===");
}
}

@ -0,0 +1,11 @@
com\campus\delivery\entity\Payment.class
com\campus\delivery\view\OrderPaymentView.class
com\campus\delivery\dao\PaymentDAO.class
com\campus\delivery\dao\OrderDAO.class
com\campus\delivery\controller\OrderController.class
com\campus\delivery\entity\Order.class
com\campus\delivery\service\OrderService.class
com\campus\delivery\controller\PaymentController.class
com\campus\delivery\service\OrderServiceImpl.class
com\campus\delivery\service\PaymentService.class
com\campus\delivery\service\PaymentServiceImpl.class

@ -0,0 +1,13 @@
C:\Users\11343\Desktop\实验四\src\main\java\com\campus\delivery\service\OrderService.java
C:\Users\11343\Desktop\实验四\src\main\java\com\campus\delivery\service\OrderServiceImpl.java
C:\Users\11343\Desktop\实验四\src\main\java\com\campus\delivery\entity\Payment.java
C:\Users\11343\Desktop\实验四\src\main\java\com\campus\delivery\view\OrderPaymentView.java
C:\Users\11343\Desktop\实验四\src\main\java\com\campus\delivery\controller\PaymentController.java
C:\Users\11343\Desktop\实验四\src\main\java\com\campus\delivery\service\PaymentService.java
C:\Users\11343\Desktop\实验四\src\main\java\com\campus\delivery\controller\OrderController.java
C:\Users\11343\Desktop\实验四\src\main\java\com\campus\delivery\entity\Order.java
C:\Users\11343\Desktop\实验四\src\main\java\com\campus\delivery\dao\OrderDAO.java
C:\Users\11343\Desktop\实验四\src\main\java\com\campus\delivery\dao\PaymentDAO.java
C:\Users\11343\Desktop\实验四\src\main\java\com\campus\delivery\dao\OrderDAOImpl.java
C:\Users\11343\Desktop\实验四\src\main\java\com\campus\delivery\dao\PaymentDAOImpl.java
C:\Users\11343\Desktop\实验四\src\main\java\com\campus\delivery\service\PaymentServiceImpl.java

Binary file not shown.

@ -0,0 +1,362 @@
# 实验一软件项目计划个人报告作业题
## 个人基本信息
- **姓名**:程璟琦
- **学号**2023210442
- **班级**计科231
- **小组**G1组
- **角色**:负责订单与支付管理功能
- **实验日期**2025-11-03
- **提交日期**2025-11-07
## 个人任务完成情况
### 1. 个人负责的功能模块分析
根据您的角色分工,详细分析您负责的功能模块:
#### 开发人员2程璟琦负责订单与支付管理功能
- **详细分析校园代取系统中订单与支付管理功能的需求**
- 订单功能:用户创建代取订单,包含取件信息、收货地址、时间要求、报酬设置等
- 支付功能:支持多种支付方式(微信、支付宝),实现支付状态同步和订单状态更新
- 订单状态管理:待支付、待接单、进行中、已完成、已取消等多种状态流转
- 订单查询与筛选:支持按状态、时间、类型等条件查询订单
- 支付记录管理:记录所有支付流水,支持支付记录查询和对账
- **描述订单创建、查询、修改和支付处理的业务流程**
- 订单创建:用户填写订单信息 → 系统验证信息有效性 → 生成订单号 → 进入待支付状态
- 支付处理:用户选择支付方式 → 跳转支付平台 → 支付成功/失败 → 回调通知系统 → 更新订单状态
- 订单查询:用户登录系统 → 进入订单管理页面 → 选择查询条件 → 显示符合条件的订单列表
- 订单修改:在特定状态下(如待接单),允许用户修改订单信息 → 系统验证并更新订单
- **分析订单状态管理和支付安全性的保障措施**
- 订单状态流转控制:通过状态机模式严格控制订单状态转换,防止非法状态变更
- 支付安全保障采用HTTPS加密传输集成第三方支付SDK实现支付结果异步通知和幂等性处理
- 数据一致性:使用事务管理确保订单和支付状态同步,防止数据不一致
- 异常处理:针对支付超时、支付失败等异常情况,实现自动取消订单或退款机制
- **说明这两个功能与其他模块的交互关系**
- 与用户模块:依赖用户身份验证,获取用户信息
- 与配送模块:订单支付成功后,推送给配送模块进行接单匹配
- 与通知模块:订单状态变更时,发送通知给相关用户
- 与评价模块:订单完成后,开放评价功能
- 与统计分析模块:为运营数据分析提供订单和支付数据支持
### 2. EA模型设计
请描述您使用EA设计的模型图
- **说明您设计的模型图类型和用途**
- 设计了需求图、用例图、甘特图和软件过程模型图,全面展示订单与支付管理功能的各个方面
- 这些模型图用于明确功能需求、业务流程、开发计划和项目管理方法
- **描述模型图中的主要元素和关系**
- 需求图包含功能需求、非功能需求、数据需求等层次结构
- 用例图包含用户、配送员、系统管理员等参与者和订单管理、支付处理等用例
- 甘特图展示了各开发任务的时间安排、依赖关系和里程碑
- 软件过程模型图采用敏捷开发方法,包含迭代计划和持续集成
- **解释模型图如何体现您的功能模块设计思路**
- 通过层次化的需求分解,确保功能覆盖全面且无遗漏
- 用例图清晰展示了系统与不同角色的交互方式
- 甘特图帮助识别关键路径和资源分配
- 过程模型图指导开发团队的协作方式和质量控制
- **具体要求**:请提供以下模型图的设计和分析
- **需求图**:展示订单与支付管理功能的需求层次,从顶层的功能概述到底层的详细功能点,清晰呈现需求之间的包含和依赖关系
- **用例图**:描述用户(下单方)、配送员(接单方)和系统管理员三个主要参与者,以及订单创建、支付处理、订单查询、订单修改、支付记录管理等用例之间的关系
- **甘特图**:展示订单与支付管理功能从需求分析到测试部署的完整开发周期,包括各任务的开始和结束时间、持续时间、依赖关系和负责人分配
- **软件过程模型图**采用Scrum敏捷开发方法分为4个迭代周期每个迭代包含计划、开发、测试和评审四个阶段
- 附上您设计的模型图截图(可放在附录)
### 3. 测试用例设计
根据您负责的功能模块,设计测试用例:
- **列出至少5个关键测试用例**
- TC001订单创建功能测试
- TC002支付处理功能测试
- TC003订单状态流转测试
- TC004订单查询与筛选测试
- TC005支付异常处理测试
- **每个测试用例包括:测试目的、输入数据、预期结果、测试步骤**
**TC001订单创建功能测试**
- 测试目的:验证用户能够成功创建代取订单
- 输入数据:取件信息(快递单号、快递公司)、收货地址、时间要求、报酬金额
- 预期结果:订单创建成功,返回订单号,订单状态为待支付
- 测试步骤:
1. 登录系统
2. 进入订单创建页面
3. 填写完整的订单信息
4. 点击提交按钮
5. 验证订单创建成功提示和订单号显示
6. 检查订单列表中是否存在新创建的订单
**TC002支付处理功能测试**
- 测试目的:验证用户能够使用微信支付方式完成订单支付
- 输入数据:待支付订单、选择微信支付
- 预期结果:支付成功,订单状态更新为待接单
- 测试步骤:
1. 登录系统
2. 找到待支付订单
3. 点击支付按钮,选择微信支付
4. 模拟微信支付成功
5. 验证支付成功提示
6. 检查订单状态是否更新为待接单
**TC003订单状态流转测试**
- 测试目的:验证订单状态能够按照规定流程正确流转
- 输入数据:不同状态的订单操作
- 预期结果:订单状态按预定规则流转
- 测试步骤:
1. 创建并支付一个订单(状态:待接单)
2. 模拟配送员接单(状态:进行中)
3. 模拟配送完成(状态:已完成)
4. 验证每个状态转换的正确性
5. 测试非法状态转换(如直接从待支付到已完成)是否被系统拒绝
**TC004订单查询与筛选测试**
- 测试目的:验证用户能够按条件查询和筛选订单
- 输入数据:查询条件(订单状态、时间范围、订单类型)
- 预期结果:系统返回符合条件的订单列表
- 测试步骤:
1. 登录系统
2. 进入订单查询页面
3. 设置不同的查询条件组合
4. 点击查询按钮
5. 验证返回的订单列表是否符合查询条件
6. 测试边界条件(如时间范围的最大值和最小值)
**TC005支付异常处理测试**
- 测试目的:验证系统能够正确处理支付超时和失败的情况
- 输入数据:待支付订单、模拟支付超时/失败
- 预期结果:系统正确处理异常,订单状态适当更新
- 测试步骤:
1. 创建一个待支付订单
2. 触发支付,然后模拟支付超时
3. 验证订单是否自动取消或恢复为待支付状态
4. 创建新的待支付订单
5. 触发支付,然后模拟支付失败
6. 验证系统是否提供重新支付选项
- **说明测试用例覆盖的功能点和边界条件**
- 覆盖了订单管理的核心功能:创建、查询、修改、状态流转
- 覆盖了支付功能:多种支付方式、支付状态同步
- 边界条件包括:输入数据验证、时间范围限制、金额限制、状态转换限制
- **分析测试用例的优先级和执行顺序**
- 优先级TC001 > TC002 > TC003 > TC004 > TC005
- 执行顺序:按照优先级顺序执行,确保核心功能正常后再测试异常情况和高级功能
### 4. 个人工作总结与甘特图分析
- **描述您在实验一中的主要工作内容和完成情况**
- 完成了校园代取系统中订单与支付管理功能模块的需求分析和详细设计
- 使用EA工具创建了需求图、用例图、甘特图和软件过程模型图
- 设计了5个关键测试用例覆盖了订单创建、支付处理、状态流转等核心功能
- 参与了团队讨论,明确了与其他模块的交互接口定义
- 完成了个人报告的编写,详细记录了设计思路和实现计划
- **分析您负责功能模块在项目甘特图中的时间安排和进度控制**
- 订单与支付管理模块计划在项目的第4周完成为期4周
- 第2周主要进行需求分析和EA建模已按时完成
- 第3周计划进行详细设计和接口定义按进度进行中
- 第4周计划进行单元测试和集成测试待完成
- 通过甘特图有效识别了关键路径,确保了进度符合项目总体计划
- **分析工作中遇到的主要问题和解决方案**
- 问题1支付安全性需求不明确
解决方案:查阅相关支付安全标准,咨询团队成员,明确了支付安全的具体要求和实现方案
- 问题2订单状态流转规则复杂
解决方案:采用状态机设计模式,清晰定义了每个状态的转换条件和限制
- 问题3与第三方支付接口集成困难
解决方案提前研究了主流支付SDK的文档设计了灵活的接口适配层
- **总结您在本次实验中的收获和体会**
- 深入理解了软件项目计划的重要性,特别是在复杂业务系统开发中的作用
- 掌握了使用EA工具进行系统建模的方法和技巧
- 学会了如何设计全面的测试用例,确保软件质量
- 体验了团队协作开发的流程,提高了沟通能力
- **评估您的工作质量和效率,提出改进措施**
- 工作质量:需求分析全面,模型设计合理,测试用例覆盖充分
- 工作效率:前期规划充分,执行过程顺利,基本按照计划完成
- 改进措施:
1. 加强对第三方支付平台的深入研究,提前识别潜在风险
2. 进一步优化订单状态机设计,提高系统可扩展性
3. 增加与团队成员的沟通频率,及时解决跨模块集成问题
### 5. 甘特图应用分析
- **说明您负责的功能模块在甘特图中的时间节点和工期安排**
- 订单与支付管理模块计划在2025年11月2日至12月20日期间进行
- 具体时间节点:
- 需求分析与建模11月2日-11月10日8天
- 详细设计与接口定义11月11日-11月31日8天
- 单元测试与集成测试12月1日-12月20日8天
- **分析您的工作与其他团队成员工作的依赖关系**
- 依赖用户模块:需要用户模块提供用户身份验证接口
- 依赖配送模块:订单支付成功后需要推送给配送模块进行接单
- 被通知模块依赖:订单状态变更时需要通知模块发送通知
- 被统计分析模块依赖:为运营数据提供基础数据支持
- **讨论甘特图中关键路径对您工作的影响**
- 订单支付功能是项目的关键路径之一,直接影响后续配送流程
- 支付接口集成工作需要优先完成,以确保整个系统的流程畅通
- 通过甘特图识别出关键路径后,调整了工作优先级,确保关键任务按时完成
- **评估甘特图对个人工作计划的指导价值**
- 甘特图帮助我清晰地了解了整个项目的时间框架和任务分配
- 通过甘特图识别了任务之间的依赖关系,合理安排了工作顺序
- 甘特图提供了可视化的进度跟踪方式,及时发现并解决进度偏差
- 甘特图促进了团队成员之间的协调和沟通,确保整体进度一致
## 实验一相关问题思考
### 问题1项目计划的重要性
- **分析软件项目计划对整个软件开发过程的影响**
- 提供明确的项目目标和范围,避免需求蔓延和范围变更
- 合理分配资源,确保人力、时间和预算的有效利用
- 设定清晰的里程碑和交付物,便于项目跟踪和评估
- 提前识别潜在风险和问题,制定应对策略
- 促进团队成员之间的沟通和协作,确保理解一致
- **结合校园代取系统项目,说明项目计划如何指导后续开发工作**
- 明确了系统的三大核心模块:用户管理、订单与支付管理、配送管理,为开发工作提供了清晰的方向
- 通过详细的功能分解,将复杂的业务需求转化为可执行的开发任务
- 制定了合理的时间计划,确保各模块开发工作有序进行,避免资源冲突
- 在订单与支付管理模块中,通过项目计划明确了与其他模块的接口定义和集成时间点
- 提前规划了测试策略和验收标准,为质量保证工作奠定了基础
### 问题2甘特图的应用价值
- **分析甘特图在项目管理中的作用和优势**
- 直观展示项目的时间线和任务安排,便于全局把握项目进度
- 清晰标识任务之间的依赖关系,帮助识别关键路径
- 便于资源分配和任务调度,确保资源利用最大化
- 提供进度跟踪和偏差分析的可视化工具
- 促进团队沟通,使所有成员了解自己的工作时间安排和责任
- **结合校园代取系统项目,说明甘特图如何帮助控制项目进度**
- 在订单与支付管理模块中,通过甘特图明确了每个功能点的开始和结束时间,为日常工作提供了参考
- 识别出支付接口集成是关键路径任务,优先分配资源确保按时完成
- 通过甘特图跟踪发现订单状态流转功能的开发进度滞后,及时调整工作计划,加班完成以避免影响后续工作
- 在与配送模块的集成工作中,甘特图帮助协调了两个团队的工作时间,确保接口开发和测试同步进行
- 定期对照甘特图检查进度,发现偏差及时采取措施,确保整个项目按时交付
## 工具使用体会
### EAEnterprise Architect使用体会
- **描述您使用EA的主要功能和操作流程**
- 使用EA创建了需求图、用例图、甘特图和软件过程模型图
- 操作流程:新建项目 → 创建包结构 → 添加图元素 → 设置元素属性 → 建立元素关系 → 美化图表 → 导出图片
- 学习了如何使用EA的各种图表模板和工具如需求层次图、用例图工具等
- **分析EA在软件建模中的优势和不足**
- 优势支持多种UML图表类型功能全面元素之间的关系设置灵活支持模型图的导出和共享提供了项目管理功能
- 不足:界面复杂,学习曲线较陡;某些操作步骤繁琐;性能在大型项目中可能会下降;部分高级功能需要付费
- **分享您在使用EA过程中遇到的困难和解决方法**
- 困难1元素之间的关系连线混乱影响图表美观
解决方法使用EA的自动布局功能手动调整连线路径使用连接器样式设置
- 困难2找不到某些图表模板和工具
解决方法查阅EA官方文档观看教程视频向同学请教
- 困难3导出的图片质量不佳
解决方法:调整导出设置,选择更高的分辨率,使用矢量格式导出
- **提出改进EA使用效率的建议**
- 提前规划好模型的结构和组织方式
- 使用EA的快捷键和工具栏按钮提高操作速度
- 善用EA的模板功能避免重复创建类似元素
- 定期保存工作,避免数据丢失
### TRAE辅助工具使用体会
- **描述您使用TRAE辅助工具的功能和体验**
- 使用TRAE辅助编写项目文档和代码注释
- 体验了AI辅助生成文本内容的便捷性
- 利用TRAE的智能提示功能提高了文档编写效率
- **分析TRAE在文档生成中的价值和局限性**
- 价值:节省了文档编写的时间;提供了结构化的文档模板;帮助快速生成初稿;减少了重复劳动
- 局限性:生成的内容有时过于通用,需要进一步个性化修改;对特定领域知识的理解有限;在处理复杂逻辑关系时可能不够准确
- **分享您在使用TRAE过程中的心得体会**
- TRAE是一个很好的辅助工具但不能完全替代人工思考和创作
- 正确的提示词和引导对获得高质量输出至关重要
- 需要对AI生成的内容进行审核和修改确保准确性和专业性
- **讨论AI辅助工具在软件开发中的应用前景**
- 随着技术发展AI辅助工具将在代码生成、文档编写、测试用例设计等方面发挥更大作用
- 可能会改变软件开发的工作方式,使开发人员能够专注于更具创造性的工作
- 需要注意AI工具的局限性避免过度依赖
### Git版本控制使用体会
- **描述您使用Git进行版本控制的基本操作**
- 学习了Git的基本命令init、add、commit、push、pull、branch等
- 实际操作了代码的提交、分支创建、合并等操作
- 使用Git进行团队协作提交了个人负责模块的代码
- **分析Git在团队协作开发中的重要性**
- 实现了代码的版本管理,便于查看历史记录和回滚
- 支持多人同时开发,避免代码冲突
- 提供了分支管理功能,便于并行开发和功能隔离
- 记录了每次代码变更的详细信息,便于项目管理和问题追溯
- **分享您在使用Git过程中遇到的问题和解决方法**
- 问题1合并分支时遇到代码冲突
解决方法:仔细分析冲突内容,手动编辑解决冲突,然后重新提交
- 问题2忘记提交某些文件导致版本不一致
解决方法使用git status检查状态确保所有修改的文件都被正确添加和提交
- 问题3误删除了重要文件
解决方法使用git checkout命令从历史版本恢复文件
- **讨论Git分支管理策略的优缺点**
- 主分支保护策略保护master/main分支通过Pull Request进行代码合并保证代码质量
- 功能分支策略:为每个新功能创建独立分支,开发完成后合并到主分支,便于功能隔离和并行开发
- 发布分支策略创建专门的发布分支进行预发布测试和bug修复稳定后合并到主分支
- 优缺点:分支管理提高了代码质量和开发效率,但需要团队成员理解和遵守分支规范,否则可能导致分支混乱
## 附录
### 附录A个人设计的EA模型图
[此处插入以下EA模型图截图
1. 订单与支付管理功能需求图
![alt text](<屏幕截图 2025-11-03 185406.png>)
2. 订单与支付管理功能用例图
![alt text](<屏幕截图 2025-11-03 185451.png>)
3. 订单与支付管理功能甘特图
![alt text](<屏幕截图 2025-11-07 132756.png>)
### 附录B个人测试用例表
| 测试用例ID | 测试功能 | 测试目的 | 输入数据 | 预期结果 | 测试步骤 | 优先级 |
|-----------|---------|---------|---------|---------|---------|--------|
| TC001 | 订单创建 | 验证用户能够成功创建代取订单 | 取件信息、收货地址、时间要求、报酬金额 | 订单创建成功,返回订单号,状态为待支付 | 登录系统→进入订单创建页面→填写信息→提交→验证结果 | 高 |
| TC002 | 支付处理 | 验证用户能够完成订单支付 | 待支付订单、选择微信支付 | 支付成功,订单状态更新为待接单 | 登录系统→找到待支付订单→点击支付→选择支付方式→验证结果 | 高 |
| TC003 | 订单状态流转 | 验证订单状态能按规定流程正确流转 | 不同状态的订单操作 | 订单状态按预定规则流转 | 创建并支付订单→模拟接单→模拟完成→验证状态转换 | 中 |
| TC004 | 订单查询与筛选 | 验证用户能按条件查询和筛选订单 | 查询条件(状态、时间范围等) | 系统返回符合条件的订单列表 | 登录系统→进入订单查询页面→设置查询条件→验证结果 | 中 |
| TC005 | 支付异常处理 | 验证系统能正确处理支付异常 | 待支付订单、模拟支付超时/失败 | 系统正确处理异常,状态适当更新 | 创建待支付订单→模拟支付超时/失败→验证系统反应 | 中 |
### 附录C个人工作日志
| 日期 | 工作内容 | 工作时长 | 完成情况 | 遇到的问题 | 解决方案 |
|------|---------|---------|---------|-----------|---------|
| 2025-11-2 | 需求分析和功能拆解 | 4小时 | 完成 | 支付安全需求不明确 | 查阅支付安全标准,咨询团队成员 |
| 2025-11-2 | 创建EA需求图和用例图 | 5小时 | 完成 | 元素关系连线混乱 | 使用自动布局功能,手动调整连线路径 |
| 2025-11-3 | 创建EA甘特图和过程模型图 | 6小时 | 完成 | 甘特图任务依赖关系设置复杂 | 学习EA甘特图教程参考示例 |
| 2025-11-4 | 设计测试用例 | 4小时 | 完成 | 测试边界条件考虑不足 | 重新梳理业务流程,补充边界测试 |
| 2025-11-5 | 编写个人报告初稿 | 5小时 | 完成 | 报告结构不清晰 | 参考模板,重新组织内容 |
| 2025-11-6 | 完善报告内容和格式 | 3小时 | 完成 | 格式调整复杂 | 学习Markdown语法统一格式标准 |
| 2025-11-7 | 检查和修改报告 | 2小时 | 完成 | 内容冗余 | 精简描述,突出重点 |
---
**提交要求**
1. 请将本报告保存为Markdown格式文件命名为"实验一软件项目计划个人报告_姓名.md"
2. 在头歌平台的个人功能分支中提交报告文件
3. 提交Pull Request给组长审查
4. 截止日期2025年11月10日
**评分标准**
1. 个人任务完成情况30分
2. EA模型设计30分
3. 实验一相关问题思考20分
4. 工具使用体会10分
5. 个人学习计划10分

@ -0,0 +1,630 @@
# 实验三 软件系统设计操作指南
**实验课时安排:** 6课时270分钟三次课程
> **版本信息**v1.0
> **更新日期**2025-11-23
> **适用项目**:校园代取系统
> **适用团队**:董玉坤,董文远,程璟琦,范孝宝
> **预计完成时间**1800分钟约30小时
> **实验环境**EAGitOpsEnterprise Architect + Git + Gitea + Jenkins + SonarQube + PostgreSQL + 头歌平台)
**重要提示:** 本文档中的"个人功能"是通用术语,学生在完成实验时应替换为自己实际负责的具体功能。例如:
- 范孝宝同学应将"个人功能"替换为"注册登录功能"
- 程璟琦同学应将"个人功能"替换为"订单支付与管理功能"
- 董文远同学应将"个人功能"替换为"人员交互功能"
- 董玉坤同学应将"个人功能"替换为"数据统计与可视化功能"
## 1. 实验环境与工具
### 1.1 硬件环境
- 个人计算机Windows 10/11操作系统
- 内存8GB以上
- 存储空间50GB以上可用空间
- 网络连接:稳定的互联网连接
### 1.2 软件环境
- **集成开发环境**IntelliJ IDEA 2023.2.5
- **版本控制系统**Git 2.43.0
- **代码托管平台**Gitea 1.21.0
- **持续集成工具**Jenkins 2.450
- **代码质量检测**SonarQube 9.9.0
- **数据库管理系统**PostgreSQL 15.4
- **UML建模工具**Enterprise Architect 16.1
- **项目构建工具**Maven 3.9.5
- **Java开发环境**JDK 17.0.9
### 1.3 工具安装与配置
请按照以下步骤安装和配置实验所需的工具:
1. **安装JDK 17**
- 从Oracle官网或OpenJDK官网下载JDK 17安装包
- 按照安装向导完成安装
- 配置环境变量JAVA_HOME指向JDK安装目录
- 将%JAVA_HOME%\bin添加到系统PATH中
2. **安装IntelliJ IDEA**
- 从JetBrains官网下载IntelliJ IDEA Ultimate或Community版本
- 按照安装向导完成安装
3. **安装Git**
- 从Git官网下载Git安装包
- 按照安装向导完成安装
- 配置Git用户名和邮箱
```bash
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
```
4. **安装PostgreSQL**
- 从PostgreSQL官网下载PostgreSQL 15.4安装包
- 按照安装向导完成安装
- 记住设置的数据库超级用户密码
- 启动PostgreSQL服务
5. **安装Maven**
- 从Apache Maven官网下载Maven 3.9.5
- 解压到本地目录
- 配置环境变量MAVEN_HOME指向Maven安装目录
- 将%MAVEN_HOME%\bin添加到系统PATH中
## 2. 实验目的与要求
### 2.1 实验目的
1. 掌握软件系统设计的基本原理和方法
2. 熟悉UML建模工具的使用
3. 学会使用Enterprise Architect绘制各种UML图表
4. 理解软件系统的架构设计和详细设计过程
5. 培养团队协作能力,完成一个完整的软件系统设计
### 2.2 实验要求
1. **团队协作**4人一组分工明确共同完成校园代取系统的设计
2. **UML建模**使用Enterprise Architect绘制以下UML图表
- 用例图
- 类图
- 序列图
- 活动图
- 状态图
- 组件图
- 部署图
3. **文档编写**:按照软件系统设计规范,编写详细的设计文档
4. **代码实现**:根据设计文档,实现校园代取系统的核心功能
5. **版本控制**使用Git进行版本控制按照分支管理规范进行开发
6. **质量保证**使用SonarQube进行代码质量检测确保代码质量
## 3. 个人功能清单与团队协作
### 3.1 个人功能清单
每位成员需要在feature_姓名拼音缩写分支中完成以下任务
1. **董玉坤(项目组长)**
- 负责项目整体规划和协调
- 负责数据统计与可视化功能的完整开发
- 完成相关功能的完整测试
- 完成相关功能的完整运维
- 完成相关功能的完整模型绘制
- 在feature_dyk分支中完成个人功能
2. **董文远开发人员1**
- 负责人员交互功能的完整开发
- 完成相关功能的完整测试
- 完成相关功能的完整运维
- 完成相关功能的完整模型绘制
- 在feature_dwy分支中完成个人功能
3. **程璟琦开发人员2**
- 负责订单支付与管理功能的完整开发
- 完成相关功能的完整测试
- 完成相关功能的完整运维
- 完成相关功能的完整模型绘制
- 在feature_cjq分支中完成个人功能
4. **范孝宝开发人员3**
- 负责注册登录功能的完整开发
- 完成相关功能的完整测试
- 完成相关功能的完整运维
- 完成相关功能的完整模型绘制
- 在feature_fxb分支中完成个人功能
### 3.2 个人功能完整开发测试流程
每位成员需要按照以下流程完成个人功能的开发和测试:
1. **需求分析**:理解个人功能的需求,绘制相关的用例图
2. **设计阶段**
- 绘制类图,定义类的属性和方法
- 绘制序列图,描述对象之间的交互
- 绘制活动图,描述业务流程
- 绘制状态图,描述对象的状态变化
3. **实现阶段**
- 在feature分支中编写代码
- 实现功能的核心逻辑
- 编写单元测试
4. **测试阶段**
- 执行单元测试
- 进行集成测试
- 修复发现的问题
5. **部署阶段**
- 构建项目
- 部署到测试环境
- 进行系统测试
6. **代码质量**
- 使用SonarQube检测代码质量
- 修复代码质量问题
- 确保代码覆盖率达到要求
### 3.3 团队协作流程
1. **项目初始化**
- 创建Git仓库
- 初始化Maven项目
- 配置.gitignore文件
- 创建开发分支和feature分支
2. **分支管理**
- 使用Git Flow工作流
- 主分支main用于发布
- 开发分支develop用于集成
- 特性分支feature_xx用于开发特定功能
- 发布分支release_xx用于发布准备
- 热修复分支hotfix_xx用于紧急修复
3. **代码提交规范**
- 提交信息应清晰、简洁
- 遵循"提交类型: 提交描述"的格式
- 常见的提交类型feat新功能、fix修复、docs文档、style代码风格、refactor重构、test测试、chore构建/依赖)
4. **代码审查**
- 功能开发完成后提交Pull Request
- 团队成员进行代码审查
- 审查通过后合并到develop分支
5. **集成测试**
- 定期在develop分支上进行集成测试
- 确保各个功能模块能够正常协同工作
- 修复集成测试中发现的问题
6. **发布流程**
- 从develop分支创建release分支
- 在release分支上进行最终的测试和修复
- 发布完成后合并到main分支并打标签
- 同时将release分支合并回develop分支
## 4. 详细实验步骤
### 4.1 第一课时90分钟项目初始化与需求分析
#### 4.1.1 项目初始化30分钟
1. **创建Git仓库**
- 在Gitea上创建新的仓库命名为"campus-delivery-system"
- 克隆仓库到本地:`git clone <仓库URL>`
- 进入项目目录:`cd campus-delivery-system`
2. **初始化Maven项目**
- 使用IntelliJ IDEA创建新的Maven项目
- 选择Java 17作为项目SDK
- 配置项目坐标GroupId、ArtifactId、Version
3. **配置.gitignore文件**
- 创建.gitignore文件添加常见的忽略项
```gitignore
# IDE files
.idea/
*.iml
*.ipr
*.iws
# Build files
target/
build/
# OS files
.DS_Store
Thumbs.db
# Log files
logs/
*.log
# Database files
*.db
*.sqlite
# Environment files
.env
.env.local
.env.*.local
# Maven files
.mvn/
mvnw
mvnw.cmd
```
4. **创建分支**
- 创建develop分支`git checkout -b develop`
- 为每位成员创建feature分支
```bash
git checkout -b feature_dyk develop
git checkout -b feature_dwy develop
git checkout -b feature_cjq develop
git checkout -b feature_fxb develop
```
#### 4.1.2 需求分析60分钟
1. **理解项目需求**
- 阅读校园代取系统的需求文档
- 明确系统的核心功能和非功能需求
- 讨论系统的业务流程和用户场景
2. **绘制用例图**
- 使用Enterprise Architect创建新的UML模型
- 为校园代取系统创建用例图
- 识别主要参与者(用户、代取人、管理员)
- 识别主要用例(注册、登录、发布订单、接单、完成订单、支付、评价等)
- 定义用例之间的关系(包含、扩展、泛化)
3. **需求规约文档**
- 编写需求规约文档,包含:
- 功能需求Functional Requirements
- 非功能需求Non-Functional Requirements
- 数据需求
- 范围限定
### 4.2 第二课时90分钟系统设计与详细设计
#### 4.2.1 系统设计45分钟
1. **架构设计**
- 确定系统的技术架构(前端、后端、数据库)
- 设计系统的分层结构(表现层、业务逻辑层、数据访问层)
- 定义系统的模块划分(用户管理、订单管理、支付管理、系统管理)
2. **数据库设计**
- 设计数据库表结构
- 定义表之间的关系(一对一、一对多、多对多)
- 设计数据字典,定义字段的类型、长度、约束等
3. **接口设计**
- 设计系统的API接口
- 定义接口的URL、请求方法、请求参数、响应格式
- 设计接口的错误处理机制
#### 4.2.2 详细设计45分钟
1. **类图设计**
- 使用Enterprise Architect绘制类图
- 定义系统中的主要类
- 定义类的属性和方法
- 定义类之间的关系(继承、实现、关联、聚合、组合)
2. **序列图设计**
- 为核心业务流程绘制序列图
- 描述对象之间的交互过程
- 展示消息的传递顺序和时序关系
3. **活动图设计**
- 为复杂业务流程绘制活动图
- 描述业务流程的各个步骤和分支
- 展示活动之间的流转关系
4. **状态图设计**
- 为重要对象(如订单)绘制状态图
- 定义对象的各个状态
- 定义状态之间的转换条件和事件
### 4.3 第三课时90分钟组件设计与部署设计
#### 4.3.1 组件设计45分钟
1. **组件识别**
- 识别系统中的主要组件
- 定义组件的职责和功能
- 确定组件之间的依赖关系
2. **组件图设计**
- 使用Enterprise Architect绘制组件图
- 展示组件之间的依赖关系和交互方式
- 定义组件的接口和端口
3. **组件接口设计**
- 设计组件的输入和输出接口
- 定义接口的方法和参数
- 确保接口的一致性和可扩展性
#### 4.3.2 部署设计45分钟
1. **部署环境分析**
- 分析系统的部署环境需求
- 确定部署的硬件和软件要求
- 考虑系统的可扩展性和容错性
2. **部署图设计**
- 使用Enterprise Architect绘制部署图
- 展示系统的物理部署架构
- 定义节点、设备和连接
3. **部署方案设计**
- 设计系统的部署方案
- 考虑负载均衡和高可用性
- 设计系统的监控和维护方案
## 5. 实验成果与提交要求
### 5.1 实验成果
每位成员需要提交以下实验成果:
1. **UML模型文件**
- 使用Enterprise Architect创建的UML模型文件.eapx
- 包含所有要求的UML图表
2. **设计文档**
- 详细的软件系统设计文档Markdown格式
- 包含需求分析、系统设计、详细设计、组件设计、部署设计等部分
3. **代码实现**
- 个人功能的完整代码实现
- 单元测试代码
- 集成测试代码
4. **测试报告**
- 个人功能的测试报告
- 包含测试用例、测试结果、测试覆盖率等
5. **版本控制记录**
- Git仓库的完整提交历史
- 按照分支管理规范进行开发的记录
### 5.2 提交要求
1. **提交方式**
- 将所有实验成果上传到Gitea仓库
- 在头歌平台上提交仓库链接和实验报告
2. **提交时间**
- 实验完成后一周内提交
- 逾期提交将影响实验成绩
3. **文档格式**
- 设计文档使用Markdown格式
- 代码注释符合JavaDoc规范
- 提交信息清晰、简洁
4. **代码质量**
- SonarQube代码质量检测结果应达到A等级
- 代码覆盖率应达到80%以上
- 无严重的代码质量问题
## 6. 评分标准
### 6.1 个人评分70%
1. **需求分析10%**
- 需求理解的准确性和完整性
- 用例图的正确性和完整性
2. **系统设计15%**
- 架构设计的合理性
- 数据库设计的正确性
- 接口设计的完整性
3. **详细设计20%**
- 类图、序列图、活动图、状态图的正确性和完整性
- 设计的合理性和可扩展性
4. **代码实现15%**
- 代码的正确性和完整性
- 代码的可读性和可维护性
- 单元测试的覆盖率和质量
5. **测试与质量10%**
- 测试报告的完整性和准确性
- SonarQube代码质量检测结果
### 6.2 团队评分30%
1. **团队协作10%**
- 分支管理的规范性
- 代码审查的有效性
- 团队沟通的顺畅性
2. **集成测试10%**
- 集成测试的完整性
- 系统的整体功能是否正常
3. **项目文档10%**
- 项目文档的完整性和质量
- 文档的一致性和准确性
## 7. 注意事项与常见问题
### 7.1 注意事项
1. **工具使用**
- 确保所有工具都已正确安装和配置
- 定期备份项目文件,避免数据丢失
2. **版本控制**
- 频繁提交代码,保持提交记录的清晰
- 避免在main分支上直接开发
- 定期从develop分支拉取最新代码
3. **团队协作**
- 保持良好的沟通,及时解决遇到的问题
- 尊重团队成员的工作,避免冲突
- 按照分工完成各自的任务,确保项目进度
4. **代码质量**
- 遵循Java编码规范保持代码风格一致
- 编写清晰的代码注释,提高代码可读性
- 定期使用SonarQube检测代码质量
### 7.2 常见问题
1. **Enterprise Architect使用问题**
- 问题无法创建UML图表
解决确保已正确安装Enterprise Architect并且项目类型设置为UML模型
- 问题:图表无法保存
解决:检查文件权限,确保有写入权限;定期备份模型文件
2. **Git使用问题**
- 问题:分支合并冲突
解决:先从远程仓库拉取最新代码,解决冲突后再提交
- 问题:无法推送代码到远程仓库
解决检查网络连接确保Git凭证正确检查仓库权限
3. **数据库问题**
- 问题:数据库连接失败
解决:检查数据库服务是否启动,检查连接参数是否正确
- 问题SQL语句执行错误
解决检查SQL语句语法确保表结构已正确创建
4. **代码实现问题**
- 问题:依赖包缺失
解决检查pom.xml文件确保所有依赖都已正确配置
- 问题:编译错误
解决:检查代码语法,确保所有依赖都已正确导入
5. **测试问题**
- 问题:测试用例失败
解决:检查测试用例逻辑,确保测试环境正确
- 问题:测试覆盖率低
解决:增加测试用例,覆盖更多的代码路径
## 8. 参考资料
1. **UML建模指南**
- 《UML精粹标准对象建模语言简明指南》
- 《UML用户指南》
- Enterprise Architect官方文档
2. **软件设计相关书籍**
- 《设计模式:可复用面向对象软件的基础》
- 《重构:改善既有代码的设计》
- 《代码整洁之道》
3. **工具使用文档**
- Git官方文档https://git-scm.com/doc
- Maven官方文档https://maven.apache.org/guides/
- PostgreSQL官方文档https://www.postgresql.org/docs/
- Jenkins官方文档https://www.jenkins.io/doc/
- SonarQube官方文档https://docs.sonarqube.org/
4. **Java开发相关资源**
- Java官方文档https://docs.oracle.com/en/java/
- Spring Boot官方文档https://spring.io/projects/spring-boot
- IntelliJ IDEA官方文档https://www.jetbrains.com/idea/documentation/
5. **代码规范**
- Google Java编码规范https://google.github.io/styleguide/javaguide.html
- Alibaba Java开发手册https://github.com/alibaba/p3c
## 9. 附录
### 9.1 项目结构参考
```
campus-delivery-system/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── campus/
│ │ │ └── delivery/
│ │ │ ├── controller/ # 控制器层
│ │ │ ├── service/ # 业务逻辑层
│ │ │ ├── dao/ # 数据访问层
│ │ │ ├── model/ # 数据模型
│ │ │ ├── dto/ # 数据传输对象
│ │ │ ├── utils/ # 工具类
│ │ │ ├── config/ # 配置类
│ │ │ └── Application.java # 应用入口
│ │ ├── resources/
│ │ │ ├── application.yml # 应用配置
│ │ │ ├── application-dev.yml # 开发环境配置
│ │ │ ├── application-prod.yml # 生产环境配置
│ │ │ └── mapper/ # MyBatis映射文件
│ │ └── webapp/
│ │ └── WEB-INF/ # Web资源
│ └── test/
│ └── java/ # 测试代码
├── pom.xml # Maven项目配置
├── .gitignore # Git忽略文件
├── README.md # 项目说明
└── docs/ # 文档目录
├── design/ # 设计文档
├── uml/ # UML图表
└── test/ # 测试文档
```
### 9.2 数据库表结构参考
#### 用户表user
| 字段名 | 数据类型 | 约束 | 描述 |
| :--- | :--- | :--- | :--- |
| `id` | `BIGINT` | `PRIMARY KEY, AUTO_INCREMENT` | 用户ID |
| `username` | `VARCHAR(50)` | `UNIQUE, NOT NULL` | 用户名 |
| `password` | `VARCHAR(100)` | `NOT NULL` | 密码(加密存储) |
| `name` | `VARCHAR(50)` | `NOT NULL` | 真实姓名 |
| `phone` | `VARCHAR(20)` | `UNIQUE, NOT NULL` | 手机号码 |
| `email` | `VARCHAR(100)` | `UNIQUE` | 邮箱地址 |
| `role` | `VARCHAR(20)` | `NOT NULL, DEFAULT 'USER'` | 角色USER/DELIVER/ADMIN |
| `status` | `VARCHAR(20)` | `NOT NULL, DEFAULT 'ACTIVE'` | 状态ACTIVE/INACTIVE/BLOCKED |
| `created_at` | `TIMESTAMP` | `NOT NULL, DEFAULT CURRENT_TIMESTAMP` | 创建时间 |
| `updated_at` | `TIMESTAMP` | `NOT NULL, DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP` | 更新时间 |
#### 订单表order
| 字段名 | 数据类型 | 约束 | 描述 |
| :--- | :--- | :--- | :--- |
| `id` | `BIGINT` | `PRIMARY KEY, AUTO_INCREMENT` | 订单ID |
| `order_no` | `VARCHAR(50)` | `UNIQUE, NOT NULL` | 订单号 |
| `user_id` | `BIGINT` | `NOT NULL, FOREIGN KEY REFERENCES user(id)` | 发布用户ID |
| `deliver_id` | `BIGINT` | `FOREIGN KEY REFERENCES user(id)` | 代取人ID |
| `pickup_location` | `VARCHAR(200)` | `NOT NULL` | 取件地点 |
| `delivery_location` | `VARCHAR(200)` | `NOT NULL` | 送达地点 |
| `item_description` | `VARCHAR(500)` | `NOT NULL` | 物品描述 |
| `expected_time` | `TIMESTAMP` | `NOT NULL` | 期望完成时间 |
| `amount` | `DECIMAL(10,2)` | `NOT NULL` | 支付金额 |
| `status` | `VARCHAR(20)` | `NOT NULL, DEFAULT 'PENDING'` | 订单状态PENDING/PAID/ACCEPTED/IN_PROGRESS/COMPLETED/CANCELLED |
| `payment_status` | `VARCHAR(20)` | `NOT NULL, DEFAULT 'UNPAID'` | 支付状态UNPAID/PAID/REFUNDED |
| `evaluation_score` | `INT` | `CHECK (evaluation_score BETWEEN 1 AND 5)` | 评价分数 |
| `evaluation_comment` | `VARCHAR(500)` | | 评价内容 |
| `created_at` | `TIMESTAMP` | `NOT NULL, DEFAULT CURRENT_TIMESTAMP` | 创建时间 |
| `updated_at` | `TIMESTAMP` | `NOT NULL, DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP` | 更新时间 |
#### 支付记录表payment_record
| 字段名 | 数据类型 | 约束 | 描述 |
| :--- | :--- | :--- | :--- |
| `id` | `BIGINT` | `PRIMARY KEY, AUTO_INCREMENT` | 支付记录ID |
| `order_id` | `BIGINT` | `NOT NULL, FOREIGN KEY REFERENCES order(id)` | 订单ID |
| `user_id` | `BIGINT` | `NOT NULL, FOREIGN KEY REFERENCES user(id)` | 用户ID |
| `amount` | `DECIMAL(10,2)` | `NOT NULL` | 支付金额 |
| `payment_method` | `VARCHAR(50)` | `NOT NULL` | 支付方式WECHAT/ALIPAY |
| `transaction_id` | `VARCHAR(100)` | `UNIQUE, NOT NULL` | 交易ID |
| `status` | `VARCHAR(20)` | `NOT NULL, DEFAULT 'PENDING'` | 支付状态PENDING/SUCCESS/FAILED |
| `created_at` | `TIMESTAMP` | `NOT NULL, DEFAULT CURRENT_TIMESTAMP` | 创建时间 |
| `updated_at` | `TIMESTAMP` | `NOT NULL, DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP` | 更新时间 |
### 9.3 接口设计参考
#### 用户管理接口
| API路径 | 方法 | 模块/文件 | 类型 | 功能描述 | 请求体JSON | 成功响应200 OK |
| :--- | :--- | :--- | :--- | :--- | :--- | :--- |
| `/api/auth/register` | `POST` | `AuthController` | `Router` | 用户注册 | `{"username": "user1", "password": "123456", "name": "张三", "phone": "13800138000", "email": "zhangsan@example.com"}` | `{"code": 200, "message": "注册成功", "data": {"id": 1, "username": "user1", "name": "张三", "phone": "13800138000", "email": "zhangsan@example.com", "role": "USER", "status": "ACTIVE"}}` |
| `/api/auth/login` | `POST` | `AuthController` | `Router` | 用户登录 | `{"username": "user1", "password": "123456"}` | `{"code": 200, "message": "登录成功", "data": {"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "user": {"id": 1, "username": "user1", "name": "张三", "phone": "13800138000", "email": "zhangsan@example.com", "role": "USER", "status": "ACTIVE"}}}` |
| `/api/users/me` | `GET` | `UserController` | `Router` | 获取当前用户信息 | N/A | `{"code": 200, "message": "获取成功", "data": {"id": 1, "username": "user1", "name": "张三", "phone": "13800138000", "email": "zhangsan@example.com", "role": "USER", "status": "ACTIVE"}}` |
| `/api/users/me` | `PUT` | `UserController` | `Router` | 更新当前用户信息 | `{"name": "张三", "phone": "13800138000", "email": "zhangsan@example.com"}` | `{"code": 200, "message": "更新成功", "data": {"id": 1, "username": "user1", "name": "张三", "phone": "13800138000", "email": "zhangsan@example.com", "role": "USER", "status": "ACTIVE"}}` |
| `/api/users/me/password` | `PUT` | `UserController` | `Router` | 修改密码 | `{"oldPassword": "123456", "newPassword": "654321"}` | `{"code": 200, "message": "密码修改成功"}` |
#### 订单管理接口
| API路径 | 方法 | 模块/文件 | 类型 | 功能描述 | 请求体JSON | 成功响应200 OK |
| :--- | :--- | :--- | :--- | :--- | :--- | :--- |
| `/api/orders` | `POST` | `OrderController` | `Router` | 创建订单 | `{"pickupLocation": "快递点A", "deliveryLocation": "宿舍1号楼", "itemDescription": "快递包裹", "expectedTime": "2025-11-25 12:00:00", "amount": 10.00}` | `{"code": 200, "message": "订单创建成功", "data": {"id": 1, "orderNo": "ORD202511240001", "pickupLocation": "快递点A", "deliveryLocation": "宿舍1号楼", "itemDescription": "快递包裹", "expectedTime": "2025-11-25 12:00:00", "amount": 10.00, "status": "PENDING", "paymentStatus": "UNPAID", "userId": 1, "createdAt": "2025-11-24 10:00:00", "updatedAt": "2025-11-24 10:00:00"}}` |
| `/api/orders` | `GET` | `OrderController` | `Router` | 获取订单列表 | N/A | `{"code": 200, "message": "获取成功", "data": [{"id": 1, "orderNo": "ORD202511240001", "pickupLocation": "快递点A", "deliveryLocation": "宿舍1号楼", "itemDescription": "快递包裹", "expectedTime": "2025-11-25 12:00:00", "amount": 10.00, "status": "PENDING", "paymentStatus": "UNPAID", "userId": 1, "createdAt": "2025-11-24 10:00:00", "updatedAt": "2025-11-24 10:00:00"}]}` |
| `/api/orders/{id}` | `GET` | `OrderController` | `Router` | 获取订单详情 | N/A | `{"code": 200, "message": "获取成功", "data": {"id": 1, "orderNo": "ORD202511240001", "pickupLocation": "快递点A", "deliveryLocation": "宿舍1号楼", "itemDescription": "快递包裹", "expectedTime": "2025-11-25 12:00:00", "amount": 10.00, "status": "PENDING", "paymentStatus": "UNPAID", "userId": 1, "createdAt": "2025-11-24 10:00:00", "updatedAt": "2025-11-24 10:00:00"}}` |
| `/api/orders/{id}/cancel` | `PUT` | `OrderController` | `Router` | 取消订单 | N/A | `{"code": 200, "message": "订单取消成功", "data": {"id": 1, "orderNo": "ORD202511240001", "status": "CANCELLED", "paymentStatus": "REFUNDED"}}` |
| `/api/orders/{id}/accept` | `PUT` | `OrderController` | `Router` | 接单 | N/A | `{"code": 200, "message": "接单成功", "data": {"id": 1, "orderNo": "ORD202511240001", "status": "ACCEPTED", "deliverId": 2}}` |
| `/api/orders/{id}/complete` | `PUT` | `OrderController` | `Router` | 完成订单 | N/A | `{"code": 200, "message": "订单完成成功", "data": {"id": 1, "orderNo": "ORD202511240001", "status": "COMPLETED"}}` |
| `/api/orders/{id}/evaluate` | `POST` | `OrderController` | `Router` | 评价订单 | `{"score": 5, "comment": "服务很好"}` | `{"code": 200, "message": "评价成功", "data": {"id": 1, "orderNo": "ORD202511240001", "evaluationScore": 5, "evaluationComment": "服务很好"}}` |
#### 支付管理接口
| API路径 | 方法 | 模块/文件 | 类型 | 功能描述 | 请求体JSON | 成功响应200 OK |
| :--- | :--- | :--- | :--- | :--- | :--- | :--- |
| `/api/payments/order/{orderId}` | `POST` | `PaymentController` | `Router` | 支付订单 | `{"paymentMethod": "WECHAT"}` | `{"code": 200, "message": "支付请求发起成功", "data": {"paymentUrl": "https://wx.tenpay.com/pay?prepay_id=wx2410000000000000000000000000", "paymentId": 1}}` |
| `/api/payments/{id}/callback` | `POST` | `PaymentController` | `Router` | 支付回调 | `{"transactionId": "4200000000000000000000000000", "status": "SUCCESS", "amount": 10.00}` | `{"code": 200, "message": "回调处理成功"}` |
| `/api/payments/{id}/status` | `GET` | `PaymentController` | `Router` | 查询支付状态 | N/A | `{"code": 200, "message": "查询成功", "data": {"id": 1, "orderId": 1, "transactionId": "4200000000000000000000000000", "status": "SUCCESS", "amount": 10.00}}` |
| `/api/payments/history` | `GET` | `PaymentController` | `Router` | 获取支付历史 | N/A | `{"code": 200, "message": "获取成功", "data": [{"id": 1, "orderId": 1, "amount": 10.00, "paymentMethod": "WECHAT", "transactionId": "4200000000000000000000000000", "status": "SUCCESS", "createdAt": "2025-11-24 10:05:00"}]}` |

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Loading…
Cancel
Save