|
|
@@ -166,6 +166,75 @@ export class OrderMtService extends GenericCrudService<OrderMt> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 取消订单
|
|
|
+ * @param tenantId 租户ID
|
|
|
+ * @param orderId 订单ID
|
|
|
+ * @param reason 取消原因
|
|
|
+ * @param userId 用户ID
|
|
|
+ * @returns Promise<void>
|
|
|
+ */
|
|
|
+ async cancelOrder(tenantId: number, orderId: number, reason: string, userId: number): Promise<void> {
|
|
|
+ const queryRunner = this.dataSource.createQueryRunner();
|
|
|
+ await queryRunner.connect();
|
|
|
+ await queryRunner.startTransaction();
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 查询订单信息
|
|
|
+ const order = await this.repository.findOne({
|
|
|
+ where: { id: orderId, tenantId }
|
|
|
+ });
|
|
|
+
|
|
|
+ if (!order) {
|
|
|
+ throw new Error('订单不存在');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证订单状态(仅允许取消支付状态为0或2的订单)
|
|
|
+ if (order.payState !== 0 && order.payState !== 2) {
|
|
|
+ throw new Error('当前订单状态不允许取消');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 对于已支付订单(支付状态=2),需要触发退款流程
|
|
|
+ if (order.payState === 2) {
|
|
|
+ // TODO: 调用支付模块的退款功能(将在Story 3中实现)
|
|
|
+ // 这里先记录日志,后续集成支付退款功能
|
|
|
+ console.log(`订单 ${orderId} 已支付,需要触发退款流程`);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新订单状态为5(订单关闭),记录取消时间和原因
|
|
|
+ await queryRunner.manager.update(OrderMt, { id: orderId, tenantId }, {
|
|
|
+ payState: 5, // 订单关闭
|
|
|
+ cancelReason: reason,
|
|
|
+ cancelTime: new Date(),
|
|
|
+ updatedBy: userId,
|
|
|
+ updatedAt: new Date()
|
|
|
+ });
|
|
|
+
|
|
|
+ // 如果订单是未支付状态,需要恢复商品库存
|
|
|
+ if (order.payState === 0) {
|
|
|
+ // 查询订单商品明细
|
|
|
+ const orderGoods = await this.orderGoodsRepository.find({
|
|
|
+ where: { orderId, tenantId }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 恢复商品库存
|
|
|
+ for (const item of orderGoods) {
|
|
|
+ await queryRunner.manager.update(GoodsMt, { id: item.goodsId, tenantId }, {
|
|
|
+ stock: () => `stock + ${item.num}`,
|
|
|
+ salesNum: () => `sales_num - ${item.num}`
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ await queryRunner.commitTransaction();
|
|
|
+ } catch (error) {
|
|
|
+ await queryRunner.rollbackTransaction();
|
|
|
+ throw error;
|
|
|
+ } finally {
|
|
|
+ await queryRunner.release();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 生成订单号
|
|
|
* 格式:年月日时分秒 + 6位随机数
|