using MiAssessment.Core.Interfaces;
using MiAssessment.Model.Data;
using MiAssessment.Model.Models.Common;
using MiAssessment.Model.Models.Order;
using MiAssessment.Model.Models.Payment;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace MiAssessment.Core.Services;
///
/// 订单服务实现
///
///
/// 提供订单模块的核心业务功能,包括:
/// - 订单列表查询
/// - 订单详情查询
/// - 订单创建
/// - 发起支付
/// - 支付结果查询
///
public class OrderService : IOrderService
{
private readonly MiAssessmentDbContext _dbContext;
private readonly ILogger _logger;
private readonly IWechatPayService _wechatPayService;
private readonly IConfigService _configService;
///
/// 构造函数
///
public OrderService(
MiAssessmentDbContext dbContext,
ILogger logger,
IWechatPayService wechatPayService,
IConfigService configService)
{
_dbContext = dbContext;
_logger = logger;
_wechatPayService = wechatPayService;
_configService = configService;
}
///
public async Task> GetListAsync(long userId, int page, int pageSize, int? orderType)
{
_logger.LogDebug("获取订单列表,userId: {UserId}, page: {Page}, pageSize: {PageSize}, orderType: {OrderType}",
userId, page, pageSize, orderType);
// 确保分页参数有效
if (page < 1) page = 1;
if (pageSize < 1) pageSize = 20;
if (pageSize > 100) pageSize = 100;
// 构建查询 - 用户数据隔离(Requirements 7.1)
// 只展示已支付或退款的订单,排除待支付(1)和已取消(6)(Requirements 9)
var query = _dbContext.Orders
.AsNoTracking()
.Where(o => o.UserId == userId && !o.IsDeleted && o.Status != 1 && o.Status != 6);
// 支持按订单类型筛选(Requirements 7.1)
if (orderType.HasValue)
{
query = query.Where(o => o.OrderType == orderType.Value);
}
// 获取总数
var total = await query.CountAsync();
// 分页查询,按创建时间降序排列
var orders = await query
.OrderByDescending(o => o.CreateTime)
.Skip((page - 1) * pageSize)
.Take(pageSize)
.Select(o => new OrderItemDto
{
Id = o.Id,
OrderNo = o.OrderNo,
OrderType = o.OrderType,
ProductName = o.ProductName,
Amount = o.Amount,
Status = o.Status,
StatusText = GetOrderStatusText(o.Status),
CreateTime = o.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"),
AssessmentRecordId = null // 稍后填充
})
.ToListAsync();
// 获取测评订单关联的测评记录信息(ID + 状态)
if (orders.Any(o => o.OrderType == 1))
{
var orderIds = orders.Where(o => o.OrderType == 1).Select(o => o.Id).ToList();
var assessmentRecords = await _dbContext.AssessmentRecords
.AsNoTracking()
.Where(r => orderIds.Contains(r.OrderId) && !r.IsDeleted)
.Select(r => new { r.OrderId, r.Id, r.Status })
.ToListAsync();
foreach (var order in orders.Where(o => o.OrderType == 1))
{
var record = assessmentRecords.FirstOrDefault(r => r.OrderId == order.Id);
if (record != null)
{
order.AssessmentRecordId = record.Id;
order.AssessmentStatus = record.Status;
}
}
}
// 获取规划订单关联的预约记录状态
if (orders.Any(o => o.OrderType == 2))
{
var bookingOrderIds = orders.Where(o => o.OrderType == 2).Select(o => o.Id).ToList();
var bookings = await _dbContext.PlannerBookings
.AsNoTracking()
.Where(b => bookingOrderIds.Contains(b.OrderId) && !b.IsDeleted)
.Select(b => new { b.OrderId, b.Status })
.ToListAsync();
foreach (var order in orders.Where(o => o.OrderType == 2))
{
var booking = bookings.FirstOrDefault(b => b.OrderId == order.Id);
if (booking != null)
{
order.BookingStatus = booking.Status;
}
}
}
// 计算综合显示状态文本
foreach (var order in orders)
{
order.DisplayStatusText = GetDisplayStatusText(order.Status, order.AssessmentStatus, order.OrderType, order.BookingStatus);
}
_logger.LogDebug("获取到 {Count} 条订单记录,总数: {Total}", orders.Count, total);
return PagedResult.Create(orders, total, page, pageSize);
}
///
public async Task GetDetailAsync(long userId, long orderId)
{
_logger.LogDebug("获取订单详情,userId: {UserId}, orderId: {OrderId}", userId, orderId);
// 查询订单,验证归属当前用户(Requirements 7.2, 7.3)
var order = await _dbContext.Orders
.AsNoTracking()
.Where(o => o.Id == orderId && !o.IsDeleted)
.FirstOrDefaultAsync();
// 订单不存在
if (order == null)
{
_logger.LogWarning("订单不存在,orderId: {OrderId}", orderId);
return null;
}
// 验证订单归属当前用户(Requirements 7.3)
if (order.UserId != userId)
{
_logger.LogWarning("订单不属于当前用户,userId: {UserId}, orderUserId: {OrderUserId}, orderId: {OrderId}",
userId, order.UserId, orderId);
return null;
}
// 构建订单详情
var orderDetail = new OrderDetailDto
{
Id = order.Id,
OrderNo = order.OrderNo,
OrderType = order.OrderType,
ProductName = order.ProductName,
Amount = order.Amount,
PayAmount = order.PayAmount,
Status = order.Status,
StatusText = GetOrderStatusText(order.Status),
CreateTime = order.CreateTime.ToString("yyyy-MM-dd HH:mm:ss"),
PayTime = order.PayTime?.ToString("yyyy-MM-dd HH:mm:ss")
};
// 根据订单类型获取关联信息(Requirements 7.2)
if (order.OrderType == 1)
{
// 测评订单 - 获取关联的测评记录
var assessmentRecord = await _dbContext.AssessmentRecords
.AsNoTracking()
.Where(r => r.OrderId == orderId && !r.IsDeleted)
.Join(
_dbContext.AssessmentTypes.AsNoTracking(),
r => r.AssessmentTypeId,
at => at.Id,
(r, at) => new { Record = r, AssessmentType = at }
)
.FirstOrDefaultAsync();
if (assessmentRecord != null)
{
orderDetail.AssessmentRecordId = assessmentRecord.Record.Id;
orderDetail.AssessmentInfo = new OrderAssessmentInfoDto
{
RecordId = assessmentRecord.Record.Id,
AssessmentName = assessmentRecord.AssessmentType.Name,
Status = assessmentRecord.Record.Status,
StatusText = GetAssessmentStatusText(assessmentRecord.Record.Status)
};
}
}
else if (order.OrderType == 2)
{
// 规划订单 - 获取关联的规划预约
var plannerBooking = await _dbContext.PlannerBookings
.AsNoTracking()
.Where(b => b.OrderId == orderId && !b.IsDeleted)
.Join(
_dbContext.Planners.AsNoTracking(),
b => b.PlannerId,
p => p.Id,
(b, p) => new { Booking = b, Planner = p }
)
.FirstOrDefaultAsync();
if (plannerBooking != null)
{
orderDetail.PlannerBookingId = plannerBooking.Booking.Id;
orderDetail.PlannerInfo = new OrderPlannerInfoDto
{
BookingId = plannerBooking.Booking.Id,
PlannerName = plannerBooking.Planner.Name,
Status = plannerBooking.Booking.Status,
StatusText = GetBookingStatusText(plannerBooking.Booking.Status)
};
}
}
_logger.LogDebug("获取订单详情成功,orderId: {OrderId}, orderType: {OrderType}", orderId, order.OrderType);
return orderDetail;
}
///
public async Task GetPayResultAsync(long userId, long orderId)
{
_logger.LogDebug("查询支付结果,userId: {UserId}, orderId: {OrderId}", userId, orderId);
// 查询订单,验证归属当前用户(Requirements 9.2)
var order = await _dbContext.Orders
.AsNoTracking()
.Where(o => o.Id == orderId && !o.IsDeleted)
.FirstOrDefaultAsync();
// 订单不存在
if (order == null)
{
_logger.LogWarning("订单不存在,orderId: {OrderId}", orderId);
return null;
}
// 验证订单归属当前用户
if (order.UserId != userId)
{
_logger.LogWarning("订单不属于当前用户,userId: {UserId}, orderUserId: {OrderUserId}, orderId: {OrderId}",
userId, order.UserId, orderId);
return null;
}
// 构建支付结果
var payResult = new PayResultDto
{
IsPaid = order.Status >= 2 && order.Status != 6, // 已支付、已完成、退款中、已退款都算已支付,已取消不算
Status = order.Status,
AssessmentRecordId = null
};
// 如果是测评订单,获取关联的测评记录ID
if (order.OrderType == 1)
{
var assessmentRecord = await _dbContext.AssessmentRecords
.AsNoTracking()
.Where(r => r.OrderId == orderId && !r.IsDeleted)
.Select(r => r.Id)
.FirstOrDefaultAsync();
if (assessmentRecord > 0)
{
payResult.AssessmentRecordId = assessmentRecord;
}
}
_logger.LogDebug("查询支付结果成功,orderId: {OrderId}, isPaid: {IsPaid}, status: {Status}",
orderId, payResult.IsPaid, payResult.Status);
return payResult;
}
///
public async Task HandlePaymentSuccessAsync(string orderNo, string transactionId)
{
_logger.LogInformation("处理支付成功回调,orderNo: {OrderNo}, transactionId: {TransactionId}", orderNo, transactionId);
var order = await _dbContext.Orders
.FirstOrDefaultAsync(o => o.OrderNo == orderNo && !o.IsDeleted);
if (order == null)
{
_logger.LogWarning("支付回调订单不存在,orderNo: {OrderNo}", orderNo);
return false;
}
// 幂等:已支付的订单不重复处理
if (order.Status >= 2)
{
_logger.LogInformation("订单已处理,跳过,orderNo: {OrderNo}, status: {Status}", orderNo, order.Status);
return true;
}
// 更新订单状态为已支付
order.Status = 2;
order.PayTime = DateTime.Now;
order.TransactionId = transactionId;
order.PayType = 1; // 微信支付
order.UpdateTime = DateTime.Now;
// 测评订单:更新关联的测评记录状态为待测评
if (order.OrderType == 1)
{
var record = await _dbContext.AssessmentRecords
.FirstOrDefaultAsync(r => r.OrderId == order.Id && !r.IsDeleted);
if (record != null)
{
record.Status = 1; // 待测评
record.UpdateTime = DateTime.Now;
}
}
await _dbContext.SaveChangesAsync();
// 佣金分配(Requirements 3.8.3)
try
{
await CreateCommissionsAsync(order);
}
catch (Exception ex)
{
// 佣金分配失败不影响订单状态,记录日志后续补偿
_logger.LogError(ex, "佣金分配异常,orderId: {OrderId},需人工处理", order.Id);
}
_logger.LogInformation("订单支付状态更新成功,orderNo: {OrderNo}, orderId: {OrderId}", orderNo, order.Id);
return true;
}
///
/// 支付成功后创建佣金记录
/// 规则:
/// - 有直接上级和间接上级:直接上级30%,间接上级10%
/// - 只有直接上级无间接上级:直接上级40%
/// - 无上级:不产生佣金
///
private async Task CreateCommissionsAsync(MiAssessment.Model.Entities.Order order)
{
if (order.PayAmount <= 0)
{
_logger.LogDebug("订单实付金额为0,跳过佣金分配,orderId: {OrderId}", order.Id);
return;
}
// 获取下单用户
var user = await _dbContext.Users
.AsNoTracking()
.FirstOrDefaultAsync(u => u.Id == order.UserId && !u.IsDeleted);
if (user == null || !user.ParentUserId.HasValue)
{
_logger.LogDebug("用户无上级,跳过佣金分配,userId: {UserId}", order.UserId);
return;
}
// 读取佣金比例配置
var directRateStr = await _configService.GetConfigValueAsync("commission_rate_direct");
var indirectRateStr = await _configService.GetConfigValueAsync("commission_rate_indirect");
var directRate = decimal.TryParse(directRateStr, out var dr) ? dr : 0.30m;
var indirectRate = decimal.TryParse(indirectRateStr, out var ir) ? ir : 0.10m;
// 查找直接上级
var parentUser = await _dbContext.Users
.FirstOrDefaultAsync(u => u.Id == user.ParentUserId.Value && !u.IsDeleted);
if (parentUser == null)
{
_logger.LogDebug("直接上级用户不存在,跳过佣金分配,parentUserId: {ParentUserId}", user.ParentUserId);
return;
}
// 查找间接上级(上上级)
MiAssessment.Model.Entities.User? grandParentUser = null;
if (parentUser.ParentUserId.HasValue)
{
grandParentUser = await _dbContext.Users
.FirstOrDefaultAsync(u => u.Id == parentUser.ParentUserId.Value && !u.IsDeleted);
}
var now = DateTime.Now;
if (grandParentUser != null)
{
// 有间接上级:直接上级30%,间接上级10%
var directCommission = Math.Round(order.PayAmount * directRate, 2);
var indirectCommission = Math.Round(order.PayAmount * indirectRate, 2);
// 直接上级佣金
_dbContext.Commissions.Add(new MiAssessment.Model.Entities.Commission
{
UserId = parentUser.Id,
FromUserId = user.Id,
OrderId = order.Id,
OrderAmount = order.PayAmount,
CommissionRate = directRate * 100,
CommissionAmount = directCommission,
Level = 1,
Status = 1,
CreateTime = now,
UpdateTime = now
});
parentUser.Balance += directCommission;
parentUser.TotalIncome += directCommission;
parentUser.UpdateTime = now;
// 间接上级佣金
_dbContext.Commissions.Add(new MiAssessment.Model.Entities.Commission
{
UserId = grandParentUser.Id,
FromUserId = user.Id,
OrderId = order.Id,
OrderAmount = order.PayAmount,
CommissionRate = indirectRate * 100,
CommissionAmount = indirectCommission,
Level = 2,
Status = 1,
CreateTime = now,
UpdateTime = now
});
grandParentUser.Balance += indirectCommission;
grandParentUser.TotalIncome += indirectCommission;
grandParentUser.UpdateTime = now;
_logger.LogInformation("佣金分配完成:直接上级{ParentId}获得{DirectAmount},间接上级{GrandParentId}获得{IndirectAmount},orderId: {OrderId}",
parentUser.Id, directCommission, grandParentUser.Id, indirectCommission, order.Id);
}
else
{
// 无间接上级:直接上级获得 directRate + indirectRate
var totalRate = directRate + indirectRate;
var commission = Math.Round(order.PayAmount * totalRate, 2);
_dbContext.Commissions.Add(new MiAssessment.Model.Entities.Commission
{
UserId = parentUser.Id,
FromUserId = user.Id,
OrderId = order.Id,
OrderAmount = order.PayAmount,
CommissionRate = totalRate * 100,
CommissionAmount = commission,
Level = 1,
Status = 1,
CreateTime = now,
UpdateTime = now
});
parentUser.Balance += commission;
parentUser.TotalIncome += commission;
parentUser.UpdateTime = now;
_logger.LogInformation("佣金分配完成:直接上级{ParentId}获得{Amount}(无间接上级),orderId: {OrderId}",
parentUser.Id, commission, order.Id);
}
await _dbContext.SaveChangesAsync();
}
///
///
/// 创建订单
///
///
/// 使用数据库事务确保多表操作的数据一致性(Requirements 8.4, 8.5)
/// - 测评订单:创建订单记录和测评记录(Requirements 8.1)
/// - 规划订单:创建订单记录和规划预约记录(Requirements 8.2)
/// - 邀请码抵扣:金额设为0,标记邀请码已使用(Requirements 8.3)
///
public async Task CreateAsync(long userId, CreateOrderRequest request)
{
_logger.LogDebug("创建订单,userId: {UserId}, orderType: {OrderType}, productId: {ProductId}, inviteCodeId: {InviteCodeId}",
userId, request.OrderType, request.ProductId, request.InviteCodeId);
// 验证订单类型
if (request.OrderType != 1 && request.OrderType != 2)
{
throw new ArgumentException("无效的订单类型");
}
// 获取产品信息和价格
string productName;
decimal amount;
if (request.OrderType == 1)
{
// 测评订单 - 获取测评类型信息
var assessmentType = await _dbContext.AssessmentTypes
.AsNoTracking()
.Where(at => at.Id == request.ProductId && !at.IsDeleted && at.Status == 1)
.FirstOrDefaultAsync();
if (assessmentType == null)
{
throw new ArgumentException("测评类型不存在或已下线");
}
productName = assessmentType.Name;
amount = assessmentType.Price;
// 验证测评信息
if (request.AssessmentInfo == null)
{
throw new ArgumentException("测评订单必须提供测评信息");
}
}
else
{
// 规划订单 - 获取规划师信息
var planner = await _dbContext.Planners
.AsNoTracking()
.Where(p => p.Id == request.ProductId && !p.IsDeleted && p.Status == 1)
.FirstOrDefaultAsync();
if (planner == null)
{
throw new ArgumentException("规划师不存在或已下线");
}
productName = planner.Name + " - 学业规划";
amount = planner.Price;
// 验证规划预约信息
if (request.PlannerInfo == null)
{
throw new ArgumentException("规划订单必须提供预约信息");
}
}
// 计算实付金额
decimal payAmount = amount;
bool needPay = true;
int? payType = null;
// 如果使用邀请码,验证并设置金额为0(Requirements 8.3)
if (request.InviteCodeId.HasValue)
{
var inviteCode = await _dbContext.InviteCodes
.Where(ic => ic.Id == request.InviteCodeId.Value && !ic.IsDeleted)
.FirstOrDefaultAsync();
if (inviteCode == null)
{
throw new ArgumentException("邀请码不存在");
}
if (inviteCode.Status == 3)
{
throw new ArgumentException("邀请码已被使用");
}
if (inviteCode.Status != 2)
{
throw new ArgumentException("邀请码状态无效");
}
// 使用邀请码,金额设为0
payAmount = 0;
needPay = false;
payType = 2; // 邀请码支付
}
// 生成订单编号
var orderNo = GenerateOrderNo();
// 使用事务确保数据一致性(Requirements 8.4, 8.5)
using var transaction = await _dbContext.Database.BeginTransactionAsync();
try
{
var now = DateTime.Now;
// 创建订单记录
var order = new MiAssessment.Model.Entities.Order
{
OrderNo = orderNo,
UserId = userId,
OrderType = request.OrderType,
ProductId = request.ProductId,
ProductName = productName,
Amount = amount,
PayAmount = payAmount,
PayType = payType,
InviteCodeId = request.InviteCodeId,
Status = needPay ? 1 : 2, // 需要支付则待支付,否则已支付
PayTime = needPay ? null : now,
CreateTime = now,
UpdateTime = now,
IsDeleted = false
};
_dbContext.Orders.Add(order);
await _dbContext.SaveChangesAsync();
long? assessmentRecordId = null;
if (request.OrderType == 1)
{
// 测评订单 - 创建测评记录(Requirements 8.1)
// 需要支付的订单,测评记录初始状态为0(待支付),支付成功后由回调设为1(待测评)
// 免支付订单(邀请码)直接设为1(待测评)
var assessmentRecord = new MiAssessment.Model.Entities.AssessmentRecord
{
UserId = userId,
OrderId = order.Id,
AssessmentTypeId = request.ProductId,
Name = request.AssessmentInfo!.Name,
Phone = request.AssessmentInfo.Phone,
Gender = request.AssessmentInfo.Gender,
Age = request.AssessmentInfo.Age,
EducationStage = request.AssessmentInfo.EducationStage,
Province = request.AssessmentInfo.Province,
City = request.AssessmentInfo.City,
District = request.AssessmentInfo.District,
Status = needPay ? 0 : 1, // 需要支付则待支付(0),免支付则待测评(1)
CreateTime = now,
UpdateTime = now,
IsDeleted = false
};
_dbContext.AssessmentRecords.Add(assessmentRecord);
await _dbContext.SaveChangesAsync();
assessmentRecordId = assessmentRecord.Id;
}
else
{
// 规划订单 - 创建规划预约记录(Requirements 8.2)
// 解析预约日期时间
DateTime bookingDate = DateTime.Today;
string bookingTime = "待确认";
if (!string.IsNullOrEmpty(request.PlannerInfo!.BookDateTime))
{
if (DateTime.TryParse(request.PlannerInfo.BookDateTime, out var parsedDateTime))
{
bookingDate = parsedDateTime.Date;
bookingTime = parsedDateTime.ToString("HH:mm");
}
}
var plannerBooking = new MiAssessment.Model.Entities.PlannerBooking
{
UserId = userId,
OrderId = order.Id,
PlannerId = request.ProductId,
BookingDate = bookingDate,
BookingTime = bookingTime,
Name = request.PlannerInfo.Name,
Phone = request.PlannerInfo.Phone,
Gender = 0,
Grade = request.PlannerInfo.Grade,
MajorName = request.PlannerInfo.MajorName,
ScoreChinese = request.PlannerInfo.ScoreChinese,
ScoreMath = request.PlannerInfo.ScoreMath,
ScoreEnglish = request.PlannerInfo.ScoreEnglish,
ScorePhysics = request.PlannerInfo.ScorePhysics,
ScoreChemistry = request.PlannerInfo.ScoreChemistry,
ScoreBiology = request.PlannerInfo.ScoreBiology,
ScoreGeography = request.PlannerInfo.ScoreGeography,
ScorePolitics = request.PlannerInfo.ScorePolitics,
FamilyAtmosphere = request.PlannerInfo.FamilyAtmosphere,
Expectation = request.PlannerInfo.Expectation,
Status = 1, // 待确认
CreateTime = now,
UpdateTime = now,
IsDeleted = false
};
_dbContext.PlannerBookings.Add(plannerBooking);
await _dbContext.SaveChangesAsync();
}
// 如果使用邀请码,标记邀请码已使用(Requirements 8.3)
if (request.InviteCodeId.HasValue)
{
var inviteCode = await _dbContext.InviteCodes
.Where(ic => ic.Id == request.InviteCodeId.Value)
.FirstOrDefaultAsync();
if (inviteCode != null)
{
inviteCode.Status = 3; // 已使用
inviteCode.UseUserId = userId;
inviteCode.UseOrderId = order.Id;
inviteCode.UseTime = now;
inviteCode.UpdateTime = now;
await _dbContext.SaveChangesAsync();
}
}
// 提交事务
await transaction.CommitAsync();
_logger.LogInformation("订单创建成功,orderId: {OrderId}, orderNo: {OrderNo}, orderType: {OrderType}, payAmount: {PayAmount}, needPay: {NeedPay}",
order.Id, orderNo, request.OrderType, payAmount, needPay);
return new CreateOrderResponse
{
OrderId = order.Id,
OrderNo = orderNo,
PayAmount = payAmount,
NeedPay = needPay,
AssessmentRecordId = assessmentRecordId
};
}
catch (Exception ex)
{
// 回滚事务(Requirements 8.4)
await transaction.RollbackAsync();
_logger.LogError(ex, "创建订单失败,userId: {UserId}, orderType: {OrderType}, productId: {ProductId}",
userId, request.OrderType, request.ProductId);
throw;
}
}
///
/// 生成唯一订单编号
///
/// 订单编号,格式:yyyyMMddHHmmss + 6位随机数
private static string GenerateOrderNo()
{
var timestamp = DateTime.Now.ToString("yyyyMMddHHmmss");
var random = new Random().Next(100000, 999999);
return $"{timestamp}{random}";
}
///
///
/// 发起支付
///
///
/// 调用微信支付统一下单接口,返回小程序调起支付所需的参数。
/// - 验证订单存在且归属当前用户
/// - 验证订单状态为待支付(Status=1)
/// - 如果订单已支付(Status>=2)或已取消(Status=6),拒绝支付请求
/// - 调用IWechatPayService发起微信支付
/// Requirements: 9.1, 9.3
///
public async Task PayAsync(long userId, long orderId)
{
_logger.LogDebug("发起支付,userId: {UserId}, orderId: {OrderId}", userId, orderId);
// 1. 查询订单
var order = await _dbContext.Orders
.AsNoTracking()
.Where(o => o.Id == orderId && !o.IsDeleted)
.FirstOrDefaultAsync();
// 2. 验证订单存在
if (order == null)
{
_logger.LogWarning("订单不存在,orderId: {OrderId}", orderId);
throw new ArgumentException("订单不存在");
}
// 3. 验证订单归属当前用户
if (order.UserId != userId)
{
_logger.LogWarning("订单不属于当前用户,userId: {UserId}, orderUserId: {OrderUserId}, orderId: {OrderId}",
userId, order.UserId, orderId);
throw new ArgumentException("无权限操作此订单");
}
// 4. 验证订单状态(Requirements 9.3)
// 订单已支付(Status>=2 且不是已取消)
if (order.Status >= 2 && order.Status != 6)
{
_logger.LogWarning("订单已支付,不能重复支付,orderId: {OrderId}, status: {Status}", orderId, order.Status);
throw new ArgumentException("订单已支付,不能重复支付");
}
// 订单已取消
if (order.Status == 6)
{
_logger.LogWarning("订单已取消,不能支付,orderId: {OrderId}", orderId);
throw new ArgumentException("订单已取消,不能支付");
}
// 订单状态不是待支付
if (order.Status != 1)
{
_logger.LogWarning("订单状态异常,不能支付,orderId: {OrderId}, status: {Status}", orderId, order.Status);
throw new ArgumentException("订单状态异常,不能支付");
}
// 5. 获取用户信息
var user = await _dbContext.Users
.AsNoTracking()
.Where(u => u.Id == userId)
.FirstOrDefaultAsync();
if (user == null)
{
_logger.LogWarning("用户不存在,userId: {UserId}", userId);
throw new ArgumentException("用户不存在");
}
// 6. 构建微信支付请求(Requirements 9.1)
var payRequest = new WechatPayRequest
{
OrderNo = order.OrderNo,
Amount = order.PayAmount,
Body = order.ProductName,
Attach = order.OrderType == 1 ? "assessment" : "planner", // 根据订单类型设置附加数据
OpenId = user.OpenId ?? string.Empty,
UserId = (int)userId
};
_logger.LogDebug("调用微信支付,orderNo: {OrderNo}, amount: {Amount}, body: {Body}",
payRequest.OrderNo, payRequest.Amount, payRequest.Body);
// 7. 调用微信支付服务
var payResult = await _wechatPayService.CreatePaymentAsync(payRequest);
// 8. 检查支付结果
if (payResult.Status != 1 || payResult.Data == null)
{
_logger.LogWarning("微信支付下单失败,orderId: {OrderId}, msg: {Msg}", orderId, payResult.Msg);
throw new InvalidOperationException(payResult.Msg ?? "支付下单失败,请稍后重试");
}
_logger.LogInformation("微信支付下单成功,orderId: {OrderId}, orderNo: {OrderNo}", orderId, order.OrderNo);
// 9. 返回支付参数
return new PayResponse
{
TimeStamp = payResult.Data.TimeStamp,
NonceStr = payResult.Data.NonceStr,
Package = payResult.Data.Package,
SignType = payResult.Data.SignType,
PaySign = payResult.Data.PaySign
};
}
///
/// 获取订单状态文本
///
/// 订单状态值
/// 状态文本
private static string GetOrderStatusText(int status)
{
return status switch
{
1 => "待支付",
2 => "已支付",
3 => "已完成",
4 => "退款中",
5 => "已退款",
6 => "已取消",
_ => "未知"
};
}
///
/// 获取综合显示状态文本(结合订单状态和测评记录状态)
///
/// 订单状态
/// 测评记录状态(可为null)
/// 用于前端展示的状态文本
private static string GetDisplayStatusText(int orderStatus, int? assessmentStatus, int orderType = 1, int? bookingStatus = null)
{
// 退款相关状态优先
if (orderStatus == 4) return "退款中";
if (orderStatus == 5) return "已退款";
if (orderStatus == 6) return "已取消";
if (orderStatus == 1) return "待支付";
// 规划订单,根据预约状态显示
if (orderType == 2 && bookingStatus.HasValue)
{
return GetBookingStatusText(bookingStatus.Value);
}
// 测评订单,根据测评记录状态显示
if (assessmentStatus.HasValue)
{
return assessmentStatus.Value switch
{
1 => "待测评",
2 => "测评中",
3 => "测评生成中",
4 => "已测评",
5 => "生成失败",
6 => "报告生成中",
_ => GetOrderStatusText(orderStatus)
};
}
return GetOrderStatusText(orderStatus);
}
///
/// 获取测评状态文本
///
/// 测评状态值
/// 状态文本
private static string GetAssessmentStatusText(int status)
{
return status switch
{
0 => "待支付",
1 => "待测评",
2 => "测评中",
3 => "生成中",
4 => "已完成",
5 => "生成失败",
6 => "报告生成中",
_ => "未知"
};
}
///
/// 获取预约状态文本
///
/// 预约状态值
/// 状态文本
private static string GetBookingStatusText(int status)
{
return status switch
{
1 => "待联系",
2 => "联系中",
3 => "已完成",
4 => "已取消",
_ => "未知"
};
}
}