using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Mapster; using Microsoft.AspNetCore.Mvc; using NCC.Common.Core.Manager; using NCC.Common.Filter; using NCC.Dependency; using NCC.DynamicApiController; using NCC.Extend.Entitys.Dto.LqEvent; using NCC.Extend.Entitys.Dto.LqEventUser; using NCC.Extend.Entitys.lq_event; using NCC.Extend.Entitys.lq_eventuser; using NCC.Extend.Interfaces.LqEvent; using NCC.FriendlyException; using SqlSugar; using Yitter.IdGenerator; namespace NCC.Extend.LqEvent { /// /// 拓客活动服务 /// [ApiDescriptionSettings(Tag = "绿纤拓客活动服务", Name = "LqEvent", Order = 200)] [Route("api/Extend/[controller]")] [ApiController] public class LqEventService : ILqEventService, IDynamicApiController, ITransient { private readonly ISqlSugarClient _db; private readonly IUserManager _userManager; /// /// 初始化一个类型的新实例 /// /// 数据库 /// 用户管理 public LqEventService(ISqlSugarClient db, IUserManager userManager) { _db = db; _userManager = userManager; } #region 获取拓客活动列表 /// /// 获取拓客活动列表 /// /// /// 分页查询拓客活动列表,支持多条件筛选和排序。 /// 返回结果包含每个活动的成员数量统计。 /// /// 示例请求: /// GET /api/Extend/LqEvent?page=1&rows=10&sidx=Id&sord=desc&eventName=春节拓客活动 /// /// 支持的条件筛选: /// - 活动名称模糊查询 /// - 活动编号模糊查询 /// - 活动负责人模糊查询 /// - 开始时间范围查询 /// - 结束时间范围查询 /// /// 支持的排序字段: /// - Id: 活动ID /// - EventName: 活动名称 /// - EventNumber: 活动编号 /// - EventCoordinator: 活动负责人 /// - StartTime: 开始时间 /// - EndTime: 结束时间 /// /// 查询参数 /// 分页的拓客活动列表,包含成员数量统计 [HttpGet("")] public async Task GetList([FromQuery] LqEventListQueryInput input) { var sidx = input.sidx == null ? "id" : input.sidx; var sord = input.sord == null ? "desc" : input.sord; // 先查询活动列表 var Data = await _db.Queryable() .WhereIF(!string.IsNullOrEmpty(input.EventName), e => e.EventName.Contains(input.EventName)) .WhereIF(!string.IsNullOrEmpty(input.EventNumber), e => e.EventNumber.Contains(input.EventNumber)) .Select(e => new LqEventListOutput { id = e.Id, eventName = e.EventName, startTime = e.StartTime, endTime = e.EndTime, eventCoordinator = e.EventCoordinator, eventNumber = e.EventNumber, memberCount = SqlFunc.Subqueryable().Where(u => u.EventId == e.Id).Count(), }) .MergeTable() .OrderBy(sidx + " " + sord) .ToPagedListAsync(input.page, input.rows); return PageResult.SqlSugarPageResult(Data); } #endregion #region 获取拓客活动详情 /// /// 获取拓客活动详情 /// /// /// 根据活动ID获取拓客活动的详细信息,包括基础信息和所有参与成员列表。 /// /// 示例请求: /// GET /api/Extend/LqEvent/1234567890123456789 /// /// 返回数据包含: /// - 活动基础信息(ID、名称、编号、负责人、开始时间、结束时间) /// - 成员列表(用户ID、部门ID、战队名称、创建时间、创建用户) /// /// 如果活动不存在,将返回404错误。 /// /// 拓客活动ID /// 拓客活动详情,包含成员信息 /// 成功返回拓客活动详情 /// 拓客活动不存在 /// 服务器内部错误 [HttpGet("{id}")] public async Task GetInfo(string id) { // 1. 获取拓客活动基本信息 var entity = await _db.Queryable().FirstAsync(p => p.Id == id); if (entity == null) { throw NCCException.Oh("拓客活动不存在"); } var output = entity.Adapt(); // 2. 获取拓客活动成员信息 var members = await _db.Queryable().Where(u => u.EventId == id.ToString()).ToListAsync(); // 3. 转换为输出格式 output.Members = members.Adapt>(); return output; } #endregion #region 创建拓客活动 /// /// 创建拓客活动 /// /// /// 创建新的拓客活动,可以同时添加参与成员。 /// 系统会自动生成活动ID,并记录创建用户信息。 /// /// 示例请求: /// POST /api/Extend/LqEvent /// Content-Type: application/json /// /// ```json /// { /// "eventName": "春节拓客活动", /// "eventNumber": "TK2024001", /// "eventCoordinator": "张三", /// "startTime": "2024-01-15T09:00:00", /// "endTime": "2024-01-20T18:00:00", /// "members": [ /// { /// "userId": "user001", /// "depId": "dept001", /// "teamName": "第一战队" /// }, /// { /// "userId": "user002", /// "depId": "dept001", /// "teamName": "第二战队" /// } /// ] /// } /// ``` /// /// 参数验证: /// - eventName: 必填,最大长度255字符 /// - eventNumber: 可选,最大长度255字符 /// - eventCoordinator: 可选,最大长度255字符 /// - members: 可选,成员列表 /// - userId: 必填 /// - depId: 可选 /// - teamName: 可选 /// /// 创建流程: /// 1. 生成新的活动ID /// 2. 插入拓客活动记录 /// 3. 插入成员记录(如果有) /// /// 创建参数 /// 无返回值 [HttpPost("")] public async Task Create([FromBody] LqEventCrInput input) { var userInfo = await _userManager.GetUserInfo(); var entity = input.Adapt(); // 生成新的ID entity.Id = YitIdHelper.NextId().ToString(); // 插入拓客活动 var isOk = await _db.Insertable(entity).ExecuteCommandAsync(); if (!(isOk > 0)) throw NCCException.Oh("创建拓客活动失败"); // 插入拓客活动成员 if (input.Members != null && input.Members.Count > 0) { var memberEntities = new List(); foreach (var member in input.Members) { memberEntities.Add( new LqEventUserEntity { Id = YitIdHelper.NextId().ToString(), EventId = entity.Id.ToString(), UserId = member.UserId, DepId = member.DepId, TeamName = member.TeamName, CreationTime = DateTime.Now, CreationUser = userInfo?.userName, } ); } await _db.Insertable(memberEntities).ExecuteCommandAsync(); } } #endregion #region 更新拓客活动 /// /// 更新拓客活动 /// /// /// 更新拓客活动信息,包括基础信息和成员列表。 /// 更新时会先删除原有成员,再添加新成员。 /// /// 示例请求: /// PUT /api/Extend/LqEvent /// Content-Type: application/json /// /// ```json /// { /// "id": "1234567890123456789", /// "eventName": "春节拓客活动(更新)", /// "eventNumber": "TK2024001", /// "eventCoordinator": "李四", /// "startTime": "2024-01-15T09:00:00", /// "endTime": "2024-01-25T18:00:00", /// "members": [ /// { /// "userId": "user003", /// "depId": "dept002", /// "teamName": "精英战队" /// } /// ] /// } /// ``` /// /// 参数验证: /// - id: 必填,拓客活动ID /// - eventName: 必填,最大长度255字符 /// - eventNumber: 可选,最大长度255字符 /// - eventCoordinator: 可选,最大长度255字符 /// - members: 可选,成员列表(为空则清空所有成员) /// /// 更新流程: /// 1. 更新拓客活动记录 /// 2. 删除原有成员记录 /// 3. 插入新成员记录(如果有) /// /// 更新参数 /// 无返回值 /// 拓客活动更新成功 /// 请求参数错误或验证失败 /// 拓客活动不存在 /// 服务器内部错误 [HttpPut("")] public async Task Update([FromBody] LqEventUpInput input) { var userInfo = await _userManager.GetUserInfo(); var entity = input.Adapt(); // 更新拓客活动 var isOk = await _db.Updateable(entity).ExecuteCommandAsync(); if (!(isOk > 0)) throw NCCException.Oh("更新拓客活动失败"); // 删除原有成员 await _db.Deleteable().Where(u => u.EventId == entity.Id.ToString()).ExecuteCommandAsync(); // 插入新成员 if (input.Members != null && input.Members.Count > 0) { var memberEntities = new List(); foreach (var member in input.Members) { memberEntities.Add( new LqEventUserEntity { Id = YitIdHelper.NextId().ToString(), EventId = entity.Id.ToString(), UserId = member.UserId, DepId = member.DepId, TeamName = member.TeamName, CreationTime = DateTime.Now, CreationUser = userInfo?.userName, } ); } await _db.Insertable(memberEntities).ExecuteCommandAsync(); } } #endregion #region 删除拓客活动 /// /// 删除拓客活动 /// /// /// 删除指定的拓客活动,会同时删除该活动的所有成员记录。 /// 删除操作不可恢复,请谨慎使用。 /// /// 示例请求: /// DELETE /api/Extend/LqEvent/1234567890123456789 /// /// 删除顺序: /// 1. 先删除所有相关成员记录 /// 2. 再删除拓客活动记录 /// /// 注意事项: /// - 删除操作不可恢复 /// - 会级联删除所有相关成员记录 /// - 如果活动不存在,将返回404错误 /// - 建议在删除前先查询确认活动信息 /// /// 拓客活动ID /// 无返回值 /// 拓客活动删除成功 /// 拓客活动不存在 /// 服务器内部错误 [HttpDelete("{id}")] public async Task Delete(string id) { // 删除拓客活动成员 await _db.Deleteable().Where(u => u.EventId == id.ToString()).ExecuteCommandAsync(); // 删除拓客活动 var isOk = await _db.Deleteable().Where(p => p.Id == id).ExecuteCommandAsync(); if (!(isOk > 0)) throw NCCException.Oh("删除拓客活动失败"); } #endregion #region 更新拓客目标数量 /// /// 更新拓客目标数量 /// /// 拓客活动ID /// 拓客目标数量 /// [HttpPut("{id}/target")] public async Task UpdateTarget(string id, int target) { var isOk = await _db.Updateable().SetColumns(it => new LqEventUserEntity { EventTarget = target }).Where(x => x.EventId == id).ExecuteCommandAsync(); if (!(isOk > 0)) throw NCCException.Oh("更新拓客目标数量失败"); } #endregion #region 获取拓客目标数量 /// /// 获取拓客目标数量 /// /// 拓客活动ID /// [HttpGet("{id}/target")] public async Task GetTarget(string id) { return await _db.Queryable().Where(x => x.EventId == id).Select(x => x.EventTarget).FirstAsync(); } #endregion #region 根据用户ID获取参与的拓客活动 /// /// 根据用户ID获取参与的拓客活动 /// /// /// 根据用户ID查询该用户参与的所有拓客活动,支持时间范围筛选。 /// 返回结果包含活动基础信息和用户在该活动中的详细信息。 /// /// 示例请求: /// GET /api/Extend/LqEvent/user/user001?startTime=2024-01-01&endTime=2024-12-31 /// /// 参数说明: /// - userId: 用户ID(必填) /// - startTime: 开始时间(可选),查询在此时间之后开始的活动 /// - endTime: 结束时间(可选),查询在此时间之前结束的活动 /// /// 返回数据包含: /// - 活动基础信息(ID、名称、编号、负责人、开始时间、结束时间) /// - 用户参与信息(部门ID、战队名称、目标数量等) /// /// 用户ID /// 开始时间(可选) /// 结束时间(可选) /// 用户参与的拓客活动列表 /// 成功返回用户参与的拓客活动列表 /// 请求参数错误 /// 服务器内部错误 [HttpGet("user/{userId}")] [ProducesResponseType(typeof(List), 200)] [ProducesResponseType(400)] [ProducesResponseType(500)] public async Task> GetUserEvents(string userId, [FromQuery] DateTime? startTime = null, [FromQuery] DateTime? endTime = null) { try { // 先测试简单的查询 var eventUsers = await _db.Queryable().Where(u => u.UserId == userId).ToListAsync(); if (!eventUsers.Any()) { return new List(); } var eventIds = eventUsers.Select(u => u.EventId).ToList(); // 查询活动信息 var events = await _db.Queryable().Where(e => eventIds.Contains(e.Id)).ToListAsync(); // 时间范围筛选 if (startTime.HasValue) { events = events.Where(e => e.StartTime >= startTime.Value).ToList(); } if (endTime.HasValue) { events = events.Where(e => e.EndTime <= endTime.Value).ToList(); } // 构建结果 var result = new List(); foreach (var eventUser in eventUsers) { var eventInfo = events.FirstOrDefault(e => e.Id == eventUser.EventId); if (eventInfo != null) { result.Add( new LqEventUserEventOutput { // 活动基础信息 EventId = eventInfo.Id, EventName = eventInfo.EventName, EventNumber = eventInfo.EventNumber, EventCoordinator = eventInfo.EventCoordinator, StartTime = eventInfo.StartTime, EndTime = eventInfo.EndTime, // 用户参与信息 UserId = eventUser.UserId, DepId = eventUser.DepId, TeamName = eventUser.TeamName, EventTarget = eventUser.EventTarget, CreationTime = eventUser.CreationTime, CreationUser = eventUser.CreationUser, } ); } } // 按开始时间降序排列 return result.OrderByDescending(x => x.StartTime).ToList(); } catch (Exception ex) { throw NCCException.Oh("获取用户参与的拓客活动失败", ex); } } #endregion } }