feat: 优化公告通知接收人过滤与客户删除同步
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
36525ca688
commit
8ac7e6487c
@ -15,11 +15,10 @@ public class NoticeCreateInput
|
||||
public string NoticeType { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 标题。
|
||||
/// 标题(公告必填;站内信可空)。
|
||||
/// </summary>
|
||||
[Required]
|
||||
[StringLength(128)]
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public string? Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 正文内容。
|
||||
|
||||
@ -227,7 +227,54 @@ public class CustomerService : ApplicationService
|
||||
public async Task DeleteAsync(IdInput input)
|
||||
{
|
||||
var entity = await GetCustomerOrThrowAsync(input.Id);
|
||||
|
||||
if (!entity.ParentCustomerId.HasValue
|
||||
&& await CustomerRepository.AnyAsync(x => x.ParentCustomerId == entity.Id))
|
||||
{
|
||||
throw new BusinessException("存在子客户,请先删除子客户");
|
||||
}
|
||||
|
||||
await CustomerRepository.DeleteAsync(entity);
|
||||
await DeleteLinkedRbacUserAsync(entity);
|
||||
}
|
||||
|
||||
private async Task DeleteLinkedRbacUserAsync(Customer entity)
|
||||
{
|
||||
var userGuid = await GetRbacUserGuidByMapIdAsync(entity.UserId);
|
||||
if (userGuid.HasValue && userGuid.Value != Guid.Empty)
|
||||
{
|
||||
await UserService.DeleteAsync(userGuid.Value);
|
||||
}
|
||||
|
||||
if (entity.ParentCustomerId.HasValue)
|
||||
{
|
||||
await TryDeleteSubCustomerRoleAsync(entity.UserId);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<Guid?> GetRbacUserGuidByMapIdAsync(int mapId)
|
||||
{
|
||||
return await RbacDbContext.Database.SqlQuery<Guid?>(
|
||||
$"select `Id` as `Value` from `user` where `userid` = {mapId} and `IsDeleted` = 0")
|
||||
.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
private async Task TryDeleteSubCustomerRoleAsync(int userId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var roles = await RoleService.GetAllRolesAsync();
|
||||
var role = roles.FirstOrDefault(x =>
|
||||
string.Equals(x.Code, $"CustomerSub_{userId}", StringComparison.OrdinalIgnoreCase));
|
||||
if (role != null)
|
||||
{
|
||||
await RoleService.DeleteAsync(role.Id);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 子客户角色清理失败不阻断客户删除
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -49,7 +49,17 @@ public class NoticeService : ApplicationService
|
||||
[HttpGet("/system/notice/list")]
|
||||
public async Task<OmsPageResult<NoticeOutput>> GetListAsync([FromQuery] NoticeListInput input)
|
||||
{
|
||||
var predicate = BuildListPredicate(input);
|
||||
var receiverUserId = CurrentUser.GetId<int>();
|
||||
if (receiverUserId <= 0)
|
||||
{
|
||||
return new OmsPageResult<NoticeOutput> { Items = [], Total = 0 };
|
||||
}
|
||||
|
||||
var expectedReceiverType = OmsSessionHelper.IsCustomerLogin(CurrentUser)
|
||||
? ReceiverTypeCustomer
|
||||
: ReceiverTypeUser;
|
||||
|
||||
var predicate = BuildListPredicate(input, receiverUserId, expectedReceiverType);
|
||||
var pageIndex = OmsDocHelper.NormalizePage(input.Page);
|
||||
var pageSize = OmsDocHelper.NormalizePageSize(input.PageSize);
|
||||
var notices = await NoticeRepository.GetPagedListAsync(
|
||||
@ -106,12 +116,13 @@ public class NoticeService : ApplicationService
|
||||
[HttpPost("/system/notice/create")]
|
||||
public async Task CreateAsync(NoticeCreateInput input)
|
||||
{
|
||||
ValidateNoticeText(input.Title, input.Content);
|
||||
var noticeType = NormalizeNoticeType(input.NoticeType);
|
||||
ValidateNoticeText(noticeType, input.Title, input.Content);
|
||||
var receiverIds = await NormalizeAndValidateReceiverIdsAsync(input.ReceiverType, input.ReceiverIds);
|
||||
await NoticeRepository.InsertAsync(new Notice
|
||||
{
|
||||
NoticeType = NormalizeNoticeType(input.NoticeType),
|
||||
Title = input.Title.Trim(),
|
||||
NoticeType = noticeType,
|
||||
Title = NormalizeTitle(input.Title),
|
||||
Content = input.Content.Trim(),
|
||||
IsPopup = NormalizePopupValue(input.IsPopup),
|
||||
ReceiverType = NormalizeReceiverType(input.ReceiverType),
|
||||
@ -126,10 +137,11 @@ public class NoticeService : ApplicationService
|
||||
public async Task UpdateAsync(NoticeUpdateInput input)
|
||||
{
|
||||
var entity = await GetNoticeOrThrowAsync(input.Id);
|
||||
ValidateNoticeText(input.Title, input.Content);
|
||||
var noticeType = NormalizeNoticeType(input.NoticeType);
|
||||
ValidateNoticeText(noticeType, input.Title, input.Content);
|
||||
var receiverIds = await NormalizeAndValidateReceiverIdsAsync(input.ReceiverType, input.ReceiverIds);
|
||||
entity.NoticeType = NormalizeNoticeType(input.NoticeType);
|
||||
entity.Title = input.Title.Trim();
|
||||
entity.NoticeType = noticeType;
|
||||
entity.Title = NormalizeTitle(input.Title);
|
||||
entity.Content = input.Content.Trim();
|
||||
entity.IsPopup = NormalizePopupValue(input.IsPopup);
|
||||
entity.ReceiverType = NormalizeReceiverType(input.ReceiverType);
|
||||
@ -162,7 +174,7 @@ public class NoticeService : ApplicationService
|
||||
{
|
||||
var notice = await GetNoticeOrThrowAsync(input.Id);
|
||||
var receiverIds = OmsDocHelper.DeserializeJson<List<int>>(notice.ReceiverIds) ?? [];
|
||||
var currentReceiverType = ReceiverTypeUser;
|
||||
var currentReceiverType = NormalizeReceiverType(notice.ReceiverType);
|
||||
var currentReceiverId = CurrentUser.GetId<int>();
|
||||
if (currentReceiverId <= 0)
|
||||
{
|
||||
@ -314,17 +326,26 @@ public class NoticeService : ApplicationService
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Expression<Func<Notice, bool>> BuildListPredicate(NoticeListInput input)
|
||||
private static Expression<Func<Notice, bool>> BuildListPredicate(
|
||||
NoticeListInput input,
|
||||
int receiverUserId,
|
||||
string expectedReceiverType)
|
||||
{
|
||||
var noticeType = input.NoticeType?.Trim();
|
||||
var receiverType = input.ReceiverType?.Trim();
|
||||
var keyword = input.Keyword?.Trim();
|
||||
var receiverIdToken = receiverUserId.ToString();
|
||||
return x =>
|
||||
(string.IsNullOrWhiteSpace(noticeType) || x.NoticeType == noticeType) &&
|
||||
(string.IsNullOrWhiteSpace(receiverType) || x.ReceiverType == receiverType) &&
|
||||
(string.IsNullOrWhiteSpace(keyword) ||
|
||||
x.Title.Contains(keyword) ||
|
||||
x.Content.Contains(keyword));
|
||||
x.Content.Contains(keyword)) &&
|
||||
x.ReceiverType == expectedReceiverType &&
|
||||
(x.ReceiverIds == $"[{receiverIdToken}]" ||
|
||||
x.ReceiverIds.StartsWith($"[{receiverIdToken},") ||
|
||||
x.ReceiverIds.Contains($",{receiverIdToken},") ||
|
||||
x.ReceiverIds.EndsWith($",{receiverIdToken}]"));
|
||||
}
|
||||
|
||||
private async Task<Notice> GetNoticeOrThrowAsync(int id)
|
||||
@ -397,9 +418,9 @@ public class NoticeService : ApplicationService
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
private static void ValidateNoticeText(string title, string content)
|
||||
private static void ValidateNoticeText(string noticeType, string? title, string content)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(title))
|
||||
if (noticeType == NoticeTypeNotice && string.IsNullOrWhiteSpace(title))
|
||||
{
|
||||
throw new BusinessException("通知标题不能为空");
|
||||
}
|
||||
@ -410,6 +431,9 @@ public class NoticeService : ApplicationService
|
||||
}
|
||||
}
|
||||
|
||||
private static string NormalizeTitle(string? title) =>
|
||||
string.IsNullOrWhiteSpace(title) ? string.Empty : title.Trim();
|
||||
|
||||
private static NoticeOutput MapNoticeOutput(Notice entity, int readCount, List<int> receiverSelectionIds)
|
||||
{
|
||||
var receiverIds = OmsDocHelper.DeserializeJson<List<int>>(entity.ReceiverIds) ?? [];
|
||||
|
||||
Loading…
Reference in New Issue
Block a user