diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/AiAccountService.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/AiAccountService.cs index 30b453ff..a95f5a2f 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/AiAccountService.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/AiAccountService.cs @@ -17,15 +17,18 @@ public class AiAccountService : ApplicationService private IAccountService _accountService; private ISqlSugarRepository _userRepository; private ISqlSugarRepository _rechargeRepository; + private ISqlSugarRepository _premiumPackageRepository; public AiAccountService( IAccountService accountService, ISqlSugarRepository userRepository, - ISqlSugarRepository rechargeRepository) + ISqlSugarRepository rechargeRepository, + ISqlSugarRepository premiumPackageRepository) { _accountService = accountService; _userRepository = userRepository; _rechargeRepository = rechargeRepository; + _premiumPackageRepository = premiumPackageRepository; } /// @@ -72,4 +75,77 @@ public class AiAccountService : ApplicationService return output; } + + /// + /// 获取利润统计数据 + /// + /// 当前成本(RMB) + /// + [Authorize] + [HttpGet("account/profit-statistics")] + public async Task 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; + } } \ No newline at end of file diff --git a/Yi.Ai.Vue3/types/components.d.ts b/Yi.Ai.Vue3/types/components.d.ts index 702505a4..dd59173e 100644 --- a/Yi.Ai.Vue3/types/components.d.ts +++ b/Yi.Ai.Vue3/types/components.d.ts @@ -19,6 +19,7 @@ declare module 'vue' { ElCard: typeof import('element-plus/es')['ElCard'] ElCollapse: typeof import('element-plus/es')['ElCollapse'] ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem'] + ElCollapseTransition: typeof import('element-plus/es')['ElCollapseTransition'] ElContainer: typeof import('element-plus/es')['ElContainer'] ElDialog: typeof import('element-plus/es')['ElDialog'] ElDivider: typeof import('element-plus/es')['ElDivider']