Commit 3b8e2c66aeb2370b7a4698e756dbc50390e564f9

Authored by “wangming”
1 parent 0380c57d

修复GetMemberRemainingItems方法中的数据类型转换问题

- 重构为分步查询方式,避免子查询返回null导致的类型转换错误
- 使用SqlFunc.AggregateSum确保聚合函数返回0而不是null
- 在内存中使用FirstOrDefault和??操作符安全处理null值
- 确保ConsumedCount和RefundedCount始终为decimal类型
- 修复了会员剩余品项查询时的Index was outside the bounds of the array错误
netcore/src/Modularity/Extend/NCC.Extend/LqKhxxService.cs
... ... @@ -548,25 +548,61 @@ namespace NCC.Extend.LqKhxx
548 548 _logger.LogWarning("会员不存在,会员ID:{MemberId}", memberId);
549 549 throw NCCException.Oh("会员不存在");
550 550 }
551   - // 2. 查询开单记录ID列表
552   - var remainingItems = await _db.Queryable<LqKdPxmxEntity>()
  551 + // 2. 分步查询,避免子查询问题
  552 + // 先查询基础品项数据
  553 + var baseItems = await _db.Queryable<LqKdPxmxEntity>()
553 554 .Where(x => x.MemberId == memberId)
554   - .Select(x => new RemainingItemInfo
  555 + .Select(x => new
555 556 {
556   - BillingItemId = x.Id,
557   - ItemId = x.Px,
558   - ItemName = x.Pxmc,
559   - ItemPrice = x.Pxjg,
560   - SourceType = x.SourceType,
561   - TotalPurchased = x.ProjectNumber,
562   - ConsumedCount = SqlFunc.Subqueryable<LqXhPxmxEntity>().Where(y => y.BillingItemId == x.Id).Sum(y => SqlFunc.ToDecimal(y.ProjectNumber)),
563   - RefundedCount = SqlFunc.Subqueryable<LqHytkMxEntity>().Where(y => y.BillingItemId == x.Id).Sum(y => SqlFunc.ToDecimal(y.ProjectNumber)),
  557 + x.Id,
  558 + x.Px,
  559 + x.Pxmc,
  560 + x.Pxjg,
  561 + x.SourceType,
  562 + x.ProjectNumber
564 563 })
565   - .Mapper(x =>
  564 + .ToListAsync();
  565 +
  566 + // 查询消费数据
  567 + var consumedData = await _db.Queryable<LqXhPxmxEntity>()
  568 + .Where(x => baseItems.Select(b => b.Id).Contains(x.BillingItemId))
  569 + .GroupBy(x => x.BillingItemId)
  570 + .Select(x => new
  571 + {
  572 + BillingItemId = x.BillingItemId,
  573 + TotalConsumed = SqlFunc.AggregateSum(x.ProjectNumber)
  574 + })
  575 + .ToListAsync();
  576 +
  577 + // 查询退卡数据
  578 + var refundedData = await _db.Queryable<LqHytkMxEntity>()
  579 + .Where(x => baseItems.Select(b => b.Id).Contains(x.BillingItemId))
  580 + .GroupBy(x => x.BillingItemId)
  581 + .Select(x => new
566 582 {
567   - x.RemainingCount = x.TotalPurchased - x.ConsumedCount - x.RefundedCount;
  583 + BillingItemId = x.BillingItemId,
  584 + TotalRefunded = SqlFunc.AggregateSum(x.ProjectNumber)
568 585 })
569 586 .ToListAsync();
  587 +
  588 + // 组装结果
  589 + var remainingItems = baseItems.Select(item => new RemainingItemInfo
  590 + {
  591 + BillingItemId = item.Id,
  592 + ItemId = item.Px,
  593 + ItemName = item.Pxmc,
  594 + ItemPrice = item.Pxjg,
  595 + SourceType = item.SourceType,
  596 + TotalPurchased = item.ProjectNumber,
  597 + ConsumedCount = consumedData.FirstOrDefault(c => c.BillingItemId == item.Id)?.TotalConsumed ?? 0,
  598 + RefundedCount = refundedData.FirstOrDefault(r => r.BillingItemId == item.Id)?.TotalRefunded ?? 0,
  599 + }).ToList();
  600 +
  601 + // 计算剩余数量
  602 + foreach (var item in remainingItems)
  603 + {
  604 + item.RemainingCount = item.TotalPurchased - item.ConsumedCount - item.RefundedCount;
  605 + }
570 606 return new MemberRemainingItemsOutput
571 607 {
572 608 MemberId = memberId,
... ...