using Admin.NET.Core.Service; using Microsoft.AspNetCore.Http; using Microsoft.CodeAnalysis.CSharp.Syntax; using Minio.DataModel; using OfficeOpenXml.FormulaParsing.Excel.Functions.Math; namespace Admin.NET.Application; /// /// Vip卡生成服务 /// [ApiDescriptionSettings(ApplicationConst.ZYGroupName, Order = 100)] public class BusVipCardInfoService : IDynamicApiController, ITransient { private readonly SqlSugarRepository _rep; private readonly SqlSugarRepository _dictdata; public BusVipCardInfoService(SqlSugarRepository rep, SqlSugarRepository _dictrep) { _rep = rep; _dictdata = _dictrep; } /// /// 分页查询Vip卡生成 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "Page")] public async Task> Page(BusVipCardInfoInput input) { var query = _rep.AsQueryable() .WhereIF(!string.IsNullOrWhiteSpace(input.SearchKey), u => u.Code.Contains(input.SearchKey.Trim()) || u.Pwd.Contains(input.SearchKey.Trim()) ) .WhereIF(!string.IsNullOrWhiteSpace(input.Code), u => u.Code.Contains(input.Code.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.Pwd), u => u.Pwd.Contains(input.Pwd.Trim())) .WhereIF(input.IsBind > 0, u => u.IsBind == input.IsBind) .WhereIF(input.Day > 0, u => u.Day == input.Day) .WhereIF(input.CardTypeId > 0, u => u.CardTypeId == input.CardTypeId) //处理外键和TreeSelector相关字段的连接 .LeftJoin((u, cardtypeid) => u.CardTypeId == cardtypeid.Id) .OrderBy(u => u.CreateTime) .Select((u, cardtypeid) => new BusVipCardInfoOutput { Id = u.Id, Code = u.Code, Pwd = u.Pwd, IsBind = u.IsBind, Day = u.Day, EndTime = u.EndTime, Money = u.Money, CardTypeId = u.CardTypeId, CardTypeIdName = cardtypeid.Name, TenantId = u.TenantId, CreateTime = u.CreateTime, UpdateTime = u.UpdateTime, CreateUserId = u.CreateUserId, CreateUserName = u.CreateUserName, UpdateUserId = u.UpdateUserId, UpdateUserName = u.UpdateUserName, IsDelete = u.IsDelete, }); if (input.EndTimeRange != null && input.EndTimeRange.Count > 0) { DateTime? start = input.EndTimeRange[0]; query = query.WhereIF(start.HasValue, u => u.EndTime > start); if (input.EndTimeRange.Count > 1 && input.EndTimeRange[1].HasValue) { var end = input.EndTimeRange[1].Value.AddDays(1); query = query.Where(u => u.EndTime < end); } } return await query.OrderBuilder(input).ToPagedListAsync(input.Page, input.PageSize); } /// /// 增加Vip卡生成 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "Add")] public async Task Add(AddBusVipCardInfoInput input) { var entity = input.Adapt(); await _rep.InsertAsync(entity); return entity.Id; } /// /// 删除Vip卡生成 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "Delete")] public async Task Delete(DeleteBusVipCardInfoInput input) { var entity = await _rep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002); await _rep.FakeDeleteAsync(entity); //假删除 //await _rep.DeleteAsync(entity); //真删除 } /// /// 更新Vip卡生成 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "Update")] public async Task Update(UpdateBusVipCardInfoInput input) { var entity = input.Adapt(); await _rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); } /// /// 获取Vip卡生成 /// /// /// [HttpGet] [ApiDescriptionSettings(Name = "Detail")] public async Task Detail([FromQuery] QueryByIdBusVipCardInfoInput input) { return await _rep.GetFirstAsync(u => u.Id == input.Id); } /// /// 获取Vip卡生成列表 /// /// /// [HttpGet] [ApiDescriptionSettings(Name = "List")] public async Task> List([FromQuery] BusVipCardInfoInput input) { return await _rep.AsQueryable().Select().ToListAsync(); } /// /// 获取卡类型Id列表 /// /// /// [ApiDescriptionSettings(Name = "SysDictDataCardTypeIdDropdown"), HttpGet] public async Task SysDictDataCardTypeIdDropdown() { return await _rep.Context.Queryable().Where(e => e.DictTypeId == 656829828702277) .Select(u => new { Label = u.Name, Value = u.Id } ).ToListAsync(); } /// /// 批量生成卡号(只可以生成高三的一年卡) /// /// [HttpPost] [ApiDescriptionSettings(Name = "GenerateVipCards")] public async Task GenerateVipCards([FromBody] GenrateVipCardRequestDto genrate) { if (genrate.Count <= 0 || string.IsNullOrWhiteSpace(genrate.Prefix)) { throw Oops.Oh("参数无效"); } var cardtypeInfo = await _dictdata.AsQueryable().Where(e => e.Id == genrate.CardTypeId).FirstAsync(); if (cardtypeInfo == null) throw Oops.Oh("卡类型无效"); var random = new Random(); var generatedCards = new List(); // 1. 查询数据库中已有的卡号,放入 HashSet var existingCodes = new HashSet(await _rep.AsQueryable().Select(c => c.Code) .ToListAsync()); // 计算卡号有效期,统一截止至当年8月31日 DateTime now = DateTime.UtcNow; DateTime expiryDate = new DateTime(now.Year, 8, 31, 23, 59, 59); if (now > expiryDate) // 如果当前时间已过8月31日,则设置为下一年的8月31日 { expiryDate = expiryDate.AddYears(1); } while (generatedCards.Count < genrate.Count) { var newCodes = new HashSet(); // 2. 一次性生成 count * 2 个随机卡号,避免频繁检查 while (newCodes.Count < genrate.Count * 2) { string cardNumber = genrate.Prefix + random.Next(100000, 999999); // 6 位随机数 if (!existingCodes.Contains(cardNumber)) // 只添加不重复的 { newCodes.Add(cardNumber); } } // 3. 过滤掉已经在数据库中的卡号 var uniqueNewCodes = newCodes.Except(existingCodes).Take(genrate.Count - generatedCards.Count).ToList(); // 4. 生成卡信息 generatedCards.AddRange(uniqueNewCodes.Select(cardNumber => new BusVipCardInfo { Code = cardNumber, Pwd = random.Next(100000, 999999).ToString(), IsBind = 0, Day = (expiryDate - now).Days, // 剩余天数 EndTime = expiryDate, Money = decimal.Parse(cardtypeInfo.Code), CardTypeId = genrate.CardTypeId, })); } // 6. 批量插入数据库 await _rep.InsertRangeAsync(generatedCards); return generatedCards; } }