Merge branch 'Test_IRC_Net8' into Uat_IRC_Net8
continuous-integration/drone/push Build is passing Details

Uat_IRC_Net8
he 2025-05-20 10:55:36 +08:00
commit 53d26c0445
10 changed files with 19662 additions and 40 deletions

View File

@ -14427,6 +14427,12 @@
定时提醒
</summary>
</member>
<member name="P:IRaCIS.Core.Application.MassTransit.Consumer.SystemDocumentPublishEvent.NewUserTypeIds">
<summary>
新增的需要发送邮件的用户角色ID列表
如果为null或空则发送给所有相关角色
</summary>
</member>
<member name="T:IRaCIS.Core.Application.MassTransit.Consumer.QCImageQuestionRecurringSchedule">
<summary>
QC 影像质疑待处理
@ -16270,6 +16276,16 @@
组件一致性和原Arm2是否有差异
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Contracts.ImageBackViewModel.ApplyReason">
<summary>
申请原因
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Contracts.ImageBackViewModel.ResultRemark">
<summary>
结果备注
</summary>
</member>
<member name="P:IRaCIS.Core.Application.Contracts.GetNextCRCChallengeInDto.QCChallengeId">
<summary>
QCChallengeId
@ -17558,20 +17574,22 @@
<param name="qaDialogCommand"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Image.QA.QCOperationService.RequestImageBack(System.Guid)">
<member name="M:IRaCIS.Core.Application.Image.QA.QCOperationService.RequestImageBack(System.Guid,System.String)">
<summary>
CRC IQC 申请影像回退
</summary>
<param name="subjectVisitId"></param>
<param name="ApplyReason"></param>
<returns></returns>
<exception cref="T:IRaCIS.Core.Infrastructure.BusinessValidationFailedException"></exception>
</member>
<member name="M:IRaCIS.Core.Application.Image.QA.QCOperationService.AuditImageBack(System.Guid,System.Boolean)">
<member name="M:IRaCIS.Core.Application.Image.QA.QCOperationService.AuditImageBack(System.Guid,System.Boolean,System.String)">
<summary>
PM 审核CRC IQC 申请影像回退
</summary>
<param name="iamgeBackRecordId"></param>
<param name="isAgree"></param>
<param name="resultRemark"></param>
<returns></returns>
<exception cref="T:IRaCIS.Core.Infrastructure.BusinessValidationFailedException"></exception>
</member>

View File

@ -49,6 +49,12 @@ public class SystemDocumentErverDayEvent : DomainEvent
public class SystemDocumentPublishEvent : DomainEvent
{
public List<Guid> Ids { get; set; }
/// <summary>
/// 新增的需要发送邮件的用户角色ID列表
/// 如果为null或空则发送给所有相关角色
/// </summary>
public List<Guid> NewUserTypeIds { get; set; }
}

View File

@ -100,8 +100,8 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
var htmlBodyStr = string.Format(
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
userinfo.UserName // 用户名 {0}
userinfo.UserName, // 用户名 {0}
_systemEmailConfig.SiteUrl
);
return (topicStr, htmlBodyStr);
@ -150,11 +150,26 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
public async Task Consume(ConsumeContext<SystemDocumentPublishEvent> context)
{
var isEn_US = CultureInfo.CurrentCulture.Name == StaticData.CultureInfo.en_US;
var systemDocQuery =
// 记录是否只发送给新增角色的日志
if (context.Message.NewUserTypeIds != null && context.Message.NewUserTypeIds.Any())
{
Console.WriteLine($"只发送给新增的角色,角色数量: {context.Message.NewUserTypeIds.Count}");
}
// 构建查询
IQueryable<UnionDocumentWithConfirmInfoView> systemDocQuery;
if (context.Message.NewUserTypeIds != null && context.Message.NewUserTypeIds.Any())
{
// 只查询新增角色的用户
systemDocQuery =
from sysDoc in _systemDocumentRepository.AsQueryable(false).Where(x => context.Message.Ids.Contains(x.Id))
from identityUser in _identityUserRepository.AsQueryable(false).Where(t => t.Status == UserStateEnum.Enable && t.UserRoleList.Where(t => t.IsUserRoleDisabled == false).Any(t => sysDoc.NeedConfirmedUserTypeList.AsQueryable().Any(c => c.NeedConfirmUserTypeId == t.UserTypeId)))
from identityUser in _identityUserRepository.AsQueryable(false)
.Where(t => t.Status == UserStateEnum.Enable &&
t.UserRoleList.Where(t => t.IsUserRoleDisabled == false)
.Any(t => context.Message.NewUserTypeIds.Contains(t.UserTypeId) &&
sysDoc.NeedConfirmedUserTypeList.AsQueryable().Any(c => c.NeedConfirmUserTypeId == t.UserTypeId)))
select new UnionDocumentWithConfirmInfoView()
{
IsSystemDoc = true,
@ -167,14 +182,39 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
FileTypeId = sysDoc.FileTypeId,
UpdateTime = sysDoc.UpdateTime,
ConfirmUserId = identityUser.Id,
RealName = identityUser.FullName,
UserName = identityUser.UserName,
IsNeedSendEmial = identityUser.IsZhiZhun || (!identityUser.IsZhiZhun && sysDoc.DocUserSignType == DocUserSignType.InnerAndOuter),
FullFilePath = sysDoc.Path
};
}
else
{
// 查询所有相关角色的用户
systemDocQuery =
from sysDoc in _systemDocumentRepository.AsQueryable(false).Where(x => context.Message.Ids.Contains(x.Id))
from identityUser in _identityUserRepository.AsQueryable(false)
.Where(t => t.Status == UserStateEnum.Enable &&
t.UserRoleList.Where(t => t.IsUserRoleDisabled == false)
.Any(t => sysDoc.NeedConfirmedUserTypeList.AsQueryable().Any(c => c.NeedConfirmUserTypeId == t.UserTypeId)))
select new UnionDocumentWithConfirmInfoView()
{
IsSystemDoc = true,
Id = sysDoc.Id,
CreateTime = sysDoc.CreateTime,
IsDeleted = sysDoc.IsDeleted,
SignViewMinimumMinutes = sysDoc.SignViewMinimumMinutes,
Name = sysDoc.Name,
Path = sysDoc.Path,
FileTypeId = sysDoc.FileTypeId,
UpdateTime = sysDoc.UpdateTime,
ConfirmUserId = identityUser.Id,
RealName = identityUser.FullName,
UserName = identityUser.UserName,
IsNeedSendEmial = identityUser.IsZhiZhun || (!identityUser.IsZhiZhun && sysDoc.DocUserSignType == DocUserSignType.InnerAndOuter),
FullFilePath = sysDoc.Path
};
}
var datalist = await systemDocQuery.IgnoreQueryFilters().Where(x => x.IsNeedSendEmial).ToListAsync();
var confirmUserIdList = datalist.Select(t => t.ConfirmUserId).Distinct().ToList();
@ -201,8 +241,8 @@ namespace IRaCIS.Core.Application.MassTransit.Recurring
var htmlBodyStr = string.Format(
CommonEmailHelper.ReplaceCompanyName(_systemEmailConfig, input.htmlBodyStr),
userinfo.UserName // 用户名 {0}
userinfo.UserName, // 用户名 {0}
_systemEmailConfig.SiteUrl
);
return (topicStr, htmlBodyStr);

View File

@ -130,6 +130,11 @@ namespace IRaCIS.Core.Application.Services
}
// 保存修改前的状态和需要确认的用户类型列表
bool beforeIsPublish = document.IsPublish;
bool beforeIsDeleted = document.IsDeleted;
var beforeUserTypeIds = document.NeedConfirmedUserTypeList.Select(x => x.NeedConfirmUserTypeId).ToList();
_mapper.Map(addOrEditSystemDocument, document);
#region 之前区分路径文件夹 现在不区分废弃
@ -153,9 +158,39 @@ namespace IRaCIS.Core.Application.Services
#endregion
var success = await _systemDocumentRepository.SaveChangesAsync();
// 检查是否需要发送邮件给新增的角色
if (beforeIsPublish && document.IsPublish && !beforeIsDeleted && !document.IsDeleted)
{
// 找出新增的用户角色ID
var newUserTypeIds = addOrEditSystemDocument.NeedConfirmedUserTypeIdList
.Where(id => !beforeUserTypeIds.Contains(id))
.ToList();
if (newUserTypeIds.Any()&& newUserTypeIds.Count()>0)
{
// 发送邮件给新增的角色
Console.WriteLine("开始 发送系统文档更新邮件给新增角色");
Console.WriteLine(string.Join(",", newUserTypeIds));
Task.Run(async () =>
{
// 创建独立作用域
using (var scope = serviceScopeFactory.CreateScope())
{
// 从新作用域解析服务
var mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
// 只发送给新增的角色
await mediator.Publish(new SystemDocumentPublishEvent {
Ids = new List<Guid> { document.Id },
NewUserTypeIds = newUserTypeIds
});
}
});
}
}
return ResponseOutput.Ok(document.Id.ToString());
}

View File

@ -1750,6 +1750,16 @@ namespace IRaCIS.Core.Application.Contracts
public string SubjectCode { get; set; } = String.Empty;
public String TrialSiteCode { get; set; } = String.Empty;
/// <summary>
/// 申请原因
/// </summary>
public string ApplyReason { get; set; } = string.Empty;
/// <summary>
/// 结果备注
/// </summary>
public string ResultRemark { get; set; } = string.Empty;
}

View File

@ -251,10 +251,11 @@ namespace IRaCIS.Core.Application.Image.QA
/// CRC IQC 申请影像回退
/// </summary>
/// <param name="subjectVisitId"></param>
/// <param name="ApplyReason"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
[HttpPut]
public async Task<IResponseOutput> RequestImageBack(Guid subjectVisitId)
public async Task<IResponseOutput> RequestImageBack(Guid subjectVisitId,string ApplyReason)
{
if (_subjectVisitRepository.Any(t => t.Id == subjectVisitId && t.QCChallengeList.Any(t => t.IsClosed == false)))
@ -290,7 +291,7 @@ namespace IRaCIS.Core.Application.Image.QA
throw new BusinessValidationFailedException(_localizer["QCOperation_SomeOneHaveApplyedImageBack"]);
}
var newRecord = new SubjectVisitImageBackRecord() { SubjectVisitId = subjectVisitId, SubmitTime = sv.SubmitTime, EarliestScanDate = sv.EarliestScanDate, LatestScanDate = sv.LatestScanDate };
var newRecord = new SubjectVisitImageBackRecord() { SubjectVisitId = subjectVisitId, ApplyReason=ApplyReason, SubmitTime = sv.SubmitTime, EarliestScanDate = sv.EarliestScanDate, LatestScanDate = sv.LatestScanDate };
if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator)
{
@ -314,10 +315,11 @@ namespace IRaCIS.Core.Application.Image.QA
/// </summary>
/// <param name="iamgeBackRecordId"></param>
/// <param name="isAgree"></param>
/// <param name="resultRemark"></param>
/// <returns></returns>
/// <exception cref="BusinessValidationFailedException"></exception>
[HttpPut]
public async Task<IResponseOutput> AuditImageBack(Guid iamgeBackRecordId, bool isAgree)
public async Task<IResponseOutput> AuditImageBack(Guid iamgeBackRecordId, bool isAgree,string? resultRemark)
{
var backRecord = (await _subjectVisitImageBackRecordReposiotry.FirstOrDefaultAsync(t => t.Id == iamgeBackRecordId)).IfNullThrowException();
@ -412,7 +414,7 @@ namespace IRaCIS.Core.Application.Image.QA
}
backRecord.AuditTime = DateTime.Now;
backRecord.ResultRemark = resultRemark??string.Empty;
await _subjectVisitRepository.SaveChangesAsync();
return ResponseOutput.Ok();

View File

@ -214,4 +214,14 @@ public class SubjectVisitImageBackRecord : BaseFullAuditEntity
public DateTime? AuditTime { get; set; }
/// <summary>
/// 申请原因
/// </summary>
public string ApplyReason { get; set; } = string.Empty;
/// <summary>
/// 结果备注
/// </summary>
public string ResultRemark { get; set; } = string.Empty;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,42 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace IRaCIS.Core.Infra.EFCore.Migrations
{
/// <inheritdoc />
public partial class ImageBack : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "ApplyReason",
table: "SubjectVisitImageBackRecord",
type: "nvarchar(400)",
maxLength: 400,
nullable: false,
defaultValue: "");
migrationBuilder.AddColumn<string>(
name: "ResultRemark",
table: "SubjectVisitImageBackRecord",
type: "nvarchar(400)",
maxLength: 400,
nullable: false,
defaultValue: "");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ApplyReason",
table: "SubjectVisitImageBackRecord");
migrationBuilder.DropColumn(
name: "ResultRemark",
table: "SubjectVisitImageBackRecord");
}
}
}

View File

@ -9073,6 +9073,11 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<string>("ApplyReason")
.IsRequired()
.HasMaxLength(400)
.HasColumnType("nvarchar(400)");
b.Property<int>("ApplyUserRole")
.HasColumnType("int");
@ -9096,6 +9101,11 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
.HasColumnType("datetime2")
.HasComment("最晚拍片日期");
b.Property<string>("ResultRemark")
.IsRequired()
.HasMaxLength(400)
.HasColumnType("nvarchar(400)");
b.Property<Guid>("SubjectVisitId")
.HasColumnType("uniqueidentifier");