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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ row.title }}
+
+
+
+
+
+ ¥{{ row.price.toFixed(2) }}
+
+
+
+ {{ row.statusName }}
+
+
+
+
+ {{ row.cjCount }}
+ 加载
+
+
+
+
+ ¥{{ row.useMoney.toFixed(2) }}
+ -
+
+
+
+
+ ¥{{ row.scMoney.toFixed(2) }}
+ -
+
+
+
+
+ ¥{{ row.reMoney.toFixed(2) }}
+ -
+
+
+
+
+ ¥{{ row.fhMoney.toFixed(2) }}
+ -
+
+
+
+
+
+ ¥{{ row.profit.toFixed(2) }}
+
+ -
+
+
+
+
+
+ {{ row.profitRate.toFixed(2) }}%
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+