From 440e929311468fb18c28b1b0ab5406ceb1f8d7af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E6=A2=93=E5=BD=AD?= Date: Tue, 31 Mar 2026 15:54:27 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BC=93=E5=AD=98=E9=85=8D=E7=BD=AE=EF=BC=8C?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E8=A1=A5=E5=85=85=EF=BC=8C=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Client/OAuthController.cs | 22 +-- YD_Event.Application/Common/SmsService.cs | 14 +- .../Event/EventArrangementService.cs | 100 ++++++++++- .../Merchant/MerchantCertificationService.cs | 15 +- .../YD_Event.Application.csproj | 3 +- YD_Event.Application/applicationsettings.json | 4 +- YD_Event.Core/InitData/sysmenu.txt | 169 +++++++++++++++++- 7 files changed, 293 insertions(+), 34 deletions(-) diff --git a/YD_Event.Application/Client/OAuthController.cs b/YD_Event.Application/Client/OAuthController.cs index 2ece3e7..d5e244c 100644 --- a/YD_Event.Application/Client/OAuthController.cs +++ b/YD_Event.Application/Client/OAuthController.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Caching.Memory; +using EasyCaching.Core; using Microsoft.Extensions.Logging; using YD_Event.Application.Client.Dtos; @@ -11,7 +11,7 @@ namespace YD_Event.Application.Client; public class OAuthController : IDynamicApiController { private readonly ISqlSugarRepository _appUserRepository; - private readonly IMemoryCache _memoryCache; + private readonly IEasyCachingProvider _cachingProvider; private readonly IIdGenerator _idGenerator; private readonly ILogger _logger; @@ -19,12 +19,12 @@ public class OAuthController : IDynamicApiController public OAuthController( ISqlSugarRepository appUserRepository, - IMemoryCache memoryCache, + IEasyCachingProvider cachingProvider, IIdGenerator idGenerator, ILogger logger) { _appUserRepository = appUserRepository; - _memoryCache = memoryCache; + _cachingProvider = cachingProvider; _idGenerator = idGenerator; _logger = logger; } @@ -93,12 +93,13 @@ public class OAuthController : IDynamicApiController public async Task Register([FromBody] MiniProgramRegisterInput input) { var cacheKey = $"{SmsCodeCachePrefix}{input.Mobile}"; - string cachedCode = null; - if (!_memoryCache.TryGetValue(cacheKey, out cachedCode) || cachedCode != input.VerificationCode) + var cachedCodeResult = _cachingProvider.Get(cacheKey); + string cachedCode = cachedCodeResult.Value; + if (!cachedCodeResult.HasValue || cachedCode != input.VerificationCode) { throw Oops.Bah("验证码错误或已过期"); } - _memoryCache.Remove(cacheKey); + _cachingProvider.Remove(cacheKey); if (await _appUserRepository.IsAnyAsync(x => x.Mobile == input.Mobile)) { @@ -144,12 +145,13 @@ public class OAuthController : IDynamicApiController public async Task ResetPassword([FromBody] MiniProgramResetPasswordInput input) { var cacheKey = $"{SmsCodeCachePrefix}{input.Mobile}"; - string cachedCode = null; - if (!_memoryCache.TryGetValue(cacheKey, out cachedCode) || cachedCode != input.VerificationCode) + var cachedCodeResult = _cachingProvider.Get(cacheKey); + string cachedCode = cachedCodeResult.Value; + if (!cachedCodeResult.HasValue || cachedCode != input.VerificationCode) { throw Oops.Bah("验证码错误或已过期"); } - _memoryCache.Remove(cacheKey); + _cachingProvider.Remove(cacheKey); var appUser = await _appUserRepository.GetFirstAsync(x => x.Mobile == input.Mobile); if (appUser == null) diff --git a/YD_Event.Application/Common/SmsService.cs b/YD_Event.Application/Common/SmsService.cs index 115b007..eb02bfb 100644 --- a/YD_Event.Application/Common/SmsService.cs +++ b/YD_Event.Application/Common/SmsService.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Caching.Memory; +using EasyCaching.Core; using YD_Event.Application.Common.Dtos; using YD_Event.Application.Sms; @@ -8,12 +8,12 @@ namespace YD_Event.Application.Common; public class SmsService : IDynamicApiController, ITransient { private readonly AliyunSmsService _smsService; - private readonly IMemoryCache _memoryCache; + private readonly IEasyCachingProvider _cachingProvider; - public SmsService(AliyunSmsService smsService, IMemoryCache memoryCache) + public SmsService(AliyunSmsService smsService, IEasyCachingProvider cachingProvider) { _smsService = smsService; - _memoryCache = memoryCache; + _cachingProvider = cachingProvider; } [HttpPost("sendVerificationCode")] @@ -22,7 +22,7 @@ public class SmsService : IDynamicApiController, ITransient public async Task SendVerificationCode([FromBody] SendVerificationCodeInput input) { var limitCacheKey = $"sms:code:limit:{input.Phone}"; - if (_memoryCache.TryGetValue(limitCacheKey, out _)) + if (_cachingProvider.Exists(limitCacheKey)) { throw Oops.Bah("发送太频繁,请稍后再试"); } @@ -32,7 +32,7 @@ public class SmsService : IDynamicApiController, ITransient await _smsService.SendVerificationCode(input.Phone, code); var codeCacheKey = $"sms:code:{input.Phone}"; - _memoryCache.Set(codeCacheKey, code, TimeSpan.FromMinutes(5)); - _memoryCache.Set(limitCacheKey, "1", TimeSpan.FromMinutes(1)); + _cachingProvider.Set(codeCacheKey, code, TimeSpan.FromMinutes(5)); + _cachingProvider.Set(limitCacheKey, "1", TimeSpan.FromMinutes(1)); } } diff --git a/YD_Event.Application/Event/EventArrangementService.cs b/YD_Event.Application/Event/EventArrangementService.cs index 2cf62ef..19007ca 100644 --- a/YD_Event.Application/Event/EventArrangementService.cs +++ b/YD_Event.Application/Event/EventArrangementService.cs @@ -2,6 +2,9 @@ using YD_Event.Application.Event.Dtos; using YD_Event.Core.Entities; using MiniExcelLibs; using SqlSugar; +using OfficeOpenXml; +using OfficeOpenXml.Style; +using System.Drawing; namespace YD_Event.Application.Event; @@ -16,6 +19,7 @@ public class EventArrangementService : BaseService _personRepository; private readonly ISqlSugarRepository _registrationRepository; private readonly ISqlSugarRepository _projectTypeRepository; + private readonly ISqlSugarRepository _eventInfoRepository; public EventArrangementService( ISqlSugarRepository eventProjectRepository, @@ -23,7 +27,8 @@ public class EventArrangementService : BaseService groupRepository, ISqlSugarRepository personRepository, ISqlSugarRepository registrationRepository, - ISqlSugarRepository projectTypeRepository) : base(projectRepository) + ISqlSugarRepository projectTypeRepository, + ISqlSugarRepository eventInfoRepository) : base(projectRepository) { _eventProjectRepository = eventProjectRepository; _projectRepository = projectRepository; @@ -31,6 +36,7 @@ public class EventArrangementService : BaseService @@ -196,9 +202,95 @@ public class EventArrangementService : BaseService Export(long eventId) { + var eventInfo = await _eventInfoRepository.GetFirstAsync(x => x.Id == eventId); var data = await Preview(eventId); - using var stream = new MemoryStream(); - stream.SaveAs(data); - return stream.ToArray(); + + // 设置 EPPlus 许可证上下文 + ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial; + + using var package = new ExcelPackage(); + var worksheet = package.Workbook.Worksheets.Add("编排表"); + + // 第一行:赛事标题(合并单元格 A1:G1) + worksheet.Cells["A1:G1"].Merge = true; + worksheet.Cells["A1"].Value = eventInfo?.EventName ?? "赛事编排表"; + + // 设置标题样式 + var titleStyle = worksheet.Cells["A1:G1"].Style; + titleStyle.Font.Bold = true; + titleStyle.Font.Size = 14; + titleStyle.HorizontalAlignment = ExcelHorizontalAlignment.Center; + titleStyle.VerticalAlignment = ExcelVerticalAlignment.Center; + titleStyle.Fill.PatternType = ExcelFillStyle.Solid; + titleStyle.Fill.BackgroundColor.SetColor(Color.FromArgb(255, 217, 179)); // 浅橙色 + + // 第二行:列标题 + string[] headers = { "时间", "参赛项目", "参赛组别", "参赛队伍", "运动员姓名", "场次", "场地" }; + for (int i = 0; i < headers.Length; i++) + { + worksheet.Cells[2, i + 1].Value = headers[i]; + } + + // 设置列标题样式 + var headerStyle = worksheet.Cells["A2:G2"].Style; + headerStyle.Font.Bold = true; + headerStyle.Font.Size = 11; + headerStyle.HorizontalAlignment = ExcelHorizontalAlignment.Center; + headerStyle.VerticalAlignment = ExcelVerticalAlignment.Center; + headerStyle.Fill.PatternType = ExcelFillStyle.Solid; + headerStyle.Fill.BackgroundColor.SetColor(Color.FromArgb(204, 255, 204)); // 浅绿色 + headerStyle.Border.Top.Style = ExcelBorderStyle.Thin; + headerStyle.Border.Bottom.Style = ExcelBorderStyle.Thin; + headerStyle.Border.Left.Style = ExcelBorderStyle.Thin; + headerStyle.Border.Right.Style = ExcelBorderStyle.Thin; + + // 填充数据行 + for (int i = 0; i < data.Count; i++) + { + var item = data[i]; + int rowIndex = i + 3; + + worksheet.Cells[rowIndex, 1].Value = item.TimeRange; + worksheet.Cells[rowIndex, 2].Value = item.ProjectName; + worksheet.Cells[rowIndex, 3].Value = item.GroupName; + worksheet.Cells[rowIndex, 4].Value = item.TeamName ?? ""; + worksheet.Cells[rowIndex, 5].Value = item.AthleteName; + worksheet.Cells[rowIndex, 6].Value = item.SessionIndex; + worksheet.Cells[rowIndex, 7].Value = item.VenueIndex; + + // 设置数据行样式 + var rowStyle = worksheet.Cells[$"A{rowIndex}:G{rowIndex}"].Style; + rowStyle.HorizontalAlignment = ExcelHorizontalAlignment.Center; + rowStyle.VerticalAlignment = ExcelVerticalAlignment.Center; + rowStyle.Border.Top.Style = ExcelBorderStyle.Thin; + rowStyle.Border.Bottom.Style = ExcelBorderStyle.Thin; + rowStyle.Border.Left.Style = ExcelBorderStyle.Thin; + rowStyle.Border.Right.Style = ExcelBorderStyle.Thin; + + // 交替行颜色 + if (i % 2 == 1) + { + rowStyle.Fill.PatternType = ExcelFillStyle.Solid; + rowStyle.Fill.BackgroundColor.SetColor(Color.FromArgb(240, 255, 240)); // 更浅的绿色 + } + } + + // 设置列宽 + worksheet.Column(1).Width = 12; // 时间 + worksheet.Column(2).Width = 18; // 参赛项目 + worksheet.Column(3).Width = 15; // 参赛组别 + worksheet.Column(4).Width = 25; // 参赛队伍 + worksheet.Column(5).Width = 15; // 运动员姓名 + worksheet.Column(6).Width = 8; // 场次 + worksheet.Column(7).Width = 8; // 场地 + + // 设置行高 + worksheet.Row(1).Height = 30; // 标题行 + worksheet.Row(2).Height = 25; // 列标题行 + + // 冻结首行和首列 + worksheet.View.FreezePanes(3, 1); + + return await package.GetAsByteArrayAsync(); } } diff --git a/YD_Event.Application/Merchant/MerchantCertificationService.cs b/YD_Event.Application/Merchant/MerchantCertificationService.cs index 1bb1641..0020acf 100644 --- a/YD_Event.Application/Merchant/MerchantCertificationService.cs +++ b/YD_Event.Application/Merchant/MerchantCertificationService.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Caching.Memory; +using EasyCaching.Core; using YD_Event.Application.Auth; using YD_Event.Application.Merchant.Dtos; using YD_Event.Core.Entities; @@ -16,7 +16,7 @@ public class MerchantCertificationService : BaseService, private readonly ISqlSugarRepository _merchantRepository; private readonly AuthManager _authManager; private readonly IIdGenerator _idGenerator; - private readonly IMemoryCache _memoryCache; + private readonly IEasyCachingProvider _cachingProvider; private readonly AliyunSmsService _smsService; public MerchantCertificationService( @@ -24,14 +24,14 @@ public class MerchantCertificationService : BaseService, ISqlSugarRepository merchantRepository, AuthManager authManager, IIdGenerator idGenerator, - IMemoryCache memoryCache, + IEasyCachingProvider cachingProvider, AliyunSmsService smsService) : base(repository) { _repository = repository; _merchantRepository = merchantRepository; _authManager = authManager; _idGenerator = idGenerator; - _memoryCache = memoryCache; + _cachingProvider = cachingProvider; _smsService = smsService; } @@ -42,7 +42,10 @@ public class MerchantCertificationService : BaseService, [HttpPost("submitCertification")] public async Task SubmitCertification(SubmitCertificationInput input) { - if (!_memoryCache.TryGetValue($"sms:code:{input.ContactPhone}", out string? cachedCode) || cachedCode != input.VerificationCode) + var cacheKey = $"sms:code:{input.ContactPhone}"; + var cachedCodeResult = _cachingProvider.Get(cacheKey); + string? cachedCode = cachedCodeResult.Value; + if (!cachedCodeResult.HasValue || cachedCode != input.VerificationCode) { throw Oops.Bah("验证码错误或已过期"); } @@ -82,7 +85,7 @@ public class MerchantCertificationService : BaseService, await _repository.UpdateAsync(certification); } - _memoryCache.Remove($"sms:code:{input.ContactPhone}"); + _cachingProvider.Remove(cacheKey); } /// diff --git a/YD_Event.Application/YD_Event.Application.csproj b/YD_Event.Application/YD_Event.Application.csproj index 14defea..5e22c1c 100644 --- a/YD_Event.Application/YD_Event.Application.csproj +++ b/YD_Event.Application/YD_Event.Application.csproj @@ -1,4 +1,4 @@ - + net8.0 1701;1702;1591 @@ -37,5 +37,6 @@ + \ No newline at end of file diff --git a/YD_Event.Application/applicationsettings.json b/YD_Event.Application/applicationsettings.json index 064c539..4b4c0bc 100644 --- a/YD_Event.Application/applicationsettings.json +++ b/YD_Event.Application/applicationsettings.json @@ -54,7 +54,7 @@ "SleepMs": 300, "dbconfig": { "ConnectionStrings": [ - "127.0.0.1:6379,password=123456,defaultDatabase=0,poolsize=7" + "8.153.108.90,Password=yd708090,SyncTimeout=15000,defaultDatabase=7,poolsize=50,ssl=false,writeBuffer=10240" ], //"Sentinels": [ // "192.169.1.10:26379", @@ -76,7 +76,7 @@ "EnableWriteDeepClone": false } }, - "type": "inmemory" //使用缓存类型 + "type": "csredis" //使用缓存类型 }, //对象存储配置 文档:https://github.com/oncemi/OnceMi.AspNetCore.OSS "OssConnection": { diff --git a/YD_Event.Core/InitData/sysmenu.txt b/YD_Event.Core/InitData/sysmenu.txt index 198afe2..e832237 100644 --- a/YD_Event.Core/InitData/sysmenu.txt +++ b/YD_Event.Core/InitData/sysmenu.txt @@ -1057,12 +1057,35 @@ "CreatedUserId": 1000, "CreatedTime": "2023-06-01T00:00:00" }, + { + "Id": 1070, + "Name": "系统设置", + "Type": 0, + "Code": "system", + "ParentId": null, + "RouteName": "system", + "Path": "/system", + "Component": "Layout", + "Redirect": "", + "Icon": "ele-Setting", + "IsIframe": "0", + "Link": "", + "IsVisible": "1", + "IsKeepAlive": "1", + "IsFixed": "0", + "Status": 0, + "Sort": 180, + "Remark": "", + "DeleteMark": false, + "CreatedUserId": 1000, + "CreatedTime": "2023-06-01T00:00:00" + }, { "Id": 1046, "Name": "权限管理", - "Type": 0, + "Type": 1, "Code": "permission", - "ParentId": null, + "ParentId": 1070, "RouteName": "permission", "Path": "/permission", "Component": "Layout", @@ -1074,7 +1097,7 @@ "IsKeepAlive": "1", "IsFixed": "0", "Status": 0, - "Sort": 170, + "Sort": 1, "Remark": "", "DeleteMark": false, "CreatedUserId": 1000, @@ -1310,6 +1333,144 @@ "CreatedUserId": 1000, "CreatedTime": "2023-06-01T00:00:00" }, + { + "Id": 1071, + "Name": "退款配置", + "Type": 1, + "Code": "refund", + "ParentId": 1070, + "RouteName": "refund", + "Path": "/refund", + "Component": "refund/index", + "Redirect": "", + "Icon": "ele-Money", + "IsIframe": "0", + "Link": "", + "IsVisible": "1", + "IsKeepAlive": "1", + "IsFixed": "0", + "Status": 0, + "Sort": 2, + "Remark": "", + "DeleteMark": false, + "CreatedUserId": 1000, + "CreatedTime": "2023-06-01T00:00:00" + }, + { + "Id": 1072, + "Name": "编辑", + "Type": 2, + "Code": "refund:edit", + "ParentId": 1071, + "RouteName": "btn_refund_edit", + "Path": "", + "Component": "", + "Redirect": "", + "Icon": "", + "IsIframe": "0", + "Link": "", + "IsVisible": "0", + "IsKeepAlive": "1", + "IsFixed": "0", + "Status": 0, + "Sort": 1, + "Remark": "", + "DeleteMark": false, + "CreatedUserId": 1000, + "CreatedTime": "2023-06-01T00:00:00" + }, + { + "Id": 1073, + "Name": "Banner配置", + "Type": 1, + "Code": "banner", + "ParentId": 1070, + "RouteName": "banner", + "Path": "/banner", + "Component": "banner/index", + "Redirect": "", + "Icon": "ele-Picture", + "IsIframe": "0", + "Link": "", + "IsVisible": "1", + "IsKeepAlive": "1", + "IsFixed": "0", + "Status": 0, + "Sort": 3, + "Remark": "", + "DeleteMark": false, + "CreatedUserId": 1000, + "CreatedTime": "2023-06-01T00:00:00" + }, + { + "Id": 1074, + "Name": "新增", + "Type": 2, + "Code": "banner:add", + "ParentId": 1073, + "RouteName": "btn_banner_add", + "Path": "", + "Component": "", + "Redirect": "", + "Icon": "", + "IsIframe": "0", + "Link": "", + "IsVisible": "0", + "IsKeepAlive": "1", + "IsFixed": "0", + "Status": 0, + "Sort": 1, + "Remark": "", + "DeleteMark": false, + "CreatedUserId": 1000, + "CreatedTime": "2023-06-01T00:00:00" + }, + { + "Id": 1075, + "Name": "编辑", + "Type": 2, + "Code": "banner:edit", + "ParentId": 1073, + "RouteName": "btn_banner_edit", + "Path": "", + "Component": "", + "Redirect": "", + "Icon": "", + "IsIframe": "0", + "Link": "", + "IsVisible": "0", + "IsKeepAlive": "1", + "IsFixed": "0", + "Status": 0, + "Sort": 2, + "Remark": "", + "DeleteMark": false, + "CreatedUserId": 1000, + "CreatedTime": "2023-06-01T00:00:00" + }, + { + "Id": 1076, + "Name": "删除", + "Type": 2, + "Code": "banner:delete", + "ParentId": 1073, + "RouteName": "btn_banner_delete", + "Path": "", + "Component": "", + "Redirect": "", + "Icon": "", + "IsIframe": "0", + "Link": "", + "IsVisible": "0", + "IsKeepAlive": "1", + "IsFixed": "0", + "Status": 0, + "Sort": 3, + "Remark": "", + "DeleteMark": false, + "CreatedUserId": 1000, + "CreatedTime": "2023-06-01T00:00:00" + }, { "Id": 1060, "Name": "积分管理", @@ -1325,7 +1486,7 @@ "IsKeepAlive": "1", "IsFixed": "0", "Status": 0, - "Sort": 161, + "Sort": 170, "Remark": "", "DeleteMark": false, "CreatedUserId": 1000,