From 190302b318b246182e8d1811d09a139c998a14b6 Mon Sep 17 00:00:00 2001 From: zpc Date: Wed, 4 Feb 2026 02:03:25 +0800 Subject: [PATCH] 21 --- honey_box/common/env.js | 4 +- .../HoneyBox/scripts/seed_box_profit_menu.sql | 43 +++ .../Controllers/StatisticsController.cs | 53 +++ .../Models/Statistics/BoxStatisticsModels.cs | 236 ++++++++++++++ .../Services/Interfaces/IStatisticsService.cs | 15 + .../Services/StatisticsService.cs | 197 ++++++++++++ .../admin-web/src/api/business/statistics.ts | 157 +++++++++ .../admin-web/src/router/modules/business.ts | 14 +- .../views/business/statistics/box-profit.vue | 304 ++++++++++++++++++ 9 files changed, 1020 insertions(+), 3 deletions(-) create mode 100644 server/HoneyBox/scripts/seed_box_profit_menu.sql create mode 100644 server/HoneyBox/src/HoneyBox.Admin.Business/Models/Statistics/BoxStatisticsModels.cs create mode 100644 server/HoneyBox/src/HoneyBox.Admin/admin-web/src/views/business/statistics/box-profit.vue diff --git a/honey_box/common/env.js b/honey_box/common/env.js index 927fcad7..6ee2ac79 100644 --- a/honey_box/common/env.js +++ b/honey_box/common/env.js @@ -11,9 +11,9 @@ // 测试环境配置 - .NET 10 后端 const testing = { - // baseUrl: 'https://app.zpc-xy.com/honey/api', + baseUrl: 'https://app.zpc-xy.com/honey/api', // baseUrl: 'http://192.168.1.24:5238', - baseUrl: 'http://192.168.195.15:2822', + // baseUrl: 'http://192.168.195.15:2822', imageUrl: 'https://youdas-1308826010.cos.ap-shanghai.myqcloud.com', loginPage: '', wxAppId: '' diff --git a/server/HoneyBox/scripts/seed_box_profit_menu.sql b/server/HoneyBox/scripts/seed_box_profit_menu.sql new file mode 100644 index 00000000..6a71e9b6 --- /dev/null +++ b/server/HoneyBox/scripts/seed_box_profit_menu.sql @@ -0,0 +1,43 @@ +-- 盒子利润统计菜单种子数据 +-- 执行前请确保统计报表目录菜单已存在 + +USE honey_box_admin; +GO + +-- 查找统计报表目录的ID +DECLARE @statisticsMenuId BIGINT; +SELECT @statisticsMenuId = Id FROM menus WHERE Path = '/business/statistics' AND MenuType = 1; + +-- 如果统计报表目录不存在,先创建它 +IF @statisticsMenuId IS NULL +BEGIN + DECLARE @businessMenuId BIGINT; + SELECT @businessMenuId = Id FROM menus WHERE Path = '/business' AND MenuType = 1; + + INSERT INTO menus (Name, Path, Component, Icon, SortOrder, MenuType, Status, ParentId, Permission, CreatedAt, UpdatedAt, IsExternal, IsCache) + VALUES (N'统计报表', '/business/statistics', NULL, 'DataAnalysis', 80, 1, 1, @businessMenuId, NULL, GETDATE(), GETDATE(), 0, 0); + + SET @statisticsMenuId = SCOPE_IDENTITY(); + PRINT N'创建统计报表目录菜单,ID: ' + CAST(@statisticsMenuId AS NVARCHAR(10)); +END + +-- 检查盒子利润统计菜单是否已存在 +IF NOT EXISTS (SELECT 1 FROM menus WHERE Path = '/business/statistics/box-profit') +BEGIN + INSERT INTO menus (Name, Path, Component, Icon, SortOrder, MenuType, Status, ParentId, Permission, CreatedAt, UpdatedAt, IsExternal, IsCache) + VALUES (N'盒子利润统计', '/business/statistics/box-profit', 'business/statistics/box-profit', 'TrendCharts', 2, 2, 1, + @statisticsMenuId, 'statistics:box-profit', GETDATE(), GETDATE(), 0, 1); + + PRINT N'创建盒子利润统计菜单成功'; +END +ELSE +BEGIN + PRINT N'盒子利润统计菜单已存在,跳过创建'; +END + +-- 查看结果 +SELECT Id, Name, Path, Component, Permission, ParentId, SortOrder, MenuType, Status +FROM menus +WHERE Path LIKE '/business/statistics%' +ORDER BY ParentId, SortOrder; +GO diff --git a/server/HoneyBox/src/HoneyBox.Admin.Business/Controllers/StatisticsController.cs b/server/HoneyBox/src/HoneyBox.Admin.Business/Controllers/StatisticsController.cs index 3b8feafc..0bc4a579 100644 --- a/server/HoneyBox/src/HoneyBox.Admin.Business/Controllers/StatisticsController.cs +++ b/server/HoneyBox/src/HoneyBox.Admin.Business/Controllers/StatisticsController.cs @@ -1,4 +1,5 @@ using HoneyBox.Admin.Business.Attributes; +using HoneyBox.Admin.Business.Models.Statistics; using HoneyBox.Admin.Business.Services.Interfaces; using Microsoft.AspNetCore.Mvc; @@ -64,4 +65,56 @@ public class StatisticsController : BusinessControllerBase var result = await _statisticsService.GetUserStatsAsync(); return Ok(result); } + + /// + /// 获取单个盒子的统计数据 + /// + /// 盒子ID + /// 开始时间 + /// 结束时间 + /// 盒子统计数据 + [HttpGet("box-statistics")] + [BusinessPermission("statistics:view")] + public async Task GetBoxStatistics( + [FromQuery] int goodsId, + [FromQuery] DateTime? startTime, + [FromQuery] DateTime? endTime) + { + var request = new BoxStatisticsRequest + { + GoodsId = goodsId, + StartTime = startTime, + EndTime = endTime + }; + + var result = await _statisticsService.GetBoxStatisticsAsync(request); + return Ok(new { code = 0, msg = "获取成功", data = result }); + } + + /// + /// 获取盒子利润统计列表 + /// + /// 请求参数 + /// 盒子利润统计列表 + [HttpGet("box-profit-list")] + [BusinessPermission("statistics:view")] + public async Task GetBoxProfitList([FromQuery] BoxProfitListRequest request) + { + var result = await _statisticsService.GetBoxProfitListAsync(request); + return Ok(new + { + code = 0, + msg = "获取数据成功", + count = result.Total, + data = result.List, + summary = new BoxProfitSummary + { + TotalIncome = 0, + TotalCost = 0, + TotalProfit = 0, + TotalReMoney = 0, + TotalFhMoney = 0 + } + }); + } } diff --git a/server/HoneyBox/src/HoneyBox.Admin.Business/Models/Statistics/BoxStatisticsModels.cs b/server/HoneyBox/src/HoneyBox.Admin.Business/Models/Statistics/BoxStatisticsModels.cs new file mode 100644 index 00000000..2da48804 --- /dev/null +++ b/server/HoneyBox/src/HoneyBox.Admin.Business/Models/Statistics/BoxStatisticsModels.cs @@ -0,0 +1,236 @@ +namespace HoneyBox.Admin.Business.Models.Statistics; + +/// +/// 盒子统计请求 +/// +public class BoxStatisticsRequest +{ + /// + /// 盒子ID + /// + public int GoodsId { get; set; } + + /// + /// 开始时间 + /// + public DateTime? StartTime { get; set; } + + /// + /// 结束时间 + /// + public DateTime? EndTime { get; set; } +} + +/// +/// 盒子统计响应 +/// +public class BoxStatisticsResponse +{ + /// + /// 盒子ID + /// + public int Id { get; set; } + + /// + /// 消费金额(充值金额 + 余额消费) + /// + public decimal UseMoney { get; set; } + + /// + /// 出货成本(奖品价值) + /// + public decimal ScMoney { get; set; } + + /// + /// 兑换成本(已回收的奖品价值) + /// + public decimal ReMoney { get; set; } + + /// + /// 发货成本(已发货的奖品价值) + /// + public decimal FhMoney { get; set; } + + /// + /// 抽奖次数 + /// + public int CjCount { get; set; } + + /// + /// 利润 = UseMoney - (ScMoney - ReMoney) + /// + public decimal Profit { get; set; } + + /// + /// 利润率 + /// + public decimal ProfitRate { get; set; } + + /// + /// 是否亏损 + /// + public bool IsNegative { get; set; } +} + +/// +/// 盒子利润统计列表请求 +/// +public class BoxProfitListRequest : PagedRequest +{ + /// + /// 盒子ID + /// + public int? GoodsId { get; set; } + + /// + /// 盒子名称 + /// + public string? Title { get; set; } + + /// + /// 状态:0-下架,1-上架 + /// + public int? Status { get; set; } + + /// + /// 盒子类型 + /// + public int? Type { get; set; } + + /// + /// 开始时间 + /// + public DateTime? StartTime { get; set; } + + /// + /// 结束时间 + /// + public DateTime? EndTime { get; set; } +} + +/// +/// 盒子利润统计列表项 +/// +public class BoxProfitItem +{ + /// + /// 盒子ID + /// + public int Id { get; set; } + + /// + /// 盒子名称 + /// + public string Title { get; set; } = string.Empty; + + /// + /// 盒子图片 + /// + public string? ImgUrl { get; set; } + + /// + /// 单价 + /// + public decimal Price { get; set; } + + /// + /// 库存 + /// + public int Stock { get; set; } + + /// + /// 状态:0-下架,1-上架 + /// + public int Status { get; set; } + + /// + /// 状态名称 + /// + public string StatusName => Status == 1 ? "上架" : "下架"; + + /// + /// 盒子类型 + /// + public int Type { get; set; } + + /// + /// 类型名称 + /// + public string TypeName { get; set; } = string.Empty; + + /// + /// 消费金额 + /// + public decimal UseMoney { get; set; } + + /// + /// 出货成本 + /// + public decimal ScMoney { get; set; } + + /// + /// 兑换成本 + /// + public decimal ReMoney { get; set; } + + /// + /// 发货成本 + /// + public decimal FhMoney { get; set; } + + /// + /// 抽奖次数 + /// + public int CjCount { get; set; } + + /// + /// 利润 + /// + public decimal Profit { get; set; } + + /// + /// 利润率 + /// + public decimal ProfitRate { get; set; } + + /// + /// 是否亏损 + /// + public bool IsNegative { get; set; } + + /// + /// 是否已加载统计数据 + /// + public bool Loaded { get; set; } +} + +/// +/// 盒子利润汇总 +/// +public class BoxProfitSummary +{ + /// + /// 总收入 + /// + public decimal TotalIncome { get; set; } + + /// + /// 总成本 + /// + public decimal TotalCost { get; set; } + + /// + /// 总利润 + /// + public decimal TotalProfit { get; set; } + + /// + /// 总兑换金额 + /// + public decimal TotalReMoney { get; set; } + + /// + /// 总发货金额 + /// + public decimal TotalFhMoney { get; set; } +} diff --git a/server/HoneyBox/src/HoneyBox.Admin.Business/Services/Interfaces/IStatisticsService.cs b/server/HoneyBox/src/HoneyBox.Admin.Business/Services/Interfaces/IStatisticsService.cs index ebae66bb..dfd166f0 100644 --- a/server/HoneyBox/src/HoneyBox.Admin.Business/Services/Interfaces/IStatisticsService.cs +++ b/server/HoneyBox/src/HoneyBox.Admin.Business/Services/Interfaces/IStatisticsService.cs @@ -1,3 +1,4 @@ +using HoneyBox.Admin.Business.Models; using HoneyBox.Admin.Business.Models.Statistics; namespace HoneyBox.Admin.Business.Services.Interfaces; @@ -30,4 +31,18 @@ public interface IStatisticsService /// /// 用户统计 Task GetUserStatsAsync(); + + /// + /// 获取单个盒子的统计数据 + /// + /// 请求参数 + /// 盒子统计数据 + Task GetBoxStatisticsAsync(BoxStatisticsRequest request); + + /// + /// 获取盒子利润统计列表 + /// + /// 请求参数 + /// 盒子利润统计列表 + Task> GetBoxProfitListAsync(BoxProfitListRequest request); } diff --git a/server/HoneyBox/src/HoneyBox.Admin.Business/Services/StatisticsService.cs b/server/HoneyBox/src/HoneyBox.Admin.Business/Services/StatisticsService.cs index 635a3fbd..c921c3ab 100644 --- a/server/HoneyBox/src/HoneyBox.Admin.Business/Services/StatisticsService.cs +++ b/server/HoneyBox/src/HoneyBox.Admin.Business/Services/StatisticsService.cs @@ -1,3 +1,4 @@ +using HoneyBox.Admin.Business.Models; using HoneyBox.Admin.Business.Models.Statistics; using HoneyBox.Admin.Business.Services.Interfaces; using HoneyBox.Model.Data; @@ -14,6 +15,20 @@ public class StatisticsService : IStatisticsService private readonly HoneyBoxDbContext _dbContext; private readonly ILogger _logger; + // 盒子类型名称映射 + private static readonly Dictionary BoxTypeNames = new() + { + { 1, "一番赏" }, + { 2, "无限赏" }, + { 3, "擂台赏" }, + { 4, "抽卡机" }, + { 5, "福袋" }, + { 6, "幸运赏" }, + { 8, "盲盒" }, + { 9, "扭蛋" }, + { 15, "福利屋" } + }; + public StatisticsService(HoneyBoxDbContext dbContext, ILogger logger) { _dbContext = dbContext; @@ -386,4 +401,186 @@ public class StatisticsService : IStatisticsService ShippedAmount = shippedAmount }; } + + /// + /// 获取单个盒子的统计数据 + /// + public async Task GetBoxStatisticsAsync(BoxStatisticsRequest request) + { + if (request.GoodsId <= 0) + { + throw new ArgumentException("盒子ID无效"); + } + + // 验证盒子存在 + var goodsExists = await _dbContext.Goods.AnyAsync(g => g.Id == request.GoodsId && g.DeletedAt == null); + if (!goodsExists) + { + throw new ArgumentException("盒子不存在"); + } + + // 获取测试用户ID列表 + var testUserIds = await _dbContext.Users + .Where(u => u.IsTest > 0 || u.Status == 2) + .Select(u => u.Id) + .ToListAsync(); + + if (!testUserIds.Any()) + { + testUserIds = new List { 0 }; + } + + // 构建时间范围条件(转换为Unix时间戳) + var hasTimeRange = request.StartTime.HasValue && request.EndTime.HasValue; + var startTimestamp = hasTimeRange ? (int)((DateTimeOffset)request.StartTime!.Value).ToUnixTimeSeconds() : 0; + var endTimestamp = hasTimeRange ? (int)((DateTimeOffset)request.EndTime!.Value).ToUnixTimeSeconds() : 0; + + // 查询1:获取消费金额(充值金额 + 余额消费) + var orderQuery = _dbContext.Orders + .Where(o => o.Status == 1) + .Where(o => o.Price > 0 || o.UseMoney > 0) + .Where(o => o.GoodsId == request.GoodsId) + .Where(o => !testUserIds.Contains(o.UserId)); + + if (hasTimeRange) + { + orderQuery = orderQuery.Where(o => o.PayTime > startTimestamp && o.PayTime < endTimestamp); + } + + var priceSum = await orderQuery.SumAsync(o => (decimal?)o.Price) ?? 0; + var useMoneySum = await orderQuery.SumAsync(o => (decimal?)o.UseMoney) ?? 0; + var useMoney = priceSum + useMoneySum; + + // 查询2:获取出货成本(奖品价值) + var scMoneyQuery = _dbContext.OrderItems + .Where(oi => oi.GoodsId == request.GoodsId) + .Where(oi => !testUserIds.Contains(oi.UserId)); + + if (hasTimeRange) + { + scMoneyQuery = scMoneyQuery.Where(oi => oi.CreatedAt > request.StartTime && oi.CreatedAt < request.EndTime); + } + + var scMoney = await scMoneyQuery.SumAsync(oi => (decimal?)oi.GoodslistMoney) ?? 0; + + // 查询3:获取兑换成本(已回收的奖品价值,status=1) + var reMoneyQuery = _dbContext.OrderItems + .Where(oi => oi.GoodsId == request.GoodsId) + .Where(oi => oi.Status == 1) + .Where(oi => !testUserIds.Contains(oi.UserId)); + + if (hasTimeRange) + { + reMoneyQuery = reMoneyQuery.Where(oi => oi.CreatedAt > request.StartTime && oi.CreatedAt < request.EndTime); + } + + var reMoney = await reMoneyQuery.SumAsync(oi => (decimal?)oi.GoodslistMoney) ?? 0; + + // 查询4:获取发货成本(已发货的奖品价值,status=2) + var fhMoneyQuery = _dbContext.OrderItems + .Where(oi => oi.GoodsId == request.GoodsId) + .Where(oi => oi.Status == 2) + .Where(oi => !testUserIds.Contains(oi.UserId)); + + if (hasTimeRange) + { + fhMoneyQuery = fhMoneyQuery.Where(oi => oi.CreatedAt > request.StartTime && oi.CreatedAt < request.EndTime); + } + + var fhMoney = await fhMoneyQuery.SumAsync(oi => (decimal?)oi.GoodslistMoney) ?? 0; + + // 查询5:获取抽奖次数(parent_goods_list_id = 0 表示主抽奖记录) + var cjCountQuery = _dbContext.OrderItems + .Where(oi => oi.GoodsId == request.GoodsId) + .Where(oi => !testUserIds.Contains(oi.UserId)) + .Where(oi => oi.ParentGoodsListId == 0); + + if (hasTimeRange) + { + cjCountQuery = cjCountQuery.Where(oi => oi.CreatedAt > request.StartTime && oi.CreatedAt < request.EndTime); + } + + var cjCount = await cjCountQuery.CountAsync(); + + // 计算利润和利润率 + var profit = useMoney - (scMoney - reMoney); + var profitRate = useMoney > 0 ? Math.Round((profit / useMoney) * 100, 2) : 0; + + return new BoxStatisticsResponse + { + Id = request.GoodsId, + UseMoney = useMoney, + ScMoney = scMoney, + ReMoney = reMoney, + FhMoney = fhMoney, + CjCount = cjCount, + Profit = profit, + ProfitRate = profitRate, + IsNegative = profit < 0 + }; + } + + /// + /// 获取盒子利润统计列表 + /// + public async Task> GetBoxProfitListAsync(BoxProfitListRequest request) + { + // 构建查询条件 + var query = _dbContext.Goods + .AsNoTracking() + .Where(g => g.DeletedAt == null); + + if (request.GoodsId.HasValue && request.GoodsId > 0) + { + query = query.Where(g => g.Id == request.GoodsId); + } + + if (!string.IsNullOrWhiteSpace(request.Title)) + { + query = query.Where(g => g.Title.Contains(request.Title)); + } + + if (request.Status.HasValue) + { + query = query.Where(g => g.Status == request.Status); + } + + if (request.Type.HasValue && request.Type > 0) + { + query = query.Where(g => g.Type == request.Type); + } + + // 获取总数 + var total = await query.CountAsync(); + + // 分页获取盒子列表 + var goods = await query + .OrderByDescending(g => g.Id) + .Skip(request.Skip) + .Take(request.PageSize) + .Select(g => new BoxProfitItem + { + Id = g.Id, + Title = g.Title, + ImgUrl = g.ImgUrl, + Price = g.Price, + Stock = g.Stock, + Status = g.Status, + Type = g.Type, + TypeName = BoxTypeNames.ContainsKey(g.Type) ? BoxTypeNames[g.Type] : "未知类型", + // 统计数据初始化为0,后续异步加载 + UseMoney = 0, + ScMoney = 0, + ReMoney = 0, + FhMoney = 0, + CjCount = 0, + Profit = 0, + ProfitRate = 0, + IsNegative = false, + Loaded = false + }) + .ToListAsync(); + + return PagedResult.Create(goods, total, request.Page, request.PageSize); + } } diff --git a/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/api/business/statistics.ts b/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/api/business/statistics.ts index bed4e53d..d5a5e2d4 100644 --- a/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/api/business/statistics.ts +++ b/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/api/business/statistics.ts @@ -163,3 +163,160 @@ export function getUserStats(): Promise> { method: 'get' }) } + +// ==================== 盒子统计类型定义 ==================== + +/** + * 盒子统计请求参数 + */ +export interface BoxStatisticsParams { + /** 盒子ID */ + goodsId: number + /** 开始时间 */ + startTime?: string + /** 结束时间 */ + endTime?: string +} + +/** + * 盒子统计响应 + */ +export interface BoxStatistics { + /** 盒子ID */ + id: number + /** 消费金额(充值金额 + 余额消费) */ + useMoney: number + /** 出货成本(奖品价值) */ + scMoney: number + /** 兑换成本(已回收的奖品价值) */ + reMoney: number + /** 发货成本(已发货的奖品价值) */ + fhMoney: number + /** 抽奖次数 */ + cjCount: number + /** 利润 */ + profit: number + /** 利润率 */ + profitRate: number + /** 是否亏损 */ + isNegative: boolean +} + +/** + * 盒子利润列表请求参数 + */ +export interface BoxProfitListParams { + /** 页码 */ + page?: number + /** 每页数量 */ + pageSize?: number + /** 盒子ID */ + goodsId?: number + /** 盒子名称 */ + title?: string + /** 状态 */ + status?: number + /** 盒子类型 */ + type?: number + /** 开始时间 */ + startTime?: string + /** 结束时间 */ + endTime?: string +} + +/** + * 盒子利润列表项 + */ +export interface BoxProfitItem { + /** 盒子ID */ + id: number + /** 盒子名称 */ + title: string + /** 盒子图片 */ + imgUrl: string + /** 单价 */ + price: number + /** 库存 */ + stock: number + /** 状态 */ + status: number + /** 状态名称 */ + statusName: string + /** 盒子类型 */ + type: number + /** 类型名称 */ + typeName: string + /** 消费金额 */ + useMoney: number + /** 出货成本 */ + scMoney: number + /** 兑换成本 */ + reMoney: number + /** 发货成本 */ + fhMoney: number + /** 抽奖次数 */ + cjCount: number + /** 利润 */ + profit: number + /** 利润率 */ + profitRate: number + /** 是否亏损 */ + isNegative: boolean + /** 是否已加载统计数据 */ + loaded: boolean +} + +/** + * 盒子利润汇总 + */ +export interface BoxProfitSummary { + /** 总收入 */ + totalIncome: number + /** 总成本 */ + totalCost: number + /** 总利润 */ + totalProfit: number + /** 总兑换金额 */ + totalReMoney: number + /** 总发货金额 */ + totalFhMoney: number +} + +/** + * 盒子利润列表响应 + */ +export interface BoxProfitListResponse { + code: number + msg: string + count: number + data: BoxProfitItem[] + summary: BoxProfitSummary +} + +// ==================== 盒子统计 API ==================== + +/** + * 获取单个盒子的统计数据 + * @param params 请求参数 + * @returns 盒子统计数据 + */ +export function getBoxStatistics(params: BoxStatisticsParams): Promise> { + return request({ + url: `${STATISTICS_BASE_URL}/box-statistics`, + method: 'get', + params + }) +} + +/** + * 获取盒子利润统计列表 + * @param params 请求参数 + * @returns 盒子利润统计列表 + */ +export function getBoxProfitList(params: BoxProfitListParams): Promise> { + return request({ + url: `${STATISTICS_BASE_URL}/box-profit-list`, + method: 'get', + params + }) +} diff --git a/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/router/modules/business.ts b/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/router/modules/business.ts index 36adf20b..c1462ed0 100644 --- a/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/router/modules/business.ts +++ b/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/router/modules/business.ts @@ -589,6 +589,16 @@ export const businessRoutes: RouteRecordRaw[] = [ permission: 'statistics:data-stand', keepAlive: true } + }, + { + path: 'box-profit', + name: 'BoxProfit', + component: () => import('@/views/business/statistics/box-profit.vue'), + meta: { + title: '盒子利润统计', + permission: 'statistics:box-profit', + keepAlive: true + } } ] } @@ -1199,7 +1209,9 @@ export const welfareTaskPermissions = { */ export const statisticsPermissions = { // 数据看板 - dataStand: 'statistics:data-stand' + dataStand: 'statistics:data-stand', + // 盒子利润统计 + boxProfit: 'statistics:box-profit' } export default businessRoutes diff --git a/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/views/business/statistics/box-profit.vue b/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/views/business/statistics/box-profit.vue new file mode 100644 index 00000000..299f3828 --- /dev/null +++ b/server/HoneyBox/src/HoneyBox.Admin/admin-web/src/views/business/statistics/box-profit.vue @@ -0,0 +1,304 @@ + + + + +