2026-03-12 10:30:13 +08:00
|
|
|
using Furion.DatabaseAccessor;
|
|
|
|
|
using Furion.DependencyInjection;
|
|
|
|
|
using Furion.DynamicApiController;
|
|
|
|
|
using Furion.FriendlyException;
|
|
|
|
|
using Mapster;
|
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
using SqlSugar;
|
|
|
|
|
using YD_Event.Application.Team.Dtos;
|
|
|
|
|
using YD_Event.Core.Entities;
|
|
|
|
|
using YD_Event.Core.Enum;
|
|
|
|
|
|
|
|
|
|
namespace YD_Event.Application.Team;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 团队管理服务
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class TeamService : BaseService<Core.Entities.Team>, IDynamicApiController, ITransient
|
|
|
|
|
{
|
|
|
|
|
private readonly ISqlSugarRepository<Core.Entities.Team> _teamRep;
|
|
|
|
|
private readonly ISqlSugarRepository<TeamMember> _memberRep;
|
|
|
|
|
private readonly ISqlSugarRepository<Core.Entities.AppUser> _userRep;
|
|
|
|
|
|
|
|
|
|
public TeamService(
|
|
|
|
|
ISqlSugarRepository<Core.Entities.Team> teamRep,
|
|
|
|
|
ISqlSugarRepository<TeamMember> memberRep,
|
|
|
|
|
ISqlSugarRepository<Core.Entities.AppUser> userRep) : base(teamRep)
|
|
|
|
|
{
|
|
|
|
|
_teamRep = teamRep;
|
|
|
|
|
_memberRep = memberRep;
|
|
|
|
|
_userRep = userRep;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 分页查询团队
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="input"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpGet("page")]
|
|
|
|
|
[DisplayName("分页查询团队")]
|
2026-03-14 11:25:39 +08:00
|
|
|
public async Task<PageResult<TeamOutput>> Page([FromQuery] TeamQueryInput input)
|
2026-03-12 10:30:13 +08:00
|
|
|
{
|
|
|
|
|
var query = _teamRep.AsQueryable()
|
|
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.Name), t => t.Name.Contains(input.Name))
|
|
|
|
|
.WhereIF(input.Status.HasValue, t => t.Status == input.Status)
|
|
|
|
|
.WhereIF(input.StartTime.HasValue, t => t.CreatedTime >= input.StartTime)
|
|
|
|
|
.WhereIF(input.EndTime.HasValue, t => t.CreatedTime <= input.EndTime)
|
|
|
|
|
.OrderByDescending(t => t.CreatedTime);
|
|
|
|
|
|
|
|
|
|
var list = await query.ToPagedListAsync(input);
|
|
|
|
|
|
|
|
|
|
// 转换并填充领队/教练信息
|
|
|
|
|
var result = list.Adapt<PageResult<TeamOutput>>();
|
|
|
|
|
|
|
|
|
|
if (result.Rows.Any())
|
|
|
|
|
{
|
|
|
|
|
var teamIds = result.Rows.Select(x => x.Id).ToList();
|
|
|
|
|
var members = await _memberRep.AsQueryable()
|
|
|
|
|
.LeftJoin<Core.Entities.AppUser>((m, u) => m.UserId == u.Id)
|
2026-03-20 02:27:26 +08:00
|
|
|
.Where(m => teamIds.Contains(m.TeamId) && (m.PersonType == PersonType.Leader || m.PersonType == PersonType.Coach))
|
|
|
|
|
.Select((m, u) => new { m.TeamId, m.PersonType, u.Name })
|
2026-03-12 10:30:13 +08:00
|
|
|
.ToListAsync();
|
|
|
|
|
|
|
|
|
|
foreach (var item in result.Rows)
|
|
|
|
|
{
|
2026-03-20 02:27:26 +08:00
|
|
|
item.LeaderNames = string.Join(", ", members.Where(m => m.TeamId == item.Id && m.PersonType == PersonType.Leader).Select(m => m.Name));
|
|
|
|
|
item.CoachNames = string.Join(", ", members.Where(m => m.TeamId == item.Id && m.PersonType == PersonType.Coach).Select(m => m.Name));
|
2026-03-12 10:30:13 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取团队详情
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="id"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpGet("{id}")]
|
|
|
|
|
[DisplayName("获取团队详情")]
|
2026-03-14 11:25:39 +08:00
|
|
|
public async Task<TeamDetailOutput> Detail([FromRoute] long id)
|
2026-03-12 10:30:13 +08:00
|
|
|
{
|
|
|
|
|
var team = await _teamRep.GetFirstAsync(t => t.Id == id);
|
|
|
|
|
if (team == null) throw Oops.Bah("团队不存在");
|
|
|
|
|
|
|
|
|
|
var output = team.Adapt<TeamDetailOutput>();
|
|
|
|
|
|
|
|
|
|
var members = await _memberRep.AsQueryable()
|
|
|
|
|
.LeftJoin<Core.Entities.AppUser>((m, u) => m.UserId == u.Id)
|
|
|
|
|
.Where(m => m.TeamId == id)
|
|
|
|
|
.Select((m, u) => new TeamMemberOutput
|
|
|
|
|
{
|
|
|
|
|
UserId = m.UserId,
|
|
|
|
|
Name = u.Name,
|
|
|
|
|
Mobile = u.Mobile,
|
2026-03-31 18:54:20 +08:00
|
|
|
PersonType = m.PersonType,
|
|
|
|
|
Gender = u.Gender,
|
|
|
|
|
BirthDate = u.BirthDate
|
2026-03-12 10:30:13 +08:00
|
|
|
})
|
|
|
|
|
.ToListAsync();
|
|
|
|
|
|
|
|
|
|
output.Members = members;
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 新增团队
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="input"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPost("add")]
|
|
|
|
|
[DisplayName("新增团队")]
|
2026-03-14 11:25:39 +08:00
|
|
|
public async Task Add([FromBody] AddTeamInput input)
|
2026-03-12 10:30:13 +08:00
|
|
|
{
|
|
|
|
|
var isExist = await _teamRep.IsAnyAsync(t => t.Name == input.Name);
|
|
|
|
|
if (isExist) throw Oops.Bah("团队名称已存在");
|
|
|
|
|
|
|
|
|
|
var team = input.Adapt<Core.Entities.Team>();
|
|
|
|
|
team.Status = AvailabilityStatus.Enable; // 默认启用
|
|
|
|
|
|
|
|
|
|
// 开启事务
|
|
|
|
|
await _teamRep.AsSugarClient().Ado.UseTranAsync(async () =>
|
|
|
|
|
{
|
|
|
|
|
var newTeam = await _teamRep.InsertReturnEntityAsync(team);
|
|
|
|
|
var members = new List<TeamMember>();
|
|
|
|
|
|
2026-04-07 14:14:25 +08:00
|
|
|
members.AddRange(input.LeaderIds.Select(uid => new TeamMember { TeamId = newTeam.Id, UserId = uid, PersonType = PersonType.Leader, JoinTime = DateTime.Now }));
|
|
|
|
|
members.AddRange(input.CoachIds.Select(uid => new TeamMember { TeamId = newTeam.Id, UserId = uid, PersonType = PersonType.Coach, JoinTime = DateTime.Now }));
|
|
|
|
|
members.AddRange(input.MemberIds.Select(uid => new TeamMember { TeamId = newTeam.Id, UserId = uid, PersonType = PersonType.Athlete, JoinTime = DateTime.Now }));
|
|
|
|
|
|
|
|
|
|
// 去重,防止同一个人在同一个团队有多个角色(如果业务允许则不需要去重,这里假设允许)
|
|
|
|
|
await _memberRep.InsertRangeAsync(members);
|
2026-03-12 10:30:13 +08:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 删除团队
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="dto"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpDelete("delete")]
|
|
|
|
|
[DisplayName("删除团队")]
|
|
|
|
|
public override async Task Delete(Core.Shared.KeyDto dto)
|
|
|
|
|
{
|
|
|
|
|
await _teamRep.AsSugarClient().Ado.UseTranAsync(async () =>
|
|
|
|
|
{
|
|
|
|
|
// 逻辑删除团队
|
2026-03-14 11:25:39 +08:00
|
|
|
await base.Delete(dto);
|
2026-03-12 10:30:13 +08:00
|
|
|
// 逻辑删除团队成员关联
|
|
|
|
|
await _memberRep.UpdateAsync(x => new TeamMember { DeleteMark = true }, x => x.TeamId == dto.Id);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 批量删除团队
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="ids"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPost("batchDelete")]
|
|
|
|
|
[DisplayName("批量删除团队")]
|
|
|
|
|
public async Task BatchDelete([FromBody] List<long> ids)
|
|
|
|
|
{
|
|
|
|
|
if (ids == null || !ids.Any()) throw Oops.Bah("请选择要删除的记录");
|
|
|
|
|
|
|
|
|
|
await _teamRep.AsSugarClient().Ado.UseTranAsync(async () =>
|
|
|
|
|
{
|
|
|
|
|
// 逻辑删除团队
|
|
|
|
|
await _teamRep.UpdateAsync(x => new Core.Entities.Team { DeleteMark = true }, x => ids.Contains(x.Id));
|
|
|
|
|
// 逻辑删除团队成员关联
|
|
|
|
|
await _memberRep.UpdateAsync(x => new TeamMember { DeleteMark = true }, x => ids.Contains(x.TeamId));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 修改团队
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="input"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
[HttpPut("update")]
|
|
|
|
|
[DisplayName("修改团队")]
|
2026-03-14 11:25:39 +08:00
|
|
|
public async Task Update([FromBody] UpdateTeamInput input)
|
2026-03-12 10:30:13 +08:00
|
|
|
{
|
|
|
|
|
var team = await _teamRep.GetFirstAsync(t => t.Id == input.Id);
|
|
|
|
|
if (team == null) throw Oops.Bah("团队不存在");
|
|
|
|
|
|
|
|
|
|
var isExist = await _teamRep.IsAnyAsync(t => t.Name == input.Name && t.Id != input.Id);
|
|
|
|
|
if (isExist) throw Oops.Bah("团队名称已存在");
|
|
|
|
|
|
|
|
|
|
input.Adapt(team);
|
|
|
|
|
|
|
|
|
|
await _teamRep.AsSugarClient().Ado.UseTranAsync(async () =>
|
|
|
|
|
{
|
|
|
|
|
await _teamRep.UpdateAsync(team);
|
|
|
|
|
|
|
|
|
|
// 全量更新成员:先删后加
|
|
|
|
|
await _memberRep.DeleteAsync(m => m.TeamId == input.Id);
|
|
|
|
|
|
|
|
|
|
var members = new List<TeamMember>();
|
2026-04-07 14:14:25 +08:00
|
|
|
members.AddRange(input.LeaderIds.Select(uid => new TeamMember { TeamId = team.Id, UserId = uid, PersonType = PersonType.Leader, JoinTime = DateTime.Now }));
|
|
|
|
|
members.AddRange(input.CoachIds.Select(uid => new TeamMember { TeamId = team.Id, UserId = uid, PersonType = PersonType.Coach, JoinTime = DateTime.Now }));
|
|
|
|
|
members.AddRange(input.MemberIds.Select(uid => new TeamMember { TeamId = team.Id, UserId = uid, PersonType = PersonType.Athlete, JoinTime = DateTime.Now }));
|
|
|
|
|
await _memberRep.InsertRangeAsync(members);
|
2026-03-12 10:30:13 +08:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|