2026-03-06 12:10:09 +08:00
|
|
|
|
using YD_Event.Application.AppUser.Dtos;
|
|
|
|
|
|
using YD_Event.Application.Auth;
|
|
|
|
|
|
using YD_Event.Core.Entities;
|
|
|
|
|
|
using AppUserEntity = YD_Event.Core.Entities.AppUser;
|
|
|
|
|
|
|
|
|
|
|
|
namespace YD_Event.Application.AppUser;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 普通用户服务
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class AppUserService : BaseService<AppUserEntity>, ITransient
|
|
|
|
|
|
{
|
|
|
|
|
|
private readonly ISqlSugarRepository<AppUserEntity> _appUserRep;
|
2026-03-11 16:00:09 +08:00
|
|
|
|
private readonly ISqlSugarClient _db;
|
2026-03-06 12:10:09 +08:00
|
|
|
|
private readonly AuthManager _authManager;
|
|
|
|
|
|
|
|
|
|
|
|
public AppUserService(ISqlSugarRepository<AppUserEntity> appUserRep,
|
2026-03-11 16:00:09 +08:00
|
|
|
|
ISqlSugarClient db,
|
2026-03-06 12:10:09 +08:00
|
|
|
|
AuthManager authManager) : base(appUserRep)
|
|
|
|
|
|
{
|
|
|
|
|
|
_appUserRep = appUserRep;
|
2026-03-11 16:00:09 +08:00
|
|
|
|
_db = db;
|
2026-03-06 12:10:09 +08:00
|
|
|
|
_authManager = authManager;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 分页查询普通用户
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="input"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
[HttpGet("page")]
|
|
|
|
|
|
public async Task<PageResult<AppUserOutput>> Page([FromQuery] AppUserPageInput input)
|
|
|
|
|
|
{
|
|
|
|
|
|
var query = _appUserRep.AsQueryable()
|
2026-03-11 16:00:09 +08:00
|
|
|
|
.Where(u => u.PersonType == 0) // 仅查询普通用户
|
2026-03-06 12:10:09 +08:00
|
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.Name), u => u.Name.Contains(input.Name))
|
|
|
|
|
|
.WhereIF(input.Gender.HasValue, u => u.Gender == input.Gender)
|
|
|
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.Mobile), u => u.Mobile.Contains(input.Mobile))
|
|
|
|
|
|
.WhereIF(input.AuditStatus.HasValue, u => u.AuditStatus == input.AuditStatus)
|
|
|
|
|
|
.WhereIF(input.StartTime.HasValue, u => u.CreatedTime >= input.StartTime)
|
|
|
|
|
|
.WhereIF(input.EndTime.HasValue, u => u.CreatedTime <= input.EndTime)
|
|
|
|
|
|
.OrderByDescending(u => u.CreatedTime);
|
|
|
|
|
|
|
|
|
|
|
|
return await query.Select<AppUserOutput>().ToPagedListAsync(input);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取普通用户详情
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="id"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
[HttpGet("{id}")]
|
|
|
|
|
|
public async Task<AppUserOutput> Detail([FromRoute] long id)
|
|
|
|
|
|
{
|
|
|
|
|
|
return await _appUserRep.AsQueryable()
|
|
|
|
|
|
.Where(u => u.Id == id)
|
|
|
|
|
|
.Select<AppUserOutput>()
|
|
|
|
|
|
.FirstAsync();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 审核普通用户
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="input"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
[HttpPost("audit")]
|
|
|
|
|
|
[UnitOfWork]
|
|
|
|
|
|
public async Task Audit([FromBody] AuditInput input)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (input.Ids == null || !input.Ids.Any()) return;
|
|
|
|
|
|
|
|
|
|
|
|
// 更新状态
|
|
|
|
|
|
await _appUserRep.UpdateAsync(u => new AppUserEntity
|
|
|
|
|
|
{
|
|
|
|
|
|
AuditStatus = input.Status,
|
|
|
|
|
|
AuditRemark = input.Remark,
|
|
|
|
|
|
UpdatedTime = DateTime.Now,
|
|
|
|
|
|
UpdatedUserId = _authManager.UserId
|
|
|
|
|
|
}, u => input.Ids.Contains(u.Id));
|
|
|
|
|
|
}
|
2026-03-11 16:00:09 +08:00
|
|
|
|
|
|
|
|
|
|
#region 领队/教练管理
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 领队/教练列表查询
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="input"></param>
|
|
|
|
|
|
/// <param name="personType">1-领队,2-教练</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
[NonAction]
|
|
|
|
|
|
private async Task<PageResult<AppUserEntity>> GetMemberPage(TeamMemberQueryInput input, int personType)
|
|
|
|
|
|
{
|
|
|
|
|
|
var (userId, merchantId) = await GetCurrentUserAndMerchantId();
|
|
|
|
|
|
|
|
|
|
|
|
var query = _appUserRep.AsQueryable()
|
|
|
|
|
|
.Where(x => x.PersonType == personType && !x.DeleteMark)
|
|
|
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.Name), x => x.Name.Contains(input.Name))
|
|
|
|
|
|
.WhereIF(input.Gender.HasValue, x => x.Gender == input.Gender)
|
|
|
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(input.Phone), x => x.Mobile.Contains(input.Phone))
|
|
|
|
|
|
.WhereIF(personType == 2 && !string.IsNullOrWhiteSpace(input.SkillLevel), x => x.SkillLevel == input.SkillLevel)
|
|
|
|
|
|
.WhereIF(personType == 2 && input.CertificationStatus.HasValue, x => x.CertificationStatus == input.CertificationStatus)
|
|
|
|
|
|
.OrderByDescending(x => x.CreatedTime);
|
|
|
|
|
|
|
|
|
|
|
|
// 权限过滤
|
|
|
|
|
|
if (merchantId.HasValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
query = query.Where(x => x.MerchantId == merchantId.Value);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
query = query.Where(x => x.CreatedUserId == userId && x.MerchantId == null);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return await query.ToPagedListAsync(input);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 领队列表查询
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="input"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
[HttpGet("leader/page")]
|
|
|
|
|
|
public async Task<PageResult<AppUserEntity>> LeaderPage([FromQuery] TeamMemberQueryInput input)
|
|
|
|
|
|
{
|
|
|
|
|
|
return await GetMemberPage(input, 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 教练列表查询
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="input"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
[HttpGet("coach/page")]
|
|
|
|
|
|
public async Task<PageResult<AppUserEntity>> CoachPage([FromQuery] TeamMemberQueryInput input)
|
|
|
|
|
|
{
|
|
|
|
|
|
return await GetMemberPage(input, 2);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 新增/更新成员
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="input"></param>
|
|
|
|
|
|
/// <param name="personType">1-领队,2-教练</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
[NonAction]
|
|
|
|
|
|
private async Task SaveMember(CreateOrUpdateMemberInput input, int personType)
|
|
|
|
|
|
{
|
|
|
|
|
|
var (userId, merchantId) = await GetCurrentUserAndMerchantId();
|
|
|
|
|
|
|
|
|
|
|
|
// 校验手机号
|
|
|
|
|
|
var query = _appUserRep.AsQueryable()
|
|
|
|
|
|
.Where(x => x.Mobile == input.Phone && x.PersonType == personType && !x.DeleteMark);
|
|
|
|
|
|
|
|
|
|
|
|
if (input.Id.HasValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
query = query.Where(x => x.Id != input.Id.Value);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (merchantId.HasValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
query = query.Where(x => x.MerchantId == merchantId.Value);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
query = query.Where(x => x.CreatedUserId == userId && x.MerchantId == null);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (await query.AnyAsync()) throw Oops.Bah($"该手机号的{(personType == 1 ? "领队" : "教练")}已存在");
|
|
|
|
|
|
|
|
|
|
|
|
AppUserEntity entity;
|
|
|
|
|
|
if (input.Id.HasValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
entity = await _appUserRep.GetByIdAsync(input.Id.Value);
|
|
|
|
|
|
if (entity == null || entity.DeleteMark) throw Oops.Bah("成员不存在");
|
|
|
|
|
|
await CheckPermission(entity);
|
|
|
|
|
|
|
|
|
|
|
|
entity.UpdatedUserId = _authManager.UserId;
|
|
|
|
|
|
entity.UpdatedTime = DateTime.Now;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
entity = new AppUserEntity
|
|
|
|
|
|
{
|
|
|
|
|
|
Id = YitIdHelper.NextId(),
|
|
|
|
|
|
PersonType = personType,
|
|
|
|
|
|
MerchantId = merchantId,
|
|
|
|
|
|
CreatedUserId = userId,
|
|
|
|
|
|
CreatedTime = DateTime.Now,
|
|
|
|
|
|
Status = AvailabilityStatus.Enable,
|
|
|
|
|
|
AuditStatus = AuditStatus.Pass
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
entity.Name = input.Name;
|
|
|
|
|
|
entity.Gender = input.Gender;
|
|
|
|
|
|
entity.Age = input.Age;
|
|
|
|
|
|
entity.IdCardNumber = input.IdCard;
|
|
|
|
|
|
entity.IdCardImageUrl = input.IdCardUrl;
|
|
|
|
|
|
entity.Mobile = input.Phone;
|
|
|
|
|
|
entity.Remark = input.Remark;
|
|
|
|
|
|
entity.AuditRemark = ""; // 或者不赋值
|
|
|
|
|
|
|
|
|
|
|
|
if (personType == 2)
|
|
|
|
|
|
{
|
|
|
|
|
|
entity.SkillLevel = input.SkillLevel;
|
|
|
|
|
|
entity.CertificationStatus = input.CertificationStatus;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await _appUserRep.InsertOrUpdateAsync(entity);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 新增/编辑领队
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="input"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
[HttpPost("leader/save")]
|
|
|
|
|
|
public async Task SaveLeader(CreateOrUpdateMemberInput input)
|
|
|
|
|
|
{
|
|
|
|
|
|
await SaveMember(input, 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 新增/编辑教练
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="input"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
[HttpPost("coach/save")]
|
|
|
|
|
|
public async Task SaveCoach(CreateOrUpdateMemberInput input)
|
|
|
|
|
|
{
|
|
|
|
|
|
await SaveMember(input, 2);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 删除成员
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="id"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
[HttpPost("member/delete")]
|
|
|
|
|
|
public async Task DeleteMember([FromBody] long id)
|
|
|
|
|
|
{
|
|
|
|
|
|
var entity = await _appUserRep.GetByIdAsync(id);
|
|
|
|
|
|
if (entity == null || entity.DeleteMark) throw Oops.Bah("成员不存在");
|
|
|
|
|
|
|
|
|
|
|
|
await CheckPermission(entity);
|
|
|
|
|
|
|
|
|
|
|
|
entity.DeleteMark = true;
|
|
|
|
|
|
entity.UpdatedUserId = _authManager.UserId;
|
|
|
|
|
|
entity.UpdatedTime = DateTime.Now;
|
|
|
|
|
|
|
|
|
|
|
|
await _appUserRep.UpdateAsync(entity);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 变更成员状态
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="input"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
[HttpPost("member/status")]
|
|
|
|
|
|
public async Task ChangeMemberStatus(ChangeMemberStatusInput input)
|
|
|
|
|
|
{
|
|
|
|
|
|
var entity = await _appUserRep.GetByIdAsync(input.Id);
|
|
|
|
|
|
if (entity == null || entity.DeleteMark) throw Oops.Bah("成员不存在");
|
|
|
|
|
|
|
|
|
|
|
|
await CheckPermission(entity);
|
|
|
|
|
|
|
|
|
|
|
|
entity.Status = input.Status;
|
|
|
|
|
|
entity.UpdatedUserId = _authManager.UserId;
|
|
|
|
|
|
entity.UpdatedTime = DateTime.Now;
|
|
|
|
|
|
|
|
|
|
|
|
await _appUserRep.UpdateAsync(entity);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async Task<(long userId, long? merchantId)> GetCurrentUserAndMerchantId()
|
|
|
|
|
|
{
|
|
|
|
|
|
var userId = _authManager.UserId;
|
|
|
|
|
|
var merchant = await _db.Queryable<YD_Event.Core.Entities.Merchant>()
|
|
|
|
|
|
.FirstAsync(m => m.CreatedUserId == userId && !m.DeleteMark);
|
|
|
|
|
|
return (userId, merchant?.Id);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async Task CheckPermission(AppUserEntity entity)
|
|
|
|
|
|
{
|
|
|
|
|
|
var (userId, merchantId) = await GetCurrentUserAndMerchantId();
|
|
|
|
|
|
|
|
|
|
|
|
if (merchantId.HasValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (entity.MerchantId != merchantId.Value) throw Oops.Bah("无权操作该成员");
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (entity.CreatedUserId != userId || entity.MerchantId != null) throw Oops.Bah("无权操作该成员");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
2026-03-06 12:10:09 +08:00
|
|
|
|
}
|