feat: 新增尊享包利润统计接口及 ElCollapseTransition 类型声明

- 在 AiAccountService 中新增 GetProfitStatisticsAsync 接口(GET account/profit-statistics),注入 PremiumPackage 仓储并统计尊享包已消耗/剩余、总成本、总收益、利润率及按200售价的成本估算。接口受授权控制。
- 注入 ISqlSugarRepository<PremiumPackageAggregateRoot> 并在构造函数中赋值。
- 在 types/components.d.ts 中新增 ElCollapseTransition 类型声明,补充前端组件类型提示。
- 注意:接口中对用户权限的判断使用了 "CurrentUser.UserName != \"Guo\" || CurrentUser.UserName != \"cc\"",该逻辑可能有误(应为 &&),建议确认并修正权限校验。
This commit is contained in:
chenchun
2025-10-30 14:38:58 +08:00
parent cf137f6307
commit 933cbb91d8
2 changed files with 78 additions and 1 deletions

View File

@@ -17,15 +17,18 @@ public class AiAccountService : ApplicationService
private IAccountService _accountService; private IAccountService _accountService;
private ISqlSugarRepository<AiUserExtraInfoEntity> _userRepository; private ISqlSugarRepository<AiUserExtraInfoEntity> _userRepository;
private ISqlSugarRepository<AiRechargeAggregateRoot> _rechargeRepository; private ISqlSugarRepository<AiRechargeAggregateRoot> _rechargeRepository;
private ISqlSugarRepository<PremiumPackageAggregateRoot> _premiumPackageRepository;
public AiAccountService( public AiAccountService(
IAccountService accountService, IAccountService accountService,
ISqlSugarRepository<AiUserExtraInfoEntity> userRepository, ISqlSugarRepository<AiUserExtraInfoEntity> userRepository,
ISqlSugarRepository<AiRechargeAggregateRoot> rechargeRepository) ISqlSugarRepository<AiRechargeAggregateRoot> rechargeRepository,
ISqlSugarRepository<PremiumPackageAggregateRoot> premiumPackageRepository)
{ {
_accountService = accountService; _accountService = accountService;
_userRepository = userRepository; _userRepository = userRepository;
_rechargeRepository = rechargeRepository; _rechargeRepository = rechargeRepository;
_premiumPackageRepository = premiumPackageRepository;
} }
/// <summary> /// <summary>
@@ -72,4 +75,77 @@ public class AiAccountService : ApplicationService
return output; return output;
} }
/// <summary>
/// 获取利润统计数据
/// </summary>
/// <param name="currentCost">当前成本(RMB)</param>
/// <returns></returns>
[Authorize]
[HttpGet("account/profit-statistics")]
public async Task<string> GetProfitStatisticsAsync([FromQuery] decimal currentCost)
{
if (CurrentUser.UserName != "Guo" || CurrentUser.UserName != "cc")
{
throw new UserFriendlyException("您暂无权限访问");
}
// 1. 获取尊享包总消耗和剩余库存
var premiumPackages = await _premiumPackageRepository._DbQueryable.ToListAsync();
long totalUsedTokens = premiumPackages.Sum(p => p.UsedTokens);
long totalRemainingTokens = premiumPackages.Sum(p => p.RemainingTokens);
// 2. 计算1亿Token成本
decimal costPerHundredMillion = totalUsedTokens > 0
? currentCost / (totalUsedTokens / 100000000m)
: 0;
// 3. 计算总成本(剩余+已使用的总成本)
long totalTokens = totalUsedTokens + totalRemainingTokens;
decimal totalCost = totalTokens > 0
? (totalTokens / 100000000m) * costPerHundredMillion
: 0;
// 4. 获取总收益(RechargeType=PremiumPackage的充值金额总和)
decimal totalRevenue = await _rechargeRepository._DbQueryable
.Where(x => x.RechargeType == Domain.Shared.Enums.RechargeTypeEnum.PremiumPackage)
.SumAsync(x => x.RechargeAmount);
// 5. 计算利润率
decimal profitRate = totalCost > 0
? (totalRevenue / totalCost - 1) * 100
: 0;
// 6. 按200售价计算成本
decimal costAt200Price = totalRevenue > 0
? (totalCost / totalRevenue) * 200
: 0;
// 7. 格式化输出
var today = DateTime.Now;
string dayOfWeek = today.ToString("dddd", new System.Globalization.CultureInfo("zh-CN"));
string weekDay = dayOfWeek switch
{
"星期一" => "周1",
"星期二" => "周2",
"星期三" => "周3",
"星期四" => "周4",
"星期五" => "周5",
"星期六" => "周6",
"星期日" => "周日",
_ => dayOfWeek
};
var result = $@"{today:M月d日} {weekDay}
尊享包已消耗({totalUsedTokens / 100000000m:F2}亿){totalUsedTokens}
尊享包剩余库存({totalRemainingTokens / 100000000m:F2}亿){totalRemainingTokens}
当前成本:{currentCost:F2}RMB
1亿Token成本:{costPerHundredMillion:F2} RMB=1亿 Token
总成本:{totalCost:F2} RMB
总收益:{totalRevenue:F2}RMB
利润率: {profitRate:F1}%
按200售价来算,成本在{costAt200Price:F2}";
return result;
}
} }

View File

@@ -19,6 +19,7 @@ declare module 'vue' {
ElCard: typeof import('element-plus/es')['ElCard'] ElCard: typeof import('element-plus/es')['ElCard']
ElCollapse: typeof import('element-plus/es')['ElCollapse'] ElCollapse: typeof import('element-plus/es')['ElCollapse']
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem'] ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
ElCollapseTransition: typeof import('element-plus/es')['ElCollapseTransition']
ElContainer: typeof import('element-plus/es')['ElContainer'] ElContainer: typeof import('element-plus/es')['ElContainer']
ElDialog: typeof import('element-plus/es')['ElDialog'] ElDialog: typeof import('element-plus/es')['ElDialog']
ElDivider: typeof import('element-plus/es')['ElDivider'] ElDivider: typeof import('element-plus/es')['ElDivider']