diff --git a/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/DistributionController.cs b/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/DistributionController.cs
index 4c5b35a..74afd00 100644
--- a/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/DistributionController.cs
+++ b/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/DistributionController.cs
@@ -3,6 +3,7 @@ using MiAssessment.Admin.Business.Models;
using MiAssessment.Admin.Business.Models.Common;
using MiAssessment.Admin.Business.Models.Distribution;
using MiAssessment.Admin.Business.Services.Interfaces;
+using ClosedXML.Excel;
using Microsoft.AspNetCore.Mvc;
namespace MiAssessment.Admin.Business.Controllers;
@@ -91,11 +92,42 @@ public class DistributionController : BusinessControllerBase
{
var items = await _distributionService.ExportInviteCodesAsync(request);
- // 生成CSV内容
- var csvContent = GenerateInviteCodeCsv(items);
- var fileName = $"invite_codes_{DateTime.Now:yyyyMMddHHmmss}.csv";
+ using var workbook = new XLWorkbook();
+ var worksheet = workbook.Worksheets.Add("邀请码列表");
- return File(System.Text.Encoding.UTF8.GetBytes(csvContent), "text/csv", fileName);
+ var headers = new[] { "ID", "邀请码", "批次号", "分配用户", "分配时间", "使用用户", "使用订单ID", "使用时间", "状态", "创建时间" };
+ for (var i = 0; i < headers.Length; i++)
+ worksheet.Cell(1, i + 1).Value = headers[i];
+
+ var headerRow = worksheet.Range(1, 1, 1, headers.Length);
+ headerRow.Style.Font.Bold = true;
+ headerRow.Style.Fill.BackgroundColor = XLColor.FromHtml("#4A90E2");
+ headerRow.Style.Font.FontColor = XLColor.White;
+
+ for (var i = 0; i < items.Count; i++)
+ {
+ var row = i + 2;
+ var item = items[i];
+ worksheet.Cell(row, 1).Value = item.Id;
+ worksheet.Cell(row, 2).Value = item.Code;
+ worksheet.Cell(row, 3).Value = item.BatchNo ?? "";
+ worksheet.Cell(row, 4).Value = item.AssignUserNickname ?? "";
+ worksheet.Cell(row, 5).Value = item.AssignTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "";
+ worksheet.Cell(row, 6).Value = item.UseUserNickname ?? "";
+ worksheet.Cell(row, 7).Value = item.UseOrderId?.ToString() ?? "";
+ worksheet.Cell(row, 8).Value = item.UseTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "";
+ worksheet.Cell(row, 9).Value = item.StatusName;
+ worksheet.Cell(row, 10).Value = item.CreateTime.ToString("yyyy-MM-dd HH:mm:ss");
+ }
+
+ worksheet.Columns().AdjustToContents();
+
+ using var stream = new MemoryStream();
+ workbook.SaveAs(stream);
+
+ return File(stream.ToArray(),
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ $"邀请码列表_{DateTime.Now:yyyyMMddHHmmss}.xlsx");
}
#endregion
@@ -162,11 +194,43 @@ public class DistributionController : BusinessControllerBase
{
var items = await _distributionService.ExportCommissionsAsync(request);
- // 生成CSV内容
- var csvContent = GenerateCommissionCsv(items);
- var fileName = $"commissions_{DateTime.Now:yyyyMMddHHmmss}.csv";
+ using var workbook = new XLWorkbook();
+ var worksheet = workbook.Worksheets.Add("佣金记录");
- return File(System.Text.Encoding.UTF8.GetBytes(csvContent), "text/csv", fileName);
+ var headers = new[] { "ID", "获佣用户", "来源用户", "订单编号", "订单金额", "佣金比例", "佣金金额", "层级", "状态", "结算时间", "创建时间" };
+ for (var i = 0; i < headers.Length; i++)
+ worksheet.Cell(1, i + 1).Value = headers[i];
+
+ var headerRow = worksheet.Range(1, 1, 1, headers.Length);
+ headerRow.Style.Font.Bold = true;
+ headerRow.Style.Fill.BackgroundColor = XLColor.FromHtml("#4A90E2");
+ headerRow.Style.Font.FontColor = XLColor.White;
+
+ for (var i = 0; i < items.Count; i++)
+ {
+ var row = i + 2;
+ var item = items[i];
+ worksheet.Cell(row, 1).Value = item.Id;
+ worksheet.Cell(row, 2).Value = item.UserNickname ?? "";
+ worksheet.Cell(row, 3).Value = item.FromUserNickname ?? "";
+ worksheet.Cell(row, 4).Value = item.OrderNo ?? "";
+ worksheet.Cell(row, 5).Value = item.OrderAmount;
+ worksheet.Cell(row, 6).Value = item.CommissionRate;
+ worksheet.Cell(row, 7).Value = item.CommissionAmount;
+ worksheet.Cell(row, 8).Value = item.LevelName;
+ worksheet.Cell(row, 9).Value = item.StatusName;
+ worksheet.Cell(row, 10).Value = item.SettleTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "";
+ worksheet.Cell(row, 11).Value = item.CreateTime.ToString("yyyy-MM-dd HH:mm:ss");
+ }
+
+ worksheet.Columns().AdjustToContents();
+
+ using var stream = new MemoryStream();
+ workbook.SaveAs(stream);
+
+ return File(stream.ToArray(),
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ $"佣金记录_{DateTime.Now:yyyyMMddHHmmss}.xlsx");
}
#endregion
@@ -292,79 +356,47 @@ public class DistributionController : BusinessControllerBase
{
var items = await _distributionService.ExportWithdrawalsAsync(request);
- // 生成CSV内容
- var csvContent = GenerateWithdrawalCsv(items);
- var fileName = $"withdrawals_{DateTime.Now:yyyyMMddHHmmss}.csv";
+ using var workbook = new XLWorkbook();
+ var worksheet = workbook.Worksheets.Add("提现记录");
- return File(System.Text.Encoding.UTF8.GetBytes(csvContent), "text/csv", fileName);
+ var headers = new[] { "提现单号", "用户昵称", "手机号", "提现金额", "提现前余额", "提现后余额", "状态", "审核时间", "审核备注", "打款时间", "打款交易号", "创建时间" };
+ for (var i = 0; i < headers.Length; i++)
+ worksheet.Cell(1, i + 1).Value = headers[i];
+
+ var headerRow = worksheet.Range(1, 1, 1, headers.Length);
+ headerRow.Style.Font.Bold = true;
+ headerRow.Style.Fill.BackgroundColor = XLColor.FromHtml("#4A90E2");
+ headerRow.Style.Font.FontColor = XLColor.White;
+
+ for (var i = 0; i < items.Count; i++)
+ {
+ var row = i + 2;
+ var item = items[i];
+ worksheet.Cell(row, 1).Value = item.WithdrawalNo;
+ worksheet.Cell(row, 2).Value = item.UserNickname ?? "";
+ worksheet.Cell(row, 3).Value = item.UserPhone ?? "";
+ worksheet.Cell(row, 4).Value = item.Amount;
+ worksheet.Cell(row, 5).Value = item.BeforeBalance;
+ worksheet.Cell(row, 6).Value = item.AfterBalance;
+ worksheet.Cell(row, 7).Value = item.StatusName;
+ worksheet.Cell(row, 8).Value = item.AuditTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "";
+ worksheet.Cell(row, 9).Value = item.AuditRemark ?? "";
+ worksheet.Cell(row, 10).Value = item.PayTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "";
+ worksheet.Cell(row, 11).Value = item.PayTransactionId ?? "";
+ worksheet.Cell(row, 12).Value = item.CreateTime.ToString("yyyy-MM-dd HH:mm:ss");
+ }
+
+ worksheet.Columns().AdjustToContents();
+
+ using var stream = new MemoryStream();
+ workbook.SaveAs(stream);
+
+ return File(stream.ToArray(),
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ $"提现记录_{DateTime.Now:yyyyMMddHHmmss}.xlsx");
}
#endregion
- #region 私有方法
-
- ///
- /// 生成邀请码CSV内容
- ///
- /// 邀请码列表
- /// CSV内容
- private static string GenerateInviteCodeCsv(List items)
- {
- var sb = new System.Text.StringBuilder();
-
- // CSV 头部
- sb.AppendLine("ID,邀请码,批次号,分配用户,分配时间,使用用户,使用订单ID,使用时间,状态,创建时间");
-
- // CSV 数据行
- foreach (var item in items)
- {
- sb.AppendLine($"{item.Id},{item.Code},{item.BatchNo ?? ""},{item.AssignUserNickname ?? ""},{item.AssignTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? ""},{item.UseUserNickname ?? ""},{item.UseOrderId?.ToString() ?? ""},{item.UseTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? ""},{item.StatusName},{item.CreateTime:yyyy-MM-dd HH:mm:ss}");
- }
-
- return sb.ToString();
- }
-
- ///
- /// 生成佣金记录CSV内容
- ///
- /// 佣金记录列表
- /// CSV内容
- private static string GenerateCommissionCsv(List items)
- {
- var sb = new System.Text.StringBuilder();
-
- // CSV 头部
- sb.AppendLine("ID,获得佣金用户ID,获得佣金用户,来源用户ID,来源用户,订单ID,订单编号,订单金额,佣金比例,佣金金额,层级,状态,结算时间,创建时间");
-
- // CSV 数据行
- foreach (var item in items)
- {
- sb.AppendLine($"{item.Id},{item.UserId},{item.UserNickname ?? ""},{item.FromUserId},{item.FromUserNickname ?? ""},{item.OrderId},{item.OrderNo ?? ""},{item.OrderAmount},{item.CommissionRate},{item.CommissionAmount},{item.LevelName},{item.StatusName},{item.SettleTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? ""},{item.CreateTime:yyyy-MM-dd HH:mm:ss}");
- }
-
- return sb.ToString();
- }
-
- ///
- /// 生成提现记录CSV内容
- ///
- /// 提现记录列表
- /// CSV内容
- private static string GenerateWithdrawalCsv(List items)
- {
- var sb = new System.Text.StringBuilder();
-
- // CSV 头部
- sb.AppendLine("ID,提现单号,用户ID,用户昵称,用户手机号,提现金额,提现前余额,提现后余额,状态,审核人ID,审核时间,审核备注,打款时间,打款交易号,创建时间");
-
- // CSV 数据行
- foreach (var item in items)
- {
- sb.AppendLine($"{item.Id},{item.WithdrawalNo},{item.UserId},{item.UserNickname ?? ""},{item.UserPhone ?? ""},{item.Amount},{item.BeforeBalance},{item.AfterBalance},{item.StatusName},{item.AuditUserId?.ToString() ?? ""},{item.AuditTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? ""},{item.AuditRemark ?? ""},{item.PayTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? ""},{item.PayTransactionId ?? ""},{item.CreateTime:yyyy-MM-dd HH:mm:ss}");
- }
-
- return sb.ToString();
- }
-
#endregion
}
diff --git a/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/OrderController.cs b/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/OrderController.cs
index e8c0b5d..b06866e 100644
--- a/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/OrderController.cs
+++ b/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/OrderController.cs
@@ -3,6 +3,7 @@ using MiAssessment.Admin.Business.Models;
using MiAssessment.Admin.Business.Models.Common;
using MiAssessment.Admin.Business.Models.Order;
using MiAssessment.Admin.Business.Services.Interfaces;
+using ClosedXML.Excel;
using Microsoft.AspNetCore.Mvc;
namespace MiAssessment.Admin.Business.Controllers;
@@ -105,7 +106,7 @@ public class OrderController : BusinessControllerBase
/// 导出订单列表
///
/// 查询请求
- /// 导出数据
+ /// Excel文件
[HttpGet("export")]
[BusinessPermission("order:view")]
public async Task Export([FromQuery] OrderQueryRequest request)
@@ -113,7 +114,45 @@ public class OrderController : BusinessControllerBase
try
{
var result = await _orderService.ExportOrdersAsync(request);
- return Ok(result);
+
+ using var workbook = new XLWorkbook();
+ var worksheet = workbook.Worksheets.Add("订单列表");
+
+ var headers = new[] { "订单编号", "用户UID", "用户昵称", "手机号", "订单类型", "商品名称", "订单金额", "实付金额", "支付方式", "状态", "支付时间", "创建时间" };
+ for (var i = 0; i < headers.Length; i++)
+ worksheet.Cell(1, i + 1).Value = headers[i];
+
+ var headerRow = worksheet.Range(1, 1, 1, headers.Length);
+ headerRow.Style.Font.Bold = true;
+ headerRow.Style.Fill.BackgroundColor = XLColor.FromHtml("#4A90E2");
+ headerRow.Style.Font.FontColor = XLColor.White;
+
+ for (var i = 0; i < result.Count; i++)
+ {
+ var row = i + 2;
+ var o = result[i];
+ worksheet.Cell(row, 1).Value = o.OrderNo;
+ worksheet.Cell(row, 2).Value = o.UserUid;
+ worksheet.Cell(row, 3).Value = o.UserNickname;
+ worksheet.Cell(row, 4).Value = o.UserPhone;
+ worksheet.Cell(row, 5).Value = o.OrderTypeName;
+ worksheet.Cell(row, 6).Value = o.ProductName;
+ worksheet.Cell(row, 7).Value = o.Amount;
+ worksheet.Cell(row, 8).Value = o.PayAmount;
+ worksheet.Cell(row, 9).Value = o.PayTypeName;
+ worksheet.Cell(row, 10).Value = o.StatusName;
+ worksheet.Cell(row, 11).Value = o.PayTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "";
+ worksheet.Cell(row, 12).Value = o.CreateTime.ToString("yyyy-MM-dd HH:mm:ss");
+ }
+
+ worksheet.Columns().AdjustToContents();
+
+ using var stream = new MemoryStream();
+ workbook.SaveAs(stream);
+
+ return File(stream.ToArray(),
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ $"订单列表_{DateTime.Now:yyyyMMddHHmmss}.xlsx");
}
catch (BusinessException ex)
{
diff --git a/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/PlannerController.cs b/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/PlannerController.cs
index 8035915..4198339 100644
--- a/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/PlannerController.cs
+++ b/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/PlannerController.cs
@@ -3,6 +3,7 @@ using MiAssessment.Admin.Business.Models;
using MiAssessment.Admin.Business.Models.Common;
using MiAssessment.Admin.Business.Models.Planner;
using MiAssessment.Admin.Business.Services.Interfaces;
+using ClosedXML.Excel;
using Microsoft.AspNetCore.Mvc;
namespace MiAssessment.Admin.Business.Controllers;
@@ -259,7 +260,7 @@ public class PlannerController : BusinessControllerBase
/// 导出预约记录列表
///
/// 查询请求
- /// 导出数据
+ /// Excel文件
[HttpGet("booking/export")]
[BusinessPermission("planner:view")]
public async Task ExportBookings([FromQuery] BookingQueryRequest request)
@@ -267,7 +268,46 @@ public class PlannerController : BusinessControllerBase
try
{
var result = await _plannerService.ExportBookingsAsync(request);
- return Ok(result);
+
+ using var workbook = new XLWorkbook();
+ var worksheet = workbook.Worksheets.Add("预约记录");
+
+ var headers = new[] { "用户UID", "用户昵称", "手机号", "订单编号", "规划师", "预约日期", "预约时间", "学生姓名", "联系电话", "性别", "年级", "状态", "创建时间" };
+ for (var i = 0; i < headers.Length; i++)
+ worksheet.Cell(1, i + 1).Value = headers[i];
+
+ var headerRow = worksheet.Range(1, 1, 1, headers.Length);
+ headerRow.Style.Font.Bold = true;
+ headerRow.Style.Fill.BackgroundColor = XLColor.FromHtml("#4A90E2");
+ headerRow.Style.Font.FontColor = XLColor.White;
+
+ for (var i = 0; i < result.Count; i++)
+ {
+ var row = i + 2;
+ var item = result[i];
+ worksheet.Cell(row, 1).Value = item.UserUid ?? "";
+ worksheet.Cell(row, 2).Value = item.UserNickname ?? "";
+ worksheet.Cell(row, 3).Value = item.UserPhone ?? "";
+ worksheet.Cell(row, 4).Value = item.OrderNo ?? "";
+ worksheet.Cell(row, 5).Value = item.PlannerName ?? "";
+ worksheet.Cell(row, 6).Value = item.BookingDate.ToString("yyyy-MM-dd");
+ worksheet.Cell(row, 7).Value = item.BookingTime;
+ worksheet.Cell(row, 8).Value = item.Name;
+ worksheet.Cell(row, 9).Value = item.Phone;
+ worksheet.Cell(row, 10).Value = item.GenderName;
+ worksheet.Cell(row, 11).Value = item.GradeName;
+ worksheet.Cell(row, 12).Value = item.StatusName;
+ worksheet.Cell(row, 13).Value = item.CreateTime.ToString("yyyy-MM-dd HH:mm:ss");
+ }
+
+ worksheet.Columns().AdjustToContents();
+
+ using var stream = new MemoryStream();
+ workbook.SaveAs(stream);
+
+ return File(stream.ToArray(),
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ $"预约记录_{DateTime.Now:yyyyMMddHHmmss}.xlsx");
}
catch (BusinessException ex)
{
diff --git a/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/UserController.cs b/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/UserController.cs
index 8a6aa90..b09c8c7 100644
--- a/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/UserController.cs
+++ b/server/MiAssessment/src/MiAssessment.Admin.Business/Controllers/UserController.cs
@@ -3,6 +3,7 @@ using MiAssessment.Admin.Business.Models;
using MiAssessment.Admin.Business.Models.Common;
using MiAssessment.Admin.Business.Models.User;
using MiAssessment.Admin.Business.Services.Interfaces;
+using ClosedXML.Excel;
using Microsoft.AspNetCore.Mvc;
namespace MiAssessment.Admin.Business.Controllers;
@@ -191,7 +192,7 @@ public class UserController : BusinessControllerBase
/// 导出用户列表
///
/// 查询请求
- /// 导出数据
+ /// Excel文件
[HttpGet("export")]
[BusinessPermission("user:view")]
public async Task Export([FromQuery] UserQueryRequest request)
@@ -199,7 +200,51 @@ public class UserController : BusinessControllerBase
try
{
var result = await _userService.ExportUsersAsync(request);
- return Ok(result);
+
+ // 生成 Excel 文件
+ using var workbook = new XLWorkbook();
+ var worksheet = workbook.Worksheets.Add("用户列表");
+
+ // 表头
+ var headers = new[] { "UID", "手机号", "昵称", "用户等级", "余额", "累计收入", "状态", "创建时间", "最后登录" };
+ for (var i = 0; i < headers.Length; i++)
+ {
+ worksheet.Cell(1, i + 1).Value = headers[i];
+ }
+
+ // 表头样式
+ var headerRow = worksheet.Range(1, 1, 1, headers.Length);
+ headerRow.Style.Font.Bold = true;
+ headerRow.Style.Fill.BackgroundColor = XLColor.FromHtml("#4A90E2");
+ headerRow.Style.Font.FontColor = XLColor.White;
+
+ // 数据行
+ for (var i = 0; i < result.Count; i++)
+ {
+ var row = i + 2;
+ var user = result[i];
+ worksheet.Cell(row, 1).Value = user.Uid;
+ worksheet.Cell(row, 2).Value = user.Phone;
+ worksheet.Cell(row, 3).Value = user.Nickname;
+ worksheet.Cell(row, 4).Value = user.UserLevelName;
+ worksheet.Cell(row, 5).Value = user.Balance;
+ worksheet.Cell(row, 6).Value = user.TotalIncome;
+ worksheet.Cell(row, 7).Value = user.StatusName;
+ worksheet.Cell(row, 8).Value = user.CreateTime.ToString("yyyy-MM-dd HH:mm:ss");
+ worksheet.Cell(row, 9).Value = user.LastLoginTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "";
+ }
+
+ // 自动列宽
+ worksheet.Columns().AdjustToContents();
+
+ using var stream = new MemoryStream();
+ workbook.SaveAs(stream);
+ stream.Position = 0;
+
+ var fileName = $"用户列表_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
+ return File(stream.ToArray(),
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ fileName);
}
catch (BusinessException ex)
{
diff --git a/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/utils/request.ts b/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/utils/request.ts
index c4e1552..70fba6b 100644
--- a/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/utils/request.ts
+++ b/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/utils/request.ts
@@ -191,6 +191,11 @@ service.interceptors.request.use(
// 响应拦截器
service.interceptors.response.use(
(response: AxiosResponse) => {
+ // blob 类型直接返回,不走业务 code 判断
+ if (response.config.responseType === 'blob') {
+ return { code: 0, message: 'success', data: response.data } as any
+ }
+
const res = response.data
// code 为 0 表示成功
diff --git a/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/views/dashboard/index.vue b/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/views/dashboard/index.vue
index afb0361..06c1a09 100644
--- a/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/views/dashboard/index.vue
+++ b/server/MiAssessment/src/MiAssessment.Admin/admin-web/src/views/dashboard/index.vue
@@ -185,7 +185,7 @@
-
-
+
@@ -234,22 +234,22 @@
快捷操作
-
+
用户管理
-
+
订单管理
-
+
规划师管理
-
+
提现审核
-
+
轮播图管理
-
+
测评管理