Compare commits

...

7 Commits

Author SHA1 Message Date
he 92fecfa024 Merge branch 'Uat_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Uat_IRC_Net8
continuous-integration/drone/push Build is passing Details
2026-06-29 16:09:36 +08:00
he cea0d7f346 只限制 changeDicomReadingQuestionAnswer 接口 以及微信通知 2026-06-29 16:09:28 +08:00
he c02fe93ad8 任务答案数量验证 2026-06-29 16:09:24 +08:00
he c58b52d1bb Revert "临时去掉锁"
This reverts commit e045302d38.
2026-06-29 16:07:15 +08:00
he 7a2720fd0e 重新发布 2026-06-29 16:07:14 +08:00
he 34f1e9452b 临时去掉锁 2026-06-29 16:07:09 +08:00
he 967438d4da 验证重复请求加锁 2026-06-29 16:06:18 +08:00
6 changed files with 124 additions and 20 deletions

View File

@ -70,6 +70,10 @@ namespace IRaCIS.Core.Application.BusinessFilter.LegacyController
{ {
this.RequestDuplication(); this.RequestDuplication();
} }
catch (BusinessValidationFailedException)
{
throw;
}
catch (Exception) catch (Exception)
{ {
@ -91,6 +95,8 @@ namespace IRaCIS.Core.Application.BusinessFilter.LegacyController
// 验证请求频繁情况 // 验证请求频繁情况
if ( if (
requestPath == "/ReadingImageTask/changeDicomReadingQuestionAnswer"&&
!requestPath !requestPath
.Split("/", StringSplitOptions.RemoveEmptyEntries) .Split("/", StringSplitOptions.RemoveEmptyEntries)
.Any(segment => segment.StartsWith("get", StringComparison.OrdinalIgnoreCase)) && .Any(segment => segment.StartsWith("get", StringComparison.OrdinalIgnoreCase)) &&
@ -106,17 +112,14 @@ namespace IRaCIS.Core.Application.BusinessFilter.LegacyController
RequestTime = DateTime.Now RequestTime = DateTime.Now
}; };
IRCSystemInfo.RequestRecordList= IRCSystemInfo.RequestRecordList.Where(x => x.RequestTime >= DateTime.Now.AddSeconds(-RequestDuplicationOptionsMonitor.CurrentValue.CacheTimeSeconds)).ToList(); var isAdded = IRCSystemInfo.TryAddRequestRecord(
requestInfo,
RequestDuplicationOptionsMonitor.CurrentValue.CacheTimeSeconds,
var requestsTimes = IRCSystemInfo.RequestRecordList.Any(x=> RequestDuplicationOptionsMonitor.CurrentValue.DuplicationWindowMs);
x.RequestTime>= requestInfo.RequestTime.AddMilliseconds(-RequestDuplicationOptionsMonitor.CurrentValue.DuplicationWindowMs)&& if (!isAdded)
x.RequestKey== requestInfo.RequestKey);
if (requestsTimes)
{ {
throw new BusinessValidationFailedException(_localizer["RequestDuplicationFilter_RequestDuplication"], ApiResponseCodeEnum.BusinessValidationFailed); throw new BusinessValidationFailedException(_localizer["RequestDuplicationFilter_RequestDuplication"], ApiResponseCodeEnum.BusinessValidationFailed);
} }
IRCSystemInfo.RequestRecordList.Add(requestInfo);
} }
} }

View File

@ -146,6 +146,31 @@ public class RequestDuplicationOptions
public static class IRCSystemInfo public static class IRCSystemInfo
{ {
public static List<RequestInfo> RequestRecordList { get; set; } = new List<RequestInfo>(); public static List<RequestInfo> RequestRecordList { get; set; } = new List<RequestInfo>();
private static readonly object requestRecordLock = new object();
public static bool TryAddRequestRecord(RequestInfo requestInfo, int cacheTimeSeconds, int duplicationWindowMs)
{
lock (requestRecordLock)
{
var now = DateTime.Now;
RequestRecordList = RequestRecordList
.Where(x => x.RequestTime >= now.AddSeconds(-cacheTimeSeconds))
.ToList();
var isDuplicate = RequestRecordList.Any(x =>
x.RequestTime >= requestInfo.RequestTime.AddMilliseconds(-duplicationWindowMs) &&
x.RequestKey == requestInfo.RequestKey);
if (isDuplicate)
{
return false;
}
RequestRecordList.Add(requestInfo);
return true;
}
}
} }
public class RequestInfo public class RequestInfo
@ -236,4 +261,4 @@ public static class AppSettings
} }
} }

View File

@ -3081,7 +3081,7 @@
SystemAnonymizationService SystemAnonymizationService
</summary> </summary>
</member> </member>
<member name="M:IRaCIS.Core.Application.Service.SystemAnonymizationService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SystemAnonymization},AutoMapper.IMapper,IRaCIS.Core.Domain.Share.IUserInfo,Microsoft.Extensions.Localization.IStringLocalizer)"> <member name="M:IRaCIS.Core.Application.Service.SystemAnonymizationService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SystemAnonymization},AutoMapper.IMapper,IRaCIS.Core.Domain.Share.IUserInfo,Microsoft.Extensions.Localization.IStringLocalizer,ZiggyCreatures.Caching.Fusion.IFusionCache)">
<summary> <summary>
SystemAnonymizationService SystemAnonymizationService
</summary> </summary>
@ -14746,7 +14746,7 @@
<param name="inDto"></param> <param name="inDto"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.VisitTask},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskInstance},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudyFile},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingNoneDicomMark},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingNoneDicomMarkBinding},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.UserLog},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionAnswer},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingOncologyTaskInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Segmentation},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SegmentBinding},IRaCIS.Core.Application.Service.IVisitTaskHelpeService,IRaCIS.Core.Application.Service.IVisitTaskService,IRaCIS.Core.Application.Contracts.IReadingClinicalDataService,IRaCIS.Core.Application.Service.IReadingCalculateService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Subject},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.UserFeedBack},Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.ServiceVerifyConfigOption},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingGlobalTaskInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingCriterionPage},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskRelation},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingJudgeInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadModule},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomInstance},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.OrganInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.OrganTrialInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialDocument},IRaCIS.Core.Application.Service.ReadingCalculate.Interface.ILuganoCalculateService,IRaCIS.Core.Application.Service.ReadingCalculate.Interface.ILuganoWithoutPETCalculateService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskQuestionMark},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTrialCriterionDictionary},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableAnswerRowInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionSystem},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskQuestionAnswer},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionCriterionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionSystem},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CriterionKeyFileRead},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialCriterionKeyFile},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudyFile},IRaCIS.Core.Application.Service.IGeneralCalculateService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskStudy},IRaCIS.Core.Application.Service.ImageAndDoc.IDownloadAndUploadService,IRaCIS.Core.Application.Interfaces.ITrialEmailNoticeConfigService,AutoMapper.IMapper,IRaCIS.Core.Domain.Share.IUserInfo,Microsoft.Extensions.Localization.IStringLocalizer,ZiggyCreatures.Caching.Fusion.IFusionCache)"> <member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.#ctor(IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.VisitTask},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Trial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskInstance},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudyFile},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingNoneDicomMark},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingNoneDicomMarkBinding},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.UserLog},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionAnswer},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingOncologyTaskInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Segmentation},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SegmentBinding},IRaCIS.Core.Application.Service.IVisitTaskHelpeService,IRaCIS.Core.Application.Service.IVisitTaskService,IRaCIS.Core.Application.Contracts.IReadingClinicalDataService,IRaCIS.Core.Application.Service.IReadingCalculateService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.Subject},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.UserFeedBack},Microsoft.Extensions.Options.IOptionsMonitor{IRaCIS.Core.Domain.Share.ServiceVerifyConfigOption},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingGlobalTaskInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingCriterionPage},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskRelation},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingJudgeInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadModule},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomInstance},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.OrganInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.OrganTrialInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialDocument},IRaCIS.Core.Application.Service.ReadingCalculate.Interface.ILuganoCalculateService,IRaCIS.Core.Application.Service.ReadingCalculate.Interface.ILuganoWithoutPETCalculateService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskQuestionMark},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTrialCriterionDictionary},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableAnswerRowInfo},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionSystem},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTableQuestionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingTaskQuestionAnswer},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionCriterionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionSystem},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CriterionKeyFileRead},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TrialCriterionKeyFile},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.NoneDicomStudyFile},IRaCIS.Core.Application.Service.IGeneralCalculateService,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.ReadingQuestionTrial},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.TaskStudy},Microsoft.Extensions.Configuration.IConfiguration,IRaCIS.Core.Application.Service.ImageAndDoc.IDownloadAndUploadService,IRaCIS.Core.Application.Interfaces.ITrialEmailNoticeConfigService,AutoMapper.IMapper,IRaCIS.Core.Domain.Share.IUserInfo,Microsoft.Extensions.Localization.IStringLocalizer,ZiggyCreatures.Caching.Fusion.IFusionCache)">
<summary> <summary>
IR影像阅片 IR影像阅片
</summary> </summary>
@ -15188,7 +15188,14 @@
<param name="visitTaskId"></param> <param name="visitTaskId"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.ComputeJudgeResult(System.Collections.Generic.List{IRaCIS.Core.Application.Service.Reading.Dto.GroupTaskAnswerDto})"> <member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.SendWeComNotifier(System.Guid,System.String)">
<summary>
发送微信通知
</summary>
<param name="visiTaskId"></param>
<returns></returns>
</member>
<member name="M:IRaCIS.Core.Application.Service.ReadingImageTaskService.ComputeJudgeResult(System.Collections.Generic.List{IRaCIS.Core.Application.Service.Reading.Dto.GroupTaskAnswerDto},System.Guid)">
<summary> <summary>
计算返回的结果 为True表示不相等 计算返回的结果 为True表示不相等
</summary> </summary>

View File

@ -5,6 +5,7 @@ using DocumentFormat.OpenXml.Office2019.Excel.ThreadedComments;
using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Helper.OtherTool;
using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.Interfaces;
using IRaCIS.Core.Application.Service.ImageAndDoc; using IRaCIS.Core.Application.Service.ImageAndDoc;
using IRaCIS.Core.Application.Service.OAuth; using IRaCIS.Core.Application.Service.OAuth;
@ -16,6 +17,7 @@ using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure;
using MassTransit; using MassTransit;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Newtonsoft.Json; using Newtonsoft.Json;
@ -80,6 +82,7 @@ namespace IRaCIS.Core.Application.Service
IGeneralCalculateService _generalCalculateService, IGeneralCalculateService _generalCalculateService,
IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository, IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository,
IRepository<TaskStudy> _taskStudyRepository, IRepository<TaskStudy> _taskStudyRepository,
IConfiguration _config,
IDownloadAndUploadService _downloadAndUploadService, IDownloadAndUploadService _downloadAndUploadService,
ITrialEmailNoticeConfigService _trialEmailNoticeConfigService, ITrialEmailNoticeConfigService _trialEmailNoticeConfigService,
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IFusionCache _fusionCache) : BaseService, IReadingImageTaskService IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IFusionCache _fusionCache) : BaseService, IReadingImageTaskService
@ -3363,6 +3366,18 @@ namespace IRaCIS.Core.Application.Service
[HttpPost] [HttpPost]
public async Task<IResponseOutput> VerifyVisitTaskQuestions(VerifyVisitTaskQuestionsInDto inDto) public async Task<IResponseOutput> VerifyVisitTaskQuestions(VerifyVisitTaskQuestionsInDto inDto)
{ {
// 验证一个问题不能有多个答案
bool hasDuplicate = await _readingTaskQuestionAnswerRepository
.Where(x => x.VisitTaskId == inDto.VisitTaskId)
.GroupBy(x => x.ReadingQuestionTrialId)
.AnyAsync(g => g.Count() > 1);
if (hasDuplicate)
{
_ = SendWeComNotifier(inDto.VisitTaskId, "阅片问题答案有重复");
}
//验证后处理影像必须传 //验证后处理影像必须传
if (_visitTaskRepository.Any(t => t.Id == inDto.VisitTaskId && t.TrialReadingCriterion.ImageUploadEnum != ReadingImageUpload.None)) if (_visitTaskRepository.Any(t => t.Id == inDto.VisitTaskId && t.TrialReadingCriterion.ImageUploadEnum != ReadingImageUpload.None))
{ {

View File

@ -1,5 +1,6 @@
using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Helper.OtherTool;
using IRaCIS.Core.Application.Service.Reading.Dto; using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Domain.Share;
@ -7,6 +8,7 @@ using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure;
using MassTransit; using MassTransit;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace IRaCIS.Core.Application.Service namespace IRaCIS.Core.Application.Service
@ -676,7 +678,7 @@ namespace IRaCIS.Core.Application.Service
JudgeDifferenceType = x.Key.JudgeDifferenceType, JudgeDifferenceType = x.Key.JudgeDifferenceType,
TaskAnswerList = x.Select(y => y.Answer).ToList(), TaskAnswerList = x.Select(y => y.Answer).ToList(),
}).ToList(); }).ToList();
noteEqual = noteEqual || ComputeJudgeResult(groupTasks); noteEqual = noteEqual || ComputeJudgeResult(groupTasks, visitTask.Id);
} }
} }
@ -708,7 +710,7 @@ namespace IRaCIS.Core.Application.Service
JudgeDifferenceType = x.Key.JudgeDifferenceType, JudgeDifferenceType = x.Key.JudgeDifferenceType,
TaskAnswerList = x.Select(y => y.Answer).ToList(), TaskAnswerList = x.Select(y => y.Answer).ToList(),
}).ToList(); }).ToList();
noteEqual = ComputeJudgeResult(groupTasks); noteEqual = ComputeJudgeResult(groupTasks, visitTask.Id);
} }
break; break;
@ -757,7 +759,8 @@ namespace IRaCIS.Core.Application.Service
JudgeDifferenceValue = x.Key.JudgeDifferenceValue, JudgeDifferenceValue = x.Key.JudgeDifferenceValue,
JudgeDifferenceType = x.Key.JudgeDifferenceType, JudgeDifferenceType = x.Key.JudgeDifferenceType,
}).ToList(); }).ToList();
noteEqual = noteEqual || ComputeJudgeResult(globalGroupTasks);
noteEqual = noteEqual || ComputeJudgeResult(globalGroupTasks, visitTask.Id);
} }
} }
@ -819,7 +822,8 @@ namespace IRaCIS.Core.Application.Service
JudgeDifferenceType = x.Key.JudgeDifferenceType, JudgeDifferenceType = x.Key.JudgeDifferenceType,
TaskAnswerList = x.Select(y => y.Answer).ToList(), TaskAnswerList = x.Select(y => y.Answer).ToList(),
}).ToList(); }).ToList();
noteEqual = noteEqual || ComputeJudgeResult(globalGroupTasks);
noteEqual = noteEqual || ComputeJudgeResult(globalGroupTasks, visitTask.Id);
} }
@ -922,12 +926,61 @@ namespace IRaCIS.Core.Application.Service
} }
/// <summary>
/// 发送微信通知
/// </summary>
/// <param name="visiTaskId"></param>
/// <returns></returns>
public async Task SendWeComNotifier(Guid visiTaskId,string msg)
{
try
{
bool isOpenWeComNotice = _config.GetValue<bool>("WeComNoticeConfig:IsOpenWeComNotice");
if (isOpenWeComNotice)
{
string webhook = _config["WeComNoticeConfig:WebhookUrl"] ?? string.Empty;
var uri = new Uri(_config["SystemEmailSendConfig:SiteUrl"]);
var baseUrl = uri.GetLeftPart(UriPartial.Authority);
var userList = _config.GetSection("WeComNoticeConfig:APINoticeUserList").Get<string[]>();
var visitTask = await _visitTaskRepository.Where(x => x.Id == visiTaskId).Include(x=>x.Subject).Include(x=>x.SourceSubjectVisit).FirstNotNullAsync();
// 🔔 异步告警(不要阻塞请求)
_ = WeComNotifier.SendAlertAsync(
webhook: webhook,
alert: new WeComAlert
{
Env = baseUrl,
UserName = msg,
Api = "",
Message = $"异常信息:{msg},受试者:{visitTask.Subject.Code},访视:{visitTask.SourceSubjectVisit.VisitName},任务Id:{visiTaskId}",
Stack = string.Empty,
AtUsers = userList ?? []
}
);
}
}
catch (Exception ex)
{
Log.Logger.Error($"MassTransit里发送企业微信出现错误{ex.Message}");
}
}
/// <summary> /// <summary>
/// 计算返回的结果 为True表示不相等 /// 计算返回的结果 为True表示不相等
/// </summary> /// </summary>
/// <param name="groupTasks"></param> /// <param name="groupTasks"></param>
/// <returns></returns> /// <returns></returns>
private bool ComputeJudgeResult(List<GroupTaskAnswerDto> groupTasks) private bool ComputeJudgeResult(List<GroupTaskAnswerDto> groupTasks,Guid visiTaskId)
{ {
var noteEqual = false; var noteEqual = false;
foreach (var item in groupTasks) foreach (var item in groupTasks)
@ -935,12 +988,12 @@ namespace IRaCIS.Core.Application.Service
// 裁判问题可以不必填 // 裁判问题可以不必填
if(item.TaskAnswerList.Count()==0) if(item.TaskAnswerList.Count()==0)
{ {
break; _ = SendWeComNotifier(visiTaskId, "两个阅片任务的答案等于0");
} }
else if (item.TaskAnswerList.Count() != 2) else if (item.TaskAnswerList.Count() != 2)
{ {
noteEqual = true; // 发送微信通知
break; _ = SendWeComNotifier(visiTaskId, "两个阅片任务的答案不等于2");
} }
else if (noteEqual) else if (noteEqual)
{ {

View File

@ -47,6 +47,7 @@ public class UserRole : BaseFullAuditEntity
[Comment("医生生成账号后,会有值")] [Comment("医生生成账号后,会有值")]
public Guid? DoctorId { get; set; } public Guid? DoctorId { get; set; }