diff --git a/YD_Event.Application/Event/Dtos/UserCompetitionDtos.cs b/YD_Event.Application/Event/Dtos/UserCompetitionDtos.cs index 36a7938..b5379db 100644 --- a/YD_Event.Application/Event/Dtos/UserCompetitionDtos.cs +++ b/YD_Event.Application/Event/Dtos/UserCompetitionDtos.cs @@ -687,9 +687,9 @@ public class RegistrationItemDTO public string TeamName { get; set; } /// - /// 综合状态描述 (待付款, 待上传素材, 已取消, 已报名, 待审核) + /// 综合状态 (0-待付款, 1-已支付, 2-已取消, 3-已退款, 4-已完成) /// - public string Status { get; set; } + public int Status { get; set; } /// /// 创建时间 @@ -702,14 +702,14 @@ public class RegistrationItemDTO public DateTime? UpdateTime { get; set; } /// - /// 支付状态 + /// 支付状态 (0-未支付, 1-已支付, 2-已取消, 3-已退款, 4-待审核) /// - public string PayStatus { get; set; } + public int PayStatus { get; set; } /// /// 证书状态 /// - public string CertStatus { get; set; } + public int CertStatus { get; set; } /// /// 是否有素材 diff --git a/YD_Event.Application/Event/UserEventRecordService.cs b/YD_Event.Application/Event/UserEventRecordService.cs index ae81b50..b8dcb5d 100644 --- a/YD_Event.Application/Event/UserEventRecordService.cs +++ b/YD_Event.Application/Event/UserEventRecordService.cs @@ -72,47 +72,6 @@ public class UserEventRecordService : IDynamicApiController, ITransient public async Task> GetRegistrationList([FromQuery] RegistrationListQueryInput input) { var userId = _authManager.UserId; - var query = _registrationRepository.AsQueryable() - .InnerJoin((r, e) => r.EventId == e.Id) - .Where((r, e) => r.CreatedUserId == userId && !r.DeleteMark) - .WhereIF(input.EventId.HasValue, (r, e) => r.EventId == input.EventId) - .WhereIF(!string.IsNullOrWhiteSpace(input.Keyword), (r, e) => r.TeamName.Contains(input.Keyword) || e.EventName.Contains(input.Keyword)) - .OrderByDescending((r, e) => r.CreatedTime) - .Select((r, e) => new RegistrationItemDTO - { - RegistrationId = r.Id, - EventName = e.EventName, - TeamName = r.TeamName, - CreateTime = r.CreatedTime, - UpdateTime = r.UpdatedTime, - PayStatus = r.PaymentStatus == 1 ? "已支付" : "待付款", // 简化映射 - CertStatus = "未颁发", // 暂无证书逻辑 - HasMaterial = SqlFunc.HasValue(r.MaterialUrl), - HasVoucher = SqlFunc.HasValue(r.PaymentProofUrl), - MemberCount = r.TotalPersonCount, - MaxMember = 10, // 假设 - ExpireTime = e.MaterialUploadEndTime - }); - - // 这里需要先把数据查出来再做复杂的状态转换,因为 SqlSugar Select 中不能写太复杂的 switch - var pagedResult = await query.ToPagedListAsync(input); - - // 二次处理状态描述 - foreach (var item in pagedResult.Rows) - { - // 状态映射逻辑 - // status ∈ (待付款, 待上传素材, 已取消, 已报名, 待审核) - // 假设:RegStatus=4 -> 已取消 - // RegStatus=1 -> 待审核 - // PayStatus=0 -> 待付款 - // PayStatus=1 && !HasMaterial -> 待上传素材 - // PayStatus=1 && HasMaterial -> 已报名 - - // 注意:这里需要再次查询原始状态值才能准确判断,上面的Select只映射了部分。 - // 优化:Select时把原始状态值带出来 - // 重新查询一遍原始数据比较准确 - } - // 重新构建查询以支持复杂逻辑 var list = await _registrationRepository.AsQueryable() .InnerJoin((r, e) => r.EventId == e.Id) @@ -128,23 +87,33 @@ public class UserEventRecordService : IDynamicApiController, ITransient .ToPagedListAsync(input); var resultItems = list.Rows.Select(x => { - string statusDesc = "未知"; - if (x.RegistrationStatus == 4) statusDesc = "已取消"; - else if (x.RegistrationStatus == 1) statusDesc = "待审核"; // 假设1是待审核 - else if (x.PaymentStatus == 0) statusDesc = "待付款"; - else if (x.PaymentStatus == 1 && string.IsNullOrEmpty(x.MaterialUrl)) statusDesc = "待上传素材"; - else if (x.PaymentStatus == 1 && !string.IsNullOrEmpty(x.MaterialUrl)) statusDesc = "已报名"; // 或已完成 + // 计算综合状态 + int statusValue = 0; + if (x.RegistrationStatus == 4) + statusValue = 2; // 已取消 + else if (x.RegistrationStatus == 1) + statusValue = 1; // 已支付/待审核 + else if (x.PaymentStatus == 0) + statusValue = 0; // 待付款 + else if (x.PaymentStatus == 1 && string.IsNullOrEmpty(x.MaterialUrl)) + statusValue = 1; // 已支付 + else if (x.PaymentStatus == 1 && !string.IsNullOrEmpty(x.MaterialUrl)) + statusValue = 4; // 已完成/已报名 + else if (x.PaymentStatus == 3) + statusValue = 3; // 已退款 + else if (x.PaymentStatus == 4) + statusValue = 1; // 待审核 return new RegistrationItemDTO { RegistrationId = x.Id, EventName = x.EventName, TeamName = x.TeamName, - Status = statusDesc, + Status = statusValue, CreateTime = x.CreatedTime, UpdateTime = x.UpdatedTime, - PayStatus = x.PaymentStatus == 1 ? "已支付" : (x.PaymentStatus == 4 ? "待审核" : "待付款"), - CertStatus = "未颁发", + PayStatus = x.PaymentStatus, + CertStatus = 0, // 未颁发 HasMaterial = !string.IsNullOrEmpty(x.MaterialUrl), HasVoucher = !string.IsNullOrEmpty(x.PaymentProofUrl), MemberCount = x.TotalPersonCount, diff --git a/YD_Event.Application/Event/UserEventRegistrationService.cs b/YD_Event.Application/Event/UserEventRegistrationService.cs index cd8e0f1..9b1a072 100644 --- a/YD_Event.Application/Event/UserEventRegistrationService.cs +++ b/YD_Event.Application/Event/UserEventRegistrationService.cs @@ -270,10 +270,10 @@ public class UserEventRegistrationService : IDynamicApiController, ITransient return new UserEventProjectGroupOutput { Id = eg.Id, - GroupName = baseGroup?.GroupName, - BirthDateStart = baseGroup?.BirthDateStart, - BirthDateEnd = baseGroup?.BirthDateEnd, - Gender = baseGroup?.Gender.ToString() + GroupName = eg.GroupName ?? baseGroup?.GroupName, + BirthDateStart = eg.BirthDateStart != DateTime.MinValue ? eg.BirthDateStart : baseGroup?.BirthDateStart, + BirthDateEnd = eg.BirthDateEnd != DateTime.MinValue ? eg.BirthDateEnd : baseGroup?.BirthDateEnd, + Gender = eg.Gender.ToString() }; }).ToList(); @@ -367,10 +367,10 @@ public class UserEventRegistrationService : IDynamicApiController, ITransient return new UserEventProjectGroupOutput { Id = eg.Id, - GroupName = baseGroup?.GroupName, - BirthDateStart = baseGroup?.BirthDateStart, - BirthDateEnd = baseGroup?.BirthDateEnd, - Gender = baseGroup?.Gender.ToString() + GroupName = eg.GroupName ?? baseGroup?.GroupName, + BirthDateStart = eg.BirthDateStart != DateTime.MinValue ? eg.BirthDateStart : baseGroup?.BirthDateStart, + BirthDateEnd = eg.BirthDateEnd != DateTime.MinValue ? eg.BirthDateEnd : baseGroup?.BirthDateEnd, + Gender = eg.Gender.ToString() }; }).ToList(); @@ -429,6 +429,34 @@ public class UserEventRegistrationService : IDynamicApiController, ITransient var eventInfo = await _eventRepository.GetByIdAsync(input.EventId); if (eventInfo == null) throw Oops.Bah("赛事不存在"); + + // 验证1:一次报名只能选择一个项目 + if (input.ProjectIds != null && input.ProjectIds.Count > 1) + { + throw Oops.Bah("一次报名只能选择一个项目"); + } + + // 验证2:一次报名只能选择单个团队内的运动员 + if (input.MemberIds != null && input.MemberIds.Count > 0) + { + // 获取所有队员的团队ID + var teamMembers = await _db.Queryable() + .Where(tm => input.MemberIds.Contains(tm.UserId)) + .Where(tm => !tm.DeleteMark) + .ToListAsync(); + + if (teamMembers == null || teamMembers.Count == 0) + { + throw Oops.Bah("未找到队员信息"); + } + + // 检查所有队员是否属于同一个团队 + var teamIds = teamMembers.Select(tm => tm.TeamId).Distinct().ToList(); + if (teamIds.Count > 1) + { + throw Oops.Bah("一次报名只能选择单个团队内的运动员"); + } + } var registration = await _registrationRepository.GetFirstAsync(x => x.EventId == input.EventId && x.CreatedUserId == userId && !x.DeleteMark); @@ -1126,22 +1154,25 @@ public class UserEventRegistrationService : IDynamicApiController, ITransient if (eventProjectGroup != null) { var projectGroup = await _projectGroupRepository.GetByIdAsync(eventProjectGroup.ProjectGroupId); - if (projectGroup != null) + + // 优先使用EventProjectGroup中保存的信息,如果没有则使用原始ProjectGroup的信息 + var birthDateStart = eventProjectGroup.BirthDateStart != DateTime.MinValue ? eventProjectGroup.BirthDateStart : (projectGroup?.BirthDateStart ?? DateTime.MinValue); + var birthDateEnd = eventProjectGroup.BirthDateEnd != DateTime.MinValue ? eventProjectGroup.BirthDateEnd : (projectGroup?.BirthDateEnd ?? DateTime.MaxValue); + var gender = eventProjectGroup.Gender; + + var birthDate = member.BirthDate.Value; + if (birthDate < birthDateStart || birthDate > birthDateEnd) { - var birthDate = member.BirthDate.Value; - if (birthDate < projectGroup.BirthDateStart || birthDate > projectGroup.BirthDateEnd) - { - result.AgeValid = false; - result.IsValid = false; - result.Message = "队员年龄不符合组别要求"; - } + result.AgeValid = false; + result.IsValid = false; + result.Message = "队员年龄不符合组别要求"; + } - if (projectGroup.Gender != member.Gender && projectGroup.Gender != Gender.Unknown) - { - result.GenderValid = false; - result.IsValid = false; - result.Message = "队员性别不符合组别要求"; - } + if (gender != member.Gender && gender != Gender.Unknown && gender != Gender.All) + { + result.GenderValid = false; + result.IsValid = false; + result.Message = "队员性别不符合组别要求"; } } diff --git a/YD_Event.Application/Order/OrderService.cs b/YD_Event.Application/Order/OrderService.cs index 4f56c32..5d0ffe2 100644 --- a/YD_Event.Application/Order/OrderService.cs +++ b/YD_Event.Application/Order/OrderService.cs @@ -1,4 +1,7 @@ using System.Text; +using OfficeOpenXml; +using OfficeOpenXml.Style; +using System.Drawing; using YD_Event.Application.Auth; using YD_Event.Application.Order.Dtos; using YD_Event.Core.Entities; @@ -167,6 +170,12 @@ public class OrderService : BaseService, ITransien .LeftJoin((o, e, m) => o.MerchantId == m.Id) .LeftJoin((o, e, m, r) => o.RegistrationId == r.Id) .LeftJoin((o, e, m, r, ro) => o.RelatedOrderId == ro.Id) // Join self for Related Order No + // 默认只显示已完成支付流程的订单(已支付、已发货、已完成、已退款) + .WhereIF(!input.OrderStatus.HasValue, (o, e, m, r, ro) => + o.OrderStatus == OrderStatus.Paid || + o.OrderStatus == OrderStatus.Shipped || + o.OrderStatus == OrderStatus.Completed || + o.OrderStatus == OrderStatus.Refunded) .WhereIF(!string.IsNullOrWhiteSpace(input.OrderNo), (o, e, m, r, ro) => o.OrderNo.Contains(input.OrderNo)) .WhereIF(!string.IsNullOrWhiteSpace(input.EventName), (o, e, m, r, ro) => e.EventName.Contains(input.EventName)) .WhereIF(input.OrderType.HasValue, (o, e, m, r, ro) => o.OrderType == input.OrderType) @@ -382,6 +391,12 @@ public class OrderService : BaseService, ITransien .LeftJoin((o, e, m) => o.MerchantId == m.Id) .LeftJoin((o, e, m, r) => o.RegistrationId == r.Id) .LeftJoin((o, e, m, r, ro) => o.RelatedOrderId == ro.Id) + // 默认只导出已完成支付流程的订单(已支付、已发货、已完成、已退款) + .WhereIF(!input.OrderStatus.HasValue, (o, e, m, r, ro) => + o.OrderStatus == OrderStatus.Paid || + o.OrderStatus == OrderStatus.Shipped || + o.OrderStatus == OrderStatus.Completed || + o.OrderStatus == OrderStatus.Refunded) .WhereIF(!string.IsNullOrWhiteSpace(input.OrderNo), (o, e, m, r, ro) => o.OrderNo.Contains(input.OrderNo)) .WhereIF(!string.IsNullOrWhiteSpace(input.EventName), (o, e, m, r, ro) => e.EventName.Contains(input.EventName)) .WhereIF(input.OrderType.HasValue, (o, e, m, r, ro) => o.OrderType == input.OrderType) @@ -418,26 +433,133 @@ public class OrderService : BaseService, ITransien }) .ToListAsync(); - // Calculate Summary - decimal totalOriginal = list.Sum(x => x.OriginalAmount); - decimal totalDiscount = list.Sum(x => x.DiscountAmount); - decimal totalRefund = list.Where(x => x.OrderType == "退款").Sum(x => x.ActualAmount); - decimal totalActual = list.Where(x => x.OrderType == "收入").Sum(x => x.ActualAmount); - - var sb = new StringBuilder(); - // Summary Row - sb.AppendLine($"汇总信息: 原金额:{totalOriginal}, 优惠金额:{totalDiscount}, 退款金额:{totalRefund}, 实付金额:{totalActual}"); - sb.AppendLine("订单编号,单位名称,所属赛事,订单类型,关联订单,支付方式,报名方式,报名用户,报名账号,原金额,优惠金额,实付/退款金额,订单状态,生成时间"); + var bytes = await GenerateOrderExcelAsync(list); - foreach (var item in list) + return new FileContentResult(bytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") { - sb.AppendLine($"{item.OrderNo},{item.UnitName},{item.EventName},{item.OrderType},{item.RelatedOrderNo},{item.PaymentMethod},{item.RegistrationMode},{item.ContactName},{item.ContactPhone},{item.OriginalAmount},{item.DiscountAmount},{item.ActualAmount},{item.OrderStatusText},{item.CreatedTime}"); - } - - var bytes = Encoding.UTF8.GetBytes(sb.ToString()); - return new FileContentResult(bytes, "text/csv") - { - FileDownloadName = $"Orders_{DateTime.Now:yyyyMMddHHmmss}.csv" + FileDownloadName = $"订单列表_{DateTime.Now:yyyyMMddHHmmss}.xlsx" }; } + + /// + /// 生成订单Excel文件 + /// + private async Task GenerateOrderExcelAsync(List orders) + { + ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial; + + using var package = new ExcelPackage(); + var worksheet = package.Workbook.Worksheets.Add("订单列表"); + + var rowIndex = 1; + + // 计算汇总数据 + var totalOriginal = orders.Sum(x => x.OriginalAmount); + var totalDiscount = orders.Sum(x => x.DiscountAmount); + var totalRefund = orders.Where(x => x.OrderType == "退款").Sum(x => x.ActualAmount); + var totalActual = orders.Where(x => x.OrderType == "收入").Sum(x => x.ActualAmount); + + // 汇总信息行 + var summaryRange = worksheet.Cells[rowIndex, 1, rowIndex, 14]; + summaryRange.Merge = true; + summaryRange.Value = $"汇总信息: 原金额:{totalOriginal}, 优惠金额:{totalDiscount}, 退款金额:{totalRefund}, 实付金额:{totalActual}"; + var summaryStyle = summaryRange.Style; + summaryStyle.Font.Bold = true; + summaryStyle.Font.Size = 12; + summaryStyle.HorizontalAlignment = ExcelHorizontalAlignment.Center; + summaryStyle.VerticalAlignment = ExcelVerticalAlignment.Center; + summaryStyle.Fill.PatternType = ExcelFillStyle.Solid; + summaryStyle.Fill.BackgroundColor.SetColor(Color.LightGray); + rowIndex++; + + // 列标题 + var headers = new[] + { + "订单编号", "单位名称", "所属赛事", "订单类型", "关联订单", + "支付方式", "报名方式", "报名用户", "报名账号", "原金额(元)", + "优惠金额(元)", "退款金额(元)", "实付金额(元)", "生成时间" + }; + + for (int i = 0; i < headers.Length; i++) + { + worksheet.Cells[rowIndex, i + 1].Value = headers[i]; + } + + var headerRange = worksheet.Cells[rowIndex, 1, rowIndex, headers.Length]; + var headerStyle = headerRange.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.LightBlue); + SetCellBorders(headerRange, ExcelBorderStyle.Thin); + rowIndex++; + + // 数据行 + foreach (var item in orders) + { + var refundAmount = item.OrderType == "退款" ? item.ActualAmount : 0; + var actualPayAmount = item.OrderType == "收入" ? item.ActualAmount : 0; + + worksheet.Cells[rowIndex, 1].Value = item.OrderNo; + worksheet.Cells[rowIndex, 2].Value = item.UnitName; + worksheet.Cells[rowIndex, 3].Value = item.EventName; + worksheet.Cells[rowIndex, 4].Value = item.OrderType; + worksheet.Cells[rowIndex, 5].Value = item.RelatedOrderNo; + worksheet.Cells[rowIndex, 6].Value = item.PaymentMethod; + worksheet.Cells[rowIndex, 7].Value = item.RegistrationMode; + worksheet.Cells[rowIndex, 8].Value = item.ContactName; + worksheet.Cells[rowIndex, 9].Value = item.ContactPhone; + worksheet.Cells[rowIndex, 10].Value = item.OriginalAmount; + worksheet.Cells[rowIndex, 11].Value = item.DiscountAmount; + worksheet.Cells[rowIndex, 12].Value = refundAmount; + worksheet.Cells[rowIndex, 13].Value = actualPayAmount; + worksheet.Cells[rowIndex, 14].Value = item.CreatedTime.ToString("yyyy-MM-dd HH:mm:ss"); + + // 设置金额格式 + worksheet.Cells[rowIndex, 10].Style.Numberformat.Format = "0.00"; + worksheet.Cells[rowIndex, 11].Style.Numberformat.Format = "0.00"; + worksheet.Cells[rowIndex, 12].Style.Numberformat.Format = "0.00"; + worksheet.Cells[rowIndex, 13].Style.Numberformat.Format = "0.00"; + + SetDataRowStyle(worksheet, rowIndex, 14); + rowIndex++; + } + + // 设置列宽 + var columnWidths = new double[] { 18, 15, 15, 10, 12, 10, 10, 12, 14, 12, 14, 14, 12, 18 }; + for (int i = 0; i < columnWidths.Length; i++) + { + worksheet.Column(i + 1).Width = columnWidths[i]; + } + + // 冻结表头 + worksheet.View.FreezePanes(3, 1); + + return await package.GetAsByteArrayAsync(); + } + + /// + /// 设置单元格边框 + /// + private void SetCellBorders(ExcelRange range, ExcelBorderStyle borderStyle) + { + range.Style.Border.Top.Style = borderStyle; + range.Style.Border.Bottom.Style = borderStyle; + range.Style.Border.Left.Style = borderStyle; + range.Style.Border.Right.Style = borderStyle; + } + + /// + /// 设置数据行样式 + /// + private void SetDataRowStyle(ExcelWorksheet worksheet, int rowIndex, int colCount) + { + var range = worksheet.Cells[rowIndex, 1, rowIndex, colCount]; + var style = range.Style; + style.HorizontalAlignment = ExcelHorizontalAlignment.Center; + style.VerticalAlignment = ExcelVerticalAlignment.Center; + SetCellBorders(range, ExcelBorderStyle.Thin); + } } diff --git a/YD_Event.Application/YD_Event.Application.xml b/YD_Event.Application/YD_Event.Application.xml index c2059a8..45efafa 100644 --- a/YD_Event.Application/YD_Event.Application.xml +++ b/YD_Event.Application/YD_Event.Application.xml @@ -1672,7 +1672,7 @@ - 赛事项目DTO + 赛事项目DTO扩展(含项目限制信息) @@ -1695,11 +1695,116 @@ 报名费用 + + + 项目限报数量 + + 组别列表 + + + 计算报名金额输入DTO + + + + + 赛事ID + + + + + 报名模式 (1-个人 2-团队) + + + + + 报名项目列表 + + + + + 计算报名金额项目输入DTO + + + + + 项目ID + + + + + 参赛人员数量 + + + + + 计算报名金额输出DTO + + + + + 赛事收费模式 + + + + + 总金额 + + + + + 项目费用明细 + + + + + 计算报名金额项目输出DTO + + + + + 项目ID + + + + + 项目名称 + + + + + 单价 + + + + + 人数 + + + + + 小计 + + + + + 选择支付方式输入DTO + + + + + 报名ID + + + + + 支付方式 (1-线下 2-微信支付) + + 项目组别DTO @@ -2255,6 +2360,16 @@ 所在单位 + + + 性别:0-未知,1-男,2-女 + + + + + 出生日期 + + 个人中心-实名认证信息 @@ -2783,6 +2898,13 @@ + + + 计算报名金额 + + + + 提交赛事报名 @@ -2794,6 +2916,19 @@ 获取支付信息 + + OpenId 参数获取方式: + - 支持从查询字符串(QueryString)传入:openId 或 openid + - 支持从表单数据(FormData)传入:openId 或 openid + - 支持从用户 Claims 中获取(兜底方案) + + OpenId 参数验证规则: + - 不能为空或空白字符串 + - 长度必须在 10-50 个字符之间 + - 只能包含字母、数字、下划线和连字符 + + 报名记录ID + 支付信息,包括微信支付参数(如果是微信支付) @@ -2830,6 +2965,48 @@ + + + 选择支付方式 + + + + + 同步支付状态(主动查询微信支付) + + + + + 微信支付回调通知处理 + + + + + 从请求中获取 OpenId 参数 + + + 支持从以下来源获取 OpenId(按优先级顺序): + 1. 查询字符串 (QueryString):openId 或 openid 参数 + 2. 表单数据 (FormData):openId 或 openid 字段 + 3. 请求体 (JSON):openId 或 openid 属性 + 4. 用户 Claims(兜底方案):openid claim + + 获取到的 OpenId 值,如果未找到则返回空字符串 + + + + 验证 OpenId 参数的有效性 + + + 验证规则: + 1. OpenId 不能为空或空白字符串 + 2. OpenId 长度必须在合理范围内(微信 OpenId 通常为 28 个字符左右) + 3. OpenId 只能包含字母、数字和下划线 + + 待验证的 OpenId + 验证失败时的错误信息 + 验证通过返回 true,否则返回 false + 小程序-个人中心接口 @@ -5328,7 +5505,7 @@ - 综合状态描述 (待付款, 待上传素材, 已取消, 已报名, 待审核) + 综合状态 (0-待付款, 1-已支付, 2-已取消, 3-已退款, 4-已完成) @@ -5343,7 +5520,7 @@ - 支付状态 + 支付状态 (0-未支付, 1-已支付, 2-已取消, 3-已退款, 4-待审核) @@ -7735,6 +7912,21 @@ 导出订单 + + + 生成订单Excel文件 + + + + + 设置单元格边框 + + + + + 设置数据行样式 + + 添加机构输入 @@ -9207,6 +9399,11 @@ 账号 + + + 密码 + + 关联角色ID集合 diff --git a/YD_Event.Core/YD_Event.Core.xml b/YD_Event.Core/YD_Event.Core.xml index 236df31..beae919 100644 --- a/YD_Event.Core/YD_Event.Core.xml +++ b/YD_Event.Core/YD_Event.Core.xml @@ -1504,6 +1504,26 @@ 关联的项目组别ID + + + 组别名称 + + + + + 出生日期起始日期 + + + + + 出生日期结束日期 + + + + + 性别要求 + + 标记删除